水曜日, 3月 20, 2013

DarkLeech Apache Moduleマルウェアのリバースエンジニアリング調査 (#OCJP-098について)

本件の内容はDarkLeech Apache Moduleに感染された事件(#OCJP-098)の続き調査となります。
今回のメインは発見したRogue Apache Moduleマルウェアのリバースエンジニアリングの内容になります。
今後サーバ側からの対策が出来るように、マルウェアの形、動き方、とその他詳細な情報を洗い出したほうがいいと考えております。

《マルウェア発見調査》


数時間前日本国内にある感染されたサーバで調査を行いました。Apacheのaccess_logにあやしい項目を発見しました、grepの結果↓
# grep "q.php" *
access_log.processed.4:xxx.xxx.xxx.xxx - - [12/Mar/2013:19:16:39 +0900] "GET /c47eba283f292f2ee6e2047328b55d7e/q.php?kwi=onl&suzmos=uzrrqxk HTTP/1.1" 404 8884 "-" "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_07"
access_log.processed.4:xxx.xxx.xxx.xxx - - [12/Mar/2013:19:16:39 +0900] "GET /c47eba283f292f2ee6e2047328b55d7e/q.php?kwi=onl&suzmos=uzrrqxk HTTP/1.1" 404 8884 "-" "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_07"
access_log.processed.8:xxx.xxx.xxx.xxx - - [08/Mar/2013:19:31:05 +0900] "GET /c47eba283f292f2ee6e2047328b55d7e/q.php?owlhh=kwfyos&nubobo=jyaxej HTTP/1.1" 404 8804 "-" "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_07"
access_log.processed.8:xxx.xxx.xxx.xxx - - [08/Mar/2013:19:31:05 +0900] "GET /c47eba283f292f2ee6e2047328b55d7e/q.php?owlhh=kwfyos&nubobo=jyaxej HTTP/1.1" 404 8884 "-" "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_07"
access_log.processed.8:xxx.xxx.xxx.xxx - - [08/Mar/2013:19:31:16 +0900] "GET /c47eba283f292f2ee6e2047328b55d7e/q.php?owlhh=kwfyos&nubobo=jyaxej HTTP/1.1" 404 8804 "-" "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_07"
access_log.processed.8:xxx.xxx.xxx.xxx - - [08/Mar/2013:19:31:16 +0900] "GET /c47eba283f292f2ee6e2047328b55d7e/q.php?owlhh=kwfyos&nubobo=jyaxej HTTP/1.1" 404 8884 "-" "Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_07"
↑このログの意味は2013年3月8日と12日にあるUA(User Agent)IEブラウザからアクセスが来て「xxx.xxx.xxx.xxx」にあるBlackhole Exploit Kit 2.xマルウェア感染サーバに転送されたが、URLが見つからず404の回答が出ました。
似たようなログが出たら間違いなくマルウェアに感染されたと思われます。

続いて、サーバの中に調査した上でRogue Apache Moduleのファイルが発見されました。
見つけた場所はやはりApacheのconfダイレクトリの周りで、confファイルの中にRogue Apache Moduleをロードするような項目を発見されました↓
$ cat ../etc/../mailman.conf| grep "mod_sec2"
LoadModule sec2_config_module modules/mod_sec2_config.so
(詳細なパスを隠しましたので、ご了承をお願いします)

Rogue Apache Moduleのパスの流れに行くと、下記のファイルを発見されました↓
$ ls -alF "./mod_sec2_config.so"
-rwxr--r--  1 xxx xxx  37296 Jun 26  2007 ./mod_sec2_config.so*
ハッシュ↓
$ md5 mod_sec2_config.so
MD5 (mod_sec2_config.so) = "81c1d493c7764f6692c30de8923c76ba"

【コメント】
これは本件の事件に感染されたDarkleechのRogue Apache Moduleマルウェアサンプルの一つです。
他の感染されたサーバにもバラバラのファイル名で書いてあると思いますが、上記と似たような検索をして下さい。
日付けはニセ日付けになり、ファイルが普通のコピー仕方ではなく、アーカイブファイルからextractしたっぽくてインストーラーがあるかもしれません。

【重要】
もう一つ重要な情報ですが、いくつかやられたサーバにはroot権限迄に取られてしまいましたので、ハッキングされた時期の/var/log/messagesのデータが消された状況が多いです。マルウェアモジュールが動くサーバは信用が出来ないと思っています。


モジュールファイルの名前可能性は↓
mod_sec2_config.so
mod_pool_log.so
mod_chart_proxy.so
mod_balance_alias.so
    :

↑この名前のフォーマットを使いconfのダイレクトリーにgrepをすれば出れますね。

検索のregexは↓
mod\_[a-z0-9]{3,}\_[a-z0-9]{3,}\.so

《バイナリ詳細情報調査》


ファイル自体はELFのi386ですね↓
file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00003050
HEXで見ると↓
0000   7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00    .ELF............
0010   03 00 03 00 01 00 00 00 50 30 00 00 34 00 00 00    ........P0..4...
0020   A0 8D 00 00 00 00 00 00 34 00 20 00 05 00 28 00    ........4. ...(.
0030   1A 00 19 00 01 00 00 00 00 00 00 00 00 00 00 00    ................
0040   00 00 00 00 F0 77 00 00 F0 77 00 00 05 00 00 00    .....w...w......
0050   00 10 00 00 01 00 00 00 00 80 00 00 00 80 00 00    ................
0060   00 80 00 00 F0 0B 00 00 84 0D 00 00 06 00 00 00    ................
0070   00 10 00 00 02 00 00 00 18 80 00 00 18 80 00 00    ................
0080   18 80 00 00 D0 00 00 00 D0 00 00 00 06 00 00 00    ................
0090   04 00 00 00 50 E5 74 64 C0 70 00 00 C0 70 00 00    ....P.td.p...p..
00A0   C0 70 00 00 7C 01 00 00 7C 01 00 00 04 00 00 00    .p..|...|.......
00B0   04 00 00 00 51 E5 74 64 00 00 00 00 00 00 00 00    ....Q.td........
 :                                :                            :
バイナリーのヘッタ(Header)↓
LOAD off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
         filesz 0x000077f0 memsz 0x000077f0 flags r-x
    LOAD off    0x00008000 vaddr 0x00008000 paddr 0x00008000 align 2**12
         filesz 0x00000bf0 memsz 0x00000d84 flags rw-
 DYNAMIC off    0x00008018 vaddr 0x00008018 paddr 0x00008018 align 2**2
         filesz 0x000000d0 memsz 0x000000d0 flags rw-
EH_FRAME off    0x000070c0 vaddr 0x000070c0 paddr 0x000070c0 align 2**2
         filesz 0x0000017c memsz 0x0000017c flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rw-
ダイナミックセクション(Dynamic Section)
NEEDED      libm.so.6
  NEEDED      libc.so.6
  SONAME      mod_sec2_config.so
  INIT        0x29f8
  FINI        0x6f74
  HASH        0xd4
  STRTAB      0x16ec
  SYMTAB      0x7bc
  STRSZ       0x964
  SYMENT      0x10
  PLTGOT      0x82cc
  PLTRELSZ    0x318
  PLTREL      0x11
  JMPREL      0x26e0
  REL         0x22c8
  RELSZ       0x418
  RELENT      0x8
  VERNEED     0x2238
  VERNEEDNUM  0x2
  VERSYM      0x2050
  RELCOUNT    0x9
バーション・リファレンス(Version Reference)↓
required from libm.so.6:
    0x0d696910 0x00 08 GLIBC_2.0
  required from libc.so.6:
    0x09691f73 0x00 07 GLIBC_2.1.3
    0x0d696911 0x00 06 GLIBC_2.1
    0x0d696914 0x00 05 GLIBC_2.4
    0x09691974 0x00 04 GLIBC_2.3.4
    0x0d696913 0x00 03 GLIBC_2.3
    0x0d696910 0x00 02 GLIBC_2.0 
セクション詳細情報(Section Details)
Idx Name          Size      VMA       LMA       File off  Algn
  0 .hash         000006e8  000000d4  000000d4  000000d4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .dynsym       00000f30  000007bc  000007bc  000007bc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynstr       00000964  000016ec  000016ec  000016ec  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.version  000001e6  00002050  00002050  00002050  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .gnu.version_r 00000090  00002238  00002238  00002238  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rel.dyn      00000418  000022c8  000022c8  000022c8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .rel.plt      00000318  000026e0  000026e0  000026e0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .init         00000017  000029f8  000029f8  000029f8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .plt          00000640  00002a10  00002a10  00002a10  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .text         00003f24  00003050  00003050  00003050  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .fini         0000001c  00006f74  00006f74  00006f74  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .rodata       0000011d  00006fa0  00006fa0  00006fa0  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .eh_frame_hdr 0000017c  000070c0  000070c0  000070c0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 13 .eh_frame     000005b4  0000723c  0000723c  0000723c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .ctors        00000008  00008000  00008000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .dtors        00000008  00008008  00008008  00008008  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .jcr          00000004  00008010  00008010  00008010  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .data.rel.ro  00000004  00008014  00008014  00008014  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dynamic      000000d0  00008018  00008018  00008018  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .got          000001e4  000080e8  000080e8  000080e8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got.plt      00000198  000082cc  000082cc  000082cc  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .data         00000770  00008480  00008480  00008480  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 22 .bss          00000184  00008c00  00008c00  00008bf0  2**5
                  ALLOC
 23 .comment      000000e4  00000000  00000000  00008bf0  2**0
                  CONTENTS, READONLY

【コメント】

拾ったマルウェアモジュールのファイルはx32ビットのバイナリーですね。どんなサーバも動かすのは可能な物です…
マルウェアバイナリーの対応しているGLIBCのバーションは2.0~2.3.4です。
linuxライブラリ「libm.so.6 or libc.so.6 」が必要です。


《バイナリー分析調査》


importモジュール一覧(import module list)↓
[Imports]

67 imports
_Jv_RegisterClasses
__ctype_b_loc
__ctype_tolower_loc
__ctype_toupper_loc
__cxa_finalize
__fprintf_chk
__gmon_start__
__memcpy_chk
__snprintf_chk
__sprintf_chk
__stack_chk_fail
__strtol_internal
__xstat
ap_add_output_filter // apr_*  <==Apache development module!
ap_hook_insert_filter
ap_md5
ap_pass_brigade
ap_register_output_filter
ap_set_flag_slot
apr_brigade_cleanup   // apr_*  <==Apache Portable Runtime!
apr_brigade_create
apr_bucket_alloc
apr_bucket_eos_create
apr_bucket_free
apr_bucket_heap_create
apr_bucket_type_eos
apr_file_close
apr_file_open
apr_palloc
apr_table_add
apr_table_get
ceil             // マルウェアが使っているコマンドはここから…
close
connect
fclose
fgets
fopen
fread
gethostbyname
getpwnam
gettimeofday
gmtime
inet_ntoa
malloc
memcpy
memset
open
opendir
rand
read
readdir
recv
remove
send
snprintf
socket
srand
strchr
strcmp
strftime
strlen
strncpy
strspn
strstr
strtok
time
uname
symbols一覧(Symbol List)↓
[Symbols]

163 symbols
ARRAY_BAN_LOCAL_IP
ARRAY_BAN_PROC
ARRAY_BAN_USERAGENT
ARRAY_BLACKLIST_URI
ARRAY_SE_REFERER
ARRAY_SUDOERS
ARRAY_TAGS_FOR_INJECT
CC_HOST
CC_REQUEST_FORMAT
CC_URI
CLIENT_IP
C_ARRAY_BAN_LOCAL_IP
C_ARRAY_BAN_PROC
C_ARRAY_BAN_USERAGENT
C_ARRAY_BLACKLIST_URI
C_ARRAY_SE_REFERER
C_ARRAY_SUDOERS
C_ARRAY_TAGS_FOR_INJECT
C_CC_HOST
C_CC_REQUEST_FORMAT
C_CC_URI
C_KEY_COOKIE_NAME
C_LIST_PREF
C_MARKER_LEFT
C_MARKER_RIGHT
C_MODULE_VERSION
C_STRING_1
C_STRING_10
C_STRING_11
C_STRING_12
C_STRING_13
C_STRING_14
C_STRING_15
C_STRING_16
C_STRING_17
C_STRING_18
C_STRING_19
C_STRING_2
C_STRING_20
C_STRING_21
C_STRING_22
C_STRING_23
C_STRING_24
C_STRING_25
C_STRING_26
C_STRING_27
C_STRING_28
C_STRING_29
C_STRING_3
C_STRING_30
C_STRING_31
C_STRING_32
C_STRING_33
C_STRING_34
C_STRING_35
C_STRING_4
C_STRING_5
C_STRING_6
C_STRING_7
C_STRING_8
C_STRING_9
C_TMP_DIR
FILENAME_UPDATING
FILTER
GEN_FILENAME_INJECT
GEN_FILENAME_SESSION
GEN_FILENAME_WAITLIST
KEY_CLIENT
KEY_COOKIE_NAME
KEY_XOR
LIST_PREF
MARKER_LEFT
MARKER_RIGHT
MODULE_VERSION
SIZE_ARRAY_BAN_PROC
SIZE_ARRAY_BAN_USERAGENT
SIZE_ARRAY_BLACKLIST_URI
SIZE_ARRAY_SE_REFERER
SIZE_ARRAY_SUDOERS
SIZE_ARRAY_TAGS_FOR_INJECT
STRING_1     // この辺に転送先CnC/C2/CCマルウェアサーバの情報があります
STRING_10
STRING_11
STRING_12
STRING_13
STRING_14
STRING_15
STRING_16
STRING_17
STRING_18
STRING_19
STRING_2
STRING_20
STRING_21
STRING_22
STRING_23
STRING_24
STRING_25
STRING_26
STRING_27
STRING_28
STRING_29
STRING_3
STRING_30
STRING_31
STRING_32
STRING_33
STRING_34
STRING_35
STRING_4
STRING_5
STRING_6
STRING_7
STRING_8
STRING_9
TMP_DIR        // TEMP環境迄…
_ADD_TO_BLACKLIST //全て _CHECK*はマルウェアの機能
_ADD_TO_WAITLIST
_CHECK_BLACKLIST
_CHECK_BOT_USERAGENT
_CHECK_JS
_CHECK_LOCAL_IP
_CHECK_PROC
_CHECK_RAW_COOKIE
_CHECK_REFERER_IS_HOST
_CHECK_REFERER_IS_SEO
_CHECK_SITE_ADMIN
_CHECK_SITE_KERNEL
_CHECK_UTMP
_CHECK_WAITLIST
_GEN_FILENAME_BLACKLIST
_INJECT_DO
_INJECT_LOAD
_INJECT_SAVE
_INJECT_SKIP
_INJECT_UPDATE
_IS_SUDOER
_SESSION_DELETE
_SESSION_KEYGEN
_SESSION_LOAD
_SESSION_SAVE
_SET_COOKIE_KEY
__bss_start
_edata
_end
_fini
_init
base64decode
base64encode
explode
filesize
from_hex
ip2long
max
min
rtrim
sec2_config_module
stristr
to_hex
urlencode
xor_decrypt_string
xor_encrypt
xor_encrypt_string
.rodataのストリングス(etc strings)↓(開発環境が残っていますね…)
.rodata:00006FA3 0000000E C /var/run/utmp  // ログイン情報…取られます…
.rodata:00006FB1 00000006 C /dev/
.rodata:00006FB7 00000006 C %i\n%s
.rodata:00006FC1 00000012 C mod_sec2_config.c  // マルウェア開発のゴミだ…
.rodata:0000700F 0000000B C ?456789:;<=   // 暗号のトレース…
.rodata:00007028 00000005 C \a\b\t\n\v                                                       
.rodata:00007047 00000014 C  !\"#$%&'()*+,-./0123                                            
.rodata:00007060 00000041 C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 
.rodata:000070AC 00000011 C 0123456789abcdef 

【重要】

マルウェアに発見したの全てのSTRINGSは→【こちら】です。
マルウェアバイナリーの全てリバースしたASMは→【こちら】

《リバースエンジニアリング調査》

スタート(start point)は「___gmon_start__」のfunctionからです↓

___gmon_start__ proc near
jmp     ds:off_845C     ; PIC mode
___gmon_start__ endp
データは暗号されたそうです、下記のように↓
↑暗号されたパターンを見るとXORされたっぽいで、XOR関係コードを先ずは探す。

バイナリーのこの辺でXORのfunctionを発見↓

0x17C8   0x17C8   xor_decrypt_string
0x17ED   0x17ED   xor_encrypt_string
0x1800   0x1800   xor_encrypt
+、びみようにニセXORキー↓
0x1CB8   0x1CB8   KEY_XOR
ニセ物を無視、xorのfunctionをコードで探す。 で、stringとgeneric XOR暗号ロジックがあります。 genericなXORロジックは↓
xor_encrypt(A8, Ac, A10, A14)
/* unknown */ void  A8;
/* unknown */ void  Ac;
/* unknown */ void  A10;
/* unknown */ void  A14;
{
 /* unknown */ void  ebx;
 /* unknown */ void  esi;
 /* unknown */ void  Vfffffff4;

    edx = A10;
    L00003117();
    ebx = ebx + 0x4f3b;
    if(edx != 0 && A8 != 0) {
        Vfffffff4 = A14;
        *esp = *( *( *( *(ebx + -300)) + 0xc));
        *(ebp - 0x10) = L00002D90();
        if(A14 > 0) {
            ecx = 0;
            do {
                edx = ecx;
                eax = ecx;
                edx = edx >> 0x1f;
                Ac = Ac / Ac;
                eax = *(ecx + A10) & 0xff;
                al = al ^ *(Ac % Ac + A8);
                *(ecx + *(ebp - 0x10)) = al;
                ecx = ecx + 1;
            } while(ecx != A14);
        }
        return *(ebp - 0x10);
    }
    *(ebp - 0x10) = 0;
    eax = *(ebp - 0x10);
    esp = esp + 0xc; }
XORのstring暗号は↓
xor_encrypt_string(A8, Ac, A10, A14)
/* unknown */ void  A8;
/* unknown */ void  Ac;
/* unknown */ void  A10;
/* unknown */ void  A14;
{
 /* unknown */ void  V0;
 /* unknown */ void  V4;
 /* unknown */ void  ebx;
 /* unknown */ void  Vfffffffc;

    ebx = ebx + 0x4f7d;
    V4 = L00003117();
    V0 = A10;
    Vfffffffc = Ac;
    *esp = A8;
    return L00002C00(); }
さらにですね、XORリバースロジックも発見しました(^^ やはりマルウェアも実行の前にリバースが必要↓
xor_decrypt_string(A8, Ac, A10, A14)
/* unknown */ void  A8;
/* unknown */ void  Ac;
/* unknown */ void  A10;
/* unknown */ void  A14;
{
 /* unknown */ void  ebx;
 /* unknown */ void  esi;
 /* unknown */ void  Vfffffff4;

    L00003117();
    ebx = ebx + 0x5001;
    esp = esp - 0xc;
    Vfffffff4 = A14 + 1;
    *esp = *( *( *( *(ebx + -300)) + 0xc));
    *(ebp - 0x10) = L00002D90();
    if(A14 > 0) {
        ecx = 0;
        do {
            edx = 0;
            eax = 0;
            edx = 0 >> 0x1f;
            Ac = Ac / Ac;
            al = *A10 & 0xff ^ *(Ac % Ac + A8);
            *( *(ebp - 0x10)) = al;
        } while(1 != A14);
    }
    esi = *(ebp - 0x10);
    *(esi + A14) = 0;
    eax = esi;
    esp = esp + 0xc;
XORがあるという事はキーが何処かにあるはずですので、 私の手元にあるサンプルでは offset 0x84a0にキーを発見しましたが、 キーをそのままで使うと下記のロジックで動かせばデータの所だけにを回すと…↓
fd.seek(キー長さ) # 32
key = fd.read(12)
for s in tab:
    fd.seek(s['offset'])
    data = fd.read(s['size'])
    decrypted = ''.join(chr(ord(c)^ord(k)) for c,k in izip(data, cycle(key)))
    clear_text = decrypted.split('\x00')[0]
    print('%s: %s') % (s['name'], clear_text)
↑全て情報が出ました(^^ ばけてる字もありますが見えない字をカットしました、して綺麗にすると↓
C_MODULE_VERSION: "2012.12.14"
C_CC_HOST: "217.23.13.6"
C_CC_URI: "/Home/index.php"
C_CC_REQUEST_FORMAT: POST %s HTTP/1.1
Host: %s
Content-Type: "application/x-www-form-urlencoded"
Content-Length: 
    %i
    %s
C_MARKER_LEFT: {{{
C_MARKER_RIGHT: }}}
C_TMP_DIR: /
C_LIST_PREF: sess_
C_COOKIE_NAME: "PHP_SESSION_ID="
C_ARRAY_TAGS_FOR_INJECT: "
    </script>
    </style>
    </head>
    </title>
    </body>
    </html>
    </table>
    </h1>
    </i>
    </ul>"
C_ARRAY_BAN_USERAGENT:" 
    CHROME
    GOOGLEBOT
    SLURP
    YAHOO
    BING
    LINUX
    OPENBSD
      :(などなど…長い書いたあるので、結論の所に纏めました)
    CURL
    PHP
    INDY LIBRARY"
C_ARRAY_BLACKLIST_URI: 
    "ADMIN"
C_ARRAY_BAN_PROC: "
  f7277f6714e4b034216cf6558cc6327b
  28878074a3dd19c7361e8a6d3f04fc17
  d0415afe195478d4d8c9af205644"
C_ARRAY_SE_REFERRER: "
    GOOGLE.
    YAHOO.
    YANDEX.
    RAMBLER.
      :(などなど…長い書いたあるので、結論の所に纏めました)
    VERDEN."
C_ARRAY_SUDOERS: r
C_STRING_1: 
    %i
    %i
    %i
    %s
C_STRING_2: "text/html"
C_STRING_3: %
C_STRING_5: "document.write('%s');" // %sにはマルウェア転送コード
C_STRING_5: r
C_STRING_6: "User-Agent"
C_STRING_7: %s%.*s
C_STRING_8: "Referer"
C_STRING_9: "X-Forwarded-For"
C_STRING_10: "Client-IP"
C_STRING_11: "X-Real-IP"
C_STRING_12: "Cookie"
C_STRING_13: ;
C_STRING_14: %s/%s%s
C_STRING_15: "INJECT"
C_STRING_16: "javascript"
C_STRING_17: "text/js"
C_STRING_18: j
C_STRING_19: 
C_STRING_20: "id="
C_STRING_21: "%a %d-%b-%Y %H:%M:%S %Z"
C_STRING_22: "Set-Cookie"
C_STRING_23: "%s%i; expires=%s; path=/"
C_STRING_24: "Set-Cookie"
C_STRING_25: w
C_STRING_26: %
C_STRING_27: "Request-Hash"
C_STRING_28: c=1&version=%s&uname=%s
C_STRING_29: c=1&version=%s&uname=
C_STRING_30: "/proc/"
C_STRING_31: 0123456789
C_STRING_32: "/proc/%s/comm"
C_STRING_33: "/usr/lib/libbdl.so.0"
C_STRING_34: U
C_STRING_35: .js

↑上記のリバースした結果をファイルウォールやプロキシフィルターに入れるとブロックが出来るはずと思います。
もう一つサンプルが御座いますので、リバースしたら中身殆ど同じなんですが↓
$ python sec3.py ./mod_pool_log.so
C_MODULE_VERSION: 2012.12.14
C_CC_HOST: 217.23.13.65
C_CC_URI: /Home/index.php
C_CC_REQUEST_FORMAT: POST %s HTTP/1.1
Host: %s
Content-Type: application/x-www-form-urlencoded
Content-Length: %i
  :
などなど…

マルウェアのCNCは「217.23.13.65」オランダのサーバです↓

【マルウェア機能の分析調査】

上記「Symbols」に書いたマルウェア機能は下記の一覧かと思われます。

_ADD_TO_BLACKLIST
_ADD_TO_WAITLIST
_CHECK_BLACKLIST
_CHECK_BOT_USERAGENT
_CHECK_JS
_CHECK_LOCAL_IP
_CHECK_PROC
_CHECK_RAW_COOKIE
_CHECK_REFERER_IS_HOST
_CHECK_REFERER_IS_SEO
_CHECK_SITE_ADMIN
_CHECK_SITE_KERNEL
_CHECK_UTMP
_CHECK_WAITLIST
_GEN_FILENAME_BLACKLIST
_INJECT_DO
_INJECT_LOAD
_INJECT_SAVE
_INJECT_SKIP
_INJECT_UPDATE
_IS_SUDOER
_SESSION_DELETE
_SESSION_KEYGEN
_SESSION_LOAD
_SESSION_SAVE
_SET_COOKIE_KEY
この機能を分析するとマルウェアの動きが分かります。

マルウェア機能をバイナリーからASMへリバースし、Cで書きました。
アクセスは→【こちら】です。

調査結果は↓
(1)コールの流れ行くとシステムコールを結構使われます(例えばsudo, utmp, host, uname, /procの情報をロード、などなど)
(2)殆どApacheモジュールのC-APIが使われます。

↑本情報のご注意が必要です。という意味ではが【ACTIVE】な感染されたウェブサーバにはroot権限が取られてしまう可能性が非常に高いです…

《マルウェアの検知率調査、参考:ウイルストータル》

サンプル1 - URL: 【クリック】

SHA256: 94ef407cc485989464dcf390fcea6e82218bc89f75394e41a95e0bb31830786b
SHA1: cc594b4d924b0710db64bcca5012d22db8842f98
MD5: 81c1d493c7764f6692c30de8923c76ba
File size: 36.4 KB ( 37296 bytes )
File name: mod_sec2_config.so
File type: ELF
Tags: elf
Detection ratio: 4 / 45
Analysis date: 2013-03-20 02:42:20 UTC ( 5 minutes ago )
【ExifTool】
MIMEType.................: application/octet-stream
CPUByteOrder.............: Little endian
CPUArchitecture..........: 32 bit
FileType.................: ELF executable
ObjectFileType...........: Shared object file
CPUType..................: i386
【マルウェア名前】
GData                    : ELF:Apmod-B
Avast                    : ELF:Apmod-B [Trj]
Microsoft                : Backdoor:Linux/Apmod.gen!A
Kaspersky                : HEUR:Backdoor.Linux.Apmod.gen
サンプル2 - URL: 【クリック】
SHA256: ece16200fd54500a33d81f37a9f864148cbf8846514978413168ffacd46d28c3
SHA1: ef3741f3cc2c60cc4cd88e6293776e39d56cd78b
MD5: ae7c369b8bd49a04f87fab72d4d3431d
File size: 36.4 KB ( 37272 bytes )
File name: mod_pool_log.so
File type: ELF
Tags: elf
Detection ratio: 5 / 45
Analysis date: 2013-03-20 02:42:45 UTC ( 9 minutes ago )
【ExifTool】
MIMEType.................: application/octet-stream
CPUByteOrder.............: Little endian
CPUArchitecture..........: 32 bit
FileType.................: ELF executable
ObjectFileType...........: Shared object file
CPUType..................: i386
【マルウェア名前】
GData                    : ELF:Apmod-B
Avast                    : ELF:Apmod-B [Trj]
Microsoft                : Backdoor:Linux/Apmod.gen!A
Kaspersky                : HEUR:Backdoor.Linux.Apmod.gen
Ikarus                   : Backdoor.Linux.Apmod

《まとめて、結論》

これで今回のDarkleechのApacheマルウェアモジュールの動きが全て分かりました。

結論は下記となります↓

1. USER-AGENTでのブロック機能があります。
今回のサンプルではIEからのアクセスをブロックされずに、 下記のボット/ブラウザ/BOTからのアクセスがブロックされます↓

SAFARI
OPERA
FIREFOX
CHROME
GOOGLEBOT
SLURP
YAHOO
BING
LINUX
OPENBSD
MACINTOSH
MAC OS
IPHONE
SYMBIANOS
NOKIA
LINKDEX
FROG/1
USER-AGENT
BLACKBERRY
MOTOROLA
APPLE-PUB
AKREGATOR
SONYERICSSON
MACBOOK
XENU LINK
METAURI
REEDER
MOODLEBOT
SAMSUNG
SINDICE-FETCHER
EZOOMS
NIKOBOT
BINLAR
DARWIN
PLAYSTATION
OPERA MINI
NINTENDO
YANDEX
CRAWLER
JIKE
SPIDER
ROBOT
PAPERLIBOT
SNAPPREVIEWBOT
BUFFERBOT
MEDIAPARTNERS
HATENA
BLUEDRAGON
WORDPRESS
XIANGUO
WOOPINGBOT
CAFFEINATED
FEEDZIRRA
BITLYBOT
FOIIABOT
PROXIMIC
VBSEO
FOLLOWSITE
SOGOU
NHN
WGET
MSNBOT
YOUDAO
STACKRAMBLER
LWP::SIMPLE
QIHOOBOT
BRUTUS
HTTPCLIENT
NIELSEN
CURL
PHP
INDY LIBRARY
2. サーバのログインユーザブロック機能
マルウェアバイナリーのsymbolsに書いたcheck_UTMPを
IT-PROで書いたUTMPの情報(日本語)↓
UNIXにおいて,who, write, loginなどの
コマンドが必要とするユーザーおよびアカウント情報を保持したファイル。
/var/logディレクトリに置かれる。
多くのシステム・プログラムがその整合性に依存しており,
utmpファイルを書き込み可能にしてはいけない。
不特定のユーザーから書き込み可能なままにしておくと,
ログ・ファイルの偽装やシステム・ファイルの改ざんを受ける危険性がある。 
manページの英文では↓
The utmp file allows one to discover information 
about who is currently using the system. 
There may be more users currently using the system, 
because not all programs use utmp logging.
本マルウェアでは、ログインユーザのブラックリストを作る為にcheck_UTMPを使っていますね。 証拠↓
0x1997   0x1997   _CHECK_UTMP
0x6FA3   0x6FA3   /var/run/utmp
0x1997   0x1997   _CHECK_UTMP
0x6FA3   0x6FA3   /var/run/utmp
00006FA3 0000000E .rodata: C /var/run/utmp
3. HTTP REQUESTのREFERERをブロックする機能↓
GOOGLE.
YAHOO.
YANDEX.
RAMBLER.
MAIL.RU
BING.
SEARCH.
MSN.
ALLTHEWEB.
ASK.
LOOKSMART.
ALTAVISTA.
WEB.DE
FIREBALL.
LYCOS.
AOL.
ICQ.
NETZERO.
FRESH-WEATHER.
FREECAUSE.
MYSEARCH-FINDER.
NEXPLORE.
ATT.
REDROVIN.
TOSEEKA.
COMCAST.
INCREDIMAIL.
CHARTER.
VERIZON.
SUCHE.
VIRGILIO.
VERDEN.
↑ですが、私がGoogleで検索してから発見したので、恐らく本ブロック機能にはバグがありますね、よかった(^^
マルウェアについてのバグが山ほどありますので、サーバが感染してもマルウェアモジュールの軌道が出来ない/動かないとの状況も発見しました↓
execve("./mod_sec2_config.so", 
["./mod_sec2_config.so"], 
[/* 21 vars */]) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

4. Cookie使い方、感染の監視について
感染の監視条件で使っているみたいです↓

Set-Cookie: id=%ランダムハッシュ%
Set-Cookie: %a %d-%b-%Y %H:%M:%S %Z //フォーマット日付け
Set-Cookie: %s%i; expires=%s; path=/ 
5. マルウェアが使っているLinuxライブラリー
/usr/lib/libbdl.so.0
/usr/lib/libm.so.6
/usr/lib/libc.so.6
さらに、下記のパスのアクセスも必要
/proc
/proc/%s/comm
↑このライブラリーをSE LINUXでセットしたら本マルウェアが動けなくなります(検証済みです)。

6. HTMLインジェクト機能↓
感染されたApacheサーバのページに下記のマルウェア転送コードをインジェクトされます。

text/html
%
document.write('%s');
r
User-Agent
%s%.*s
Referer
X-Forwarded-For
Client-IP
X-Real-IP
Cookie
;
%s/%s%s
INJECT
javascript
text/js
7.a. 本マルウェアは下記のApacheモジュールを使っています↓
ap_add_output_filter
ap_hook_insert_filter
ap_md5
ap_pass_brigade
ap_register_output_filter
ap_set_flag_slot
7.b. そして下記のApacheモジュールのランタイムも使っています↓
apr_brigade_cleanup
apr_brigade_create
apr_bucket_alloc
apr_bucket_eos_create
apr_bucket_free
apr_bucket_heap_create
apr_bucket_type_eos
apr_file_close
apr_file_open
apr_palloc
apr_table_add
apr_table_get
8. 本マルウェアが使っているUNIX/Cコールコマンド一覧↓
ceil
close
connect
fclose
fgets
fopen
fread
gethostbyname
getpwnam
gettimeofday
gmtime
inet_ntoa
malloc
memcpy
memset
open
opendir
rand
read
readdir
recv
remove
send
snprintf
socket
srand
strchr
strcmp
strftime
strlen
strncpy
strspn
strstr
strtok
time
uname
9. マルウェアが使っている暗号機能の一覧
base64decode
base64encode
to_hex
urlencode
xor_decrypt_string
xor_encrypt
xor_encrypt_string

リバースエンジナイリング調査レポート以上です。

もしご質問が御座いましたらツイッターで@unixfreaxjpにご連絡下さい。

宜しくお願いします。

--
【ご注意】
本件のポストに書いた情報は(c)0day.jpのマルウェア研究調査の物となります。調査内容の無断転載禁止です。使いたい方は@unixfreaxjpにご連絡下さい。

3 件のコメント:

  1. How they are installing those modules in server?

    返信削除
    返信
    1. Time passed by, so I can answer more freely: Plesk Exploit.

      削除