Flag: Tornado! Hurricane!

Blogs >> joestewart's Blog

Created: Wednesday, August 23 2006 08:44.39 CDT Modified: Wednesday, August 23 2006 08:48.04 CDT
Printer Friendly ...
Mocbot Command Decoding
Author: joestewart # Views: 53706

I had someone ask me how I decoded the Mocbot command encryption. I thought I'd share the answer here - its not really article-worthy but someone may get some use out of it.

First I had to do a little RCE to figure out the command flow - in the case of an encrypted communication, I find the "recv" calls and work forward from there (and backwards from "send", if the client uses encryption as well). Eventually I saw that at 0x403062 there is a command parser that executes the functions received from the botmaster. I checked in to the channel to get a sample of the encrypted commands, and saw that the syntax was something like:

!Q gjcaekepejeocacdha

So, following the command parser to the "Q" command (0x51) I landed at 0x4031d9. At that point I saw a loop right below it starting at 0x403204, which contained some "sub" and "shl" instructions which seemed to be the focus of the loop. Sounds like a trivial encryption loop. So I just went line-by-line converting the ASM into a Perl script, because I like to have a command-line tool for decrypting strings from stuff like this in the future.

Sometimes its easy to see what is happening in the decryption loop just by looking at the code. Sometimes its a little harder, so when that happens I just step through the loop, observe registers and memory locations and comment *everywhere* so I get a grasp of what the ASM does and build up a picture of the loop's functionality. Even if I'm unfamiliar with the specific ASM instruction, observing registers and memory it is referencing can tell me what its purpose is.

Here is the decryption ASM from Mocbot along with my comments:

004031D9  |>MOV EAX,DWORD PTR SS:[EBP+8]             ;  code 51 = Q (arg)
004031DC  |>MOVSX EAX,BYTE PTR DS:[EAX+1]            ; decrypt command and process
004031E0  |>CMP EAX,20
004031E3  |>JNZ exe11554.004032A9
004031E9  |>MOV EAX,DWORD PTR SS:[EBP+8]             ; command
004031EC  |>INC EAX                                  ;  skip two chars
004031ED  |>INC EAX
004031EE  |>MOV DWORD PTR SS:[EBP-40C],EAX           ;  40c = ptr to start
004031F4  |>AND DWORD PTR SS:[EBP-408],0             ; offset
004031FB  |>AND DWORD PTR SS:[EBP-404],0
00403202  |>JMP SHORT exe11554.00403212
00403204  |>/MOV EAX,DWORD PTR SS:[EBP-408]          ; loop start
0040320A  |>|INC EAX
0040320B  |>|INC EAX
0040320C  |>|MOV DWORD PTR SS:[EBP-408],EAX
00403212  |> MOV EAX,DWORD PTR SS:[EBP-40C]          ;  ptr to start
00403218  |>|ADD EAX,DWORD PTR SS:[EBP-408]          ;  offset
0040321E  |>|MOVSX EAX,BYTE PTR DS:[EAX]             ;  got some content?
00403221  |>|TEST EAX,EAX
00403223  |>|JE SHORT exe11554.0040328C              ;  jump if not
00403225  |>|MOV EAX,DWORD PTR SS:[EBP-40C]          ;  ptr
0040322B  |>|ADD EAX,DWORD PTR SS:[EBP-408]          ;  +offset
00403231  |>|MOVSX EAX,BYTE PTR DS:[EAX]             ;  first dword
00403234  |>|SUB EAX,61                              ;  subtract 61
00403237  |>|SHL EAX,4                               ;  << 4
0040323A  |>|MOV ECX,DWORD PTR SS:[EBP-404]          ;  storage
00403240  |>|MOV BYTE PTR SS:[EBP+ECX-400],AL        ;  store lower byte
00403247  |>|MOV EAX,DWORD PTR SS:[EBP-40C]          ;  ptr
0040324D  |>|ADD EAX,DWORD PTR SS:[EBP-408]          ;  +offset
00403253  |>|MOVSX EAX,BYTE PTR DS:[EAX+1]           ;  +1
00403257  |>|SUB EAX,61                              ;  sub 61
0040325A  |>|MOVSX EAX,AL                            ;  get it
0040325D  |>|MOV ECX,DWORD PTR SS:[EBP-404]          ;  storage
00403263  |>|MOVSX ECX,BYTE PTR SS:[EBP+ECX-400]     ;  grab stored byte
0040326B  |>|ADD ECX,EAX                             ;  add result
0040326D  |>|MOV EAX,DWORD PTR SS:[EBP-404]
00403273  |>|MOV BYTE PTR SS:[EBP+EAX-400],CL
0040327A  |>|MOV EAX,DWORD PTR SS:[EBP-404]
00403280  |>|INC EAX
00403281  |>|MOV DWORD PTR SS:[EBP-404],EAX
00403287  |>\JMP exe11554.00403204

Here is the resulting perl script:

#!/usr/bin/perl

my $crypt = $ARGV[0];
die "Usage: $0 <Mocbot crypted command>\n" unless $crypt =~ /^[a-z]+$/;
for (my $i = 0; $i < length($crypt); $i+=2)
{
        print chr((ord(substr($crypt, $i, 1)) - 0x61 << 4) +
                (ord(substr($crypt, $i+1, 1)) - 0x61));
}
print "\n";

Last thing to do is test against our known encrypted command:

./decode.pl gjcaekepejeocacdha
i JOIN #p

So the decrypted command is "i", a raw IRC command and the arguments tell the bot to join a second channel.

That's about it - just a little short-duration but highly focused RCE and some scripting.




Add New Comment
Comment:









There are 31,314 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
hi!
Jul/01
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit