Malware Definition and Historical Research
This definition is written by the latest observation of the large infection case occurred caused by this malware's infection on Linux Apache Web Servers.
Darkleech Apache Malware Module version (there is also detected an NGNIX version of this malware as per mentioned --> here by Eric Romang) is the malware implemented in Linux OS served with Apache web server with the Apache API interactive module. Malware module was loaded and activated into the Apache web server system by LoadModule command defined in the module configuration file. Once it is loaded into the system it perform general malicious functionality of: [1] Self injection of compromised server's web pages with the code to redirect victim to the malware sites and [2] Backdoor the compromised server system from the remote access.
Before starting the details of infection it is good to understand the background of malware to be about to discussed in this post:
This malware is already recognized by antivirus products with the reference name of Linux/Chapro.x or other names, you can seek it in Google--> here. Historically, this malware's infection attack was firstly exposed by Unmask Parasites on August 13th, 2012 in--> here and was firstly very detailed disclosed in October 2012 by russian malware researcher in PDF presentation shared at yandex.ru--> here. (Direct download PDF is--> here). And I believe the first english coverage of this malware was written by Unmask Parasites in--> here. Following by various anti virus research reports and coverage i.e. by ESET, Securelist, Symantec, etc.
The bad actor group who is using Darkleech Apache Module is the same bad guys behind the Cryptome infection more than 1 year ago, and LA Times incident a while ago. This was exposed in Malware Don't Drink Coffee blog in--> here. And the latest mass-infection detected using this malware was pointing to Blackhole Exploit Kit with spreading combination of Trojan PWS/Downloader collaborated with FakeAV and/or ZeroAccess malware, exposed in--> here.
The first time the related malware sample was uploaded to Virus Total is in--> here. And the link between Darkleech underground forum to this malware firstly exposed via Eric Romang's post in--> here, which pointing to the Russian underground forum (forum snapshot is below).
Latest Infection Details
The malware was found in web server systems with below characteristic:Linux RedHat-base distribution without SE Linux properly set Apache httpd web server 2.x (rpm-base, as per it is) Cgi-base web admin panel and/or Wordpress system's servedMalware module file was found with the below regex:mod\_[a-z0-9]{3,}\_[a-z0-9]{3,}\.soWith the below file names:mod_sec2_config.so mod_pool_log.so mod_chart_proxy.so mod_balance_alias.so mod_local_log.so mod_build_cache.so :Malware was loaded in various malicious conf file with using Apache module's LoadModule method below:$ cat ../etc/../modules/[VARIOUS].conf| grep "mod_" LoadModule sec2_config_module modules/mod_sec2_config.soPS: malware module files was using old dates.
Infection Symptoms
When an Apache web server get infected by this malware it shows the unwanted redirection to the remote web servers served with the malware infection codes, mostly are Exploit Kit's landing page. One real infection session is shown as below PCAP record:
Landing page like: Before redirection occurred the malware injection code will be detected in the previous HTTP GET traffic in the infected server as per below PCAP (see the 1st request) In the first traffic we'll see the malware injected code: contains the javascript wrapped iframe code like below: which will trigger the malware downloads like real sample below:There are several malware infection conditions that "supposed" to be met for an infection. All of the prerequisites for infection was defined in the client's HTTP access to the infected web servers, also in the checked values of the infected web servers. Unmask Parasites blog in--> here is explaining the very useful guides for us to break down the recent malware Apache module spotted, below are the details:Infection Condition
1. The usage of referer to block unwanted browsers. By reversing, we found the malware has function (C_ARRAY_BAN_USERAGENT) to ban unwanted browsers with the below list:The malware tries to identify unwanted access from web site admins, server login admins, server unwanted processes as per spotted malicious functions below:SAFARI YANDEX OPERA CRAWLER FIREFOX JIKE CHROME SPIDER GOOGLEBOT ROBOT SLURP PAPERLIBOT YAHOO SNAPPREVIEWBOT BING BUFFERBOT LINUX MEDIAPARTNERS OPENBSD HATENA MACINTOSH BLUEDRAGON MAC OS WORDPRESS IPHONE XIANGUO SYMBIANOS WOOPINGBOT NOKIA CAFFEINATED LINKDEX FEEDZIRRA FROG/1 BITLYBOT USER-AGENT FOIIABOT BLACKBERRY PROXIMIC MOTOROLA VBSEO APPLE-PUB FOLLOWSITE AKREGATOR SOGOU SONYERICSSON NHN MACBOOK WGET XENU LINK MSNBOT METAURI YOUDAO REEDER STACKRAMBLER MOODLEBOT LWP::SIMPLE SAMSUNG QIHOOBOT SINDICE-FETCHER BRUTUS EZOOMS HTTPCLIENT NIKOBOT NIELSEN BINLAR CURL DARWIN PHP PLAYSTATION INDY LIBRARY OPERA MINI NINTENDO2. Checked referer sites Detected malware modules was checking below sites before injecting the redirection code, spotted in value of C_ARRAY_SE_REFERRER below:GOOGLE. ICQ. YAHOO. NETZERO. YANDEX. FRESH-WEATHER. RAMBLER. FREECAUSE. MAIL.RU MYSEARCH-FINDER. BING. NEXPLORE. SEARCH. ATT. MSN. REDROVIN. ALLTHEWEB. TOSEEKA. ASK. COMCAST. LOOKSMART. INCREDIMAIL. ALTAVISTA. CHARTER. WEB.DE VERIZON. FIREBALL. SUCHE. LYCOS. VIRGILIO. AOL. VERDEN.After some tests on the infected sites we found that the referer below was not infecting the sites. 3. Others malware blacklist method:
The malware is having below condition to be passed for performing infection as per described in the below details:C_ARRAY_BAN_LOCAL_IP (contains IP addresses) C_ARRAY_BLACKLIST_URI "ADMIN" C_ARRAY_SUDOERS (contains list of user with sudoers right) C_ARRAY_BAN_PROC (contains MD5 of banned process) i.e.: f7277f6714e4b034216cf6558cc6327b 28878074a3dd19c7361e8a6d3f04fc17 d0415afe195478d4d8c9af2056444. Malware checked conditions:
We spotted the blacklist was saved in the temporary directory set in the Linux system environment TEMP or TMP variable (i.e.: "/var/tmp/" or also "/")under file names:_CHECK_BLACKLIST 0x3D20 _CHECK_BOT_USERAGENT 0x3650 _CHECK_JS 0x3180 _CHECK_LOCAL_IP 0x44F0 _CHECK_PROC 0x3980 _CHECK_RAW_COOKIE 0x3190 _CHECK_REFERER_IS_HOST 0x31C0 _CHECK_REFERER_IS_SEO 0x3540 _CHECK_SITE_ADMIN 0x3860 _CHECK_SITE_KERNEL 0x31B0 _CHECK_UTMP 0x3BB0 _CHECK_WAITLIST 0x55005. The Blacklist files
Which is having various value of blacklist data described in the above conditions./var/tmp/sess_
During investigation our friend in crusade @it4sec offered help on analysis infection condition. He found and posted the good theory of malware usage of cookies his blog "On Daily Basis" in--> here. Which I recommend you to read.
6. Usage of cookies to control infection
We are in coordination with jvoisin of dustri.org for reversing the current module under pure unix environment using python logic. jvoisin was making the best reversing method for this malware as per mentioned in his blog in--> here, which I recommend you to read. Also I used reference of an older version of this malware module source code spotted in pastebin in--> here.
7. Finally, the post-check, code injection Injection methods:INJECT javascript text/jsInjection Code BoundariesC_MARKER_LEFT: {{{ C_MARKER_RIGHT: }}}Inject commands:_INJECT_DO _INJECT_LOAD _INJECT_SAVE _INJECT_SKIP _INJECT_UPDATEReversing Darkleech Malware Module
Below is the reversing steps of the recent modules spotted between March 17th to March 22nd, 2013 in hundreds of infected sites we cleaned up. We used two permitted samples to be uploaded into virus total as per below details:
Sample 1 URL --> hereWe positively PoC'ed web admins (i.e.: cPanel, Plesk, Webmin and WordPress) panel vulnerability was used as main vector of penetration into vectim's machine in this attack. In the current incident there are mostly same web admins panel (Plesk) were detected in almost all infected servers as per this list, with the same vulnerability. It looks like the attackers were beforehand well-prepared with some penetration method to gain web exploitation which were used to gain shell access and did the privilege escalation unto root. (I am not allowed to expose this detail further at this moment). Since the root were gained in all infected servers, there is no way we can trust the host or its credentials anymore, we suggest you to offline the machine and use the backup data to start new service, AND remember to change all of server's user since there are strong possibilities the leaked server's admin credentials.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 【Malware Name】 GData : ELF:Apmod-B Avast : ELF:Apmod-B [Trj] Microsoft : Backdoor:Linux/Apmod.gen!A Kaspersky : HEUR:Backdoor.Linux.Apmod.genSample 2 URL --> hereSHA256: 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 【Malware Name】 GData : ELF:Apmod-B Avast : ELF:Apmod-B [Trj] Microsoft : Backdoor:Linux/Apmod.gen!A Kaspersky : HEUR:Backdoor.Linux.Apmod.gen Ikarus : Backdoor.Linux.ApmodFile Information (the first file only)$ ls -alF ./mod_sec2_config.so -rwxr--r-- 1 xxx xxx 37296 Jun 26 2007 ./mod_sec2_config.so* // md5.. $ md5 mod_sec2_config.so MD5 (mod_sec2_config.so) = 81c1d493c7764f6692c30de8923c76ba // file info file format elf32-i386 architecture: i386, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x00003050 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........ :For unixmen, fire your objdump to gain these values:Program 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 References: 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 Sections: 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, READONLYFull strings used:0x16ED 0x16ED __gmon_start__ 0x16FC 0x16FC _init 0x1702 0x1702 _fini 0x1708 0x1708 __cxa_finalize 0x1717 0x1717 _Jv_RegisterClasses 0x172B 0x172B to_hex 0x173A 0x173A _CHECK_JS 0x1744 0x1744 _CHECK_RAW_COOKIE 0x1756 0x1756 KEY_CLIENT 0x1761 0x1761 _CHECK_SITE_KERNEL 0x1774 0x1774 _CHECK_REFERER_IS_HOST : : 0x8BF1 0x8BF1 GCC: (GNU) 4.1.1 20060525 (Red Hat 4.1.1-1) 0x8C1E 0x8C1E GCC: (GNU) 4.1.1 20070105 (Red Hat 4.1.1-51) 0x8C4C 0x8C4C GCC: (GNU) 4.1.1 20070105 (Red Hat 4.1.1-51) 0x8C7A 0x8C7A GCC: (GNU) 4.1.1 20070105 (Red Hat 4.1.1-51) 0x8CA8 0x8CA8 GCC: (GNU) 4.1.1 20060525 (Red Hat 4.1.1-1) : : 0x8D55 0x8D55 .ctors 0x8D5C 0x8D5C .dtors 0x8D68 0x8D68 .data.rel.ro 0x8D75 0x8D75 .dynamic 0x8D83 0x8D83 .got.plt 0x8D8C 0x8D8C .data 0x8D97 0x8D97 .commentHere's the full list--> here Separating import modules & symbols values: Imported modules:$ rabin2 -i ./mod_sec2_config.so | cut -d" " -f7 | cut -c6- | sort [Imports] 67 imports _Jv_RegisterClasses __ctype_b_loc __ctype_tolower_loc __ctype_toupper_loc __cxa_finalize __fprintf_chk __gmon_start__ __memcpy_chk :Symbols...$ rabin2 -s ./mod_sec2_config.so | cut -d" " -f8 | cut -c6- | sort [Symbols] 163 symbols ARRAY_BAN_LOCAL_IP ARRAY_BAN_PROC ARRAY_BAN_USERAGENT ARRAY_BLACKLIST_URI ARRAY_SE_REFERER ARRAY_SUDOERS :Full list of imported modules & symbols--> here We'll the XOR endoded strings like: At the last part of reversed symbols we found XOR functions:0x17C8 0x17C8 xor_decrypt_string 0x17ED 0x17ED xor_encrypt_string 0x1800 0x1800 xor_encryptI reversed them to confirm XOR method: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_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_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;}So it looks decode and encode the XOR'ed strings. Question: what strings? It is actually contains malware hidden data:C_MODULE_VERSION: C_CC_HOST: C_CC_URI: C_CC_REQUEST_FORMAT: C_MARKER_LEFT: C_MARKER_RIGHT: C_TMP_DIR: C_LIST_PREF: C_COOKIE_NAME: C_ARRAY_TAGS_FOR_INJECT: C_ARRAY_BAN_USERAGENT: C_ARRAY_BLACKLIST_URI: C_ARRAY_SE_REFERRER: C_ARRAY_SUDOERS: C_ARRAY_BAN_PROC: C_ARRAY_BAN_LOCAL_IP: C_STRING_1: C_STRING_2: C_STRING_3: : C_STRING_35: C_STRING_36:We need to find size & offset per variable, i.e.:{'name':'C_MODULE_VERSION', 'size':10, 'offset':0x8491}, {'name':'C_CC_HOST', 'size':12, 'offset':0x849b}, {'name':'C_CC_URI', 'size':15, 'offset':0x84a7}, {'name':'C_CC_REQUEST_FORMAT', 'size':96, 'offset':0x84c0}, {'name':'C_MARKER_LEFT', 'size':3, 'offset':0x8520}, {'name':'C_MARKER_RIGHT', 'size':3, 'offset':0x8523}, {'name':'C_TMP_DIR', 'size':8, 'offset':0x8526}, {'name':'C_LIST_PREF', 'size':5, 'offset':0x852e}, {'name':'C_COOKIE_NAME', 'size':15, 'offset':0x8533}, {'name':'C_ARRAY_TAGS_FOR_INJECT','size':77, 'offset':0x8560}, {'name':'C_ARRAY_BAN_USERAGENT', 'size':622,'offset':0x85c0}, {'name':'C_ARRAY_BLACKLIST_URI', 'size':5, 'offset':0x882e}, {'name':'C_ARRAY_SE_REFERRER', 'size':281,'offset':0x8840}, {'name':'C_ARRAY_SUDOERS', 'size':1, 'offset':0x8959}, {'name':'C_ARRAY_BAN_PROC', 'size':94, 'offset':0x8960}, {'name':'C_ARRAY_BAN_LOCAL_IP', 'size':48, 'offset':0x89e0}, {'name':'C_STRING_1', 'size':12, 'offset':0x8a10}, {'name':'C_STRING_2', 'size':9, 'offset':0x8a1c}, {'name':'C_STRING_3', 'size':1, 'offset':0x8a25}, : : : {'name':'C_STRING_33', 'size':20, 'offset':0x8b3e}, {'name':'C_STRING_34', 'size':1, 'offset':0x8b52}, {'name':'C_STRING_35', 'size':3, 'offset':0x8b5a}And figured the XOR offset & size, i.e. at the second sample:0x0000847a (02) 0000 ADD [EAX], AL 0x0000847c (02) 0000 ADD [EAX], AL 0x0000847e (02) 0000 ADD [EAX], AL 0x00008480 (06) dc9ba14f377b FCOMP QWORD [EBX+0x7b374fa1] // <== 0x00008486 (01) 40 INC EAX 0x00008487 (04) c114ca42 RCL DWORD [EDX+ECX*8], 0x42 0x0000848b (02) ff08 DEC DWORD [EAX] 0x0000848d (01) 16 PUSH SS 0x0000848e (01) 95 XCHG EBP, EAX 0x0000848f (05) 3544eeab90 XOR EAX, 0x90abee44 0x00008494 (02) 7d19 JGE 0x000084af ; 1Then put the offset & size in the jvoisin's script:// first sample: fd.seek(0x8480) key = fd.read(17) //second sample: fd.seek(0x84a0) key = fd.read(23)And we got the XOR decoded output values like:$ python sec2.py "./mod_sec2_config.so" 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>" :or$ 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" "%s" C_MARKER_LEFT: "{{{" C_MARKER_RIGHT: "}}}" C_TMP_DIR: "/var/tmp" C_LIST_PREF: "sess_" C_COOKIE_NAME: "PHP_SESSION_ID=" :You'll see the injection method used:C_STRING_2: text/html C_STRING_3: % C_STRING_5: document.write('%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: jInjected code is saved in %s as as per PoC'ed in traffic PCAP: These are ment to inject redirection code after tags:C_ARRAY_TAGS_FOR_INJECT: </script> </style> </head> </title> </body> </html> </table> </h1> </i> </ul>Like the below code (usage after tag): The ID, Cookies and Hashes used:C_COOKIE_NAME: PHP_SESSION_ID= 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-HashContacting mother ships with method: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: %iInfection method & traces
One should not try to seek traces on infection in /var/log/messages, is useless since the related logs were deleted. But I advise to go straight to see the traces in the Apache modules directories to grep the rogue module filenames with the above described regex, or see the TMP or TEMP environment for the "sess_" malware's blacklist / saved files.
#MalwareMustDie!Attack source IP
These are redirected IPs & source of preliminary attack:65.75.139.229 129.121.99.242 129.121.176.15 149.47.146.13 149.47.146.139 173.192.50.193 :These USA networks were used as EK redirection:65.75.190.0/18,19,20,24 https://twitter.com/MalwareMustDie/status/313007473546117120 69.50.224.0/19 https://twitter.com/MalwareMustDie/status/313002510199693312 69.89.0.0/20 https://twitter.com/MalwareMustDie/status/312999183130968064 129.121.0.0/16, https://twitter.com/MalwareMustDie/status/312995306113466368 149.47.0.0/16 https://twitter.com/MalwareMustDie/status/312991655429033985And latest attack source detected was moved to Netherland:217.23.13.65Additional
The malware is not 100% working in some infected systems. In some systems it crashes with signal 11:execve("./mod_sec2_config.so", ["./mod_sec2_config.so"], [/* 21 vars */]) = 0 --- SIGSEGV (Segmentation fault) @ 0 (0) --- +++ killed by SIGSEGV +++Blocking below libs from unknown usage willl help:/usr/lib/libbdl.so.0 /usr/lib/libm.so.6 /usr/lib/libc.so.6Blocking unknown user access to this path will help:/proc /proc/%s/comm /var/run/utmpGLIBC version used to run malware module (to block):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.0Encoding used:base64decode base64encode to_hex urlencode xor_decrypt_string xor_encrypt xor_encrypt_stringReversing Notes: Disassembly of malware functions is--> here. Complete disassembly of malware module is--> here.Samples
For raising the AV's detection ratio and research, we are sharing the samples --> here.Credits
Thank you to the wonderful individuals who help us in detection, analysis, cooperation for current threat handling: @kafeine - without him infection will be wide-spread. Denis Sinegubko of Unmask Parasites who wrote good facts of the threat from beginning! jvoisin - without this genious young man I will stuck in reversing the XOR'ed string Denis Laskov - good analysis for malware module's cookie scheme for infection Jim Kesselring - the MMD "Razor" to shut all US based infection Eric Romang - your related report helped a lot, specially NGNIX part, you know that? :-) David Harley - for the clarification of Linux/Chapro facts To all MalwareMustDie members & supporters involved in this investigation, This post is dedicated to sleepless hundreds admins who did great job in removing malwares, reinstalling and re-tuning their website due to this incident.