声明
本文是B站你想有多PWN学习的笔记,包含一些视频外的扩展知识。
有问题的源码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char sh[]="/bin/sh";
int func(char *cmd){
system(cmd);
return 0;
}
int main(){
char a[8] = {};
char b[8] = {};
puts("input:");
gets(a); // gets函数可以读取超过8个字节的数据,然后写入a,造成越界写b
printf(a);
if(b[0]=='a'){ // b数组出现'a',即进入获取shell的分支
func(sh);
}
return 0;
}
编译调试
直接hack
gcc question_1.c -o question_1_x64
用gdb调试理解这个过程
-
查看断点应该设置哪个位置
-
设置断点
输入13个a
-
查看内存中的值
p $rbp-0x10
往0x7fffffffe330前面多打几个内存看看,从0x7fffffffe310开始往后以16进制格式,按8个字节进行显示,连续打印20个。
x/20gx 0x7fffffffe310
可以看到输入输入13个a后,成功将b数组的值也越界写成aaaaa,所以b[0] == 'a’的条件会满足。
用gdb改变寄存器的值hack
1.将断点打在main
b main
2.打印$rip的汇编
x/20i $rip
3.在分支比较处设置断点
b *0x5555555552ce
4.通过GDB设置寄存器的值
0x61就是a的ascii码
- 程序进入到获取shell的分支