Setting up the environment ========================== For this analysis I used 3 computers with the following network configuration: C1 C2 |---------| 193.x.x.x eth0 |-----------------------| eth1 |-----| |-----------------| | internet|-------------------> |Linux router / firewall| -------------| Hub |--------| computer "victim| |---------| | with masquerading | 192.168.x.x |-----| |-----------------| |-----------------------| C3 |------------| |Windows Box | |------------| C1 - P4 with TFM linux 2 installed on it . This is the firewall station where the network traffic from victim to the net can be sniffed and analided . Also i used this computer to try to communicate with the-binary installed on C2 C2 - Our "victim" computer is a 386 computer with Rh 6.2 installed ( this is the computer where the-binary will be "on wild" , and also the debugging session are performed C3 - Stand alone Windows Computer ( only used to dissassemble the-binary using reverse engineering tool IDA Pro ( www.datarescue.com ) since Datarescue didn't developed a Linux version for this GREAT tool ) C1 eth0 -> IP - 193.x.x.x ( DLink 500 TX ) eth1 -> IP - 192.168.1.1 ( DLink 500 TX ) C2 eth0 -> IP - 192.168.1.2 ( DLink 220E ) I prefer using 10M / sec eth cards on the "victims" and 100M / sec eth cards on routers and firewalls. First touch: ============ The executable is an standard ELF, statically linked , with no debugging information included. after running strings the-binary >strings.txt and a little bit of editting ( to remove some garbage ) i obtained strings.txt On the first glance it contains /bin/csh -f -c "%s" 1> %s 2>&1 so it seems that executable somehow can execute commands on the "victim" This assumption will be confirmed later after the dissassemby. Dissasembly =========== After moving the executable on the windows system and dissassemble it IDA the first results come to life . After spending time in IDA finding int 0x80 calls and sorting them by hand ( IDA does not yet recognize glibc and libc ) i was able to recognize the network part , and the startup checks. The main routine starts at 0x8048134 When executed the executable name in memory will be changed to [mingetty] it will check for root priviledge , bind raw mode protocol 11 , fork and exit . The functions table can be found at 0x804832c ( the table that contains all the functions that can be executed if a "good" packet is received by the binary . If a packet with IP protocol 11 is received the program first decode the pachet and if the packet is "correct" it will execute the associated function . Error checking is almost non existant . The only check that is done in the decrypting part is that function byte is between 0 and 11 . if function byte is over 11 the packet is discarded . A detailed list of the functions is described below . ====================================================================================================================== Functions are numbered from 01 to 12 Description for each function : function no 1 ============== No effect . function no 2 ============== Linux time sys_call function no 3 ============== remote exec 1 function no 4 ============== Another one DNS flooder See for more details function 9 Example of traffic : 04:33:23.146127 75.206.78.19.13363 > 130.191.229.14.domain: 721+ SOA? com. (21) 0x0000 4500 0031 2e00 0000 ed11 9e0c 4bce 4e13 E..1........K.N. 0x0010 82bf e50e 3433 0035 001d 0000 02d1 0100 ....43.5........ 0x0020 0001 0000 0000 0000 0363 6f6d 0000 0600 .........com.... 0x0030 01 . 04:33:23.155967 75.206.78.19.13363 > 130.192.3.21.domain: 38186+ SOA? com. (21) 0x0000 4500 0031 dd00 0000 f111 cd04 4bce 4e13 E..1........K.N. 0x0010 82c0 0315 3433 0035 001d 0000 952a 0100 ....43.5.....*.. 0x0020 0001 0000 0000 0000 0363 6f6d 0000 0600 .........com.... 0x0030 01 . 04:33:23.165962 75.206.78.19.13363 > 130.192.3.24.domain: 26517+ SOA? com. (21) 0x0000 4500 0031 af00 0000 9111 5b02 4bce 4e13 E..1......[.K.N. 0x0010 82c0 0318 3433 0035 001d 0000 6795 0100 ....43.5....g... 0x0020 0001 0000 0000 0000 0363 6f6d 0000 0600 .........com.... 0x0030 01 . function no 5 ============== root shell bind on a port function no 6 ============== Linux kill function no 7 ============== function exec with wait function no 8 ============== Linux kill sys_call function no 9 ============== Another one DNS flooder Details about this can be found here: http://teso.scene.at/advisories/teso-advisory-003.tar.gz |09|xx|xx|xx|xx|xx|xx|xx|xx|Victim ip or name Example of traffic : 04:07:06.194269 193.230.227.35.12593 > 146.175.129.3.domain: 14882+ SOA? com. (21) 0x0000 4500 0031 8100 0000 b111 cffe c1e6 e323 E..1...........# 0x0010 92af 8103 3131 0035 001d 0000 3a22 0100 ....11.5....:".. 0x0020 0001 0000 0000 0000 0363 6f6d 0000 0600 .........com.... 0x0030 01 . 04:07:06.194676 193.230.227.35.12593 > 146.176.1.5.domain: 39526+ SOA? com. (21) 0x0000 4500 0031 6300 0000 be11 60fc c1e6 e323 E..1c.....`....# 0x0010 92b0 0105 3131 0035 001d 0000 9a66 0100 ....11.5.....f.. 0x0020 0001 0000 0000 0000 0363 6f6d 0000 0600 .........com.... 0x0030 01 . 04:07:06.195089 193.230.227.35.12593 > 146.176.2.5.domain: 29733+ SOA? com. (21) 0x0000 4500 0031 5500 0000 8911 a2fc c1e6 e323 E..1U..........# 0x0010 92b0 0205 3131 0035 001d 0000 7425 0100 ....11.5....t%.. 0x0020 0001 0000 0000 0000 0363 6f6d 0000 0600 .........com.... function no 10 ============== Another Syn Flooder. More details on this http://www.cert.org/advisories/CA-1996-21.html |0a|xx|xx|xx|xx|xx|PP|PP|SS|SS|SS|SS|xx|xx|Victim ip or name| PP - victim port ( 2 bytes ) SS - Spoofed IP ( 4 bytes ) victim ip or name - victim ip ( 4 bytes ) xx - unknown purpouse 04:00:29.259280 48.49.50.48.12579 > 193.230.227.35.12593: S 2039290:2039290(0) win 678 0x0000 4500 0028 05b7 0000 ea06 c3ad 3031 3230 E..(........0120 0x0010 c1e6 e323 3123 3131 001f 1dfa 0000 0000 ...#1#11........ 0x0020 5002 02a6 2564 0000 322e 3136 2e34 P...%d..2.16.4 04:00:29.260358 48.49.50.48.36036 > 193.230.227.35.12593: S 1894501:1894501(0) win 1157 0x0000 4500 0028 0649 0000 8a06 231c 3031 3230 E..(.I....#.0120 0x0010 c1e6 e323 8cc4 3131 001c e865 0000 0000 ...#..11...e.... 0x0020 5002 0485 fd7a 0000 322e 3136 2e34 P....z..2.16.4 04:00:29.270626 48.49.50.48.25007 > 193.230.227.35.12593: S 16132434:16132434(0) win 738 0x0000 4500 0028 08d0 0000 ce06 dc94 3031 3230 E..(........0120 0x0010 c1e6 e323 61af 3131 00f6 2952 0000 0000 ...#a.11..)R.... 0x0020 5002 02e2 e86c 0000 322e 3136 2e34 P....l..2.16.4 04:00:29.280318 48.49.50.48.20715 > 193.230.227.35.12593: S 19806401:19806401(0) win 225 0x0000 4500 0028 0975 0000 d906 d0ef 3031 3230 E..(.u......0120 0x0010 c1e6 e323 50eb 3131 012e 38c1 0000 0000 ...#P.11..8..... 0x0020 5002 00e1 eb8a 0000 322e 3136 2e34 P.......2.16.4 04:00:29.290315 48.49.50.48.4561 > 193.230.227.35.12593: S 5413108:5413108(0) win 1564 0x0000 4500 0028 0de4 0000 c606 df80 3031 3230 E..(........0120 0x0010 c1e6 e323 11d1 3131 0052 98f4 0000 0000 ...#..11.R...... 0x0020 5002 061c c612 0000 322e 3136 2e34 P.......2.16.4 function no 11 ============== Syn Flooder More details on this http://www.cert.org/advisories/CA-1996-21.html |0b|xx|xx|xx|xx|xx|PP|PP|SS|SS|SS|SS|xx|xx|Victim ip or name| PP - victim port ( 2 bytes ) SS - Spoofed IP ( 4 bytes ) victim ip or name - victim ip ( 4 bytes ) xx - unknown purpouse 12:40:38.281848 48.49.50.48.3207 > 193.230.227.35.12593: S 6105370:6105370(0) win 697 0x0000 4500 0028 08ec 0000 cf06 db78 3031 3230 E..(.......x0120 0x0010 c1e6 e323 0c87 3131 005d 291a 0000 0000 ...#..11.])..... 0x0020 5002 02b9 3e8f 0000 c266 f908 0101 P...>....f.... 12:40:38.290536 48.49.50.48.25599 > 193.230.227.35.12593: S 12573384:12573384(0) win 1498 0x0000 4500 0028 0541 0000 a806 0624 3031 3230 E..(.A.....$0120 0x0010 c1e6 e323 63ff 3131 00bf dac8 0000 0000 ...#c.11........ 0x0020 5002 05da 31e5 0000 c266 f908 0101 P...1....f.... 12:40:38.290813 48.49.50.48.35961 > 193.230.227.35.12593: S 28175401:28175401(0) win 1423 0x0000 4500 0028 06ee 0000 c106 eb76 3031 3230 E..(.......v0120 0x0010 c1e6 e323 8c79 3131 01ad ec29 0000 0000 ...#.y11...).... 0x0020 5002 058f f766 0000 c266 f908 0101 P....f...f.... 12:40:38.291091 48.49.50.48.19440 > 193.230.227.35.12593: S 6480426:6480426(0) win 374 0x0000 4500 0028 07c0 0000 e006 cba4 3031 3230 E..(........0120 0x0010 c1e6 e323 4bf0 3131 0062 e22a 0000 0000 ...#K.11.b.*.... 0x0020 5002 0176 4753 0000 c266 f908 0101 P..vGS...f.... 12:40:38.291369 48.49.50.48.9526 > 193.230.227.35.12593: S 25535170:25535170(0) win 696 0x0000 4500 0028 0d50 0000 9306 1315 3031 3230 E..(.P......0120 0x0010 c1e6 e323 2536 3131 0185 a2c2 0000 0000 ...#%611........ 0x0020 5002 02b8 ab10 0000 c266 f908 0101 P........f.... 12:40:38.291646 48.49.50.48.18593 > 193.230.227.35.12593: S 35134753:35134753(0) win 605 0x0000 4500 0028 0bc4 0000 b106 f6a0 3031 3230 E..(........0120 0x0010 c1e6 e323 48a1 3131 0218 1d21 0000 0000 ...#H.11...!.... 0x0020 5002 025d 0d0f 0000 c266 f908 0101 P..].....f.... function no 12 ============== DNS traffic amplify ( flood function ) This will make DNS requests Details about this can be found here: http://teso.scene.at/advisories/teso-advisory-003.tar.gz Command format: |0c|xx|xx|xx|xx|VV|VV|VV|VV|yy|yy|yy|yy|hostname of dns server|00| xx - unknown purpouse ( maybe some sort of counter ) VV - Victim IP yy - unknown purpouse ( maybe some sort of conter ) hostname of dns server = DNS server that will flood the victim Example of Traffic generated by this kind of flood : example 1: ---------- 12:03:57.616549 32.32.32.32.8224 > 192.168.0.1.domain: 30953+ SOA? edu. (21) 12:03:57.616561 32.32.32.32.8224 > 192.168.0.1.domain: 30953+ SOA? edu. (21) 12:03:57.616762 32.32.32.32.8224 > 192.168.0.1.domain: 32079+ SOA? org. (21) 12:03:57.616773 32.32.32.32.8224 > 192.168.0.1.domain: 32079+ SOA? org. (21) 12:03:57.617231 32.32.32.32.8224 > 192.168.0.1.domain: 64204+ SOA? usc.edu. (25) 12:03:57.617270 32.32.32.32.8224 > 192.168.0.1.domain: 64204+ SOA? usc.edu. (25) 12:03:57.617234 32.32.32.32.8224 > 192.168.0.1.domain: 45479+[|domain] 12:03:57.617281 32.32.32.32.8224 > 192.168.0.1.domain: 45479+[|domain] 12:03:57.617549 32.32.32.32.8224 > 192.168.0.1.domain: 7160+[|domain] example 2 : ----------- 12:13:04.062601 49.49.49.48.12848 > 193.230.227.35.domain: 196+[|domain] 0x0000 4500 0030 b900 0000 d511 2551 3131 3130 E..0......%Q1110 0x0010 c1e6 e323 3230 0035 001c 0000 00c4 0100 ...#20.5........ 0x0020 0001 0000 0000 0000 0364 6500 0006 0001 .........de..... =================================================================================================== I developed a decoder for the data received from the network , a encoder to encode commands wich can be send to the-binary and a sender program in a attempt to better understand what this executable is. All this files can be found in files.tar The most time consuming part from all of this was to reverse the actual data decoding algorithm and to code an encoder for pachets . After the coding both coder and decoder i could make some tests with the executable . and i used gdb to watch closesly the parameters for some functions . There are still some functions that needs more attention but since this is a how to defend and not how to remote control the executable i did not comment all the parameters for functions. I outlined the main functions for each of them. To watch what happens to a packet received by the-binary i used the my encoder and gdb on the "victim" on C2 : [root@victim /]# gdb (gdb) attach 497 Attaching to Pid 497 0x8056b74 in ?? () (gdb) b *0x8048325 Brackpoint 1 at 0x8048325 (gdb) c Continuing At this point on the C1 i send a encoded packet to C2 and the breakpoint on gdb will be reached and tracing can be done . the-binary has also another trick wich makes tracing very hard to do before any commands gets to be executed it forks. Decoding routine ================ The attacker comunicate with the-binary using crypted packets . The executable contains a routine for decrypting them as shown below in assembly language : ; _text:0804A1E7 align 4 _text:0804A1E8 _text:0804A1E8 ; S U B R O U T I N E _text:0804A1E8 _text:0804A1E8 ; Attributes: bp-based frame _text:0804A1E8 _text:0804A1E8 Pack_decode proc near ; CODE XREF: sub_0_8048134+1D8 _text:0804A1E8 _text:0804A1E8 var_10 = byte ptr -10h _text:0804A1E8 result_buf = dword ptr -4 _text:0804A1E8 buf_len = dword ptr 8 _text:0804A1E8 received_buf = dword ptr 0Ch _text:0804A1E8 temp_buf = dword ptr 10h _text:0804A1E8 _text:0804A1E8 push ebp _text:0804A1E9 mov ebp, esp _text:0804A1EB sub esp, 4 _text:0804A1EE push edi _text:0804A1EF push esi _text:0804A1F0 push ebx _text:0804A1F1 mov edi, [ebp+buf_len] _text:0804A1F4 lea ebx, [edi-1] _text:0804A1F7 lea eax, [edi+3] _text:0804A1FA and al, 11111100b _text:0804A1FC sub esp, eax _text:0804A1FE mov [ebp+result_buf], esp _text:0804A201 mov al, ds:byte_0_80675E5 _text:0804A207 mov esi, [ebp+temp_buf] _text:0804A20A mov [esi], al _text:0804A20C test ebx, ebx _text:0804A20E jl loc_0_804A29B _text:0804A214 _text:0804A214 loc_0_804A214: ; CODE XREF: Pack_decode+AD _text:0804A214 lea edx, [ebx-1] _text:0804A217 test ebx, ebx _text:0804A219 jz short loc_0_804A22C _text:0804A21B mov esi, [ebp+received_buf] ; bffff44a _text:0804A21B ; _text:0804A21E movzx eax, byte ptr [ebx+esi] _text:0804A222 movzx edx, byte ptr [edx+esi] ; real pack len _text:0804A222 ; _text:0804A226 sub eax, edx _text:0804A228 jmp short loc_0_804A232 _text:0804A228 ; _text:0804A22A align 4 _text:0804A22C _text:0804A22C loc_0_804A22C: ; CODE XREF: Pack_decode+31 _text:0804A22C mov esi, [ebp+received_buf] _text:0804A22F movzx eax, byte ptr [esi] _text:0804A232 _text:0804A232 loc_0_804A232: ; CODE XREF: Pack_decode+40 _text:0804A232 lea ecx, [eax-23] _text:0804A235 test ecx, ecx _text:0804A237 jge short loc_0_804A244 _text:0804A239 lea esi, [esi+0] _text:0804A23C _text:0804A23C loc_0_804A23C: ; CODE XREF: Pack_decode+5A _text:0804A23C add ecx, 256 _text:0804A242 js short loc_0_804A23C _text:0804A244 _text:0804A244 loc_0_804A244: ; CODE XREF: Pack_decode+4F _text:0804A244 xor edx, edx _text:0804A246 cmp edx, edi _text:0804A248 jge short loc_0_804A25D _text:0804A24A lea esi, [esi] _text:0804A24C _text:0804A24C loc_0_804A24C: ; CODE XREF: Pack_decode+73 _text:0804A24C mov esi, [ebp+temp_buf] _text:0804A24F mov al, [edx+esi] _text:0804A252 mov esi, [ebp+result_buf] _text:0804A255 mov [edx+esi], al _text:0804A258 inc edx _text:0804A259 cmp edx, edi _text:0804A25B jl short loc_0_804A24C _text:0804A25D _text:0804A25D loc_0_804A25D: ; CODE XREF: Pack_decode+60 _text:0804A25D mov esi, [ebp+temp_buf] _text:0804A260 mov [esi], cl _text:0804A262 mov edx, 1 _text:0804A267 cmp edx, edi _text:0804A269 jge short loc_0_804A27E _text:0804A26B nop _text:0804A26C _text:0804A26C loc_0_804A26C: ; CODE XREF: Pack_decode+94 _text:0804A26C mov esi, [ebp+result_buf] _text:0804A26F mov al, [edx+esi-1] _text:0804A273 mov esi, [ebp+temp_buf] _text:0804A276 mov [edx+esi], al _text:0804A279 inc edx _text:0804A27A cmp edx, edi _text:0804A27C jl short loc_0_804A26C _text:0804A27E _text:0804A27E loc_0_804A27E: ; CODE XREF: Pack_decode+81 _text:0804A27E mov esi, [ebp+result_buf] _text:0804A281 push esi _text:0804A282 push ecx _text:0804A283 push offset aCS ; "%c%s" _text:0804A288 mov esi, [ebp+temp_buf] _text:0804A28B push esi _text:0804A28C call sprintf _text:0804A291 add esp, 10h _text:0804A294 dec ebx _text:0804A295 jns loc_0_804A214 _text:0804A29B _text:0804A29B loc_0_804A29B: ; CODE XREF: Pack_decode+26 _text:0804A29B lea esp, [ebp+var_10] _text:0804A29E pop ebx _text:0804A29F pop esi _text:0804A2A0 pop edi _text:0804A2A1 mov esp, ebp _text:0804A2A3 pop ebp _text:0804A2A4 retn _text:0804A2A4 Pack_decode endp _text:0804A2A4 This can be translated to the following C code : int pack_decode(unsigned char *result, unsigned char *received , int len) /* received = buffer address without header . that means actual_receved_buffer - 22 len = received len - 22 */ { unsigned char temp_buf[5000]; int i , j ; int calculus; i = len - 1 ; temp_buf[0]= 0; while ( i >= 0 ) { if ( i != 0 ) calculus = received[i] - received[i - 1]; else calculus = received[0]; calculus = calculus - 23; while ( calculus < 0 ) calculus += 0x100; for ( j = 0 ; j < len ; j ++) result[j] = temp_buf[j] ; temp_buf[0] = calculus ; for ( j = 1 ; j < len ; j ++) temp_buf[j] = result[j - 1]; sprintf(temp_buf,"%c%s",calculus,result); i-- ; } /* here in temp_buf we have an good old plain text mode + command */ } Another aproach to this method ( translating manually from ASM to C ) is to take the ASM sequence and to add it as it is to a C wrapper . But in this case it can not be done easyly due to call of sprintf. Of course this is not the place for a HowTo Translate ASM to C by hand, but if anyone is interested in such an info i will relese a separate paper to outline the main steps. Once i completed the decoder in the C i started to reverse it to obtain a coder. In this case things were preety easy. But i saw some decoding algorithms that can't be reversed that easily . Here is the result : int pack_encode(unsigned char *result, unsigned char *received , int len) { unsigned char temp_buf[5000]; int i , j ; int calculus; i = len - 1 ; received[0] = 0; for ( i = 0 ; i <= len ; i ++ ) received[i] = 0x100 - received[i]; for ( i = 1 ; i <= len ; i ++ ) { calculus = - received[i-1] + received[i]; calculus -= 23; calculus = 0x100 - calculus ; received[i] = calculus; } } In files.tar you will find source for encoder , decoder , and sender . Sender source is hardcoded to work in the configuration shown at the begining at this paper but it can be easyly addapted to another configuration ( IPs ). Conclusions =========== The binary is a "all in one wonder" . That means if the binary is installed an running on one system a remote attacker can remotely execute arbitrary commands on the system and can flood another computers. Basicly it's a Control and Flood tool. The attacker can execute any arbitrary commands on the infected system The atacker can flood another netowrks using: a) DNS Smurf type attack ( more details on this http://www.cert.org/incident_notes/IN-2000-04.html ) b) SYN flood attack (more details on this http://www.cert.org/advisories/CA-1996-21.html ) Since it uses a connection less protocol the Source IP of the atacker can be spoffed and this maked hacker tracking hard . If a system is compromised any commands can be executed on the system wich can make the system recovery hard. The best way to clean a compromised system is to reinstall it . If a compromised system is not taken out of service before the intruder is able to use any of the malicious functions contained in the program serious damage to other internal systems or to external entities may ocur. Detection of the-binary network traffic ======================================= Since the comunication betwen attacker and victim is done using protocol 11 like shown in the below traffic: root@analize# tcpdump -n tcpdump: listening on eth1 02:45:40.810845 arp who-has 192.168.1.2 tell 192.168.1.1 02:45:40.811673 arp reply 192.168.1.2 is-at 0:80:c7:75:c9:84 02:45:40.811695 192.168.1.1 > 192.168.1.2: ip-proto-11 215 You can use Snort (http://www.snort.org) and the following rule alert ip !$HOME_NET any -> $HOME_NET any (msg: "the-binary attacker to client traffic detected"; ip_proto: 11; ) or you can use tcpdump ip proto 11 to see the traffic.