进程隐藏 上周由于工作原因接触到xorddos的样本,这个样本在过去一年的时间里非常常见, 变种也很多,拿到的样本比较有趣的是 ps 无法发现进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@localhost ~]# ps -ef | grep /usr/bin ... root 4597 4594 0 00:37 ? 00:00:00 gnome-pty-helper root 4598 4594 0 00:37 pts/1 00:00:00 bash oracle 5359 1 0 00:41 ? 00:00:00 ora_smco_orcl oracle 5378 1 0 00:41 ? 00:00:00 ora_w000_orcl oracle 5586 1 0 00:42 ? 00:00:00 ora_j000_orcl oracle 5588 1 0 00:42 ? 00:00:00 ora_j001_orcl root 5666 1 0 00:43 ? 00:00:00 sh root 5669 1 0 00:43 ? 00:00:00 echo "find" root 5672 1 0 00:43 ? 00:00:00 ls -la root 5675 1 0 00:43 ? 00:00:00 bash root 5678 1 0 00:43 ? 00:00:00 gnome-terminal root 5683 1 0 00:43 ? 00:00:00 cd /etc root 5686 1 0 00:43 ? 00:00:00 top root 5689 1 0 00:43 ? 00:00:00 sh root 5692 1 0 00:43 ? 00:00:00 gnome-terminal root 5695 1 0 00:43 ? 00:00:00 ifconfig root 5696 4598 0 00:43 pts/1 00:00:00 ps -ef
而使用lsof却可以清除地看见样本正在努力地干活。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@localhost ~]# lsof +d /usr/bin COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME hidd 1853 root txt REG 3,1 33708 2467454 /usr/bin/hidd ckucbzknt 2014 root txt REG 3,1 610331 2459176 /usr/bin/ckucbzkntb xfs 2143 xfs txt REG 3,1 107460 2468483 /usr/bin/xfs Xorg 3117 root txt REG 3,1 1890596 2466732 /usr/bin/Xorg gnome-ses 4073 root txt REG 3,1 129356 2459482 /usr/bin/gnome-session ssh-agent 4201 root txt REG 3,1 88996 2467513 /usr/bin/ssh-agent dbus-laun 4245 root txt REG 3,1 23796 2471600 /usr/bin/dbus-launch gnome-key 4255 root txt REG 3,1 97396 2473617 /usr/bin/gnome-keyring-daemon metacity 4290 root txt REG 3,1 521080 2464500 /usr/bin/metacity gnome-pan 4296 root txt REG 3,1 540868 2465177 /usr/bin/gnome-panel nautilus 4298 root txt REG 3,1 1348932 2461620 /usr/bin/nautilus gnome-vol 4310 root txt REG 3,1 65240 2464498 /usr/bin/gnome-volume-manager bt-applet 4334 root txt REG 3,1 30452 2464773 /usr/bin/bt-applet nm-applet 4352 root txt REG 3,1 312432 2467723 /usr/bin/nm-applet gnome-pow 4381 root txt REG 3,1 195284 2459473 /usr/bin/gnome-power-manager pam-panel 4383 root txt REG 3,1 39148 2461862 /usr/bin/pam-panel-icon dbus-laun 4473 root txt REG 3,1 23796 2471600 /usr/bin/dbus-launch gnome-scr 4512 root txt REG 3,1 168628 2468487 /usr/bin/gnome-screensaver gnome-ter 4594 root txt REG 3,1 309368 2464648 /usr/bin/gnome-terminal gadcgkcqn 4681 root txt REG 3,1 610331 2460159 /usr/bin/gadcgkcqni gadcgkcqn 4684 root txt REG 3,1 610331 2460159 /usr/bin/gadcgkcqni gadcgkcqn 4687 root txt REG 3,1 610331 2460159 /usr/bin/gadcgkcqni gadcgkcqn 4690 root txt REG 3,1 610331 2460159 /usr/bin/gadcgkcqni gadcgkcqn 4693 root txt REG 3,1 610331 2460159 /usr/bin/gadcgkcqni
阅读汇编代码,分析具体原因,发现xorddos将一些关键信息加密了,F5处理过的代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int __cdecl encrypt_code (int a1, int a2) { signed int v2; if ( a2 > 0 ) { v2 = 0 ; do { *(_BYTE *)(v2 + a1) ^= xorkeys[(((_BYTE)v2 + ((unsigned int )(v2 >> 31 ) >> 28 )) & 0xF ) - ((unsigned int )(v2 >> 31 ) >> 28 )]; ++v2; } while ( v2 != a2 ); } return a1; }
xorkey 为 BB2FA36AAA9541F0
用idapython 写个小脚本,简单处理一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 from idautils import *from idc import *def get_string (addr ): out = "" while True : if Byte(addr) != 0 : out += chr (Byte(addr)) else : break addr += 1 return out def decrypt (data ): xorkey = 'BB2FA36AAA9541F0' length = len (data) o = "" if length > 0 : v2 = 0 while v2 < length: o += chr ( ord (data[v2]) ^ ord (xorkey[((v2 + ((v2 >> 31 ) >> 28 )) & 0xF ) - ( (v2 >> 31 ) >> 28 )]) ) v2 += 1 return o ea = ScreenEA() string = get_string(ea) dec = decrypt(string) print 'Addr: 0x%x, %s' % (ea, dec)MakeComm(ea, dec)
处理后可以看到伪装的命令行信息,daemonname。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 .data:080CBB40 daemonname db '!#Ff3VE.-7',17h,'V[_ 0',0 ; DATA XREF: main+31Eo .data:080CBB40 ; main+4AEo ... .data:080CBB40 ; cat resolv.conf .data:080CBB51 align 4 .data:080CBB54 a12 db '1*2',0 ; sh .data:080CBB58 db 0 .data:080CBB59 db 0 .data:080CBB5A db 0 .data:080CBB5B db 0 .data:080CBB5C db 0 .data:080CBB5D db 0 .data:080CBB5E db 0 .data:080CBB5F db 0 .data:080CBB60 db 0 .data:080CBB61 db 0 .data:080CBB62 db 0 .data:080CBB63 db 0 .data:080CBB64 db 0 .data:080CBB65 db 0 .data:080CBB66 db 0 .data:080CBB67 db 0 .data:080CBB68 db 20h ; bash .data:080CBB69 db 23h ; # .data:080CBB6A db 41h ; A .data:080CBB6B db 2Eh ; . .data:080CBB6C db 41h ; A .data:080CBB6D db 0 .data:080CBB6E db 0 .data:080CBB6F db 0 .data:080CBB70 db 0 .data:080CBB71 db 0 ... .data:080CBBB8 db 2Eh ; . ; ls -la .data:080CBBB9 db 31h ; 1 .data:080CBBBA db 12h .data:080CBBBB db 6Bh ; k .data:080CBBBC db 2Dh ; - .data:080CBBBD db 52h ; R .data:080CBBBE db 36h ; 6 .data:080CBBBF db 0 .data:080CBBC0 db 0 .data:080CBBC1 db 0 .data:080CBBC2 db 0 .data:080CBBC3 db 0 .data:080CBBC4 db 0 .data:080CBBC5 db 0 .data:080CBBC6 db 0 .data:080CBBC7 db 0 .data:080CBBC8 db 0 .data:080CBBC9 db 0 .data:080CBBCA db 0 .data:080CBBCB db 0 .data:080CBBCC db 36h ; 6 ; top .data:080CBBCD db 2Dh ; - .data:080CBBCE db 42h ; B .data:080CBBCF db 46h ; F .data:080CBBD0 db 0 .data:080CBBD1 db 0 .data:080CBBD2 db 0 ...
呵呵,已经看到 top, ls -al 等信息了,查看daemonname 的交叉引用,发现在main函数 中,到main里看看。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 .text:0804AC30 ; int __cdecl main(int argc, const char **argv, const char **envp) .text:0804AC30 public main .text:0804AC30 main proc near ; DATA XREF: _start+17o .... .text:0804AF4E mov ebx, offset daemonname ; "!#Ff3VE.-7\x17V[_ 0" ... .text:0804AFC2 loc_804AFC2: ; CODE XREF: main+3ABj .text:0804AFC2 mov [esp], ebx .text:0804AFC5 add ebx, 14h .text:0804AFC8 mov dword ptr [esp+4], 14h .text:0804AFD0 call encrypt_code .text:0804AFD5 cmp ebx, offset unk_80CBD0C .text:0804AFDB jnz short loc_804AFC2
这段汇编代码,使用了一个循环,调用encrypt_code 对daemonname进行了解密。 后面的代码,用到了daemonname的地方有下面几处,
第一处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .text:0804B29F call getpid .text:0804B2A4 mov dword ptr [esp+8], (offset aDD+3) ; "%d" .text:0804B2AC mov dword ptr [esp+4], 0Ah .text:0804B2B4 mov [esp], esi ;第三形参 pid .text:0804B2B7 mov [esp+0Ch], eax .text:0804B2BB call snprintf .text:0804B2C0 mov dword ptr [esp+4], 17h .text:0804B2C8 mov dword ptr [esp], 0 .text:0804B2CF call randomid .text:0804B2D4 mov [esp+8], esi .text:0804B2D8 mov [esp], edi ;第一形参 要跑的木马 .text:0804B2DB movzx eax, ax .text:0804B2DE lea eax, [eax+eax*4] .text:0804B2E1 lea eax, daemonname[eax*4] ; "!#Ff3VE.-7\x17V[_ 0" .text:0804B2E8 mov [esp+4], eax ; 第二形参 daemonname .text:0804B2EC call LinuxExec_Argv2
第二处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .text:0804B932 lea edx, [ebp+var_1888] .text:0804B938 add ebx, 1 .text:0804B93B mov [esp], edx .text:0804B93E call randmd5 .text:0804B943 mov [ebp+var_22], 0 .text:0804B94A mov [ebp+var_1E], 0 .text:0804B951 mov [ebp+var_1A], 0 .text:0804B957 call getpid .text:0804B95C mov dword ptr [esp+8], (offset aDD+3) ; "%d" .text:0804B964 mov dword ptr [esp+4], 0Ah .text:0804B96C mov [esp], esi .text:0804B96F mov [esp+0Ch], eax .text:0804B973 call snprintf .text:0804B978 mov dword ptr [esp+4], 17h .text:0804B980 mov dword ptr [esp], 0 .text:0804B987 call randomid .text:0804B98C mov [esp+8], esi .text:0804B990 movzx eax, ax .text:0804B993 lea eax, [eax+eax*4] .text:0804B996 lea eax, daemonname[eax*4] ; "!#Ff3VE.-7\x17V[_ 0" .text:0804B99D mov [esp+4], eax .text:0804B9A1 lea eax, [ebp+var_1888] .text:0804B9A7 mov [esp], eax .text:0804B9AA call LinuxExec_Argv2
第三处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .text:0804B9DF lea edx, [ebp+var_1C88] .text:0804B9E5 add ebx, 1 .text:0804B9E8 mov [esp], edx .text:0804B9EB call randmd5 .text:0804B9F0 mov [ebp+var_22], 0 .text:0804B9F7 mov [ebp+var_1E], 0 .text:0804B9FE mov [ebp+var_1A], 0 .text:0804BA04 call getpid .text:0804BA09 mov dword ptr [esp+8], (offset aDD+3) ; "%d" .text:0804BA11 mov dword ptr [esp+4], 0Ah .text:0804BA19 mov [esp], esi .text:0804BA1C mov [esp+0Ch], eax .text:0804BA20 call snprintf .text:0804BA25 mov dword ptr [esp+4], 17h .text:0804BA2D mov dword ptr [esp], 0 .text:0804BA34 call randomid .text:0804BA39 mov [esp+8], esi .text:0804BA3D movzx eax, ax .text:0804BA40 lea eax, [eax+eax*4] .text:0804BA43 lea eax, daemonname[eax*4] ; "!#Ff3VE.-7\x17V[_ 0" .text:0804BA4A mov [esp+4], eax .text:0804BA4E lea eax, [ebp+var_1C88] .text:0804BA54 mov [esp], eax .text:0804BA57 call LinuxExec_Argv2
都是作为LinuxExec_Argv2 参数使用的,接着来看LinuxExec_Argv2 的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 .text:08048520 LinuxExec_Argv2 proc near ; CODE XREF: DelService+B3p .text:08048520 ; DelService+CBlp ... .text:08048520 .text:08048520 argv = dword ptr -18h .text:08048520 var_14 = dword ptr -14h .text:08048520 var_10 = dword ptr -10h .text:08048520 var_C = dword ptr -0Ch .text:08048520 var_8 = dword ptr -8 .text:08048520 var_4 = dword ptr -4 .text:08048520 file = dword ptr 8 .text:08048520 arg_4 = dword ptr 0Ch .text:08048520 arg_8 = dword ptr 10h .text:08048520 .text:08048520 push ebp .text:08048521 mov ebp, esp .text:08048523 sub esp, 28h .text:08048526 mov [ebp+var_4], esi .text:08048529 mov esi, [ebp+file] .text:0804852C mov [ebp+var_8], ebx .text:0804852F mov [ebp+argv], 0 .text:08048536 mov [ebp+var_14], 0 .text:0804853D mov [ebp+var_10], 0 .text:08048544 mov [ebp+var_C], 0 .text:0804854B call doublefork .text:08048550 test eax, eax .text:08048552 jz short ZERO .text:08048554 mov ebx, [ebp+var_8] .text:08048557 mov esi, [ebp+var_4] .text:0804855A mov esp, ebp .text:0804855C pop ebp .text:0804855D retn .text:0804855E ; --------------------------------------------------------------------------- .text:0804855E .text:0804855E ZERO: ; CODE XREF: LinuxExec_Argv2+32j .text:0804855E mov ebx, 3 .text:08048563 .text:08048563 LOOP: ; CODE XREF: LinuxExec_Argv2+54j .text:08048563 mov [esp], ebx ; fd .text:08048566 add ebx, 1 .text:08048569 call close .text:0804856E cmp ebx, 400h ;400h == 1024 .text:08048574 jnz short LOOP .text:08048576 mov eax, [ebp+arg_4] .text:08048579 mov [ebp+argv], esi .text:0804857C mov [esp], esi ; file .text:0804857F mov [ebp+var_14], eax .text:08048582 mov eax, [ebp+arg_8];eax = pid .text:08048585 mov [ebp+var_10], eax .text:08048588 lea eax, [ebp+argv] .text:0804858B mov [esp+4], eax ; argv .text:0804858F call execvp .text:08048594 mov dword ptr [esp], 0 ; status .text:0804859B call exit .text:0804859B LinuxExec_Argv2 endp
LinuxExec_Argv2 有三个参数。最终执行了execvp
1 2 3 4 .text:0804857C mov [esp], esi ; file ... .text:0804858B mov [esp+4], eax ; argv .text:0804858F call execvp
伪代码为,
file 就是arg_0, 需要分析argv, 调出栈图就比较清晰了。
1 2 3 4 5 6 7 8 9 10 11 12 -00000018 argv dd ? ; offset -00000014 var_14 dd ? -00000010 var_10 dd ? -0000000C var_C dd ? -00000008 var_8 dd ? -00000004 var_4 dd ? +00000000 s db 4 dup(?) +00000004 r db 4 dup(?) +00000008 file dd ? ; offset +0000000C arg_4 dd ? +00000010 arg_8 dd ?
首先是这句
1 2 3 4 5 6 .text:08048529 mov esi, [ebp+file] ... .text:0804852F mov [ebp+argv], 0 ... .text:08048579 mov [ebp+argv], esi
执行了这几句代码后,栈图发生了变化
1 2 3 4 5 6 7 8 9 10 11 -00000018 argv arg_0 ; offset -00000014 var_14 dd ? -00000010 var_10 dd ? -0000000C var_C dd ? -00000008 var_8 dd ? -00000004 var_4 dd ? +00000000 s db 4 dup(?) +00000004 r db 4 dup(?) +00000008 file dd ? ; offset +0000000C arg_4 dd ? +00000010 arg_8 dd ?
再看这几句代码
1 2 3 4 .text:08048576 mov eax, [ebp+arg_4] .text:08048579 mov [ebp+argv], esi ... .text:0804857F mov [ebp+var_14], eax
执行了这几句代码后,栈图发生了变化
1 2 3 4 5 6 7 8 9 10 11 -00000018 argv arg_0 ; offset -00000014 var_14 arg_4 -00000010 var_10 dd ? -0000000C var_C dd ? -00000008 var_8 dd ? -00000004 var_4 dd ? +00000000 s db 4 dup(?) +00000004 r db 4 dup(?) +00000008 file dd ? ; offset +0000000C arg_4 dd ? +00000010 arg_8 dd ?
接下来是这几句代码
1 2 .text:08048582 mov eax, [ebp+arg_8];eax = pid .text:08048585 mov [ebp+var_10], eax
执行了这几句代码后,栈图发生了变化
1 2 3 4 5 6 7 8 9 10 11 12 -00000018 argv arg_0 ; offset -00000014 var_14 arg_4 -00000010 var_10 arg_8 -0000000C var_C 0 -00000008 var_8 dd ? -00000004 var_4 dd ? +00000000 s db 4 dup(?) +00000004 r db 4 dup(?) +00000008 file dd ? ; offset +0000000C arg_4 dd ? +00000010 arg_8 dd ? `
main函数中对LinuxExec_Argv2 的调用的为代码为
1 LinuxExec_Argv2('木马路径', '伪装命令行', pid);
因此最后调用的execvp的伪代码为
将进入 main 函数参数个数为3的流程,用IDA重命名后,关键代码为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 text:0804B5D3 PARAM_NUM_3: ; CODE XREF: main+3CDj .text:0804B5D3 lea eax, [ebp+var_18] .text:0804B5D6 mov [esp+4], eax .text:0804B5DA lea eax, [ebp+self_path] .text:0804B5E0 mov [esp], eax .text:0804B5E3 call readfile .text:0804B5E8 mov edx, [ebp+argv_arr] .text:0804B5EE mov ebx, [edx+4] .text:0804B5F1 mov [ebp+self_file_content], eax .text:0804B5F7 mov [esp], ebx .text:0804B5FA call strlen .text:0804B5FF mov [esp+4], ebx .text:0804B603 mov [esp+8], eax .text:0804B607 lea eax, [ebp+fake_cmd] .text:0804B60D mov [esp], eax .text:0804B610 call memmove .text:0804B615 mov dword ptr [esp+0Ch], 0 .text:0804B61D mov dword ptr [esp+8], 0Ah .text:0804B625 mov dword ptr [esp+4], 0 .text:0804B62D mov edx, [ebp+argv_arr] .text:0804B633 mov eax, [edx+8] .text:0804B636 mov [esp], eax .text:0804B639 call __strtol_internal .text:0804B63E mov esi, eax .text:0804B640 mov eax, [ebp+argv_arr] .text:0804B646 mov ebx, [eax] .text:0804B648 mov [esp], ebx .text:0804B64B call strlen .text:0804B650 mov [esp], ebx .text:0804B653 mov dword ptr [esp+4], 0 .text:0804B65B mov [esp+8], eax .text:0804B65F call memset .text:0804B664 mov edx, [ebp+argv_arr] .text:0804B66A mov ebx, [edx+4] .text:0804B66D mov [esp], ebx .text:0804B670 call strlen .text:0804B675 mov [esp], ebx .text:0804B678 mov dword ptr [esp+4], 0 .text:0804B680 mov [esp+8], eax .text:0804B684 call memset .text:0804B689 mov eax, [ebp+argv_arr] .text:0804B68F mov ebx, [eax+8] .text:0804B692 mov [esp], ebx .text:0804B695 call strlen .text:0804B69A mov [esp], ebx .text:0804B69D mov dword ptr [esp+4], 0 .text:0804B6A5 mov [esp+8], eax .text:0804B6A9 call memset .text:0804B6AE lea edx, [ebp+fake_cmd] .text:0804B6B4 mov [esp+4], edx .text:0804B6B8 mov edx, [ebp+argv_arr] .text:0804B6BE mov eax, [edx] .text:0804B6C0 mov [esp], eax .text:0804B6C3 call strcpy .text:0804B6C8 lea eax, [ebp+filename] .text:0804B6CE mov [esp+0Ch], esi .text:0804B6D2 lea esi, [ebp+randstr_10]
上面代码的原理大致等同于下面这段代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main (int argc, char **argv) { char fake_cmd[256 ]; memset (&fake_cmd, 0 , 256 ); char * argv_arr_1 = argv[1 ]; int argv_arr_1_length = strlen (argv[1 ]); memmove(&fake_cmd, argv_arr_1, argv_arr_1_length); long pid_long = strtol(argv[2 ], 0 , 10 ); char * v29 = (char *)*argv; int v30 = strlen (*argv); memset (v29, 0 , v30); char * v31 = argv[1 ]; int v32 = strlen (argv[1 ]); memset (v31, 0 , v32); char * v33 = argv[2 ]; int v34 = strlen (argv[2 ]); memset (v33, 0 , v34); strcpy (*argv, fake_cmd); sleep(300 ); }
编译后执行可以看到效果和运行样本的一样。
1 2 3 4 5 6 7 8 9 10 11 ➜ ~ gcc -o fakeexe exe.c ➜ ~ ./fakeexe "ls -al" 2554 ➜ ~ cat /proc/2605/cmdline ls -al➜ ~ ls -l /proc/2605/exe lrwxrwxrwx. 1 henices henices 0 8月 2 12:01 /proc/2605/exe -> /home/henices/research/xorddos/fakeexe ➜ ~ ps -elf | grep "ls -al" | grep -v grep 0 S henices 2605 25307 0 80 0 - 1043 hrtime 12:01 pts/5 00:00:00 ls -al
其实效果并不好,可以轻易发现踪迹。
1 2 3 ➜ ~ ps -e | grep fakeexe 2605 pts/9 00:00:00 fakeexe
其实有更好的做法,使用 prctl ,至少可以把ps给搞定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/prctl.h> int main (int argc, char **argv) { char fake_cmd[256 ]; memset (&fake_cmd, 0 , 256 ); char * argv_arr_1 = argv[1 ]; int argv_arr_1_length = strlen (argv[1 ]); memmove(&fake_cmd, argv_arr_1, argv_arr_1_length); long pid_long = strtol(argv[2 ], 0 , 10 ); char * v29 = (char *)*argv; int v30 = strlen (*argv); memset (v29, 0 , v30); char * v31 = argv[1 ]; int v32 = strlen (argv[1 ]); memset (v31, 0 , v32); char * v33 = argv[2 ]; int v34 = strlen (argv[2 ]); memset (v33, 0 , v34); strcpy (*argv, fake_cmd); prctl(PR_SET_NAME, "bash" ); sleep(300 ); }
编译执行后可以看到效果。
1 2 3 4 5 6 7 8 ➜ ~ ps -e | grep bash 4858 pts/5 00:00:00 bash ➜ ~ cat /proc/4858/cmdline ls -al➜ ~ lsof -d txt | grep fakeexe bash 4858 henices txt REG 253,2 8816 4588423 /home/henices/research/xorddos/fakeexe
xorddos 的多态 (Polymorphic) xorddos这个样本还值得一提的是,这个样本会不断变化,多态这个词翻译的可能不太准确, 可以参见上面的英文,自行理解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int __cdecl randmd5 (char *filename) { int fd; int fd_dup; mode_t v4; int addr; int v6; __int16 v7; char v8; addr = 0 ; v6 = 0 ; v7 = 0 ; v8 = 0 ; fd = open(filename, 1 , v4); fd_dup = fd; if ( fd > 0 ) { lseek(fd, 0 , SEEK_END); randstr((int )&addr, 10 ); write(fd_dup, &addr, 11u ); close(fd_dup); } return 0 ; }
xorddos 样本多态主要就是用这个函数,每次在文件末尾写上10个字节的随机字符。 这样样本md5和大小都会发生变化,使得一些检测方法失效。
其他 正因为这种隐藏方法并不理想,后面xorddos出现了带rootkit的版本,进化了。