-
-
[原创]ROP Tricks - Stack smash
-
发表于: 2020-3-21 22:14 8948
-
在程序加了 canary 保护之后,如果我们输入的内容覆盖掉 canary 的话就会报错,程序就会执行 __stack_chk_fail 函数来打印 argv[0] 指针所指向的字符串,正常情况下,这个指针指向了程序名,但是如果我们能够利用栈溢出控制这个东西,那我们就可以让 __stack_chk_fail 打印出我们想要的东西
这个题可以在 6faK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2B7j5i4u0$3K9i4y4G2K9W2)9J5k6h3y4G2L8g2)9J5c8W2)9J5y4X3&6T1M7%4m8Q4x3@1u0Q4c8e0g2Q4b7e0c8Q4z5p5c8Q4c8e0N6Q4z5p5g2Q4b7U0l9`.
IDA 分析看一下,在 _IO_getc(&v3) 处存在栈溢出
注意,下面有个 memset 指令,也就是说即便你不去第二遍输入程序自己也会给你设置成 0
memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:
void * memset( void * ptr, int value, size_t num );
参数说明:
ptr 为要操作的内存的指针。
value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII 码相互转换。
num 为 ptr 的前 num 个字节,size_t 就是unsigned int。
运行一下,发现输出了文件名,也就是 argv[0],如果可以把 argv[0] 的指针变成 flag 就可以了
但是问题是第二次输入的时候会把 flag 给覆盖掉,这就涉及到 ELF 文件的映射了,x86-64 程序的映射是从 0x400000 开始的,也就 flag 会在内存中出现两次,分别位于 0x00600d20 和 0x00400d20
这样的话即便被覆盖掉也没事,去 0x00400d20 找就是了
gdb调试一下,现在想要确定一下 argv[0] 在什么地方,在 main 函数处下个断点,然后运行起来,可以看到,在 0x7fffffffe12f 处存放着 程序的名称,而这个地址是放在 0x7fffffffdd68 的,只要把 0x7fffffffdd68 放的内容改成 flag 的地址就可以了
用 p & __libc_argv[0] 更方便,可以看下一个例题
在来找一下它相当于我们输入的时候的栈顶的位置,在 call _IO_gets 的地方下个的断点,然后 c 让他继续运行起来
可以看到此时,栈顶是 0x7fffffffdb50,用 0x7fffffffdd68 减一下,得到偏移:0x218
也就是说,我们输入的内容要 0x218 以后才能把 argv[0] 给覆盖掉,那么写了 0x218 之后把 0x00400d20 写上就可以了
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
- 对某款智能手表的分析与攻击 14913
- [原创][车联网安全]使用STM32开发板实战汽车UDS诊断 17761
- [分享]binwalk路径穿越导致RCE(CVE-2022-4510) 10534
- [原创]Hack-A-Sat 2020预选赛 beckley 14071
- [原创]一个BLE智能手环的分析 32924