首页
社区
课程
招聘
[原创]Angr符号执行练习--XorDDoS某样本字符串解密
发表于: 2025-4-25 20:09 4148

[原创]Angr符号执行练习--XorDDoS某样本字符串解密

scz 活跃值
5
2025-4-25 20:09
4148

☆ 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://7cdK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4k6A6M7Y4g2K6N6r3!0@1j5h3I4Q4x3X3g2U0L8$3@1`./gui/file/0e9e859d22b009e869322a509c11e342
XorDDoS僵尸网络家族的某样本
https://7cdK9s2c8@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}"
    #
    # 返回str
    #
    info    = r2.cmd( cmd )
    #
    # 返回list
    #
    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}"
    #
    # 返回str
    #
    info    = r2.cmd( cmd )
    #
    # 返回list
    #
    info    = json.loads( info )
    for item in info :

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (2)
雪    币: 58782
活跃值: (21875)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
感谢小四的分享!
2025-4-27 17:56
0
雪    币: 1498
活跃值: (2533)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
学习啦 很有用
2天前
0
游客
登录 | 注册 方可回帖
返回