Sprintf 缓冲区溢出 - RIP 寄存器包含垃圾数据

Sprintf buffer-overflow - RIP register contains garbage data

我尝试在我的程序中利用 sprintf c 函数,它是这样使用的:

char line[512];
sprintf(line,"[%s]", UserCommand);

如您所见,该行可以被利用并触发其他内容。我找到了如何更改 rbp 寄存器但是当涉及到 RIP 寄存器时,我可以用 "0xFFFF7FFFEBFF8C10" 来改变它,但是我不能用 "0x00007FFFEBFF8C10",前 2 个字节“00 00”被 0x2D5D ( ]) 替换为 0x2D5D7FFFEBFF8C10。该地址不能将我带到我的任意代码所在的缓冲区。

堆栈 $rsp-100: 0x7fffebff8d94: 0xd23148f6 0x3bc08348 0xebe8050f 0x2fffffff 0x7fffebff8da4: 0x2f6e6962 0x4168732f 0x41414141 0x41414141 0x7fffebff8db4: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffebff8dc4: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffebff8dd4: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffebff8de4: 0xffffffff 0x41414141 0x0000155a 0x41414141 0x7fffebff8df4: 0x41414141 0xebff8c10 0x205d7fff 0x00000000 0x7fffebff8e04: 0x00000000 0x00bd5760 0x00000000 0x00000000

gdb 中的回溯: 0 0x00000000004093a0 in ProcessCmd (Ctx=40, Connect=27, Msg=0x7fffebff9e32 '0' <repeats 200 times>..., Len=522) at /home/sam/srv/cmd/proc.c:305 1 0x205d7fffebff8c10 in ?? () 2 0x0000000000000000 in ?? ()

报名:

info r
rax            0xffffffff       4294967295
rbx            0x7fffebfff700   140737152808704
rcx            0x7ffff78cb1fd   140737346580989
rdx            0x919f40 9543488
rsi            0x0      0
rdi            0x919f40 9543488
rbp            0x4141414141414141       0x4141414141414141
rsp            0x7fffebff8df8   0x7fffebff8df8
r8             0x0      0
r9             0x29     41
r10            0x11     17
r11            0x0      0
r12            0x1      1
r13            0x7fffebfff9c0   140737152809408
r14            0x7fffebfff700   140737152808704
r15            0x0      0
rip            0x4093a0 0x4093a0 <ProcessCmd+407>
eflags         0x10202  [ IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0

我想知道这是否可以被利用?

有没有什么方法可以在 RIP 寄存器中获得一个有效的规范地址并删除使我的地址无效的 2 个字节?

提前致谢

sprintf(line,"[%s] ", UserCommand);sprintf 会将 '[' 写入 line,然后你的输入是 NULL terminated string,然后是 ']'' ',最后一个 NULL terminator。假设您输入包含 shellcode 的字符串并以 return 地址结尾。如您所知,%s 格式说明符在找到 NULL byte.

时将 停止 写入此输入

案例 1:

Non_NULL_Shellcode = Your_shellcode
Return_address = 0xFFFF7FFFEBFF8C10

如您所见,您的输入中没有 NULL 字节。所以 sprintf 会将 '[' 写入 line,然后你的输入 NULL terminated string 包含 shellcode 和 complete return 地址,然后是 ']'' ',最后是 NULL terminator。效果很好。

案例二:

Non_NULL_Shellcode = Your_shellcode
Return_address = 0x00007FFFEBFF8C10

有什么区别?是的,您的 return 地址末尾包含两个 NULL bytesprintf 将其解释为 STOP 从您的输入中写入的标记。所以这会发生。 sprintf'[' 写入 line,然后您的输入 NULL terminated string 包含 shellcode 和 不完整 return 地址,然后是 ']'' ',最后是 NULL terminator']' == 0x5d' ' == 0x20 在 ascii 中。当写你的 return 地址时(假设在小端) sprintf 会写 0x10, 0x8C, 0xFF, 0xEB, 0xFF, 0x7F 并继续写入 0x5D, 0x20, 最后 0x00NULL terminator。所以它解释了为什么你的地址 0x00007FFFEBFF8C10 更改为 0x205D7FFFEBFF8C100x205D 不是垃圾数据,它是您的字符串。希望对您有所帮助:).