打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
实战中遇到的sql小姿势


笔者有个好习惯就是喜欢做笔记,即使当时没来来得及弄懂,之后也可以慢慢研究。今天就选取出一些之前所做笔记里的个人认为比较有趣的,关于 SQL 注入/ SQL 方面的小东西,以及它们带给我的思考,简单来说就是笔者的一些点滴的成长过程。这些东西也并不怎么高深,比较适合入门的看看。另外就是由于可能比较敏感,所以就尽量不放图了。

逻辑推理注入

访问网站,看到的是一个登录界面,在用户名处随意输入 .'', ,页面就返回 500,显示的是下面这个鬼东西。

之后对用户登录处的用户名进行 payload 测试,最终发现

测试:admin')--

结果:验证失败

测试:asdfsdf')--

结果:无用户信息

之后再测试 admin');waitfor delay '0:0:5'--,页面延迟了,可以判断出数据库类型为 mssql,用星号 * 标记注入点,之后用 Sqlmap 跑跑。

sqlmap.py --random-agent -r req.txt --dbms mssql

结果如下:

Parameter: #1* ((custom) POST)
Type: stacked queries
Title: Microsoft SQL Server/Sybase stacked queries (comment)
PAYLOAD: ...
Vector: ;IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]'--
Type: AND/OR time-based blind
Title: Microsoft SQL Server/Sybase time-based blind (IF)
PAYLOAD:...
Vector: IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]'

数据跑出来了,当然,故事到这里并没有结束,这里发现的注入类型只是延迟注入。大表哥表示这里有布尔型注入,之后笔者尝试使用 --technique b,一直没搞出来,后来被告知需要添加 --level 5

当时笔者的内心是这样想的,之前 sqlmap 白学了?不是 level 1 测试当前 HTTP 请求中的参数,level 2 Cookie 字段,level 3User-Agent/Referer 头部字段 .等等.. 这样子的吗?

笔者也曾翻过 Sqlmap 官方手册,但是手册上根本就没讲得很清楚,所以就一直没怎么注意。

Option: --level

This option requires an argument which specifies the level of tests to perform.

There are five levels. The default value is 1 where limited number of tests

(requests) are performed. Vice versa, level 5 will test verbosely for a much larger

number of payloads and boundaries (as in pair of SQL payload prefix and suffix).

The payloads used by sqlmap are specified in the textual file xml/payloads.xml.

Following the instructions on top of the file, if sqlmap misses an injection, you

should be able to add your own payload(s) to test for too!

之后笔者使用 -v 3 去看看 Sqlmap 的系统信息与 payload 信息,才知道,level 越高,尝试使用的 payload 越多,level 1 时候就跳过了下面这个 payload。

[DEBUG] skipping test 'Boolean-based blind - Parameter replace (CASE) (original value)' because the level (3) is higher than the provided (2)

最后使用了 --level 3 后 Sqlmap 终于布尔型注入,payload 是这样的,在 sqlmap 的源码 XML 文档中也有说明。

Parameter: #1* ((custom) POST)
Type: boolean-based blind
Title: Microsoft SQL Server/Sybase boolean-based blind - Parameter replace
Payload: ...
Vector: (SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELE
CT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))

在网上翻了翻文章,乌云上的前辈早就有提及了,奈何就是不知道。

其实呢,学习 sqlmap 看什么源码,傻啊(有完全看懂的大佬忽略)。简单点,只要把 sqlmap 的关键参数弄懂,对着 -v 2 信息慢慢捋一遍,其实就可以了,奈何当初也不知道。

POST 注入

故事这样的,一群菜鸡搞了几天,也没找到几个漏洞,大表哥就只好出手了,“看,这不就是一个 SQL 注入吗”底下的一群菜鸡挠头。

这个网站在测试的时候是没有 WAF 的,然后在 BurpSuit 中有这么一条记录,请求类型为 GET:

controller.do?method=getInfo&page=&calogType=

笔者用过 BurpSuit 的 ActiveScan,也用过 Sqlmap 跑过,AWVS 扫过,手工搞过,但是也没发现什么名堂。

但是....表哥的 Payload 是这样的:

POST /controller.do
Host: www.test.com
Connection: close
Content-Type: multipart/form-data;boundary=123
--123
Content-Disposition:form-data;name='method'
get
--123
Content-Disposition:form-data;name='page'
1
--123
Content-Disposition:form-data;name='calogType'
*
--123--

诶,怎么瞅着好眼熟啊?等等..这不是文件上传的那个吗...这里是在绕 WAF 吗...但不是没 WAF 吗?(其实是有的,只是没表现出来,这 WAF 也很骚啊.)

这里主要有两个要点需要弄清楚:

1)这个 web 应用在这个地方为什么会处理 POST 里面的数据?

2)为什么 POST 的数据可以以文件上传 multipart/form-data 的形式提交?

先回答问题 1。注意这是一个后端语言是用 JAVA 写的网站,笔者后来去学习了一下 JAVA WEB,了解到了程序员使用的 Servlet 中,通常会在 doPost() 里面调用 doGet() 方法,在写代码的时候只需要使用 doGet() 就好。这样一来,就不必区分客户端的请求是 GET 还是 POST 了,省事多了;而 PHP 中也有类似的情况,比如 $_REQUEST;而 .NET 中应该也有类似的操作,后来笔者在 PHP、.NET 中都有遇到过这样的情况。

然后说说问题 2。通常情况下,我们使用表单提交数据,如果没有文件的话,除非向下面这样特意指明,否则浏览器在提交的时候都是给的 Content-Type 类型默认是 application/x-www-form-urlencoded 。

form action='post.php' method='post' enctype='multipart/form-data'>
   input type='text' name='username' id='username'>br>
   input type='submit' name='submit' value='submit'>
form>

笔者起初以为问题 2 是由于 WEB 容器的强大解析功能导致...对于该种 Content-Type ,笔者首先在 PHP+Apache 中,使用 $_POST、$_REQUEST 进行试验,发现可以直接获取到 username 数据。

随后使用 tomcat-apache+java,发现在 Servlet 中是无法通过 request.getParameter('username') 来直接获取到 multipart/form-data 方式中表单提交的数据,还需要使用其他额外的库,对客户端过来的请求报文进行处理,才能像在 PHP 中一样拿到数据。就此表明,该问题是后台语言本身的一些兼容处理导致的一种表现,与容器无关。(ASP.NET 的就实在懒得弄了)

那还有没有其他 POST 数据的姿势呢?有的。

在实现了 RESTful 接口的网站里,可能会支持application/json 、text/json 、application/xml 、text/xml ,可参考四种常见的 POST 提交数据方式:

https://imququ.com/post/four-ways-to-post-data-in-http.html

笔者 YY 一下,那可不可以反过来用 application/x-www-form-urlencoded 来上传文件?问题是 RFC 文档中根本没有这样玩法,ServletPHP 本身也就不会支持,当然自己自定规则自己玩也没问题...

在这节中,笔者另外想多 BB 几句。很多人会一本正经地说,HTTP 的 GET 与 POST 的方法不同在于,GET 是向服务器请求资源,POST 是向服务器提交资源。一开始笔者是有点懵逼的,不都可以提交数据吗???

后来笔者发现这只是 RFC 文档上的规定,可能教科书也是这么写的,而实际上我们在使用的使用时有这么严格区分吗,而且说这段话没有意义,甚至还不如不知道...至少对于普通数据(application/x-www-form-urlencoded)的提交,它们表现得差不多。

所以应该这么回答,通常,服务器(后台)会默认 GET 请求为 application/x-www-form-urlencoded 数据类型,并忽略其 Content-Type与请求报文的消息主体;对于 POST 请求,服务器在找不到 Content-Type 时将默认其为 application/x-www-form-urlencoded ,对于 请求行 中的 query_string 则依然会像GET中一样对它进行处理。

放几张图方便懵逼的小伙伴们理解:

本章节最后,笔者从RFC文档摘取一些关于 mulitipart/form-data 的东西给大伙瞧瞧:


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
SqlMap检测注入点
前后端联调之Form Data与Request Payload,你真的了解吗?
一次简单的渗透测试
sqlmap不为人知的骚操作
WAF绕过之SQL注入(归来)
[zz]sqlmap简单中文说明 | 0x50sec.org
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服