PHP代码审计8-XSS-XXE #
XSS一般挖的是存储型的
XSS一般按照功能点测试 按照代码点来查看
案例一:EyouCMS XSS #
符合XSS的点就是无论你上传的文件或者输入的文字打印在了页面中就可以测试XSS
可以看到我们上传的文件名是显示在上面的我们就可以测试上传一个JS代码的看能不能触发因为文件名不能包含<>所以我们发包测试
发送过去查看发现可能有过滤我们换一个img的试试
替换为img的
成功弹窗并且是存储型XSS
代码中使用fetch assign来输出没有过滤选项
案例二:PBOOT CMS #
前台发现留言板到后台我们留言看看
我们到后台密码123456默认密码 右键HTML格式查看可以发现直接实例化了
admin.php/Message/index)
找到源文件
admin/controller/content/MessageController.php
public function index()
{
$this->assign('list', true);
$this->assign('fields', $this->model->getFormFieldByCode(1)); // 获取字段
$this->assign('messages', $this->model->getList());
$this->display('content/message.html');
}
发现里面有一个getList数据库函数
public function getList()
{
return parent::table('ay_message')->where("acode='" . session('acode') . "'")
->order('id DESC')
->decode(false)
->page()
->select();
}
getlist有select函数
final public function select($type = null)
{
// 闭包查询
if (is_callable($type)) {
$type($this);
return $this->select();
}
if (! isset($this->sql['field']))
$this->sql['field'] = '*';
// 如果调用了分页函数且分页,则执行分页处理
if (isset($this->sql['paging']) && $this->sql['paging']) {
// 生成总数计算语句
$count_sql = $this->buildSql($this->countSql, false);
// 获取记录总数
if (! ! $rs = $this->getDb()->one($count_sql)) {
$total = $rs->sum;
// 分页内容
$limit = Paging::getInstance()->limit($total, true);
// 获取分页参数并设置分页
$this->limit($limit);
}
}
// 构建查询语句
$sql = $this->buildSql($this->selectSql);
if ($type === false) {
return $sql;
}
$result = $this->getDb()->all($sql, $type);
return $this->outData($result);
}
select里面有 outdata查看信息 decode_slashes
final protected function outData($result)
{
if ($this->decode) {
$result = decode_string($result);
$this->decode = false;
} else {
$result = decode_slashes($result);
}
if ($this->showRs) {
print_r($result);
exit();
} else {
return $result;
}
}
发现了实体化
// 字符反转义斜杠,支持字符串、数组、对象
function decode_slashes($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = decode_slashes($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = decode_slashes($value);
}
} else { // 字符串处理
$string = stripcslashes($string);
}
return $string;
}
但是里面有stripcslashes 它可以让字符16进制进来然后转换 就是说我们可以传入16进制字符
payload 对应16进制<和>
\x3cscript\x3ealert(\x221111111\x22)\x3b\x3c/script\x3e
\x3c→ 十六进制3C→ 对应 ASCII 字符<(小于号)。\x3e→ 十六进制3E→ 对应 ASCII 字符>(大于号)
案例三:PHPSHE XXE #
搜索XML关键代码
simplexml_load_string 找到位置查看引用地方
function pe_getxml() {
$xml = file_get_contents("php://input");
return $xml = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
}
include/plugin/payment/wechat/notify_url.php
得知通过POST直接发包所以我们直接发包测试