代码审计流程
-反向查找流程
-案例
-反向查找流程特点
-使用反向查找流程挖掘漏洞
-根源:危险函数导致漏洞
-特点:
-正向查找流程(MVC架构 Model View Controller)Controller主要分发处理请求逻辑,Model专门处理数据库相关操作,View显示给用户的一些内容
-案例
-根源:程序员疏忽或逻辑问题导致漏洞
-特点:
-双向查找流程
PHP-SQL注入漏洞挖掘技巧
-PHP+Mysql连接方法
-SQL注入漏洞常见过滤方法
-- intval / addslashes / mysql_real_escape
-- mysqli_escape_string / mysqli_real_escape_string / mysqli::escape_string
-- PDO::quote
-- 参数化查询
-addslashes / mysql_real_escape
\'
// \ ==> \\
// " ==> \"
// \x00 ==> \0
$sql = "SELECT * FROM dual WHERE id = '$id';";
echo $sql;
?>
-mysqli::escape_string / PDO::quote
-参数化查询
-案例:贷齐乐系统header注入
-略读代码,了解架构
-目标:找到没有进行过滤的输入点
-结果:$SERVER[HTTP\*]均无过滤导致注入
-入手点
-案例:ThinkSNS某版本SQL注入漏洞
-略读代码,了解架构
-目标:找到t函数过滤完成以后也可以注入的点
-结果:表名位置SQL注入漏洞
-案例:Metinfo企业网站管理系统SQL注入漏洞
-略读代码,了解架构
-目标:获取绕过全局GPC的方法
-结果:利用base64_decode来引入单引号
上方部分总结
-文件名 $_FILES[][name]
-php://input
-引入单引号(转义符)的方法
简单分析SQL注入的诱因
前言配置
我的common.php中配置
我的mysql中表的值
第一个SQL代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
这题明显没有任何过滤,并且是最基础的sql注入漏洞直接联合查询就可以搞过
第二个SQL代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
这题加了一个addslashes将单引号转义了,在单引号前面加了个\所以这题是无法注入的,宽字节注入得是上下文gbk编码什么能够宽字节编码的,所以这题也无法注入,应该说,以我技术看不出来。
第三个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
分析一下htmlspecialchars,查文档说将特殊符号转换为html实体编码,处理xss漏洞的一个防御函数
开发者因为没有足够理解这个函数的关于单引号的触发机制导致漏洞,因为必须得设置ENT_QUOTES参数设置后才能转单引号,所以可以直接sql注入
第四个SQL注入代码分析
{$age};";
echo $query."
";
$stmt = $conn->prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
很明显的开发者因为数字比较,忽略单引号闭合,所以也不需要用单引号逃逸,所以这题也存在盲注和联合查询注入,addslashes相当于无用了
第五个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
和addslashes差不多的意思,str_replace函数将子字符串的替换,将单引号替换成\加上单引号。但是和addslashes也有很大的区别,因为它会将\也变成双\,但是str_replace就只会变一次
举例
addslashes会将我们传入的数据?name=一号\‘
转换成 ==> 一号\\\' (导致我们无法逃逸单引号)
但是开发者用str_replace时,会导致我们可以sql注入
当传入?name=一号\'
会解析成 ==> 一号\\' (单引号前的\会被转义让我们的'得以逃逸,形成sql注入)
第六个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
这个也并没有发现能够注入点,intval会将其中的字符给去掉。
第七个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
}
} catch (PDOException $e) {
echo $e->getMessage();
}
并没有将过滤后的语句传入sql语句,所以这个intval等于无用,直接注入。
第八个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
逻辑错误的分析,is_numeric会检测,如果是数字就可以执行,如果不是数字,就会弹404页面。但是解析器会继续向下运行,所以会导致SQL注入
第九个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
在if中加了个exit,让解析器无法继续执行,所以这个是无法注入的
第十个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
分析:因为这里的$order传参是控制 查询出来的结果是升序(asc)或者降序(desc)
这里我们可以控制order导致sql盲注,因为这里没有报错信息,所以无法报错注入,利用,添加排序字段实现注入语句使用
,if(1=1,sleep(1),0)
或者是
and(if(1=1,sleep(1),0)) # 注意这里得用括号
第十一个SQL注入代码分析
prepare($query); // stmt = PDOStatement 预处理状态
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
分析:就是第十个代码的添加了一个过滤,必须包含asc或者desc,但是这过滤并不全,并且也没有太多限制,用,添加多一个asc就可以绕过了,如果你想让这个代码变得无法SQL注入的话
payload=asc,if(1=1,sleep(1),1)
修改代码使其无法注入
!preg_match('/^(DESC|ASC)$/i', $order)
第十二个SQL注入代码分析
prepare($query);
$stmt->bindValue("name", $name);
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
标准的预编译代码,我无法注入
第十三个SQL注入代码分析
prepare($query);
$stmt->execute();
$stmt->bind_result($name, $age,$email,$country);
while ($stmt->fetch()){
echo "$email"."
";
}
} catch (PDOException $e) {
echo $e->getMessage();
}
分析:这题其实不加urldecode是无法注入的,但是urldecode可以让我们绕过addslashes,从而绕过单引号
’ ==> %27 #单次url编码 因为浏览器会自动解码一次
‘ ==> %25%32%37 #双次url编码
payload=一号%25%32%37 union select 1,2,user(),4 %23