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 byte
,sprintf
将其解释为 STOP 从您的输入中写入的标记。所以这会发生。 sprintf
将 '['
写入 line
,然后您的输入 NULL terminated string
包含 shellcode 和 不完整 return 地址,然后是 ']'
、' '
,最后是 NULL terminator
。 ']' == 0x5d
和 ' ' == 0x20
在 ascii 中。当写你的 return 地址时(假设在小端) sprintf
会写 0x10
, 0x8C
, 0xFF
, 0xEB
, 0xFF
, 0x7F
并继续写入 0x5D
, 0x20
, 最后 0x00
即 NULL terminator
。所以它解释了为什么你的地址 0x00007FFFEBFF8C10 更改为 0x205D7FFFEBFF8C10。 0x205D 不是垃圾数据,它是您的字符串。希望对您有所帮助:).