SQL注入-代码审计

记录SQL靶场的代码审计学习。

sqli-Less-1

原代码:

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables 
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity 


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo "<font size='5' color= '#99FF00'>";
  	echo 'Your Login name:'. $row['username'];
  	echo "<br>";
  	echo 'Your Password:' .$row['password'];
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	print_r(mysql_error());
	echo "</font>";  
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

?>

漏洞点在于:
(1)参数的输入

if(isset( $_GET[‘id’]))
{
$id= $_GET[‘id’];

(2)使用拼接来进行SQL语句查询

$ sql=“SELECT * FROM users WHERE id=’ $id’ LIMIT 0,1”;

(3)明文密码的直接输出

if( $row){
echo “< font size=‘5’ color= ‘#99FF00’>”;
echo ‘Your Login name:’. $ row[‘username’];
echo “< br>”;
echo ‘Your Password:’ .$row[‘password’];
echo “< /font>”;
}

SQL注入存在的原因是对用户输入的$id没有进行任何过滤,在进行SQL语句查询的时候,也是直接进行字符串的拼接。

防御,参数化查询:

①
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
②
$stmt = $mysqli->prepare('SELECT * FROM users WHERE id = ?');

sqlib-Less-2

与第一关类似:

$ sql=“SELECT * FROM users WHERE id=$id LIMIT 0,1”;

看SQL查询语句,参数id的值为数字型。

sqlib-Less-3

$ sql=“SELECT * FROM users WHERE id=(‘$id’) LIMIT 0,1”;

与上一关的区别,参数闭合方式

sqlib-Less-4

$ sql=“SELECT * FROM users WHERE id=($id) LIMIT 0,1”;

与上一关的区别,参数闭合方式

sqlib-Less-5

原代码:

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity 


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo '<font size="5" color="#FFFF00">';	
  	echo 'You are in...........';
  	echo "<br>";
    	echo "</font>";
  	}
	else 
	{
	
	echo '<font size="3" color="#FFFF00">';
	print_r(mysql_error());
	echo "</br></font>";	
	echo '<font color= "#0000ff" font size= 3>';	
	
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

?>

漏洞点:

print_r(mysql_error());

相比上面的几关,第五关没有进行明文密码的输出,但存在一个报错回显的函数。

sqlib-Less-6

print_r(mysql_error());

与上一关的区别,参数闭合方式不同

sqlib-Less-7

原代码:

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity 


$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo '<font color= "#FFFF00">';	
  	echo 'You are in.... Use outfile......';
  	echo "<br>";
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	echo 'You have an error in your SQL syntax';
	//print_r(mysql_error());
	echo "</font>";  
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

?>

漏洞成因:

if($row)
	{echo 'You are in.... Use outfile......';}
	else 
	{echo 'You have an error in your SQL syntax';}

虽然还是直接拼接的SQL参数查询,但代码中没有涉及报错信息的回显,也没有将密码以明文形式输出,但在代码中存在一个if语句,如果输入的内容不正确,会出现错误提示:‘You have an error in your SQL syntax’。据此可以进行布尔盲注。

sqlib-Less-8

echo ‘You are in… Use outfile…’;

同上一关,参数闭合方式不同

sqlib-Less-9

if($row)
{echo ‘You are in… Use outfile…’;}
else
{echo ‘You are in… Use outfile…’;}

页面没有错误回显,也不存在页面变化,但参数的输入因为没有进行过滤(直接拼接到SQL查询语句),可以利用时间盲注。

sqlib-Less-10

与上一关的区别,参数闭合方式

sqlib-Less-11

原代码:

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);

// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
	$uname=$_POST['uname'];
	$passwd=$_POST['passwd'];

	//logging the connection parameters to a file for analysis.
	$fp=fopen('result.txt','a');
	fwrite($fp,'User Name:'.$uname);
	fwrite($fp,'Password:'.$passwd."\n");
	fclose($fp);


	// connectivity 
	@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
	$result=mysql_query($sql);
	$row = mysql_fetch_array($result);

	if($row)
	{
  		//echo '<font color= "#0000ff">';	
  		
  		echo "<br>";
		echo '<font color= "#FFFF00" font size = 4>';
		//echo " You Have successfully logged in\n\n " ;
		echo '<font size="3" color="#0000ff">';	
		echo "<br>";
		echo 'Your Login name:'. $row['username'];
		echo "<br>";
		echo 'Your Password:' .$row['password'];
		echo "<br>";
		echo "</font>";
		echo "<br>";
		echo "<br>";
		echo '<img src="../images/flag.jpg"  />';	
		
  		echo "</font>";
  	}
	else  
	{
		echo '<font color= "#0000ff" font size="3">';
		//echo "Try again looser";
		print_r(mysql_error());
		echo "</br>";
		echo "</br>";
		echo "</br>";
		echo '<img src="../images/slap.jpg" />';	
		echo "</font>";  
	}
}
?>

漏洞点:

@ $ sql=“SELECT username, password FROM users WHERE username=’ $uname’ and password=’ $passwd’ LIMIT 0,1”;

参数没有过滤,密码明文输出,SQL参数直接拼接查询,POST传参,闭合后直接进行显注。

sqlib-Less-12

与上一关的区别,参数闭合方式不同

sqlib-Less-13

if($row)
{…}
else
{print_r(mysql_error());}

数据库获取的内容无法直接显示,但代码存在有报错信息回显的函数,报错注入。

sqlib-Less-14

与上一关的区别,参数闭合方式不同

sqlib-Less-15


if($row)
	{
  		echo "<br>";
		echo '<font color= "#FFFF00" font size = 4>';
		echo '<font size="3" color="#0000ff">';	
  	}
	else  
	{
		echo '<font color= "#0000ff" font size="3">';
		//print_r(mysql_error());
	}
}

报错函数被注释,但登录失败与成功的页面回显不同,使用布尔盲注。

sqlib-Less-16

与上一关的区别,参数闭合方法不同

sqlib-Less-17

原代码:

if(isset($_POST['uname']) && isset($_POST['passwd']))

{
//making sure uname is not injectable
$uname=check_input($_POST['uname']);  
$passwd=$_POST['passwd'];

//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname."\n");
fwrite($fp,'New Password:'.$passwd."\n");
fclose($fp);

// connectivity 
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";

$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
	{
  		//echo '<font color= "#0000ff">';	
		$row1 = $row['username'];  	
		//echo 'Your Login name:'. $row1;
		$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
		mysql_query($update);
  		echo "<br>";
		if (mysql_error())
		{
			echo '<font color= "#FFFF00" font size = 3 >';
			print_r(mysql_error());
			echo "</br></br>";
			echo "</font>";
		}
		else
		{...}
	...
  	}
	else  
	{...}
}

?>

输入的参数没有做过滤,参数直接拼接到SQL查询语句,有报错信息的回显,使用报错注入。

sqlib-Less-18

原代码:

$uagent = $_SERVER['HTTP_USER_AGENT'];
	$IP = $_SERVER['REMOTE_ADDR'];
	echo "<br>";
	echo 'Your IP ADDRESS is: ' .$IP;
	echo "<br>";
if(isset($_POST['uname']) && isset($_POST['passwd']))
	{
	$uname = check_input($_POST['uname']);
	$passwd = check_input($_POST['passwd']);
	
	//logging the connection parameters to a file for analysis.	
	$fp=fopen('result.txt','a');
	fwrite($fp,'User Agent:'.$uname."\n");
	
	fclose($fp);
	$sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
	$result1 = mysql_query($sql);
	$row1 = mysql_fetch_array($result1);
		if($row1)
			{
			$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
			mysql_query($insert);	
			echo 'Your User Agent is: ' .$uagent;
			print_r(mysql_error());			
			}
		else
			{print_r(mysql_error());}
	}
?>

对于用户名和密码的输入做了验证,不存在注入点

$ uname = check_input( $_POST[‘uname’]);
$ passwd = check_input($_POST[‘passwd’]);

漏洞成因:
(1)参数uagent的的输入没有做过滤

    $uagent = $_SERVER['HTTP_USER_AGENT'];
	$IP = $_SERVER['REMOTE_ADDR'];
	echo 'Your IP ADDRESS is: ' .$IP;

(2)SQL插入语句直接拼接

$sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";

#只有当用户名和密码输入都正确时,才会将ip和uagent的值插入到数据库中
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";

mysql_query($insert);
echo 'Your User Agent is: ' .$uagent;

(3)报错信息回显函数

print_r(mysql_error()

存在报错注入,但注入点在uagent

sqlib-Less-19

$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
mysql_query($insert);
echo 'Your Referer is: ' .$uagent;

和上一关的区别在于,页面显示的数据来自referer字段,注入点也在referer位置。

sqlib-Less-20

#对cookie的值没有做过滤
if(!isset($_COOKIE['uname']))

#用户名和密码还是做了过滤
if(isset($_POST['uname']) && isset($_POST['passwd']))
		{
		$uname = check_input($_POST['uname']);
		$passwd = check_input($_POST['passwd']);
		}
		
#发现SQL查询语句中,直接拼接的cookie参数
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";

在cookie处存在报错注入

sqlib-Less-21

if(!isset($_COOKIE['uname']))

$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";

#本来以为只是闭合方式不同,后面抓完包,发现还多了个base64的加密
setcookie('uname', base64_encode($row1['username']), time()-3600);

#又去看了19关的代码,发现cookie没有经过加密
setcookie('uname', $row1['username'], time()-3600);

和上一关的区别,闭合方式不同,使用了base64加密

sqlib-Less-22

if(!isset($_COOKIE['uname']))

$cookee = base64_decode($cookee);
			$cookee1 = '"'. $cookee. '"';
			echo "<br></font>";
			$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";

与上一关的区别,闭合方式不同。

sqlib-Less-23

if(isset($_GET['id']))
{
$id=$_GET['id'];

$reg = "/#/";
$reg1 = "/--/";
$replace = "";
}
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

对参数id的输入内容做了过滤,将以下三种字符做了过滤:
.#
–+
空格

相当于把闭合符给过滤掉了,需要绕过。

将最后一个字段作为输入闭合
or关键词绕过
(详细绕过姿势,见上篇博客)

sqlib-Less-24

 $username = mysql_real_escape_string($_POST["login_user"]);
 $password = mysql_real_escape_string($_POST["login_password"]);
 $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";

方法1:
mysql_real_escape_string()函数对特殊字符做了转义,这里可以用宽字节注入%df
方法2:
在密码修改处,没有对username的输入进行转义,可进行二次注入

$username= $_SESSION["username"];

sqlib-Less-25

#黑名单防御
$id= blacklist($id);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
#and和or字段被过滤
function blacklist($id)
{
	$id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)
	$id= preg_replace('/AND/i',"", $id);		//Strip out AND (non case sensitive)
	return $id;
}

绕过:大小写、双写,&&和||

0~15关代码审计,详细见大佬文章:
sql注入——php源码的审计(以sql-lab 1~15为例)(超详细)
后续待更新……

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值