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 命令非常复杂,并且混合了许多不常见的语法和变量替换。看起来像是某种混淆或恶意代码,用于隐蔽执行特定的命令。让我逐步解构这个命令:
"${@#IV}"
和"${@,,}"
:
"$@"
是一个特殊变量,表示脚本或函数的所有参数。"${@#IV}"
表示从每个参数中删除以 "IV" 开头的部分。"${@,,}"
表示将所有参数转换为小写字母。''p''"${@,,}"rintf %s
:
- 看起来是将
printf
命令和某些拼接的参数结合起来,可能是为了输出某些内容。$( ... )
:
$( ... )
是命令替换的语法,表示执行括号中的命令并将结果作为该命令的输出。Ax=' '"'"'E'"'"'"V"A"L"
:
- 这部分看起来像是定义了一个变量
Ax
,并用一些拼接的方式存储字符串。引号和转义字符的使用让它变得复杂。$(${@,} P"R"I'"'"''"'"'\NTF %S '"'"'23- C- TUC | MUS5DM
:
- 这一部分显然使用了复杂的字符替换和转义来执行某些操作。它像是在构造一个命令字符串,并将其传递给
$( ... )
执行。- 其他部分:
- 命令中包含了很多类似
&&
、|
、$@
等,表示逻辑操作和命令管道。看起来像是希望通过某种方式组合多个命令进行执行。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#
无法在正常系统中运行,但是在 wine 中可以跑。尝试使用 winedbg
使用指令 info proc mappings
可以查看进程分布,发现 nfuncs.exe 执行了一个 conhost.exe,看起来是启动的控制台
请求输入的时候,暂停,然后 info thread
然后 thread 0x1e0
info share
看栈 info stack
00000001a71b1018
这里什么都不是
经查看,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 一下,就可以看到一些东西了
然后上一个函数,是对这一个函数的解密
再看到 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
好吧, 这就是个 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个字节😂,看来手搓是不可能的了。不过还要上课,先润了~