freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

php代码审计-sql注入初级篇
2021-09-29 16:35:54

概述

代码审计顾名思义就是检查源代码中的缺点和错误信息,分析并找到这些问题引发的安全漏洞,并提供代码修订措施和建议。这篇文章的目的是为了让小伙伴们对php代码审计有一个基本的了解,采用的代码都是自己写的仅仅能体现出漏洞所以会略显简洁。并且这次文章的主要内容为代码审计所以不会写太多的注入语句,更多的是对代码的分析,有兴趣的同学可以百度查查资料。

环境要求

phpstudy和一篇简单易懂的php源码

sql注入

SQL 注入(SQL Injection) 是发生在 Web 程序中数据库层的安全漏洞,是网站存在最多也是最简单的漏洞。 主要原因是程序对用户输入数据的合法性没有判断和处理,导致攻击者可以在 Web 应用程序中事先定义好的 SQL 语句中添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步获取到数据信息。 简而言之,SQL 注入就是在用户输入的字符串中加入 SQL 语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的 SQL 语句就会被数据库服务器误认为是正常的 SQL 语句而运行,攻击者就可以执行计划外的命令或访问未被授权的数据。

一、union查询注入

union查询注入是MySQL注入中的一种方式,在SQL注入中说了注入漏洞存在的相关条件,而联合查询注入这种方法需要满足查询的信息在前端有回显,回显数据的位置就叫回显位。

源代码

<?php
        require 'db.php';
        header('Content-type:text/html;charset=utf8');
        $username=$_POST["username"]; //获取用户输入
        $password=$_POST["password"];
        $dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
        $ck=mysqli_query($db,$dl);
        $row = mysqli_fetch_array($ck);
        if($row) {
      echo "你的账号为:".$row['username'];
      echo "你的密码为:".$row['password'];
        } else {
echo "你的输入" .$username;
}

这段代码一上来加载了一个文件db.php根据名字可以判断是连接数据库文件,接着设置编码为UTF8,然后获取用户输入的账号和密码设置为变量,赋入sql查询语句判断账号密码是否输入正确,利用query执行sql语句,再用mysqli_fetch_array把结果作为数组输出到row中。最后用if语句判断sql语句是否执行,执行成功输出用户的账号和密码,执行失败会输出用户输入的账号。代码没有任何防御,有两个回显位所以直接union注入。

注入语句为-1' union select 1,2  #

二、sql盲注

所谓的盲注就是在服务器没有错误回显的时候完成的注入攻击。服务器没有错误回显,对于攻击者来说缺少了非常重要的“调试信息

源代码

<?php
        require 'db.php';
        header('Content-type:text/html;charset=utf8');
        $username=$_POST["username"]; //获取用户输入
        $password=$_POST["password"];
        $dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
        $ck=mysqli_query($db,$dl);
        $row = mysqli_fetch_array($ck);
        if($row) {
            echo "你的输入" .$username;
        } else {
echo "输入错误" ;
}

代码和上面联合查询基本一样只是执行成功以后没有了回显,只返回成功和失败,我们可以使用用布尔盲注通过返回构造的注入语句正确与否来获取数据库里的信息。

注入语句

1' and length(database())=3 # 

三、sql延时注入

时间差注入也叫延迟注入,是一种盲注的手法提交对执行时间铭感的函数sql语句,通过执行时间的长短来判断是否执行成功,比如:正确的话会导致时间很长,错误的话会导致执行时间很短,这就是所谓的高级盲注。

源代码

<?php
        require 'db.php';
        header('Content-type:text/html;charset=utf8');
        $username=$_POST["username"]; //获取用户输入
        $password=$_POST["password"];
        $dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
        $ck=mysqli_query($db,$dl);
        $row = mysqli_fetch_array($ck);
        if($row) {
            echo "你的输入" .$username;
        } else {
            echo "你的输入" .$username;
}

这次执行成功和失败返回的结果一模一样布尔盲注的方法也不行了,我们可以使用延时注入语句让浏览器语句执行成功的同时延时五秒,延时注入一般用if()加sleep语句配合burpsuite。

注入语句

1' and if((length(database())=3),sleep(5),1) #

四、报错注入

报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。

源代码

<?php
    require 'db.php';
    header('Content-type:text/html;charset=utf8');
    $username = $_POST["username"]; //获取用户输入
    $password = $_POST["password"];
    $dl = "SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
    $ck = mysqli_query($db, $dl);
    $row = mysqli_fetch_array($ck);
	if($row)
	{
  	echo "登录成功";
  	}
	else 
	{
	print_r(mysql_error());
	}
}

报错注入就是利用返回错误信息的函数,把注入的结果通过错误信息返回来,这里可以看到代码执行失败以后会调用报错函数,可以直接在账号框里构造报错注入代码,下面示范采用的updatexml语句。报错注入常用的有floor,updatexml,extractvalue这三种。

注入语句

admin") and updatexml(1,concat(0x7e,(select database()) ,0x7e),1) #

五、cookie注入

Cookie注入简单来说就是利用Cookie而发起的注入攻击。从本质上来讲,Cookie注入与传统的SQL注入并无不同,两者都是针对数据库的注入,只是表现形式上略有不同罢了。

先来看看源码

<?php
require 'db.php';
header('Content-type:text/html;charset=utf8');
$username=addslashes($_POST['username']);
$password=MD5($_POST['password']);
$dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
$ck=mysqli_query($db,$dl);
$row = mysqli_fetch_array($ck);
if($_POST['login']){
if($row) {
setcookie('uname',$row['username']);
$cooke=$_COOKIE['uname'];
$ql="select * from xs where username='$cooke'";
$qk=mysqli_query($db,$ql);
$row1 = mysqli_fetch_array($qk);
if($row1){
echo "nidecooke 创建成功";
}
}
}?>

可以看到cookie注入和上面的代码有很大的区别。前面一大段是正常的登录判断语句,账号用了addslashes()语句进行转义,密码通过MD5加密。而cookie语句在if($row)主体里,也就是说只有我们绕过了或者输入正确的账号和密码才会去创建cookie。创建cookie以后带入了sql语句里直接执行。从代码上面来看注入位置不在登录框在cookie里。cookie查询语句执行完以后也没有回显,所以我们在cooki位置用布尔盲注试试。先用burpsuite抓包就能看见cookie了。切记在注入的时候一定要输入正确的账号和密码也就是if($row)需要返回正确的值下面的语句才会执行。

可以看到uname=1 uname是上面代码中创建的cookie我们只需在在这个位置进行布尔盲注就可以拿到想要的数据。构造这个获取当前数据库长度语句返回成功说明当前数据长度为3.

sql注入初级篇就完结了,这一篇只是小打小闹让对代码审计还不了解的同学有一个初步的认识,接下来几篇会为大家讲解一些比较难和有防御措施的代码。

# SQL注入 # 漏洞分析 # 代码审计
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录