点击上方蓝字关注我们
学习代码审计的目标是能够独立完成对一个CMS的代码安全监测,其通用的思路有
include
文件夹下的common_fun.php
,或者有类似关键字的文件config
关键字的文件,找到mysql.class.php文件的connect()函数,查看在数据库连接时是否出现漏洞index.php,
了解程序运作时调用了哪些函数和文件以index.php文件作为标线,一层一层去扩展阅读所包含的文件,了解其功能,之后进入其功能文件夹的首页文件,进行扩展阅读..
,/<font face="-apple-system, SF UI Text, Arial, PingFang SC, Hiragino Sans GB, Microsoft YaHei, WenQuanYi Micro Hei, sans-serif, SimHei, SimSun">,</font>``\
检查传入的参数,做出限制,停止程序往下执行include()/include_once()
,require()/require_once()
寻找可控变量
1.php<?php
dirfine("ROOT",dirname(__FILE__).'/');
$mod = $_GET('mod');
include(ROOT.$mod.'.php');
?>
2.php
<?php phpinfo() ?>
allow_url_include = on
搜索关键函数
file_get_contents()
highlight_file()
fopen()
read file()
fread()
fgetss()
fgets()
parse_ini_file()
show_source()
file()
搜索关键函数
move_uploaded_file()
接着看调用这个函数的代码是否存在为限制上传格式或者可以绕过
.asp
,.cdx
, .asa
,.cer
等<?php
function getExt($filename)
{
return substr($file,strripos($filename,'.')+1);
}
$disallowed_types = array("php","asp","aspx");
$filenameExt = strtolower(getExt($_FILES['file']['name']));
if(in_array($filenameExt,$disallowed_types))
{
die("disallow type");
}
else
{
$filename = time().".".$filenameExt;
move_uploaded_file($_FILES['file']['temp'],'upload/'.$filename);
}
?>
不被允许的文件格式.php
,但是我们可以上传文件名为
1.php
(注意后面有一个空格)
content-type
验证绕过getimagesize()
函数:验证文件头只要为GIF89a,就会返回真$_FILES["file"]["type"]
的值 就是人为限制content-type为可控变量in_array()
或 利用三等于===
对比扩展名md5(time() + rand(1,1000))
搜索关键函数
unlink()
利用回溯变量的方式session_destroy()
,可以删除文件,现已基本被修复
Metinfo的任意文件删除漏洞<?php
$action = $_GET['action'];
$filename = $_GET['filename'];
if($action = "delete") {
if(is_array($filenames)) {
foreach($filenames as $filename) {
unlink('../../databack'.$filename);
}
}
}
else {
if(fileext($filenames) == "sql") {
$filenamearray = explode(".sql",$filename);
unlink('../../databack'.$filename);
unlink('../../databack/sql/metinfo_'.$filenamearray[0].'zip');
}
elae {
unlink('../../databack/'.$fileon.'/'.$filename);
}
}
?>
$action = delete
即可删除.sql
的文件,如果文件不是sql
直接删除提交的文件名
target.com/recovery.php?&action=delete&filename=../../index.php
搜索关键函数
eval()
assert()
preg_replace()
call_user_func()
call_user_func_array()
array_map()
preg_replace()
函数mixed preg_replace(mixed replacement,mixed limit = -1[,int &$count]])
当replacement 会被当做php代码执行
第一个参数为回调函数,第二个参数是回调函数的参数
<?php
$b = "phpinfo()";
call_user_func($_GET['a'],$b);
?>
eval()
和assert()
当assert()的参数为字符串时 可执行PHP代码
eval("phpinfo();"); = False eval("phpinfo()"); = True assert("phpinfo();"); = True assert("phpinfo()"); = False
#!php
<?php
$_GET['a']($_GET['b']);
?>
搜索关键函数
system()
exec()
shell_exec()
passthru()
pcntl_exec()
popen()
proc_open()
popen
和proc_open()
#!php
<?php
popen( 'whoami >> /Users/bingdaojueai/Desktop/1.txt', 'r' );
?>
所在路径就会出现一个1.txt 里面的内容为命令执行后的结果
whoami
; 直接就可以执行命令$a = 1
echo "$a" = output:1
echo '$a' = output:$a
双引号时,可以直接解析变量,造成代码执行漏洞,过狗绕过
int extract(array &$var_array,int $extract_type = EXTR_OVERWRITE,string $prefix = null)
void parse_str(string $str,array &$arr)
bool import_request_variables(string $type,string $prefix)
<?php
$a = 1;
foreach(array("_COKKIE","POST","GET") as $_request) {
foreach($$_request as $_key => $value) {
echo $_key."<br>";
$$_key = addslashes($value);
}
}
echo $a;
?>
需要思考的问题
in_array()
: 比较之前会自动转换类型
<?php
if(in_array($_GET['type_id'],array(1,2,3,4))) {
$sql = "SELECT ... WHERE type_id = '".$_GET['type_id']."'";
}
?>
is_numeric()
当传入参数为hex时 直接通过并返回true 并且MYSQL可以直接使用hex编码代替字符串明文 可以二次注入 并且可能造成XSS漏洞
==
和三等于===
in_array()
是一样的问题。exit
/return
/die
#!php
<?php
if(file_exists('install.lock)){
header("Location:xxx.com");
//exit();
}
echo "test";
?>
test依旧会被输出,替换成安装流程,PHP依旧会进行
#!php
<?php
if (check_money($price)){
//Do something
//花费几秒
$money = $money
- $price;
}
?>
可能导致漏洞函数: str_replace()
<?php
//省略
$order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']);
$order_sn = trim($order_sn);
if(!check_money($order_sn,$_GET['total_fee'])) {
//省略
}
function check_money($log_id,$money) {
$sql = "SELECT order_amount FROM xx WHERE log_id = '".$log_id."'";
//省略
}
?>
#!php
<?php
$a = addslashes($_GET['a']);
$b = addslashes($_GET['b']);
echo "$a<br>$b<br>";
$c = str_replace($a,'',$b);
echo trim($c);
?>
COOKIE验证:没有使用SESSION验证,将信息直接保存在COOKIE中
类型
==>
SQL注入/XSS<?php
$conn = mysql_connect("localhost","root","root");
mysql_select_db("test",$sonn);
$a = addslashes($_POST['pwd']);
if(!empty($a) && isset($_POST['sub'])) {
$sql1 = "UPDATE user SET password = '".$a."' WHERE name = 'sixwhale'";
$sql2 = "SELECT * FROM user WHERE name = 'sixwhale'";
if(mysql_query($sql1)) {
echo "update ok<br>";
}
else {
echo mysql_error();
}
if($row = mysql_fetch_assoc(mysql_query($sql2))) {
echo "select ok<br>";
}
}
else {
echo "no";
}
echo "select * from xx where = '".$row['password']."'<br>";
echo $a;
?>
<html>
<from action="" method="POST">
<input type="text" name="pwd">
<input type="submit" name="sub">
</from>
</html>
$_SERVER
变量:PHP5以后,$_SERVER取到的header不再受GPC影响,就算开启特殊字符也不会被转义,存在注入
编码问题转换%df '
单引号自动被转义成(%5c),同时%df
与%5c
连在一起组合成運
字单引号依然在,成功闭合。【php与mysql交互过程中发生的编码转换问题】1. mb_convert_encoding()
#!php
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<?php
$sql = "WHERE id='".urldecode("-1%df%5c' == ")."'";
print_r(mb_convert_encoding($sql,"UTF-8","GBK"));
?>
#!php
<?php
include($_GET['file'].'.php');
//1.php?file=2.txt%00
//2.txt里面是 <?php phpinfo()?>
?>
iconv函数字符编码转换截断:【对PHP版本有要求】
#!php
chr(128)—chr(255)可以截断字符
<?php
$a = '1'.chr(130).'2’;
echo $a."<br>";
echo iconv("UTF-8", "GBK", $a); //1
?>
php:// 输入输出流
#!php
<?php
include($_GET[‘file']);
?>
1.php?file=php://filter/convert.base64-encode(内容被base64编码)/resource=example.txt(远程文件)
php代码解析标签
<script language="php">…</script>
<?…?>
:php3.0.4版本后可用<%…%>
:asp标签,需要asp_tags=on,默认是off
正则表达式<?php
¥conn= mysql_connect("localhost","root","root");
mysql_select_db("test",$conn);
$sql1 = "SELECT 1 FROM (SELECT count(*),concat(USER(),floor(rand(0)*2)) x FROM
information_schema.TABLES GROUP BY x) a";
$sql2 = "SELECT * FROM user WHERE id = 1 and
(extractvalue(1,concat(0x5c,(SELECT user()))))";
$sql3 = "SELECT * FROM user WHERE id = 1 and
(updatexml(1.concat(0x5c24,(SELECT user()),0x5e24),1))";
$sql4 = "SELECT * FROM user WHERE id = 1 and
GeometryCollection((SELECT * FROM(SELECT * FROM(SELECT user())a)b))";
$sql5 = "SELECT * FROM user WHERE id = 1 and
polygon((SELECT * FROM(SELECT * FROM(SELECT user())a)b))";
$sql6 = "SELECT * FROM user WHERE id = 1 and
multipoint((SELECT * FROM(SELECT * FROM(SELECT user())a)b))";
$sql7 = "SELECT * FROM user WHERE id = 1 and
multilinestring((SELECT * FROM(SELECT * FROM(SELECT user())a)b))";
$sql8 = "SELECT * FROM user WHERE id = 1 and
multiolygon((SELECT * FROM(SELECT * FROM(SELECT user())a)b))";
$sql9 = "SELECT * FROM user WHERE id = 1 and
linestring((SELECT * FROM(SELECT * FROM(SELECT user())a)b))";
$sql10 = "SELECT * FROM user WHERE id = 1 and
exp(~(SELECT * FROM(SELECT user())a))";
$res = mysql_query($sql10);
if(!res){
echo mysql_error();
}
?>
windows findfirstfile
利用:若要搜索12345.txt文件,可使用1<<
来代替或者12<<
,不可以单独使用一个"<"
或">"
,因为单独一个只是代表了一个字符,两个代表多个字符
[0]参考文章:https://blog.csdn.net/m0_60640202/article/details/121713032
如果想要系统学习网络安全技术
不妨加入知识星球课程
《60天入门网络安全渗透测试》
从入门到案例,贴合实战
轻松易懂、好玩实用
限时领取
知识星球
活动优惠券
跟着60天入门学习路线一起学
期待你的到来!
往期推荐
从入门到入狱的技术,可以学,别乱用!
网络安全学习方向和资源整理(建议收藏)
一个web安全工程师的基础学习规划
资源 | 渗透测试工程师入门教程(限时领取)
5年老鸟推荐10个玩Python必备的网站
推荐十个成为网络安全渗透测试大佬的学习必备网站!
那些社工师不为人知的秘密。。。
更多内容请关注公众号
网络安全自修室
点个在看你最好看