sqli-labs Basic Challenges Less 17-18

Less 17  POST - Update Query- Error Based - String

这一关是基于报错的字符型更新查询注入,参数提交方式是post。

打开页面显示如下

很明显是一个更改用户密码的界面。尝试更改Dumb的密码观察页面响应

可以看到返回了一张成功更改密码的图片,也是没有多余显示位的。那么这里先判断一下查询语句的结构,在uname参数后面添加单引号

页面不仅没有报错,看起来还检测到了我们添加的单引号是属于黑客攻击。看看源码是怎么回事吧。

从源码来看的话,服务器端对传递的uname参数做了处理,而passwd参数则是直接带入了查询语句中进行拼接。接下来再看看对uname参数做处理的check_input()函数都做了些什么。

可以看到该函数先是截取了参数值的前15个字符。接着就判断php中的magic_quotes_gpc是否开启。

这里当magic_quotes_gpc=On的时候,函数get_magic_quotes_gpc()就会返回1,当magic_quotes_gpc=Off的时候,函数get_magic_quotes_gpc()就会返回0。

如果是magic_quotes_gpc开启了的话,stripslashes()函数就会删除由 addslashes() 函数对参数值添加的反斜杠。这里值得注意的就是默认地PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。

然而addslashes() 函数的作用就是返回在预定义字符之前添加反斜杠的字符串。该函数的预定义字符有:单引号(')、双引号(")、反斜杠(\)、NULL。

这里对参数值进行这样的处理就是防止出现当magic_quotes_gpc也开启时,和addslashes() 函数对参数值进行双重转义。这样的话就无法起到转义特殊字符的作用了。

将addslashes()添加的反斜杠删除之后,又判断参数值是否是数字,不是数字的话就对参数中的以下字符前添加反斜杠: \x00, \n, \r, \, ', " 和 \x1a。

被check_input()函数处理过的参数值才会带入到sql语句中,所以前面在uname参数值后面添加单引号才没有引起报错。但是这里passwd参数没有进过任何处理,所以我们可以通过passwd参数来进行测试。

在passwd参数后面添加单引号页面报错了,从报错信息来看参数确实是被单引号包裹的。因为这里没有显示位,所以无法使用union联合注入,接下来就是基于报错的注入过程了。

通过floor()和rand()函数报错获取当前用户名

通过updatexml()函数报错获取当前数据库名

通过extractvalue()函数报错获取当前数据库版本

使用exp()函数报错获取当前用户名

根据以往的exp()报错注入方法却没有显示错误信息。考虑到可能是因为这里不是用的select查询语句而是update语句。在exp()函数之前加上^符号则成功执行并返回报错信息。

查阅许多资料无果,个人感觉可能是因为之前的都是用在select查询中的,所以exp()函数执行了。但是这里是uodate语句,所以exp()无法执行也就无法报错了。但是在exp()函数之前加入位运算符就不一样了。因为上图在数据库中的语句如下:

UPDATE users SET password = 'Dumb1’ ^ exp(~(select * from (select user())x)) #' WHERE username='Dumb'

在#后面的语句我们可以忽略掉,但是值得注意的是

'Dumb1’ ^ exp(~(select * from (select user())x))

因为exp()函数返回的本就是一个数字值,这里是将前面的'Dumb1’与后面exp()返回的值做一个按位异或运算。既然要做运算那么当然就要先执行exp()来返回其中的值了。因此也就可以实现报错效果了。接着我们用按位或|运算验证一下。

可以看到依然是报错成功了。所以针对于update语句中的报错注入时,要特别注意的就是exp()函数报错注入。

 

 

Less 18  POST - Header Injection - Uagent field - Error based

从题目来看的话,这一关是基于报错的头部注入。到底是怎么回事呐?先访问一下页面看看是什么样子的

从页面响应来看的话,也是一个登陆界面。唯一不同的是下面有访问者的ip地址记录。我们用Dumb账号登录看看。

从页面显示的内容来看,多了一行数据是显示user agent的。

User-Agent是Http协议中的一部分,属于http头部的组成部分,User Agent也简称UA。用较为普通的一点来说,UA是一种向访问网站提供你所使用的浏览器类型、操作系统及版本、CPU 类型、浏览器渲染引擎、浏览器语言、浏览器插件等信息的标识。UA字符串在每次浏览器 发起HTTP 请求时发送给服务器。

看到页面的这个user agent,我就不由得看向了题目中的Uagent field。这两者之间必然是有着某种联系的。

这里先不管那么多,看看源码是如何处理的。

可以看到这一关对提交的用户名和密码都做了相应的处理,都对敏感字符进行了转义。所以看来通过这两个点来进行注入是行不通了。

但是继续看到在下面的语句中服务器端并未对uagent和ip_address参数做处理就拼接到了sql语句中。因此我们可以通过这两个地方进行注入。

这里值得注意的一个点就是$_SERVER数组。$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目都是由 Web 服务器创建的。在源码中uagent、ip_address的变量值也是从中获取的。

我们先抓包看看

可以看到http头部中User-Agent属性的值跟页面响应中的内容是一模一样的。这里猜测通过$_SERVER['HTTP_USER_AGENT']的值就是User-Agent属性的值,并且没有任何改变。

如果是这样的话,在后面的语句中uagent的值又是直接拼接到了sql语句中带入数据库执行,那么这里很有可能就是一个注入点。

首先在User-Agent属性值后面添加单引号测试一下

从报错信息来看这里确实是一个注入点,但是由于这里执行的语句是insert,所以不能像之前一样用#将后面的语句给注释掉。当#注释掉后面就无法正常插入执行 SQL语句了。

所以这里要如下构造带入数据库才能在不影响正常语句的执行,又能获取数据。

User-Agent:ceshi’ or (select 1 from(select count(*),concat(user(),floor(rand(0)*2))a from information_schema.tables

group by a)b) or ‘

这里通过floor()报错获得了当前的数据库用户名。再尝试通过extractvalue()函数报错来获取数据库名

以前的联合查询、报错、布尔盲注以及延时注入,通常这些方法都是基于 select 查询语句中的 sql 注入点来实现的。但是这两关却是使用的update以及insert语句,对于注入语法的构造也是有一些不一样的地方,具体如何注入还需要在理解了sql注入原理之后结合实际的应用场景来实现攻击。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值