☆ XorDDoS某样本
参看
有VirusTotal企业账号的,可下载该ELF样本,也可尝试从微步在线下载。
用IDA32反汇编,样本没有strip,留有调试符号。
样本含有一些加密字符串,dec_conf()用于解密字符串。
dst用于保存解密结果,src是固化在.rodata中的加密数据,size对应src的长度。dec_conf()实际调用encrypt_code()完成解密。
encrypt_code()并不复杂,就是简单异或,xorkeys内置在ELF中,固定。但我们假设encrypt_code()很复杂,比如被控制流平坦化过,不想静态分析其逻辑,准备用angr模拟调用dec_conf()或encrypt_code(),黑盒调用,只关心in/out。
样本不只调用dec_conf()解密字符串,也会直接调用encrypt_code()解密字符串。下面是几处直接调用encrypt_code()解密字符串的地方:
还有其他调用encrypt_code()解密字符串的地方,但那些地方都是动态提供输入,不是固定串,此处略过。
☆ 用r2pipe模块静态分析
关于r2pipe模块,参看
1) 获取函数入口/出口地址
将来angr模拟调用dec_conf(),至少有两种方案。一种需要知道函数入口/出口地址,另一种只需知道函数入口地址。
假设已打开r2句柄,此处简化处理,假设ret是最后一条指令。
2) 获取到指定函数的交叉引用
样本调用dec_conf()的模式是固定的,只要找到"call dec_conf"指令所在地址,可从附近的汇编指令析取dec_conf()的参数,比如加密字符串的地址、长度。通过交叉引用找出所有"call dec_conf"指令所在地址。
3) 析取dec_conf()的参数
此实现只针对调用dec_conf()的情形,意思是,从"call dec_conf"向低址方向移动四条指令,反汇编这四条指令,分别析取第二条、第一条指令的立即数。
假设处理上述代码片段,get_call_params()将返回(0x80b2fb1,0xb),此即一条加密字符串,分别是地址、长度。
4) static_analyses()
将前面的小模块整合到一起,完成r2pipe静态分析
用r2分析样本,比用angr的CFGFast分析样本快得多。
☆ 用angr模拟调用dec_conf()
参看
angr至少有两种模拟调用dec_conf()的办法,分别是call_state、callable。前者控制粒度更细,比如执行到函数中部某个位置便停止模拟;后者使用起来更简洁。
1) proj.factory.call_state
sm.explore()的find参数可位于函数中部某个位置,不一定是ret指令所在地址。
2) proj.factory.callable
用callable时,无需知道函数出口地址。
☆ r2pipe+angr
将前面的小模块整合到一起
正常的话,应该输出
☆ 用angr模拟调用encrypt_code()
☆ 后记
据小宋说,XorDDoS家族现仍在活跃,但流行变种已将原始版本的rootkit部分移除。
本文目的并非分析XorDDoS样本,仅视之为Angr符号执行的练习目标,毕竟是现实世界逆向工程真实案例,而非CTF案例。
本文学习目的是黑盒式模拟调用关键函数,尝试获取函数结果。
方便测试,附件是样本,infected
创建: 2025-04-24 22:26
更新: 2025-04-25 19:04
目录:
☆ XorDDoS某样本
☆ 用r2pipe模块静态分析
1) 获取函数入口/出口地址
2) 获取到指定函数的交叉引用
3) 析取dec_conf()的参数
4) static_analyses()
☆ 用angr模拟调用dec_conf()
1) proj.factory.call_state
2) proj.factory.callable
☆ r2pipe+angr
☆ 用angr模拟调用encrypt_code()
☆ 后记
创建: 2025-04-24 22:26
更新: 2025-04-25 19:04
目录:
☆ XorDDoS某样本
☆ 用r2pipe模块静态分析
1) 获取函数入口/出口地址
2) 获取到指定函数的交叉引用
3) 析取dec_conf()的参数
4) static_analyses()
☆ 用angr模拟调用dec_conf()
1) proj.factory.call_state
2) proj.factory.callable
☆ r2pipe+angr
☆ 用angr模拟调用encrypt_code()
☆ 后记
XorDDoS僵尸网络家族的某样本
https://11dK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4k6A6M7Y4g2K6N6r3!0@1j5h3I4Q4x3X3g2U0L8$3@1`./gui/file/0e9e859d22b009e869322a509c11e342
XorDDoS僵尸网络家族的某样本
https://a70K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4k6A6M7Y4g2K6N6r3!0@1j5h3I4Q4x3X3g2U0L8$3@1`./gui/file/0e9e859d22b009e869322a509c11e342
$ file -b 0e9e859d22b009e869322a509c11e342
ELF 32-bit LSB executable, Intel 80386, ..., statically linked, ..., not stripped
$ file -b 0e9e859d22b009e869322a509c11e342
ELF 32-bit LSB executable, Intel 80386, ..., statically linked, ..., not stripped
0804CFA3 C7 44 24 08 0B 00 00 00 mov dword ptr [esp+8], 0Bh
0804CFAB C7 44 24 04 B1 2F 0B 08 mov dword ptr [esp+4], offset aM7a4nqNa_0 ; "m7A4nQ_/nA"
0804CFB3 8D 85 B3 EA FF FF lea eax, [ebp+var_154D]
0804CFB9 89 04 24 mov [esp], eax
0804CFBC E8 67 B2 FF FF call dec_conf
0804CFC1 C7 44 24 08 07 00 00 00 mov dword ptr [esp+8], 7
0804CFC9 C7 44 24 04 BC 2F 0B 08 mov dword ptr [esp+4], offset aMN3_0 ; "m [(n3"
0804CFD1 8D 85 B3 E9 FF FF lea eax, [ebp+var_164D]
0804CFD7 89 04 24 mov [esp], eax
0804CFDA E8 49 B2 FF FF call dec_conf
0804CFA3 C7 44 24 08 0B 00 00 00 mov dword ptr [esp+8], 0Bh
0804CFAB C7 44 24 04 B1 2F 0B 08 mov dword ptr [esp+4], offset aM7a4nqNa_0 ; "m7A4nQ_/nA"
0804CFB3 8D 85 B3 EA FF FF lea eax, [ebp+var_154D]
0804CFB9 89 04 24 mov [esp], eax
0804CFBC E8 67 B2 FF FF call dec_conf
0804CFC1 C7 44 24 08 07 00 00 00 mov dword ptr [esp+8], 7
0804CFC9 C7 44 24 04 BC 2F 0B 08 mov dword ptr [esp+4], offset aMN3_0 ; "m [(n3"
0804CFD1 8D 85 B3 E9 FF FF lea eax, [ebp+var_164D]
0804CFD7 89 04 24 mov [esp], eax
0804CFDA E8 49 B2 FF FF call dec_conf
dec_conf(v23, "m7A4nQ_/nA", 11);
dec_conf(v22, "m [(n3", 7);
dec_conf(v21, "m6_6n3", 7);
dec_conf(v19, aM4s4nacNZv, 18);
dec_conf(v18, aMN4C, 17);
dec_conf(v17, "m.[$n3", 7);
dec_conf(v16, a6f6, 512);
dec_conf(v20, "m4S4nAC/nA", 11);
dec_conf(v23, "m7A4nQ_/nA", 11);
dec_conf(v22, "m [(n3", 7);
dec_conf(v21, "m6_6n3", 7);
dec_conf(v19, aM4s4nacNZv, 18);
dec_conf(v18, aMN4C, 17);
dec_conf(v17, "m.[$n3", 7);
dec_conf(v16, a6f6, 512);
dec_conf(v20, "m4S4nAC/nA", 11);
08048228 dec_conf proc
08048228 55 push ebp
08048229 89 E5 mov ebp, esp
0804822B 83 EC 18 sub esp, 18h
0804822E 8B 45 10 mov eax, [ebp+arg_8]
08048231 89 44 24 08 mov [esp+8], eax
08048235 8B 45 0C mov eax, [ebp+arg_4]
08048238 89 44 24 04 mov [esp+4], eax
0804823C 8B 45 08 mov eax, [ebp+arg_0]
0804823F 89 04 24 mov [esp], eax
08048242 E8 09 E6 01 00 call memmove
08048247 8B 45 10 mov eax, [ebp+arg_8]
0804824A 89 44 24 04 mov [esp+4], eax
0804824E 8B 45 08 mov eax, [ebp+arg_0]
08048251 89 04 24 mov [esp], eax
08048254 E8 9B 11 00 00 call encrypt_code
08048259 B8 00 00 00 00 mov eax, 0
0804825E C9 leave
0804825F C3 retn
0804825F dec_conf endp
08048228 dec_conf proc
08048228 55 push ebp
08048229 89 E5 mov ebp, esp
0804822B 83 EC 18 sub esp, 18h
0804822E 8B 45 10 mov eax, [ebp+arg_8]
08048231 89 44 24 08 mov [esp+8], eax
08048235 8B 45 0C mov eax, [ebp+arg_4]
08048238 89 44 24 04 mov [esp+4], eax
0804823C 8B 45 08 mov eax, [ebp+arg_0]
0804823F 89 04 24 mov [esp], eax
08048242 E8 09 E6 01 00 call memmove
08048247 8B 45 10 mov eax, [ebp+arg_8]
0804824A 89 44 24 04 mov [esp+4], eax
0804824E 8B 45 08 mov eax, [ebp+arg_0]
08048251 89 04 24 mov [esp], eax
08048254 E8 9B 11 00 00 call encrypt_code
08048259 B8 00 00 00 00 mov eax, 0
0804825E C9 leave
0804825F C3 retn
0804825F dec_conf endp
int dec_conf(char *dst, char *src, int size )
{
memmove( dst, src, size );
/*
* 就地修改dst,而非返回什么
*/
encrypt_code( dst, size );
return 0;
}
int dec_conf(char *dst, char *src, int size )
{
memmove( dst, src, size );
/*
* 就地修改dst,而非返回什么
*/
encrypt_code( dst, size );
return 0;
}
/*
* 就地修改buf
*/
char *__cdecl encrypt_code(char *buf, int size)
{
char *p;
int i;
p = buf;
for ( i = 0; i < size; ++i )
*p++ ^= xorkeys[i % 16];
return buf;
}
/*
* 就地修改buf
*/
char *__cdecl encrypt_code(char *buf, int size)
{
char *p;
int i;
p = buf;
for ( i = 0; i < size; ++i )
*p++ ^= xorkeys[i % 16];
return buf;
}
080CF3E8 42 42 32 46 41 33 36 41…xorkeys db 'BB2FA36AAA9541F0'
080CF3E8 42 42 32 46 41 33 36 41…xorkeys db 'BB2FA36AAA9541F0'
08048C08 C7 44 24 08 0A 00 00 00 mov dword ptr [esp+8], 0Ah
08048C10 C7 44 24 04 07 2D 0B 08 mov dword ptr [esp+4], offset aM7a4nqNa ; "m7A4nQ_/nA"
08048C18 8D 85 F1 FA FF FF lea eax, [ebp+var_50F]
08048C1E 89 04 24 mov [esp], eax
08048C21 E8 2A DC 01 00 call memmove
08048C26 C7 44 24 04 0A 00 00 00 mov dword ptr [esp+4], 0Ah ; int
08048C2E 8D 85 F1 FA FF FF lea eax, [ebp+var_50F]
08048C34 89 04 24 mov [esp], eax ; char *
08048C37 E8 B8 07 00 00 call encrypt_code
08048C08 C7 44 24 08 0A 00 00 00 mov dword ptr [esp+8], 0Ah
08048C10 C7 44 24 04 07 2D 0B 08 mov dword ptr [esp+4], offset aM7a4nqNa ; "m7A4nQ_/nA"
08048C18 8D 85 F1 FA FF FF lea eax, [ebp+var_50F]
08048C1E 89 04 24 mov [esp], eax
08048C21 E8 2A DC 01 00 call memmove
08048C26 C7 44 24 04 0A 00 00 00 mov dword ptr [esp+4], 0Ah ; int
08048C2E 8D 85 F1 FA FF FF lea eax, [ebp+var_50F]
08048C34 89 04 24 mov [esp], eax ; char *
08048C37 E8 B8 07 00 00 call encrypt_code
0804F12F C7 44 24 08 00 02 00 00 mov dword ptr [esp+8], 200h
0804F137 C7 44 24 04 4C 32 0B 08 mov dword ptr [esp+4], offset unk_80B324C
0804F13F C7 04 24 C0 1C 0D 08 mov dword ptr [esp], offset remotestr
0804F146 E8 05 77 01 00 call memmove
0804F14B C7 44 24 04 00 02 00 00 mov dword ptr [esp+4], 200h ; int
0804F153 C7 04 24 C0 1C 0D 08 mov dword ptr [esp], offset remotestr ; char *
0804F15A E8 95 A2 FF FF call encrypt_code
0804F12F C7 44 24 08 00 02 00 00 mov dword ptr [esp+8], 200h
0804F137 C7 44 24 04 4C 32 0B 08 mov dword ptr [esp+4], offset unk_80B324C
0804F13F C7 04 24 C0 1C 0D 08 mov dword ptr [esp], offset remotestr
0804F146 E8 05 77 01 00 call memmove
0804F14B C7 44 24 04 00 02 00 00 mov dword ptr [esp+4], 200h ; int
0804F153 C7 04 24 C0 1C 0D 08 mov dword ptr [esp], offset remotestr ; char *
0804F15A E8 95 A2 FF FF call encrypt_code
memmove(remotestr, &unk_80B324C, 512);
encrypt_code(remotestr, 512);
memmove(remotestr, &unk_80B324C, 512);
encrypt_code(remotestr, 512);
0804D093 C7 45 CC 00 00 00 00 mov [ebp+var_34], 0
0804D09A EB 26 jmp short loc_804D0C2
0804D09C
0804D09C loc_804D09C:
0804D09C 8B 55 CC mov edx, [ebp+var_34]
0804D09F 89 D0 mov eax, edx
0804D0A1 C1 E0 02 shl eax, 2
0804D0A4 01 D0 add eax, edx
0804D0A6 C1 E0 02 shl eax, 2
/*
* daemonname位于.data,而非.rodata
*/
0804D0A9 05 20 F1 0C 08 add eax, offset daemonname ; "!#Ff3VE.-7"
0804D0AE C7 44 24 04 14 00 00 00 mov dword ptr [esp+4], 14h ; int
0804D0B6 89 04 24 mov [esp], eax ; char *
0804D0B9 E8 36 C3 FF FF call encrypt_code
0804D0BE 83 45 CC 01 add [ebp+var_34], 1
0804D0C2
0804D0C2 loc_804D0C2:
0804D0C2 83 7D CC 16 cmp [ebp+var_34], 16h
0804D0C6 76 D4 jbe short loc_804D09C
0804D093 C7 45 CC 00 00 00 00 mov [ebp+var_34], 0
0804D09A EB 26 jmp short loc_804D0C2
0804D09C
0804D09C loc_804D09C:
0804D09C 8B 55 CC mov edx, [ebp+var_34]
0804D09F 89 D0 mov eax, edx
0804D0A1 C1 E0 02 shl eax, 2
0804D0A4 01 D0 add eax, edx
0804D0A6 C1 E0 02 shl eax, 2
/*
* daemonname位于.data,而非.rodata
*/
0804D0A9 05 20 F1 0C 08 add eax, offset daemonname ; "!#Ff3VE.-7"
0804D0AE C7 44 24 04 14 00 00 00 mov dword ptr [esp+4], 14h ; int
0804D0B6 89 04 24 mov [esp], eax ; char *
0804D0B9 E8 36 C3 FF FF call encrypt_code
0804D0BE 83 45 CC 01 add [ebp+var_34], 1
0804D0C2
0804D0C2 loc_804D0C2:
0804D0C2 83 7D CC 16 cmp [ebp+var_34], 16h
0804D0C6 76 D4 jbe short loc_804D09C
for ( i = 0; i <= 22; ++i )
encrypt_code(&daemonname[20 * i], 20);
for ( i = 0; i <= 22; ++i )
encrypt_code(&daemonname[20 * i], 20);
《Angr符号执行练习--SecuInside 2016 mbrainfuzz》
https://scz.617.cn/unix/202503311347.txt
《Angr符号执行练习--SecuInside 2016 mbrainfuzz》
https://scz.617.cn/unix/202503311347.txt
def get_func_info ( r2, func ) :
cmd = f"afij sym.{func}"
info = r2.cmd( cmd )
info = json.loads( info )
info = info[0]
func_entry = info['offset']
func_exit = info['offset'] + info['size'] - 1
return ( func_entry, func_exit )
def get_func_info ( r2, func ) :
cmd = f"afij sym.{func}"
info = r2.cmd( cmd )
info = json.loads( info )
info = info[0]
func_entry = info['offset']
func_exit = info['offset'] + info['size'] - 1
return ( func_entry, func_exit )
def find_xrefs_to_func ( r2, func ) :
xrefs = []
cmd = f"axtj sym.{func}"
info = r2.cmd( cmd )
info = json.loads( info )
for item in info :
xrefs.append( item['from'] )
return xrefs
def find_xrefs_to_func ( r2, func ) :
xrefs = []
cmd = f"axtj sym.{func}"
info = r2.cmd( cmd )
info = json.loads( info )
for item in info :
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!