本文为B站国资社畜大佬《你想有多PWN》视频教程的学习实践笔记,感兴趣的可以点击阅读原文去看视频教程。
char sh[]="/bin/sh";
int init_func(){
setvbuf(stdin,0,2,0);
setvbuf(stdout,0,2,0);
setvbuf(stderr,0,2,0);
return 0;
}
int func(char *cmd){
system(cmd);
return 0;
}
int main(){
init_func();
char a[8] = {};
char b[8] = {};
puts("input:");
gets(a);
printf(a);
if(!strcmp(b,"deadbeef")){
func(sh);
}
return 0;
}
使用如下指令编译:
gcc -o vuln -g question_2.c
- 首先观察这段代码,跟上一篇的代码的区别就在于比较逻辑从b[0]==’a’变为了!strcmp(b,"deadbeef"),从单个字符比较变成了整个字符串比较;
- 那么我们先反编译main函数:
disassemble main
- 看看关键代码:
0x00000000000012f8 <+99>: lea rax,[rbp-0x10]
0x00000000000012fc <+103>: lea rsi,[rip+0xd08] # 0x200b
0x0000000000001303 <+110>: mov rdi,rax
0x0000000000001306 <+113>: call 0x10f0 <strcmp@plt>
我们关注调用strcmp之前这一段逻辑,需要读取[rbp-0x10]和[rip+0xd08]这两个地址传入rdi和rsi寄存器中,rdi就是函数的第一个参数,rsi就是函数的第二个参数;
- 为了印证我们的想法,我们可以在*main+113处打上断点,然后观察rdi和rsi存储的值:
x/s address //可以方便的查看字符串信息
- 可以看到rdi就是b数组的内容(我输入了9个a),一个a溢出到了数组b,而rsi就是strcmp的另一个参数,我们的猜想是正确的
- 那么,如果rdi和rsi的内容相等,就会getshell,我们使用set命令把rdi修改为rsi内容:
set $rdi = $rsi
1.此时我们的rdi和rsi值是相等的,然后继续执行,成功GetShell:
原文始发于微信公众号(赛博安全狗):【零基础学习PWN】GDB调试缓冲区溢出之strcmp
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论