Monday, November 30, 2015

Discuz SQLi Duplicate entry for key

Saw this sql injection attempt likely related to the Discuz! Internet Forum software probably from earlier this year. I think it may come from a PoC like this. Here's the attack seen. POST /faq.php

action=grouppermission
gids[99]='
gids[100][0]=) and (select 1 from (select count(*),concat((select substr(authkey,1,62) from cdb_uc_applications limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#


The vulnerability is apparently in unsanitized parameter gids. Let's quickly breakdown what the attacker is attempting to do when taking advantage of the vuln. If you rip the sql statement apart, the first portion (deepest nested) actually getting executed is ...

select substr(authkey,1,62) from cdb_uc_applications limit 0,1


Which is saying select the first 62 characters of the authorization key found in the cdb_uc_applications table. This appears to be where the php myadmin authorization key is stored that can be used as we'll see later on to login and administrate the server. The query limits the results to only returning 0 or 1 authorization keys, nothing more. Then the next command is executed on the results

select count(*),concat( ( RESULT ABOVE ) ) ,floor(rand(0)*2) x from information_schema.tables group by x


Which is essentially appending a random 0 or 1 to the authorization key. The attacker will be able to simply drop off that random number and still have the original authorization key. It prints out the same authorization key and 0/1 many times. It actually prints it out once for every table in the database. Then below it'll finish off.

select 1 from ( RESULT ABOVE ) a


by printing the number '1' (literally the number 1) and then

) and ( RESULT ABOVE ) #

comment out (hash symbol) the rest of the sql statement to finish off the sql injection.

So now you might be scratching your head? If the final results was just the number '1', then did anything actually occur? Was any information leaked? Actually yes. Since it attempts to print out the same authorization key and appended 0/1 in a group by statement, it's actually going to fire a database duplicate key error message. Duplicate entry Duplicate entry 'root*309B17546BD34849D627A4DE183D3E35CD939E68 1' for key. And the attacker is banking on the fact that the error message will get displayed back onto the page, thus he's able to exfiltrate data from a mysql table via an error message. Pretty clever!

The github exploit linked above shows how this is utilized then ...

content = response.read()
reg = re.compile('Duplicate entry \'1\^(.*?)\' for key')
res = reg.findall(content)


You can see above that they use a regular expression to look for the error message in the http response. They pull out with the \1 the original authorization key.

cls.get_shell(args['options']['target'], uc_key, args['options']['target'])
args['result']['webshell'] = args['options']['target'] + '/config.inc.php'


Then they end up turning around and passing the authorization key (uc_key) back to the config.inc.php (phpMyAdmin's configuration file) to complete they're exploit and own the server. The attack post was here.



More about neonprimetime


Top Blogs of all-time
  1. pagerank botnet sql injection walk-thru
  2. php injection walk-thru
  3. vbulletin rce walk-thru


Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.

No comments:

Post a Comment