xorddos 样本进程隐藏的小伎俩

进程隐藏

上周由于工作原因接触到xorddos的样本,这个样本在过去一年的时间里非常常见,
变种也很多,拿到的样本比较有趣的是 ps 无法发现进程。

[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却可以清除地看见样本正在努力地干活。

[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处理过的代码如下

int __cdecl encrypt_code(int a1, int a2)
{
  signed int v2; // ecx@2

  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 写个小脚本,简单处理一下。

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。

.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里看看。

.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的地方有下面几处,

第一处

.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

第二处

.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

第三处

.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 的代码

.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

.text:0804857C                 mov     [esp], esi      ; file 
...
.text:0804858B                 mov     [esp+4], eax    ; argv
.text:0804858F                 call    execvp

伪代码为,

execvp(file, &argv);

file 就是arg_0, 需要分析argv, 调出栈图就比较清晰了。

-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 ?

首先是这句

.text:08048529                 mov     esi, [ebp+file]
...
.text:0804852F                 mov     [ebp+argv], 0
...
.text:08048579                 mov     [ebp+argv], esi

执行了这几句代码后,栈图发生了变化

-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 ?

再看这几句代码

.text:08048576                 mov     eax, [ebp+arg_4]
.text:08048579                 mov     [ebp+argv], esi
...
.text:0804857F                 mov     [ebp+var_14], eax

执行了这几句代码后,栈图发生了变化

-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 ?

接下来是这几句代码

.text:08048582                 mov     eax, [ebp+arg_8];eax = pid
.text:08048585                 mov     [ebp+var_10], eax

执行了这几句代码后,栈图发生了变化

-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 的调用的为代码为

LinuxExec_Argv2('木马路径', '伪装命令行', pid);

因此最后调用的execvp的伪代码为

execvp('木马路径', argv);

将进入 main 函数参数个数为3的流程,用IDA重命名后,关键代码为

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]

上面代码的原理大致等同于下面这段代码

#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);
}

编译后执行可以看到效果和运行样本的一样。

➜  ~ 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

其实效果并不好,可以轻易发现踪迹。

➜  ~ ps -e | grep fakeexe
 2605 pts/9    00:00:00 fakeexe

其实有更好的做法,使用 prctl ,至少可以把ps给搞定。

#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);
}

编译执行后可以看到效果。

➜  ~ 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这个样本还值得一提的是,这个样本会不断变化,多态这个词翻译的可能不太准确,
可以参见上面的英文,自行理解。

int __cdecl randmd5(char *filename)
{
  int fd; // eax@1
  int fd_dup; // esi@1
  mode_t v4; // [sp+8h] [bp-20h]@0
  int addr; // [sp+15h] [bp-13h]@1
  int v6; // [sp+19h] [bp-Fh]@1
  __int16 v7; // [sp+1Dh] [bp-Bh]@1
  char v8; // [sp+1Fh] [bp-9h]@1

  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的版本,进化了。


xorddos 样本进程隐藏的小伎俩
https://usmacd.com/cn/xorddos_hide/
作者
henices
发布于
2023年9月6日
许可协议