由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。
RedCode Team 拥有对此文章的修改和解释权如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
0x00 前言
0x01 漏洞分析
打开index.php,看到了include_once,如图定义了一些数据库配置信息,$db_conn变量为mysqli的实例,我们再来看一下contorl.php定义了一些函数信息,5-11行进行全局的GET请求过滤。了解一些东西之后回到Include/web_inc.php下继续往下翻一翻代码。调用了web_language_ml函数?我们跟进看一下。发送了一次SELECT查询的SQL语句,携带参数1参数2,我们看一看参数的来源。注入漏洞产生了,$_SERVER[REQUEST_URI]是用来获取url的(协议://域名/ 除外),如图:我们都知道,在发送GET请求时,问号后的内容会被当做参数处理,那么符合REQUEST_URI的气质,问号后的内容也被获取到了。在程序判断中通过 斜杠/ 分隔,随后直接引入程序中的SQL语句中,从而引发SQL注入漏洞。你可能会问,刚刚不是还过滤了全局GET吗?除此之外REQUEST_URI所接收的值不会被url解码而变化,比如我传入%0a(换行符)就原封不动的取出。我们举个例子与$_GET作一下比较。如图:我们都知道%20为空格,我们通常都会通过空格从注入语句中分隔语句。避免造成语法错误。而HTTP请求中GET是不允许出现未urlencode编码过的字符串的,如图:不符合HTTP协议规则,直接爆出400错误!这里可以想到Mysql中 [空格]--[空格] 的注释方式被BAN掉!!!又因为程序通过 斜杠(/) 分隔来代入SQL语句中,所以/**/这种注释语句也被BAN掉了!还有一种#注释姿势,很遗憾,HTTP请求依然不允许,如图:
构造Payload:/?'or+if(substr((select+user()),1,1)like'r',sleep(2),1)-'因为当前处于where条件中,我的闭合语句为-',在MySQL眼里为逻辑减的意思。所以这里可以进行语句闭合。0x02 开个玩笑
刚刚不是说到HTTP协议的规则嘛,其实标准的HTTP协议规则是那样子的,完全由于Apache对请求包解析太过于严格,下面我们看一下Nginx的请求包情况。~$Urlink=array('url_link'=>$row['language_url'],'url_ml'=>"../",'ID'=>$row['ID']);
这个时候$urlml携带着SQL语句的结果集,我们通过前台模板看一下在哪里输出了该结果集。将SQL语句下标为url_link拼接给web_url_meate变量,好了,我们回到index.php找一下模板文件。Payload:?111' UNION SELECT 1,2,3,user(),5,6,7,8,9#0x03 漏洞信息
GET /?'or+if(substr((select+user()),1,1)like'r',sleep(2),1)-'
GET /?111' UNION SELECT 1,2,3,user(),5,6,7,8,9# HTTP/1.1