Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Notesearch Exploit anomalies (Hacking: Art of Exploitation)

Tags:

c

This question is about the exploit for the program notesearch on pg 121 of the book Hacking: Art of Exploitation 2nd Edition.

There is something I do not understand in the exploit:

When the System executes the ./notesearch 'xyz....' the argument 'xyz...' overflows the string buffer in the child program thereby overwriting the return address....that much is clear.

The assumption here is that the notesearch program's stack frame comes ontop of the calling exploit's Stack frame. This holds true when the compiled versions exist on the same system.

My first question is 1. Will this work even as a remote hack?

My second question is 2. Since the buffer has been used to overwrite all variables including and beyond the return address, how does the notesearch program work as intended? Variables like "printing" etc which sit in this stackframe and decide whether messages are printed or not all seem to work fine. Even though the calling functions sit ontop of the relevant stackframe, where the string buffer which is being flooded sits, there are certain key variables whioch would have been overwritten.

Question no. 3. Given that String buffer is part of a new stack frame pushed in after execution of notesearch starts, the buffer overwrites all the given variables in that notesearch program. Also the buffer is the value for the search string. By the program logic since the search string does not match with message, the program should not output details of the User messages. In this case, the messages appear. I want to know why?

like image 958
azero Avatar asked Nov 02 '22 07:11

azero


1 Answers

(For reference: the book is http://www.tinker.tv/download/hacking2_sample.pdf and the code is downloadable for free from http://www.nostarch.com/hacking2.htm.)

Keep reading the book; another example is given on page 122, and then there's plenty of explanatory text that tells all about the exploits.

Here's the relevant part of notesearch's code:

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

    if(argc > 1)                        // If there is an arg
        strcpy(searchstring, argv[1]);   //   that is the search string
    else                                // otherwise
        searchstring[0] = 0;             //   search string is empty

    userid = getuid();
    fd = open(FILENAME, O_RDONLY);   // open the file for read-only access

You wrote:

The assumption here is that the notesearch program's stack frame comes ontop of the calling exploit's Stack frame.

No, that's wrong. There is only one stack frame that's relevant here: the stack frame of the main() function in notesearch. The fact that we invoke ./notesearch xyz... via a system() call inside exploit_notesearch is irrelevant; we could just as well invoke ./notesearch xyz... directly on the bash command line, or trick some other process (such as, you know, bash) into executing it on our behalf.

  1. Will this work even as a remote hack?

Of course.

  1. Since the buffer has been used to overwrite all variables including and beyond the return address, how does the notesearch program work as intended?

Well, it doesn't really work as intended. Look at the output again:

reader@hacking:~/booksrc $ gcc exploit_notesearch.c
reader@hacking:~/booksrc $ ./a.out
[DEBUG] found a 34 byte note for user id 999
[DEBUG] found a 41 byte note for user id 999
-------[ end of note data ]-------
sh-3.2#

Giving you a shell clearly doesn't count as "working as intended". But even before that, the program claims to find notes for userid 999 in /var/notes, which might indicate that it's a little bit confused. In our role as the malicious hacker, we don't care about this garbage output from the notesearch program; all we care about is that it eventually reaches the end of main() and returns to our shellcode, giving us access to the shell.

But, if you're wondering how we managed to overwrite the return address without overwriting local variables userid, printing, and fd, there are at least three obvious possibilities:

A. Maybe those variables are allocated below searchstring on the stack.

B. Maybe those variables are allocated in registers instead of on the stack.

C. Overwhelmingly likely, those variables are being overwritten, but their initial values simply don't matter to the program. For example, userid can get any value at all, because that garbage value will immediately be overwritten with getuid() on the next line. The only variable whose initial value matters is printing. And even printing changes the behavior of the program only if it happens to get the value 0 — and it can't get the value 0, because the data we're copying in consists entirely of non-zero bytes, by design.

like image 197
Quuxplusone Avatar answered Nov 15 '22 06:11

Quuxplusone