I recently came across a pentest that taught me to love thy scripture; stringent conditions force you to get a different perspective. The client network was abstractly setup as below :
The network was fairly good because of the firewall on one end but a few problems became evident leading to the attack surface below:
- Scan for domains related to the main domain revealed a number of sub domains
- Some of the sub domains on quick checks had no Firewall in line.
- Some of the sub domains authenticated on active directory denoting they had some form of trust.
- Find sub domains to create large attack surface
- Find e-mail addresses and public address lists
- Single out key sub domains based on reviews and talks online.
- Password spray generic accounts collected (reveals easy passwords) – Good old MailSniper always comes through against windows environments.
- Download the Global Address List (GAL) from exchange and voila username list done all that remains is passwords.
- Digging key web applications authenticating via AD as indicated on login page reveals an arbitrary file upload.(Developers never cease to amaze you – When you think they have done nothing wrong they do wrong two fold)
- Web shell uploaded
It was all going well when the shell went through until you realize the server is fairly well configured. Patches installed so most exploits thought of and suggested tend to fail. It is at this point that you remember:
love thy scripture for thy scripture shall salvage you on that hardened server with idiotic mistakes .
There was a challenge with the fact that most exploits were failing however; we mostly forget the basics in a pentest that at times you can bribe your way in. Analyzing our environment:
- Server is fairly well patched with a slightly hardened kernel so it would break but it would take a lot of time
- PHP application authenticates on domain controller via LDAP; PHP LDAP extension is loaded so now we already see the
- ARP cache shows the actual domain controller address and domain name 😀 (arp -a)
- There was no firewall it would have caught our web shell and while in the server no indication of blocking commands running; making it a better choice to continue with our spray/bruteforce
- We have half the information i.e. information on AD usernames from the GAL
Thy Scripture Come to me
Code is beautiful and beauty should be rewarded.
We are stuck with PHP as the best choice for efficiency so we make a minimal interface.
The Bruteforce Client
The application has brute force protection that is a slow avenue so we need to create our own bruteforce interface. To do this we basically need the following:
- Define LDAP host and Port
- Have a simple html form to pick our username and password from our external bruteforce/spray tool.
- Bind to the host and port using the username and password
- echo failure message or success message to determine state of success.
The script enforcing this can be found here.
The Bruteforce or Password Spray Tool
There are two possible strategies depending on your analysis of the environment :
- Password spray i.e. test one password against all usernames and iterate through the password list
- Bruteforce i.e. try a combo of usernames and passwords
For the bruteforce method good old fashioned hydra can work against our script as below:
hydra -L uniq_users.txt -P uniq_pass.txt -o found.txt victim.com https-form-post “/path/to/bruteforce_interface.php:username=^USER^&password=^PASS^:F=Login Failed: Please check your username or password” -t 10 -w 30
For the password spray method you would have to create a bash script to run as below:
while read LINE; do hydra -L uniq_users.txt -p “$LINE” -s 443 victim.com https-form-post “/path/to/bruteforce_interface.php:username=^USER^&password=^PASS^:F=Login Failed: Please check your username or password” -vV -u -o “$LINE”.cracked; done < uniq_pass.txt
you can love thy scripture and create a python script to do this in a slightly slower decent fashion; hydra can be fast and overwhelming. As expected though :
Thy scriptures shall teach you patience to discover powers thou thought not to have.
For those that love to push it like me well here is a sample that implements password spraying a bit slow but safer :-D. There is no rush when in control for “only the wicked run when not being chased”. Find the script here on github.
If the force is with you and you get a domain admin password like I did you can remind yourself how painful PHP is in this case and just throw in a script to login as the domain admin and dump all users and designations from the schema to the web 😀 . evil but it feels good to look at that list. Find the sample script here.
- Everything is critical and HOLISTIC security is important. All elements directly or indirectly related to critical elements should be defended with the same bias.
- Basic scripts for regular administrative functionality can rock a pentest.
- Don’t be limited to route when more lucrative paths are available.