网络安全:sql注入基础

 

有一阵时间没在写博客,倒是没有闲下来。只是能写的东西到了一段落。

 

新起一个段落。本来这个分类是为了写信息安全的东西,包括网络和系统两方面。能力加精力的原因,下面以网络安全为主吧。

 

这篇文章介绍sql注入的基础,会从一个简单的例子进入,一点点讲解sql注入的基础原理。大佬让行就好了,不要在这里浪费时间。

 

如果你是小白,对渗透感兴趣,但也只是停留在了解的层面上,希望你看完这篇文章有一点新的认识。

 

首先,环境搭建。(这是你练习技术的主要手段,不要尝试着在没有拿到授权的情况下,渗透别人的网站。那是wei(二声) fa(三声)的,算不上fan(四声) zui(四声),因为既然你在看这篇文章,就说明你的技术水平不允许你fan zui。)

 

例子借助DVWA讲解,有很多小盆友不晓得是啥子。这是一个歪果仁写的web,旨在学习渗透。链接在这里:

 

https://github.com/ethicalhack3r/DVWA

 

当下来部署在本地,就可以在本地进行渗透测试,你也就不用担心人家查水表了。本地服务器怎么部署呢?我们借助phpstudy。又有小朋友不知道phpstudy是啥子。emmmm,它是一个web集成环境Apache + PHP + MySQL。

 

apache是什么?php呢?(小声BB)

 

emmm,要不然您别往下看了,有点难。(笑)

 

好吧,apache和php听说过就好,如果sql语句不懂,就真的别在往下看了。你的时间很珍贵,先去学习数据库基础。

 

apache就是我们经常说的服务器,其实并不准确,apache只是一个容器,让你可以去访问它。既然访问了它,就要它提供一些服务,比如你点开这篇文章,服务器返回给了你这篇博文,这就是它提供给你的服务。至于提供什么服务,需要代码编写,php就是其中一种语言。

 

最后mysql是数据库的一种,以下的内容,默认你有sql基础。phpstudy下载链接:

 

https://www.xp.cn/

 

这里的部署过程我们就不说了,去搜索一下,很简单。

 

 

把下载好的DVWA解压到www目录下面。

 

启动服务器:

                                 

打开浏览器访问:localhost/DVWA-master(或127.0.0.1/DVWA-master),就会跳转到登录页面。默认登录账号密码admin和password。

 

登录成功后:

 

左侧列表会看到一些渗透的目录,sql注入就是我们接下来要用的。phpstudy还有很多玩法,感兴趣的小朋友自己去寻吧。

 

首先,在下方位置:

调换一下难度系数。既然我们的水平那么好,那我们就选最low的那个。(记得点击submit)

 

之后我们进入sql注入:

 

随便输入点什么东西。

  

 

其它选项--mysql工具--mysql命令行。

 

phpstudy集成了数据库可视化工具及可视化web工具,这里我们不使用。还是最开始说的,本文章旨在弄懂原理。

 

查看数据库,如果DVWA部署没问题,会自动创建一个dvwa数据库。看看里面有什么东西。

 

里面有两张表(table),users和guestbook。我们查看users表的内容,发现其中的first_name字段就是网页上显示出来的内容。也就是说,服务器将收到我们网页传过来的1和2作为user_id对users表进行查询,拿出来first_name字段显示在网页上。而我们要做的就是,通过修改传递给服务器的数据,让你输出一些其他的东西。比如这个表中的password字段。

 

下一步,看这里:

url(拜托别问我url是什么,网址!!!!)中,?之后的为传递的参数,通过url传递参数的这种方式叫做GET,另一个常用的方法是POST。

 

简单了解下就行,这里有篇以前写的文章,主要写的是抓包后的修改,对GET和POST没什么了解的可以简单看下。知道区别就行。(不翻墙可能有点慢,别急)

 

https://huayuquan.github.io/page/Http_request_response.html

 

我们知道了,url中id的值就是我们输入的参数。尝试下直接修改url,把id=2换成id=1,回车访问看看是不是admin?

 

这种url中有类似?id=xx,U_id=xx,诸如此类的,就是我们判断可能存在注入的警示。

 

如何判断?输入一些奇特但又符合语法的东西,例如1' and 1=1#:

 

网页正常返回,就说明存在注入。什么意思呢?我们回到最开始的地方,这个输入框的功能是什么?接收用户发送的一个数字,然后查询数据库,把对应ID的name给你返回。

 

注意,它默认你输入的是数字,并没有对你的输入进行检测。这就是问题所在,我们可以通过输入一些变相的sql语句让它查询一些我们想要查询的东西。

 

一般我们都是进行黑盒测试,即在不知道源码的情况下进行渗透。为了方便讲解,为什么这样可以判断是否有渗透。我们看下源码它是怎样处理的。

 

在web的尾部,有个view source:

                                              

 

这是一段php脚本,不懂没关系,等会我教你做英语翻译。

文本也放出来:

<?php 

if( isset( $_REQUEST[ 'Submit' ] ) ) { 
    // Get input 
    $id = $_REQUEST[ 'id' ]; 

    // Check database 
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; 
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

    // Get results 
    while( $row = mysqli_fetch_assoc( $result ) ) { 
        // Get values 
        $first = $row["first_name"]; 
        $last  = $row["last_name"]; 

        // Feedback for end user 
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>"; 
    } 

    mysqli_close($GLOBALS["___mysqli_ston"]); 
} 

?> 

 

发散一下,我们在做英语阅读或者英语翻译的时候。词都不认识,即阅读了,但是没理解。怎么办?

 

找主干,比如:

 

A boy, who was considered smart and handsome, achieve a great socroe in this exam ,which we feel normal.

 

最后剩下什么呢?A boy achieve a great score(随便找的例子,原题这里应该写错了)。一个小男孩得到一个不错的分数。(完,其他那么多东西知不知道,完全不重要。)

 

回来看那段php脚本。找主干:

 

划拉划拉,就剩一句(这里纯粹是为了搞笑,当然不影响你对这篇文章的阅读,但是如果你想在这个方向继续下去,php语言是必须会的,起码要看懂。小本本记上,找时间把php补回来。):

 

当我们从前端传递参数1时,$id的位置就会被1替换。形成如下的sql语句:

 

 $query = " select first_name, last_name from users where user_id = '1'; ";

 

而数据库中执行的就是双引号中的语句:

 

select first_name, last_name from users where user_id = '1';

 

我说过,你要有sql基础,如果上面请你离开的时候,你坚持到了现在。Now,你可以点击关闭了,因为我不会说基础的sql语法知识,只谈逻辑。

 

好的,扯回来。后面我们发送了1' and 1=1#,为什么它能判断是否有注入。把输入替换$id看看是什么:

 

"select first_name, last_name from usres where user_id = '1' and 1=1# ' ;  ";

 

同样的,数据库执行双引号之间的sql语句:

 

select first_name, last_name from usres where user_id = '1' and 1=1# ' ;

 

mysql中#为注释,也就是说#之后的内容不会执行。

 

换而言之数据库执行的sql语句是:

 

select first_name, last_name from usres where user_id = '1' and 1=1

 

返回来说,我们通过一些特殊方法,让数据库执行的sql语句与正常相比多了一条 and 1=1语句。如果页面正常返回了说明什么?

 

对,and 1=1被执行了。如果他没有执行,会报错的。

 

在回看一下参数对$id的替换,明白后我们继续。

 

我们说过,渗透一般是黑盒测试,我们根本不知道数据库里面表有什么,内容是什么。而这就是我们注入要做的。

 

首先,我们需要猜测,后台执行的sql语句有几个字段。通过源码我们看到select first_name, last_name两个字段,但是我们不知道源码。这时需要order by 配合着报错信息来碰出来。

 

先介绍order by,大家肯定不陌生。就是对查询结果排序嘛。例如:

 

我们对first_name排序。有一种方法大家可能不熟悉,order by后可以接数字。例如:

order by 2是什么意思?就是按你查询字段的第二个字段排序,select user_id(第一个字段), first_name(第二个字段)

 

如果我们order by 3呢?

 

 

报错了!!!

 

此时你应该开心,因为你发现如果order by的字段不存在就会报错。那怎么注入呢?

 

 

同样的,如果理解不了,就把输入替换$id看看是什么:

 

"select first_name, last_name from usres where user_id = '1' order by 1# ' ;  ";

 

执行SQL语句为:select first_name, last_name from usres where user_id = ‘1’ order by 1

 

网页正常返回,说明order by 1正确执行了。 说明select 的字段大于等于1!

 

换个数,我们直接换成3:

 

报错了!!!Amazing!!换成2,正常返回。得到了,后台执行的sql语句查询了两个字段。

 

有什么用呢?别急,先放下,我们说另一个sql关键词union。

 

简单点说,就是把两个查询结果合并,例:

 

网页不是会显示查询结果吗。那我们就把伪造的后半段结果合并到查询结果里,让网页显示出来,这就是整个的思路。

 

之前介绍一个mysql的系统函数,database();

 

显示当前所在数据库,换句话说,我们可以执行此命令获得数据库的名字。

 

我们知道union前后的查询结果需要相同数量的字段(union本身的要求),这就是我们爆破前半句sql查询字段数的原因所在。

 

继续注入:  1' union select 1,database()#

 

实际执行语句:select first_name, last_name from usres where user_id = ‘1’ union select 1,database()

 

有看到一些重要的东西吗?数据库的名字被显示出来了——dvwa。

 

目前为止,黑盒测试中,我们知道了这个表在一个叫做dvwa的数据库中。下一步是什么?yeah,得到这个表的名字。

 

先不急下一步注入,说下理论。

 

mysql命令行中show databases;,可以看到所有的数据库,也有我们的dvwa。

 

这之中有一个数据库很重要,就是图中的第一个——information_schema。

 

这个数据库你可以了理解成是这个mysql中数据库的宏图。进去看看有什么:

众多的table中,有几个很重要。tables,columns,schemata。

 

tables表中存着数据库中所有表的结构信息。columns中放着列(或者说字段)的信息。schemata中放着数据库信息,和show databases的结果相同。

 

现在我们从tables表中获取dvwa数据库中的表(注意tables表中的两个字段table_name和table_schema):

 

 

现在我们知道了dvwa数据库中有两个表,一个是users,一个是guestbook。我们想得到users中的字段信息。How?对,就是infomation_schema中的columns表。(注意两个字段column_name和table_name)

 

这样我们就得到了users表中的字段名。我们惊奇的发现竟然有password。吼吼。来,返回到前面,继续注入。注入的流程就是刚刚我们展示的流程。

 

黑盒测试中,我们通过database()系统函数知道了数据库名字是dvwa。

 

下一步,看dvwa中的表。

 

注入:1' union select 1, table_name from information_schema.tables where table_schema="dvwa"#

 

如果前面看懂了,这里不复杂。我们看到这里爆出了dvwa表的名字,其中有一个users表。

 

 

为了美观,你可以使用group_concat函数。效果如下:1' union select 1, group_concat(table_name) from information_schema.tables where table_schema="dvwa"#

会将此字段的结果合并起来。

 

现在得到了users表的名字,继续下手,看表里的字段。

 

注入:1' union select 1, column_name from information_schema.columns where table_name="users"#

数据之大,一页放不下。还是用美观版本的吧。加group_concat()

 

注入:1' union select 1, group_concat(column_name) from information_schema.columns where table_name="users"#

 

好看多了是吧,而且一目了然。有user_id,first_name, last_name, password.......,竟然有password。别管呵呵还是嘿嘿了。

 

拿出来!!!

 

现在我们有了所有的信息,sql语句在一个叫dvwa的数据库中执行,其中有一个users表,里面有个password字段。

 

最后一脚,注入,把id为1的那个用户的名字和密码调出来!!!:

 

注入:1' union select first_name, password from users where user_id='1'#

 

看到这个有什么反应?Ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh。

 

有的同学疑问,用户名admin我知道,password那一堆是什么东西:5f4dcc3b5aa765d61d8327deb882cf99。

 

不用疑问,它就是密码,只是MD5加密过了,我们登录的时候需要的是明文。解密超简单,找个md5在线工具,查一下:

 

Ohhhhhhhhhhhh,这就是我们最开始登录Dvwa网站时候用的用户admin和password,致此,我们的一次简单渗透完成了。而最终的结果,我们得到了一个可以登录网站的账户。酷吗?

 

 

 

 

 

后记:

 

为什么存在sql注入,因为后台需要前端用户提交的输入参数。为了防止被sql注入,后台都会对用户的输入进行过滤,比如把你输入中的and,union,order by等等去掉,防止信息泄露。

 

但是注意一点,它必须需要你的输入,那过滤就是不完全的,总有绕过它的方法。如果你的注入失败了,那是因为姿势不正确(我这句话没有一个污点,麻烦不要突然开车)。

 

举个例子,后台对union进行了过滤,输入的数据会把union去掉之后再去执行。比如注入1' union select 1,2 from users#。在执行前,先过滤union,你的参数就变了1' select 1,2 from users#。

 

替换$id是什么?

 

SELECT first_name, last_name FROM users WHERE user_id = '1' select 1,2 from users。

 

这完全是个错误语句,执行失败,报错。你的注入到此为止。

 

我说过是姿势不对,试想,如此注入:1' uniunionon select 1,2 from users#

 

在union之间任意位置插入union,过滤时把union过滤掉,然后呢?就成了1' union select 1,2 from users#。

 

哈哈哈,没想到吧。你过滤掉之后,我前后的内容仍旧能拼出来一个union。

 

这只是一种绕过的姿势,而且在之后的学习过程中,你会使用各种各样奇葩的工具,根本不用如此大费周章的进行注入。学习到的绕过技巧也会越来越多,越来越花哨。

 

此例中的数据库仅为mysql,不用担心。流程都是一样的,只是不同的数据库结构的不同,对症下药即可。像最开始说的,这篇博文只为让入门的小盆友搞清注入的原理。入了门,剩下的就是怎么把“刀”磨亮了。

 

以下是看雪的一张ppt截图,贴出来,当个总结吧。

 

希望这篇博文没有让你丧失对网络安全的热情。

           

 

(ps:初学者,撰写错误与不妥之处欢迎指出,我会将您的评论贴进去。另,最近在找社会工程的教程,如果有哪位读者有,又无所谓分享的话,也欢迎一并散出。阿里卡多~)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值