2016西安“华山杯”部分Writeup

作者: 分类: CTF 时间: 2016-09-11 评论: 暂无评论

2016西安“华山杯”部分Writeup

Web


打不过~

删掉disabled="true",加上type="submit",随便提交一个,抓包,发现返回的header头里有

Str: OGM0MzU1NTc3MTdhMTQ4NTc4ZmQ4MjJhYWVmOTYwNzk=

base64解一下再解个md5就拿下了。

系统管理

发现有提示:

<!-- $test=$_POST['username']; $test=md5($test); if($test=='0') -->

乌云有篇文章谈php弱类型的有说到,0e12353...这样的字符串等于,也就是说,我们要找到一个字串的md5是这样的形式,主义0e后面要全是数字才可以。写个脚本爆破一下子就拿到了:

md5.png

脚本代码在这里,5层循环简单粗暴

提交byGcY,提示user.php,访问得到新提示

$unserialize_str = $_POST['password']; $data_unserialize = unserialize($unserialize_str); if($data_unserialize['user'] == '???' && $data_unserialize['pass']=='???') { print_r($flag); }

是一个序列、反序列的问题,自己本地构造一下:

$t=array(
    'pass'=>'???',
    'user'=>'???'
);
$x=serialize($t);
print $x;
print gettype($x);

最后得到所要的a:2:{s:4:"pass";s:3:"???";s:4:"user";s:3:"???";}

最后到首页去连带之前的byGcY用户名一起提交,就拿下了。

序列和反序列下面还有一题,等下提供一些资料。

简单js

一段js,很简单,把关键代码拿出来,丢到Console一跑秒出。

var a,b,c,d,e,f,g;
a = 1.2;
b = a * 5;
c = a + b;
d = c / b + a;
e = c - d * b + a;
f = e + d /c -b * a;
g = f * e - d + c * b + a;
a = g * g;
a = Math.floor(a);

js.png

233

老套路,页面源码可以得到一串jsfuck代码,Console跑一下,得到一句话,Unicode转一下ANSI就得到了

unicode2ansi.png

php很烦人

根据提示

$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}

需要构造userfile。一下就能看出关键在于file_get_contents找个函数

php_input.png

查阅下资料发现,可以构造出file_get_contents('php://input','r')这样的形式,然后就会读取POST过来的数据,而不再是读取文件的内容了。

phpReadFile.png

file参数则构造php://filter/read=convert.base64-encode/resource=class.php,分别读取class.phpindex.php

<?php

class Read{//f1a9.php
    public $file;
    public function __toString(){
        if(isset($this->file)){
            echo file_get_contents($this->file);
        }
        return "__toString was called!";
    }
}
?>
<?php
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    if(preg_match("/f1a9/",$file)){
        exit();
    }else{
        include($file); //class.php
        $pass = unserialize($pass);
        echo $pass;
    }
}else{
    echo "you are not admin ! ";
}

?>

<!- -
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}
-->

发现要读取的f1a9.php被过滤了,这边要构造pass,传入序列以便反序列输出。序列反序列上面也有说到,这边给出一个官网的资料,关于序列后的格式:

<?
/*
Anatomy of a serialize()'ed value:

String
s:size:value;

Integer
i:value;

Boolean
b:value; (does not store "true" or "false", does store '1' or '0')

Null
N;

Array
a:size:{key definition;value definition;(repeated per element)}

Object
O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}

String values are always in double quotes
Array keys are always integers or strings
    "null => 'value'" equates to 's:0:"";s:5:"value";',
    "true => 'value'" equates to 'i:1;s:5:"value";',
    "false => 'value'" equates to 'i:0;s:5:"value";',
    "array(whatever the contents) => 'value'" equates to an "illegal offset type" warning because you can't use an
    array as a key; however, if you use a variable containing an array as a key, it will equate to 's:5:"Array";s:5:"value";',
     and
    attempting to use an object as a key will result in the same behavior as using an array will.
*/
?>

class.php里写了一个Read类用于读取文件,于是我们构造pass,根据上面的对象(Object)的格式来构造,pass=O:4:"Read":1:{s:4:"file";s:8:"f1a9.php";}

phpObject.png

序列和反序列,还是挺有趣的玩意儿。

序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。

可以把一个数组或对象转化成一个字符串,方便传输和存储。

下面是一些资料:

支持的协议和封装协议

php:// — 访问各个输入/输出流(I/O streams)

通过PHP反序列化进行远程代码执行

Misc


Try Everything

其实每次打CTF最享受的就是用python写脚本,特爽。

题目下来一个file,用file看了一下是gzip压缩的,gunzip解压了发现一串有点乱但是有明确flag就在里面的字串:

a o pcrcr6yteSoahTos ehaek,a:rcsht  on:@dgace.no aipl9 cr eepotr_b pFveoe{niur_deddwhahe hn kisf4taocy utuagewi vX1ooearim nvEw  mi Acmeudbbnftninofmeh}Se t 8eaimer

binwalk看了一下,发现是很多压缩包一起的,仔细看了一下,存在编号的,第一个是24,也就是说每个字符被压缩在一个包里,要按照1,2,3...的顺序解压拼接起来得到flag。

AnalyseFile.png

知道套路之后就是写脚本,直接把文件进行切割,再抓取序号,按顺序输出就得到结果了。

Since the eavesdropper have obtained our communication key, therefore we have adopted a new communication program.This is our new key:flag_Xd{hSh_ctf:4Ea9F16bA8b@c}

脚本在这里

标签: CTFPythonPHP

声明:文章基本原创,允许转载,但转载时必须以超链接的形式标明文章原始出处及作者信息。

添加新评论