Logo WP

Defcon Quals 没做出来但是也有一点收获的 wp

DEFCON 2025#

Description#

$ export INPUT="____ ___ _______"  # some string goes here
$ "${@#IV}"  ''p''"${@,,}"rintf  %s  "$(  Ax='  '"'"'E'"'"'"V"A"L" "$( ${@,}  P"R"I'"'"''"'"'\NTF %S  '"'"'23- C- TUC | MUS5DM | tupni$ OHCE ;ENOD ;LLUN/VED/> MUS5DM | tupni$ OHCE ;I$ PEELS OD ;)0001 1 QES($ NI I ROF'"'"'  ${*##.}|${@%;}  RE${@}V${*%%O1}  ${@%\`}   )" '$*  &&${@/-_/\{}p$'\162i'${*##E}n${*%%B*}tf  %s  "${Ax~~}"  $@ ;  ${!*}   )"  "$@" | b"a"sh  ${*//c}

Remember the flag format. Please put the output within flag{} before submission.

解释一下这段 shell 命令 "\(\({@#IV}" ''p''"${@,,}"rintf %s "$( Ax=' '"'"'E'"'"'"V"A"L" "$( ${@,} P"R"I'"'"''"'"'\NTF %S '"'"'23- C- TUC | MUS5DM | tupni$ OHCE ;ENOD ;LLUN/VED/> MUS5DM | tupni$ OHCE ;I$ PEELS OD ;)0001 1 QES($ NI I ROF'"'"' ${\){*//c}`

ChatGPT said:#

这段 shell 命令非常复杂,并且混合了许多不常见的语法和变量替换。看起来像是某种混淆或恶意代码,用于隐蔽执行特定的命令。让我逐步解构这个命令:

  1. "${@#IV}""${@,,}"
    • "$@" 是一个特殊变量,表示脚本或函数的所有参数。
    • "${@#IV}" 表示从每个参数中删除以 "IV" 开头的部分。
    • "${@,,}" 表示将所有参数转换为小写字母。
  2. ''p''"${@,,}"rintf %s
    • 看起来是将 printf 命令和某些拼接的参数结合起来,可能是为了输出某些内容。
  3. $( ... )
    • $( ... ) 是命令替换的语法,表示执行括号中的命令并将结果作为该命令的输出。
  4. Ax=' '"'"'E'"'"'"V"A"L"
    • 这部分看起来像是定义了一个变量 Ax,并用一些拼接的方式存储字符串。引号和转义字符的使用让它变得复杂。
  5. $(${@,} P"R"I'"'"''"'"'\NTF %S '"'"'23- C- TUC | MUS5DM
    • 这一部分显然使用了复杂的字符替换和转义来执行某些操作。它像是在构造一个命令字符串,并将其传递给 $( ... ) 执行。
  6. 其他部分
    • 命令中包含了很多类似 &&|$@ 等,表示逻辑操作和命令管道。看起来像是希望通过某种方式组合多个命令进行执行。
  7. b"a"sh ${\*//c}
    • 最后,命令通过 b"a"sh(有可能是 bash 的变种或拼写)来执行一个命令,并传递了一些参数。${*//c} 是变量替换,表示将所有的 c 字符替换为空。

总结:#

这段代码似乎是故意混淆过的,可能用于执行某种隐藏的命令或脚本。它利用了参数替换、变量拼接、命令替换等技巧,目的是让代码更难以理解,可能在安全研究或渗透测试中看到这种代码。

如果这是你正在分析的恶意代码,最好小心处理。

用 zsh 不行,bash 可以

$ echo "${@#IV}"  ''p''"${@,,}"rintf  %s  "$(  Ax='  '"'"'E'"'"'"V"A"L" "$( ${@,}  P"R"I'"'"''"'"'\NTF %S  '"'"'23- C- TUC | MUS5DM | tupni$ OHCE ;ENOD ;LLUN/VED/> MUS5DM | tupni$ OHCE ;I$ PEELS OD ;)0001 1 QES($ NI I ROF'"'"'  ${*##.}|${@%;}  RE${@}V${*%%O1}  ${@%\`}   )" '$*  &&${@/-_/\{}p$'\162i'${*##E}n${*%%B*}tf  %s  "${Ax~~}"  $@ ;  ${!*}   )"  "$@" | b"a"sh  ${*//c}
evalfor i in $(seq 1 1000); do sleep $i; echo $INPUT | md5sum >/dev/null; done; echo $INPUT | md5sum | cut -c -32

稍微格式化一下

for i in $(seq 1 1000);
	do sleep $i; echo $INPUT | md5sum >/dev/null;
done;
echo $INPUT | md5sum | cut -c -32

发现, 没有对 $INPUT 进行包裹,可以尝试注入

关键的是,最后有一个 bash,是把 INPUT 中的所有 c 删掉然后执行,这有什么特征呢?

 

nfuncs1#

Article Image

Article Image

无法在正常系统中运行,但是在 wine 中可以跑。尝试使用 winedbg

使用指令 info proc mappings 可以查看进程分布,发现 nfuncs.exe 执行了一个 conhost.exe,看起来是启动的控制台

Article Image

请求输入的时候,暂停,然后 info thread

Article Image

然后 thread 0x1e0

info share

Article Image

看栈 info stack

Article Image

00000001a71b1018

这里什么都不是

Article Image

经查看,0x14000173c 根本不是代码,是一段乱码,0x140001510 是一个 call

   140001510:   e8 b9 7a b7 14          call   0x154b78fce

或许需要断点 1510 或者 173c 才能知晓一切了

不行,segfault 了,莫名其妙。

不过尝试断点 b puts ,确实断点到了,不过不好 dump 内存。上 winedbg --gdb

dump memory memdump.bin 0x0000000140001000  0x0000000208c42ef8

太大了,dump 不出来,dump 部分试试

dump memory memdump.bin 0x0000000140001000 0x0140201000

然后用 ida 定位到上面的0x140001510,再手动 C 一下,就可以看到一些东西了

Article Image

然后上一个函数,是对这一个函数的解密

Article Image

再看到 0x140001510 函数,v18 看样子是个 char[8],可以 Y 一下,然后 v16 看下来,和本函数的参数没有什么关系,可以调试获取,再就是 v8 这个应该是个加密函数,也可以通过 gdb dump 整一下

pwndbg> x/i 0x140001733
   0x140001733: mov    rbx,QWORD PTR [rip+0x6707bbf6]        # 0x1a707d330 就是上面的 v8
pwndbg> dump memory memdump_enc.bin 0x1a707d330 0x1a717d330

但是发现 dump 下来的东西,代码不正常,可能又被 smc 回去了。那还是断点一下吧

b *0x140001733

但是没法断点,因为这时候还没 SMC 呢,int 3 没法下,下了又会导致其他的错误了。

往上一步,在 SMC 之前就 b 了

b *0x140001480

好,成功断点,再断点一个解密结束,另外,这里最后面调用了一个函数,进去就卡住请求输入了,所以要在之前断点

b *0x1400014F4

最后再断 1733 b *0x140001733

Article Image

好吧, 这就是个 read,那 v8 就是 read,再dump出v16,就能解密出来 v18

box = [0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
       0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,
       0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,
       0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,
       0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,
       0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,
       0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,
       0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,
       0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,
       0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,
       0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,
       0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
       0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
       0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,
       0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x84,
       0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,
       0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,
       0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,
       0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa3,0xa4,
       0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
       0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,
       0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
       0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,
       0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,
       0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,
       0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,
       0xdd,0xde,0xdf,0xe0,0xe1,0xe2,0xe3,0xe4,
       0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,
       0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,
       0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,
       0xfd,0xfe,0xff,0x00,0x01,0x02,0x03,0x04,
       0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
 ]

enc = [0x96, 0x5D, 0x5B,0x54,0x1A,0x17,0x27,0x17]

res = []
for i in range(len(enc)):
    for j in range(256):
        if enc[i] == box[j]:
            res.append(j)
            break

print(res)

解密出来是个 PNG 头!

> cat 1.png | wine nfuncs.exe
:)
:)
:(

通过验证之后的下一个解密,估计就是下一个 SMC 了,不过这里的密钥是输入,那就得现场设置数据了。

不过有经验了,可以直接 b _read

tb _read
c
fin
tb *0x1400017CF
c
set {unsigned char[8]}($rsp+0x148) =  { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}
tb *0x140001936
c

然后慢慢 si 下去 同样的,dump 出来,注意基址是 0x14000f000

# 下一步
tb *0x14000F09c
set {unsigned char[8]}($rsp+0x38) = {0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52}
tb *0x14000F1B6
c

下一个函数是 0x140021280

又是一个类似的函数,每次检查8个字节😂,看来手搓是不可能的了。不过还要上课,先润了~