一、 前言介绍
随着Web端在互联网行业的普遍的应用,关注Web端安全对于各行业来说已到了不再推脱和避免的形势,然而表现上的安全问题,都是通过代码层去解决的,所以代码审计能解决表面上发现不了的安全问题,从而更好的为用户提供服务。
二、 相关漏洞及代码
2.1SQL注入
2.1.1介绍
SQL注入是在程序设计时忽略了对输入字符串中夹带的SQL指令的检查,被数据库误认为是正常的SQL指令而运行,从而使数据库受到攻击,导致数据被窃取、更改、删除的行为发生的漏洞。
2.1.2漏洞演示
代码举例:
1. <?php
2. $id = $_GET['id'];
3. $conn = mysql_connect('localhost','root','root');
4. mysql_select_db('test',$conn);
5. $sql = "SELECT * FROM USER WHERE id =$id";
6. $result = mysql_query($sql) or die(mysql_error());
7. while($row = mysql_fetch_array($result)){
8. echo "ID:".$row['id']."<br>";
9. echo "USERNAME:".$row['user']."<br>";
10. echo "PASSWROD:".$row['password']."<br>";
11. }
12. mysql_close($conn);
13. echo "<br>";
14. echo $sql;
15. ?>
执行结果:
分析运行结果可知,数据库在查询数据时,将union select 1,user(),3当成的数据库执行语句放入数据库中执行,导致了数据库的信息泄露。
2.1.3防御
在PHP中对参数id加单引号进行强制转换为字符串进行处理,并使用addslashe()及mysql_real_escape_string()函数,对单引号、双引号、反斜杆、空字符等进行过滤处理。
处理后的代码:
1. <?php
2. $id = $_GET['id'];
3. $id = addslashes($id); //addslashe函数
4. $conn = mysql_connect('localhost','root','root');
5. mysql_select_db('test',$conn);
6. $id = mysql_real_escape_string($id); //mysql_real_escape_string函数
7. $sql = "SELECT * FROM USER WHERE id ='$id'"; //加单引号
8. $result = mysql_query($sql) or die(mysql_error());
9. while($row = mysql_fetch_array($result)){
10. echo "ID:".$row['id']."<br>";
11. echo "USERNAME:".$row['user']."<br>";
12. echo "PASSWROD:".$row['password']."<br>";
13. }
14. mysql_close($conn);
15. echo "<br>";
16. echo $sql;
17. ?>
2.2命令执行
2.2.1介绍
命令执行是因为在程序设计时采用了system、exec、shell_exec、passthru等危险函数,并且对用户的输入过滤不严格导致的漏洞,可执行操作系统层的shell命令,导致服务器权限失控。
2.2.2漏洞演示
代码举例:
1. <?php
2. $cmd = $_GET['cmd'];
3. echo exec($cmd);
4. ?>
执行结果:
2.2.3防御
尽量不要执行外部的应用程序或命令,或使用自定义函数或函数库实现外部应用程序或命令的功能,或使用escapeshellcmd、escapeshellarg函数过滤输入的命令及参数等等方法进行防御。
2.3代码执行
2.3.1介绍
代码执行是指程序设计时,对用户的输入过滤不严谨,导致用户可调用PHP函数执行系统层的命令,例如:eval、assert、preg_replace等函数。
2.3.2演示
代码举例:
1. <?php
2. $cmd =$_GET['cmd'];
3. eval($cmd);
4. ?>
执行结果:
2.3.3防御
对于程序设计过程中使用eval、assert、pre_replace等函数调用参数时,可使用escappeshellarg函数对参数进行过滤或着限定执行函数的可输入参数。
2.4XSS漏洞
2.4.1介绍
2.4.2漏洞演示
代码举例:
1. <?php
2. header("Content-type: text/html; charset=utf-8");
3. error_reporting(0);
4. $id = trim($_POST['id']);
5. $name = trim($_POST['name']);
6. $conn = mysql_connect('localhost','root','root');
7. mysql_select_db('test',$conn);
8. $sql = "INSERT INTO xss(id,name) VALUES('$id','$name');";
9. $result = mysql_query($sql) or die(mysql_error());
10. ?>
11. <html>
12. <body>
13. <form action="" method="POST">
14. ID:<input type="text" name="id"></br>
15. 用户名:<input type="text" name="name"></br>
16. <input type="submit" value="submit"></br>
17. </form>
18. </body>
19. </html>
20. <html>
21. <body>
22. <form action="./show.php" method="POST">
23. <input type="text" name="id">
24. <input type="submit">
25. </form>
26. </body>
27. </html>
执行结果:
2.4.3防御
采用stripslashes、htmlspecialchars、mysql_real_escape_string等函数对传入的参数进行过滤。
1. <?php
2. header("Content-type: text/html; charset=utf-8");
3. error_reporting(0);
4. $id = trim($_POST['id']);
5. $user = trim($_POST['user']);
6. $password = trim($_POST['password']);
7. $name = stripslashes($name);
8. $name = mysql_real_escape_string($name);
9. $name = htmlspecialchars($name);
2.5CSRF漏洞
2.5.1介绍
2.5.2演示
2.5.3防御
2.6文件上传漏洞
2.6.1介绍
2.6.2演示
2.6.3防御
2.7目录穿越及文件包含
2.7.1介绍
2.7.2演示
2.7.3防御
2.8任意文件读取及删除漏洞
2.8.1介绍
2.8.2演示
2.8.3防御
2.9变量覆盖漏洞
2.9.1介绍
2.9.2演示
2.9.3防御
2.10PHP伪协议
2.10.1介绍
PHP伪协议,指的是PHP其支持的协议及封装协议,涉及的相关协议有:file://、php://filter、php://input、zip://、compress.bzip2://、compress.zlib://、data://。
2.10.2演示
2.10.3防御
2.11PHP弱类型
2.11.1介绍
PHP 中存在 == (相等)、!= (不等)和 === (全等)、!== (不全等)两组运算符。由于在程序编写过程中选择了不恰当的运算符,导致程序的某些逻辑可被绕过,导致程序无法正常的运行。
2.11.2演示
代码举例:
1. <?php
2. $a = $_GET['a'];
3. $b = $_GET['b'];
4. $a_md5 = md5($a);
5. $b_md5 = md5($b);
6. if(isset($a) && isset($b)){
7. if ($a != $b && $a_md5 == $b_md5) {
8. echo "good";
9. } else {
10. echo "Sorry, just think more";
11. }
12. }
13. else{
14. echo "bad";
15. }
16. ?>
程序比较输入的a和b参数的MD5值是否相等,并且a和b的值不能相等。在PHP手册中指明了如果用 == 或 != 比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行,所以只要寻找传入的a和b的MD5一样的值就可成功输出good。
执行结果:
2.11.3防御
PHP手册中指明了如果用 == 或 != 比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行,当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。所以在进行变量比较时得仔细选择相应的运算符。