热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

BWAPP之SQL注入通关

1、SQLinjection(GETsearch)low输入单引号直接报错,说明有注入点直接orderby二分法得出主查询字段数为7直接union注入





1、SQL injection(GET/search)


low

输入单引号直接报错,说明有注入点

直接order by二分法得出主查询字段数为7

直接union注入,测出回显点为2,3,4,5


image-20210411191254273

查数据库信息:


image-20210411191455987

测出数据库名为bwapp,用户为root,版本为5.5.53

查询表名:


image-20210411191918327

查询字段名:


image-20210411193238583

查字段值:


image-20210411193613249

没有难度。


medium

尝试多种方法都不行,看了一眼源码:

image-20210411201445656

发现是用addslashes()进行转义的,尝试了下宽字节绕过,也不行。

看了下原来数据库采用的是urf8编码,本来想改成gbk复现一下,结果改不成。

image-20210411201421085

character_set_system:数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式。

所以暂时想不到什么绕过方法。


high

使用了mysql_real_escape_string()函数将特殊字符转义

受影响的字符:


  • \x00
  • \n
  • \r
  • \
  • "
  • \x1a

暂时无法注入。




2、SQL Injection(GET/Select)

是一个选择表单的格式,但这也不妨碍注入。直接在url中注入

image-20210411203039359


low

输入单引号报错,说明存在注入点。

判断是数字型


image-20210411204738873

order by测出主查询字段数为7

直接union注入


image-20210411205150179

找到了回显点。

查询数据库名 bwapp

查询表名

可以用limit来限制回显个数,也可以用group_concat()一次性查出效率更高

image-20210411205605947

查询字段名


image-20210411205827571

查询数据


image-20210411210039402

medium

虽然用了addslashes()函数进行了转义,但因为是数字型的不需要单引号闭合,所以没什么用,方法和上面一样。


high

采用了PDO技术,做了参数化和预处理,将sql语句和用户输入分离,有效预防了sql注入。

image-20210411213504350




3、SQL Injection (POST/Search)


low

由于是post型注入,所以直接burp抓包:

输入单引号直接报错


image-20210411213930830image-20210411213945366

order by 测到8报错,所以确定主查询为7个字段


image-20210411214136517image-20210411214146269

测出回显点位2,3,4,5。剩下的就和上面一样了,暴数据库名、表名、字段名、字段值

image-20210411214320864


medium

用了addslashes()函数进行了转义’ " \ null,所以绕过比较困难。

但并不是说,只要加了这个函数就可以防御所有情况,这篇文章给了三种情况:

1、参数没有加引号的,直接绕过

2、宽字节注入(两种情况1.数据库字符集为gbk,2.代码中用了转换字符编码的函数)

3、addslashes()过滤后进行了url解码,直接url双重编码绕过。

总之比较灵活,还是要具体情况具体对待。

但是对这一关而言,绕过还是比较难的。


high

用了mysql_real_escape_string()函数进行了转义,绕过比较困难。

image-20210411222546698




4、SQL Injection (POST/Select)

这一关与SQL Injection(GET/Select)只是请求方式上的差异。




5、SQL Injection (AJAX/JSON/jQuery)

image-20210416194856755

可以看到通过AjAX异步请求发送到sqli_10-2.php,然后其他的和前面一样。




5、SQL Injection(CAPTCHA)

这一关和前面的区别就是多了一道验证码,正确输入验证码进入后,直接注入,手法和之前一样。




6、SQL Injection (Login Form/Hero)

使用万能密码直接登入(需要提前知道用户名)


image-20210416221804644

在用户名的位置进行注入测试:

用order by测出主查询字段数为4


image-20210416222118304image-20210416222140974

进行union注入:


image-20210416222340148image-20210416222354753

如图所示,获得回显点为2和4

获取数据库名和用户名:


image-20210416222517842image-20210416222533159

获取表名:


image-20210416222745351image-20210416222756873

获取字段名:


image-20210416222926422image-20210416222950809

获取字段值:


image-20210416223152774image-20210416223210014

最后将密码利用md5在线解密网站进行解密。

打完收工。

medium级别使用addslashes()进行转义

high级别使用mysql_real_escape_string()函数将特殊字符转义




7、SQL Injection (Login Form/User)

进行注入测试,发现存在sql注入:


image-20210417113727287image-20210417113737019

order by测出主查询字段数为9,但是无法进一步union注入。


image-20210417115702840image-20210417115710471

看一眼源码:

image-20210417115546667

发现只有密码通过后面的验证之后才能回显。

image-20210417115838168

而这一段payload回显password值为3,显然无法通过判断。

所以要想进一步注入,就要知道bee账号对应的密码的散列值,这要在实战中直接就拉闸了,顶多能进账户,想脱库很难。

为了演示,假设我们已经知道bee账号对应的散列值,重新更改payload:

image-20210417120303184

如图所示,这样的回显应该可以通过检测了。

试一下:


image-20210417120436025image-20210417120447031

果然如此,和猜想一致,不过要注意的是password字段的值要加引号,不然会报错。

然后进一步暴数据库名:


image-20210417120649472image-20210417120655581

接着暴表名、字段名、字段值。

与上一关不同之处在于,上一关在回显之前并没有验证密码,如图所示:

image-20210417141033334




8、SQL Injection - Stored (Blog)

先随便输一个:333


image-20210417144756056

发现直接将输入的语句回显到了页面上,于是判断后台应该是先将用户输入的内容存入数据库,然后查询回显。

语句大概是这样: insert into blog values(username, now(), ‘$content’)


思路一:

所以可以尝试使用报错注入:

insert into blog values(username, now(), ''or updatexml(1,concat(0x7e,database()),2) or ‘’)


image-20210417145445869image-20210417145431115

如图所示,成功爆出数据库名。

接着暴表名:


image-20210417145739868image-20210417145800030

暴字段名:


image-20210417145944671image-20210417145957365

暴字段值:


image-20210417150307715image-20210417150317964

如图所示,成功爆出用户名和字段的md5值,但是回显的字符串长度有限制,已经被截断了。

于是可以使用substr()函数来截取后一段:


image-20210417151044412image-20210417151057427

以此类推,将所有的密码截取完拼接起来。

小结:

注意报错注入一定要用concat()函数,否则无法正常回显。


思路二:

还有一种思路是构造闭合,在注入字段的后面字段中做文章。

条件:注入的那个字段,不是insert语句中的最后一个字段。

例如原句为:

insert into blog (login, content, date) values(username, ‘$content’, now())

理想效果:

insert into blog (login,content, date) values(username, ‘hello baby’, database())#’)

这是我们先验证注入字段的位置:


image-20210417143610693image-20210417143629004

如图所示报错:Column count doesn’t match value count at row 1

说明注入的字段并不是insert语句中的最后一个,满足条件。

于是加一个字段,继续测试:


image-20210417153841882image-20210417153851271

这一次没有报错,成功插入!

于是可以在后面的那个字段上做文章:

查询数据库名:


image-20210417154033235image-20210417154044248

暴表名:


image-20210417154227347image-20210417154237724

暴字段名:


image-20210417154353890image-20210417154402113

暴字段值:


image-20210417154519163image-20210417154526843

打完收工!




9、SQL Injection - Stored (User-Agent)

image-20210417170015897

从页面回显的内容来看,猜测网站会将数据包中的host和user-agent字段存入数据库中,然后回显到页面。

所以注入点可能在user-agent字段,然后后端的语句应该是insert

所以报错注入来一波:

image-20210417170348992

如图所示,成功回显数据库名,然后再依次暴表名、字段名、字段值,姿势与上面类似这里不再赘述。




10、SQL Injection - Stored (XML)

image-20210417170746266

点击any bugs然后抓包:

image-20210417170822108

发现请求包的数据是一个xml格式。

于是尝试更改bee为单引号:

image-20210417170950797

结果报错。

分析页面的功能,发现是重置秘密的,所以可能是update语句

于是报错注入来一波:

image-20210417171209740

如图所示,成功爆出数据库名。后续脱库步骤与上面相仿。


源码分析:

//sqli_8-1.php
<script type="text/Javascript">function ResetSecret(){var xmlHttp;// Code for IE7+, Firefox, Chrome, Opera, Safariif(window.XMLHttpRequest){xmlHttp = new XMLHttpRequest();}// Code for IE6, IE5else{xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");}xmlHttp.open("POST","sqli_8-2.php",true);xmlHttp.setRequestHeader("Content-type","text/xml; charset=UTF-8");xmlHttp.send("login"])){echo $_SESSION["login"];}?>Any bugs?"); //利用Ajax技术将xml文件发送到sqli_8-2.php}script>

//sqli_8-2.php$body = file_get_contents("php://input"); //访问请求的原始数据的只读流// If the security level is not MEDIUM or HIGH
if($_COOKIE["security_level"] != "1" && $_COOKIE["security_level"] != "2")
{ini_set("display_errors",1);$xml = simplexml_load_string($body); // 函数转换形式良好的 XML 字符串为 SimpleXMLElement 对象// Debugging// print_r($xml);$login = $xml->login;$secret = $xml->secret;if($login && $login != "" && $secret){$sql = "UPDATE users SET secret = &#39;" . $secret . "&#39; WHERE login = &#39;" . $login . "&#39;";// Debugging// echo $sql; $recordset = $link->query($sql);if(!$recordset){die("Connect Error: " . $link->error);}$message = $login . "&#39;s secret has been reset!";}

从上面的代码可以看出,sqli_8-1.php利用Ajax技术将xml数据发送到sqli_8-2.php后,进行xml解析,然后没有进行任何过滤直接将解析的数据拼接到sql语句中执行了,所以造成sql注入漏洞。修复方法:在拼接sql语句之前,将参数进行过滤或转义,或者使用PDO技术进行预处理和参数化。

相关函数:

file_get_contents(“php://input”) //访问请求的原始数据的只读流 详细

simplexml_load_string() //函数转换形式良好的 XML 字符串为 SimpleXMLElement 对象




11、SQL Injection - Blind - Boolean-Based

输入单引号直接报错:


image-20210417180426349image-20210417180437633

经过多次尝试,无论输入什么都只会回显The movie exists in our database!和The movie does not exist in our database!两种情况。如下图:


image-20210417180227921image-20210417180240431

image-20210417180304352image-20210417180318182

于是判断是布尔盲注。



//猜解数据库名

先猜解数据库名长度


image-20210417182503227image-20210417182647890

测出数据库名的第一个字母ascii为96(b)


image-20210417181450961image-20210417181504262

以此类推一共猜解5次测出数据库名为bwapp;



//猜解表名

先猜解数据库中表的数量

二分法测出表的数量为5


image-20210417182822493image-20210417182829752

猜解第一个表的长度:

二分法猜解出表的长度为4


image-20210417183637184image-20210417183646071

猜解第一个表的第一个字母

二分法测出为98(b)


image-20210417183230562image-20210417183242726

然后通过更改substr的参数更换字母,逐个猜解出表名的每个字母;然后再更改limit的参数更换表名,重复上述过程猜解出每张表的表名。最后猜解出表名依次为blog,heroes,movies,users,visitors。



//猜解字段名,字段值与上述过程相仿。


总结猜解三步走:

1、猜解数量

例:and (select count(table_name) from information_schema.tables where table_schema=database())>6

2、猜解长度

例:and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)>5

3、猜解值

例:and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>110

以上三步不断迭代方可制胜





12、SQL Injection - Blind - Time-Based


image-20210417205805924image-20210417205817979

image-20210417210244431image-20210417210233764

如图所示,根据回显延迟的大小就可判断。只需将布尔注入的语句与if函数和sleep函数相结合便可完成注入。

扔进sqlmap中一会就完事。




收获

关于addslashes()函数绕过的三种方式

报错注入时一定要与concat()函数相结合,不然无法正常回显

报错注入的两种思路

盲注时三步走:猜解数量、猜解长度、猜解值


推荐阅读
  • php连接mysql显示数据,php连接mysql数据库的算法思想
    本文目录一览:1、怎么用php显示mysql数据表数据 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • MySQL笔记_MySQL笔记1|数据库17问17答
    本文由编程笔记#小编为大家整理,主要介绍了MySQL笔记1|数据库17问17答相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 最近学习了关于使用最为流行的jquery发送请求,在实践中以最为简单的聊天室作为测验的辅助工具,对相关网页开发有一个初步的认识,希望大家能够一起学习进步。首先介绍一下 ... [详细]
  • 大厂首发!思源笔记docker
    JVMRedisJVM面试内存模型以及分区,需要详细到每个区放什么?GC的两种判定方法GC的三种收集方法:标记清除、标记整理、复制算法的 ... [详细]
  • 《PHP精粹:编写高效PHP代码》——2.7节设计数据库
    本节书摘来自华章社区《PHP精粹:编写高效PHP代码》一书中的第2章,第2.7节设计数据库,作者:(美 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
author-avatar
巢i仔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有