Xanda's Blog !~!

Refreshing EK Hunting Technique (Enrichment) via TTP

Jan
02

Happy new year!

It has been a while since the last update.

Today I’ve saw an update in malware-traffic-analysis on RIG EK. Nothing new, but i asked myself if my old hunting technique is still relevant today, since i left EK hunting ‘industry’ 1 year++ ago. So i wrote a simple script to perform a quick check:

xanda:tmp xanda$ ./loop.sh 109.234.36.0
109.234.36.133
109.234.36.210
DONE!

I’ve found 2 IPs; 109.234.36.133 (currently serving RIG, mentioned in malware-traffic-analysis blog) and 109.234.36.210. 109.234.36.210 is not yet serving anything malicious, but my prediction, it will be serving RIG EK in/within the next 7 days.

Some tips on this fingerprinting technique:

  1. Based on the initial IP found, look for the IP range assigned to the same ASN, in this case 109.234.36.0/24
  2. Identify the HTTP header response from the known bad IP, and use it to fingerprint the rest.
  3. Based from my experience, 1 batch of EK server setup will have similar (or almost similar) HTTP header response, and some EK will use 1 subnet for 1 batch (but not necessarily)
  4. EK server will always (mostly) be dedicated. If you found historical pDNS record on that IP, verify (with dig/nslookup) for the current IP resolved by the domain(s). For example; 109.234.36.210 has 3 historical pDNS record, but at the moment, 1 of the domain has expired, and another 2 domains are now pointing to different IP(s).
  5. This method will only works if the “scanned” hosts are alive at that particular moment

Hope it helps. Happy hunting

How Did I Find APT16 New Infa with VirusTotal pDNS and a lil Bit of Luck

Jan
25

[Quick and short update]

Last couple of weeks, I was reading the The EPS Awakens – Part 2 blog entry from FireEye and found this one IP, 121.127.249.74, was previously used as their C2 server. I used VirusTotal IP information, these few domains appeared:

2015-07-01 frppl.com
2015-07-01 jrjfj.com
2015-07-01 pjntx.com
2015-07-01 vzflx.com
2015-07-01 yeaqm.com

I went and check more information on each domain listed and found new infra (IPs) being used:

frppl.com domain information
2015-12-21 123.60.73.10
2015-07-01 121.127.249.74
 
jrjfj.com domain information
2015-12-21 123.60.73.8
2015-07-01 121.127.249.74
 
pjntx.com domain information
2015-12-28 123.60.73.9
2015-07-01 121.127.249.74
 
yeaqm.com domain information
2015-12-27 123.60.73.6
2015-07-01 121.127.249.74

I quickly check the server HTTP response header and this is what I’ve found that they are all the same:

HTTP/1.1 403 Forbidden
Server: nginx/1.6.2
Date: (current time of check)
Content-Type: text/html
Content-Length: 168
Connection: keep-alive

Okay, we already have 123.60.73.6, 123.60.73.8, 123.60.73.9, 123.60.73.10. Lets just quickly perform the HTTP response header loop for the whole /24 subnet (or maybeee i lil bit more). This is the result:

123.60.73.1
123.60.73.2
123.60.73.3
123.60.73.4
123.60.73.5
123.60.73.6
123.60.73.7
123.60.73.8
123.60.73.9
123.60.73.10
123.60.73.11
123.60.73.12
123.60.73.13
123.60.73.14
123.60.73.15
123.60.73.16
123.60.73.17
123.60.73.18
123.60.73.19
123.60.73.21
123.60.73.22
123.60.73.23
123.60.73.24
123.60.73.25
123.60.73.26
123.60.73.27
123.60.73.28
123.60.73.29
123.60.73.30
123.60.73.31
123.60.73.32
123.60.73.33
123.60.73.34
123.60.73.35
123.60.73.36
123.60.73.37
123.60.73.38
123.60.73.39
123.60.73.40
123.60.73.41
123.60.73.42
123.60.73.43
123.60.73.44
123.60.73.45
123.60.73.46
123.60.73.47
123.60.73.48
123.60.73.49
123.60.73.50
123.60.73.51
123.60.73.52
123.60.73.53
123.60.73.54
123.60.73.55
123.60.73.56
123.60.73.57
123.60.73.58
123.60.73.59
123.60.73.60
123.60.73.61
123.60.74.1
123.60.74.2
123.60.74.3
123.60.74.4
123.60.74.5
123.60.74.6
123.60.74.7
123.60.74.8
123.60.74.9
123.60.74.10
123.60.74.11
123.60.74.12
123.60.74.13
123.60.74.14
123.60.74.15
123.60.74.16
123.60.74.17
123.60.74.18
123.60.74.19
123.60.74.20
123.60.74.21
123.60.74.22
123.60.74.23
123.60.74.24
123.60.74.25
123.60.74.26
123.60.74.27
123.60.74.28
123.60.74.29
123.60.74.30
123.60.74.31
123.60.74.32
123.60.74.33
123.60.74.34
123.60.74.35
123.60.74.36
123.60.74.37
123.60.74.38
123.60.74.39
123.60.74.40
123.60.74.41
123.60.74.42
123.60.74.43
123.60.74.44
123.60.74.45
123.60.74.46
123.60.74.47
123.60.74.48
123.60.74.49
123.60.74.50
123.60.74.51
123.60.74.52
123.60.74.53
123.60.74.54
123.60.74.55
123.60.74.56
123.60.74.57
123.60.74.58
123.60.74.59
123.60.74.60
123.60.74.61

Okay i’m running out of time, my kids are waiting for me outside.

From my quick check on the domain resolved to the IP range 123.60.73.1 – 123.60.73.61 , I can safely assume that those are APT16 new infra. But I not really confident to attribute 123.60.74.1 – 123.60.74.61, but those IPs in that range, and domains revolved to that range, are fishy!

Happy hunting

Yara Rule for Angler EK redirector JS

Aug
28

Few friends ping-ed me recently and asked for intel on Angler EK. One of the thing that i can really release publicly at the moment without interfering/conflicting with my employer’s interest, is the yara rule to detect the Angler Exploit Kit redirector. The redirector is actually JS code, injected to innocent page to redirect visitor to Angler Exploit Kit.

Here you go:

rule AnglerEKredirector
{
   meta:
      description = "Angler Exploit Kit Redirector"
      ref = "http://blog.xanda.org/2015/08/28/yara-rule-for-angler-ek-redirector-js/"
      author = "adnan.shukor@gmail.com"
      date = "08-July-2015"
      impact = "5"
      version = "1"
   strings:
      $ekr1 = "<script>var date = new Date(new Date().getTime() + 60*60*24*7*1000);" fullword
      $ekr2 = "document.cookie=\"PHP_SESSION_PHP="
      $ekr3 = "path=/; expires=\"+date.toUTCString();</script>" fullword
      $ekr4 = "<iframe src=" fullword
      $ekr5 = "</iframe></div>" fullword
   condition:
      all of them
}

Yara rule for jjencode

Jun
10

I’ve recently worked on yara rule to detect jjencode. So here is my simple rule:

rule jjEncode
{
   meta:
      description = "jjencode detection"
      ref = "http://blog.xanda.org/2015/06/10/yara-rule-for-jjencode/"
      author = "adnan.shukor@gmail.com"
      date = "10-June-2015"
      version = "1"
      impact = 3
      hide = false
   strings:
      $jjencode = /(\$|[\S]+)=~\[\]\;(\$|[\S]+)\=\{[\_]{3}\:[\+]{2}(\$|[\S]+)\,[\$]{4}\:\(\!\[\]\+["]{2}\)[\S]+/ fullword 
   condition:
      $jjencode
}

See you next time 🙂

Fingerprinting (potential) Sinkhole Server

Jul
01

A short update, a note for myself

Last May, while discussing with a friend, we’ve concluded that these 2 header (HTTP header) example indicate that those servers are sinkhole servers:

HTTP/1.0 200 OK
Server: Apache 1.0/SinkSoft
Date: Tue, 27 May 2014 06:11:29 GMT
Content-Length: 0
Connection: close
HTTP/1.1 200 OK
Date: Mon, 26 May 2014 07:26:20 GMT
Server: Apache/2.2.20 (Ubuntu)
X-Sinkhole: malware-sinkhole
Vary: Accept-Encoding
Content-Length: 0
Content-Type: text/html

So we can look for:

  • Apache 1.0/SinkSoft
  • X-Sinkhole:

Today, I’ve found “Server: TornadoServer” is another indicator. But i’m not yet 100% sure. Comments are welcome