Friday, May 23, 2014

MMD-0023-2014 - Linux/pscan & Linux/sshscan: SSH bruter malware: A payback with attacker's email disclosure.

For about 2 weeks I analyzed the SSH login brute attacks that came into my dummy service, as per shown in the report in this link-->[Pastebin], and compiled it to graphical report of source IP of attacker in here-->[MMD Stat Site].

Even now, I am still collecting a good share of amount attacker log as per PoC'ed in below video, and toying with many configuration to learn the nature of the attack itself:

For the summary, in my observation the attacks are showing the characteristic as per below:

Using the automation for bruting SSH login account
Reconnecting to the host upon disconnected to re-try to login
Came from varied IP address, but same attack pattern
Fast in re-connecting (mili-secs!), showing an automation lightweight tools used
Coming from compromise sites/servers
About 70% source IP addresses came from nearest range, in my case: China

It was so difficult to predict the nature of attack in the beginning due to the limited reference, but IF you take time and analyze the pattern of attack well after some longer time with the good volume of logs, you will see that even majority attackers came from a certain country's IP, yet, IP with source from other countries are using the exactly similar pattern, some of these pattern are so typical like:

Firstly, aiming ssh version 1 by default
Seeking the allowed login username & retries to it
"Admin" and "root" are "heavily" aimed
All attacks has similar special characters password, suggesting wordlist used

So it is clearly that the attack were performed by the same group/community/actors, or by using same tools, or manually conducted using the exactly same methodology. Knowing how the crooks work, the second option will likely the answer, and, understanding the above attack characteristic details we can start to hunt these "bruter scheme" tools used, with hoping the bonus of the actor's info grabbed in the same time as the payback. Thank's to the dedication of our team mate, we successfully "seized in action" many of recent tools used and I found the perfect match for the weapon they used to performed this attack. I can't explain in details how we managed to "hunt" the actor's environment for the security purpose, but we peel its scheme very deep, so please see the next section for the details :-)

Bulk port scanner ELF "pscan" & a companion ELF "scanssh" (or ssh_scan) SSH login bruter

After some investigation into the recent "seized tools" in action. It came to the conclusion that the attacks is "powered" by the mass port scanner hack tool called "pscan" and follows by "scanssh" (or ssh_scan) as the SSH login bruter hack tool. Below are some of the VT detections of pscan variants (version 1 and 2) .

A variant of version pscan version 1 (original code):-->[link]

SHA256: 50bd83192d03f0b1adcbcabe34fb24e364237b04d91cec74ad4542129f506bbf
File name: pscan
Detection ratio: 1 / 52
Analysis date:  2014-05-22 23:14:15 UTC ( 0 minutes ago ) 

This is the recent variant of pscan version 2, the modded version:-->[link]

SHA256: 4422633b12627c70246d868d86cabd6702908b79f3826bcf9222ab20501cb394
File name: pscan2
Detection ratio: 21 / 51
Analysis date: 2014-05-22 23:13:06 UTC ( 0 minutes ago ) 
As the bonus :-) I pasted the "jinxed" source code of this version two in the VT comment :D for the research and mitigation purpose.

Accompanied SSH login bruter tool ELF "scanssh" or "ssh_scan". In VT is as per below:-->[link]

SHA256: 93df64cc0ff902ad1e80ada56023610ec2c44c3ecde2d36d37a3a748c7fd42bd
File name: ssh-scan
Detection ratio: 37 / 52
Analysis date:  2014-05-23 00:16:32 UTC ( 0 minutes ago ) 

How ELF "pscan(v2 and v1)" works

Since we grabbed the source code :-D - No need to reverse this one, so I am making explanation from the recent discovered C code itself.
This tool is to be executed as per below:

Usage: pscan(n)   [c-block]
it will check the file "a" in the same directory:
if (!(outfd = fopen(outfile, "a")))
The "a" script file is the starter script, control the overall flow of malicious process. In the pscan version 2, the "a" script contains instruction to scan the port 22 of the fed target listed in "$1" (the first argument that the attacker will type, according to the Usage instruction above, i.e. as per executed command line below:
././pscan2 $1 22
Executed, p2scan version 2 is coded to check & handle the flock of IPs inputted by the fed arguments:
 memset(&ip, 0, 20);
 sprintf(ip, "%s.%d.%d", argv[1], bb, cip);
 connlist[i].addr.sin_addr.s_addr = inet_addr(ip);
 if (connlist[i].addr.sin_addr.s_addr == -1)
     fatal("Invalid IP.");
 connlist[i].addr.sin_family = AF_INET;
 connlist[i].addr.sin_port = htons(atoi(argv[2]));
 connlist[i].a = time(0);
 connlist[i].status = S_CONNECTING;
it makes output, in stdout basis as per below snips:
cip = 0;
for (x = 0; x < strlen(last); x++)
memset(&last, 0, sizeof(last));
snprintf(last, sizeof(last) - 1, "%s.%d.* (total: %d) (%.1f%% done)"
    argv[1], bb, tot, (bb / 255.0) * 100);
printf("%s", last);
And always logging into a dropped scan.log text file, by default:
if (argc == 3)
    snprintf(outfile, sizeof(outfile) - 1, "scan.log", arg
else if (argc >= 4)
    snprintf(outfile, sizeof(outfile) - 1, "scan.log", arg
    bb = atoi(argv[3]);
    if ((bb < 0) || (bb > 255))
        fatal("Invalid b-range.\n");
On the other hand, for the pscan version 1, instead the the following execution of simple line, it needs different execution method in command (and its argument) to create the desired mfu.txt as the text of IP address feed to be passed to the "scanssh" login bruter program afterward.
cat $1.pscan.22 |sort |uniq > mfu.txt
oopsnr2=`grep -c . mfu.txt`
In the most cases, the "scan.log" file will be deleted in the "a" script afterwards to avoid evidence, i.e.:
mv scan.log # together w/several etc files..
So the port scanner's job was done and next, in the end, the "a" script executes the "scanssh" or "ssh_scan" tool, which is a very well-known ELF (Linux) shell hack tool for simulating the SSH connection (compiled with OpenSSL & Blowfish support too) that can be used to scan, compromise & gain access to attack the remote system's SSH service.

Additional: PoC of malware attack in progress

We finally can gain this PoC of the current case, an attack in progress and recorded well, please see the below video:

How SSH bruter ELF "scanssh" (or ssh_scan) works

The codes of the "scanssh" or "ssh_scan" tool is huge. It was compiled with the OpenSSL support (tested), and looks supporting to Blowfish authentication too (untested), it will be long to cover it all so I will be specific to the scope of this post only. In our "pscan" case, the ssh_scan is used mainly to check for the vulnerable SSH login and extract the output in a text file. Since there is no source code (yet), below is reversing snips of ssh_scan binary that reads the range IP (from the pscan) and wordlist from a text file and extracting the result in another text file. Understanding this scheme will help others to search-grep/scan and dissect the threat for the future.

This is the function to read the list of IP addresses, as you can also see, the pscan created mfu.txt was seeked:

";; Reversed section: .text ADDR: 0x804864D-0x804867B"
;; File: "ssh_scan" 93df64cc0ff902ad1e80ada56023610ec2c44c3ecde2d36d37a3a748c7fd42bd
;; asm:
0x804864D   sub     esp, 8
0x8048650   push    offset aR ; contains: "r"
0x8048655   push    offset aMfu_txt ; contains: "mfu.txt"
0x804865A   call    sub_809A210
0x804865F   add     esp, 10h
0x8048662   mov     [ebp+var_C], eax
0x8048665   cmp     [ebp+var_C], 0
0x8048669   jnz     short loc_8048681
0x804866B   sub     esp, 0Ch
0x804866E   push    offset aUndeIMfu_txt ; contains: "Unde-i mfu.txt\n"
0x8048673   call    sub_8099CA0
0x8048678   add     esp, 4
0x804867B   push    eax
And below is the function to read list of password to be bruted, as you can see it seeks the pass_file text file contains wordlist :
";; Reversed section: .text ADDR: 0x80486F0-0x804873B"
; File: "ssh_scan" 93df64cc0ff902ad1e80ada56023610ec2c44c3ecde2d36d37a3a748c7fd42bd
; asm:
0x80486F0    call    sub_80A9340
0x80486F5    test    eax, eax
0x80486F7    jnz     loc_804886B
0x80486FD    mov     ds:dword_811A684, 0
0x8048707    sub     esp, 8
0x804870A    push    offset aR ; contains "r"
0x804870F    push    offset aPass_file ; contains "pass_file"
0x8048714    call    sub_809A210
0x8048719    add     esp, 10h
0x804871C    mov     [ebp+var_424], eax
0x8048722    cmp     [ebp+var_424], 0
0x8048729    jnz     short loc_8048741
0x804872B    sub     esp, 0Ch
0x804872E    push    offset aUndeIPass_file ; contains "Unde-i pass_file\n"
0x8048733    call    sub_8099CA0
0x8048738    add     esp, 4
0x804873B    push    eax
As per described in above working summary, this is the function to write result in the file vuln.txt:
";; Reversed section: .text ADDR: 0x80484C2-0x804852D"
; File: "ssh_scan" 93df64cc0ff902ad1e80ada56023610ec2c44c3ecde2d36d37a3a748c7fd42bd
; asm:
0x80484C2    sub     esp, 8
0x80484C5    push    offset aA  ; contains:  "a+"
0x80484CA    push    offset aVuln_txt ; contains: "vuln.txt"
0x80484CF    call    sub_809A210
0x80484D4    add     esp, 10h
0x80484D7    mov     [ebp+var_9C], eax
0x80484DD    sub     esp, 8
0x80484E0    push    [ebp+arg_8]
0x80484E3    push    [ebp+arg_4]
0x80484E6    push    [ebp+arg_0]
0x80484E9    lea     eax, [ebp+var_88]
0x80484EF    push    eax
0x80484F0    push    offset aSSSS ; contains: "%s%s:%s:%s\n"
0x80484F5    push    [ebp+var_9C]
0x80484FB    call    sub_8099C70
0x8048500    add     esp, 20h
0x8048503    sub     esp, 0Ch
0x8048506    push    [ebp+arg_8]
0x8048509    push    [ebp+arg_4]
0x804850C    push    [ebp+arg_0]
0x804850F    lea     eax, [ebp+var_88]
0x8048515    push    eax
0x8048516    push    offset aSlAmprins___SS ; contains: 
                     "%sL-amPrins... !! ->%s:%s:%s\n"
0x804851B    call    sub_8099CA0
0x8048520    add     esp, 20h
0x8048523    mov     ds:dword_811A680, 1
0x804852D    jmp     short locret_8048545
And the output file format will be as per below text file contains credentials of the successfully compromised system, with noted the prefix "DUP" will appear and stand for "Duplication" in compromised login entries:
DUP user:password:IP_ADDRESS
DUP user:password:IP_ADDRESS
DUP user:password:IP_ADDRESS
Overall snippet of disassembler data is here-->[link]

Nasty tool-set & scheme isn't it? :-|
FYI. Yes, we know now that Romanian coder is behind this attack (explaining the texts in Romanian).
Moving forward, the next section is explaining how we payback these attacker! :D

The Payback: Time for these moronz to sweat!

Knowing the nature of the threat and the technique to fool attacker (thank's to @wirehack), I can grab the email addresses that are used by the hackers to send back the SSH credentials extracted by the ssh_scan to their mailbox, and trust me..these data is on the way to law enforcement right now. Some of the tool-set of pscan & ssh_scan are accompanied by perl IRC bot which revealing some handle name too. To get the email address is actualy very easy. the attacker needs to get the data extracted by the SSH bruter, as per mentioned in reversing part above, the vuln.txt. Basically they just mail (literally, yes, mail!) this file to their malbox :-D
Well this method works very well as I gained about 20+ email addresses of the active bruter actors now.

Hey, bruter skido! It is time FOR YOU to sweat now! Expect some knock on your door! ;-))

I made the video of some of the hack tools we seized (not all, for security matter), to illustrate a how to for law enforcement agencies to detect, where and what exactly the email addresses of the attacker searched in each of the packages used. The video is also to PoC the above analysis with the real result that we can get from the attacker's environment.
Hopefully this detail writing and video will describe the disclosure anatomy of major SSH bruter that keep on coming hitting us in daily basis, to be used as knowledge for all of us to dissect and mitigate this attack in our servers. :-D

Stay save folks! And.. "Thou shalt not hack!"