In part1 I talked about identifying Hipchat endpoints and promised to discuss proxying the application. In this post I will show how to proxy some of Hipchat's traffic using Burp.
This is specific to Hipchat client for Windows. The current version at the time of writing was is 2.2.1361. Atlassian is skipping version 3 and version 4 still in beta.
1. EZ-Mode Proxy Settings
To see the proxy settings, log off and select Configure Connection. Note that in the most recent version (2.2.1395) this added to the settings menu inside the application and there is no need to logoff.
Yay for proxy settings. So you think you can use Burp? It's not going to be that easy, otherwise why would I been writing this?
My Burp proxy is listening on
127.0.0.1:8080 so I will add it as proxy.
You can also enable proxy settings by modifying the
%appdata%\Atlassian\Hipchat.ini file (on Windows). We need to modify these settings:
httpHostname=localhost httpPort=8080 proxyType=Http
Now login. We will see some requests in Burp. We have seen them before, first one is the
Latest News and the second one is the emoticon associated with it. The emoticon is loaded over HTTPs while latest news is loaded over HTTP. We will play with it later.
1. http://downloads.hipchat.com/blog_info.html # section 2.2 in part 1 2. https://s3.amazonaws.com/uploads.hipchat.com/10804/368466/FM3tGM05hUCySVj/freddie.png # emoticon in this case it is Freddie Mercury # note that this changes because last time I saw success kid # section 2.3 in part 1. 3.<?xml version='1.0'?><stream:stream to='chat.hipchat.com' # looks like the start of an XMPP handshake.
hipchatserver.com, our imaginary Hipchat server's IP is
10.11.1.25 in this post.
The third request looks like the start of an XMPP handshake which has been cut off by Burp. It should be something like this:
<?xml version='1.0'?><stream:stream to='chat.hipchat.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
2. Why did Burp, Burp?
To diagnose the problem, we must look at the traffic capture. Run Netmon and login to Hipchat again. Remember that you cannot capture Hipchat's traffic to Burp with Netmon or Wireshark as it is local (from
127.0.0.1:8080) so you need to sniff local traffic with something like RawCap. But we can look at Burp's outbound traffic in Netmon. Look for traffic belonging to the
javaw.exe process (for Burp).
Or using sequence diagram created on https://www.websequencediagrams.com. We have a bunch of internal licenses for this at Cigital so I have started adding sequence diagrams to all of my blog posts and reports :D.
As we see the XMPP handshake is incomplete. In short, Burp somehow messes up the first part of the XMPP handshake and drops the packet just after it sees
to='chat.hipchat.com' and sends an incomplete payload which causes the server to reject it and reset the connection.
3. Burp's SSL Pass Through
It's time to talk about another one of Burp's capabilities. This one is named
SSL Pass Through and is very useful for exactly the situation we are in. We can specify endpoints (domain/IP and port) and tell Burp not to mess with the to/from those points and just pass it through as it is. This means that Burp will not Man-in-the-Middle (MitM) the connection and just ignore the traffic. It is located at
Proxy > Option > SSL Pass Through (scroll all the way to the bottom). Let's tell Burp not to proxy anything to/from the
Now let's take a look at these requests. We have already seen the first two before.
1. GET: http://downloads.hipchat.com/blog_info.html 2. GET: https://s3.amazonaws.com/uploads.hipchat.com/10804/368466/FM3tGM05hUCySVj/freddie.png 3. GET: https://www.hipchat.com/img/silhouette_125.png 4. GET: https://hipchat.com/release_notes/appcast/qtwindows?auth-uid=351&auth-token=JHAgpsxHVva3SMC 5. GET: https://www.hipchat.com/release_notes/appcast/qtwindows?auth-uid=351&auth-token=JHAgpsxHVva3SMC
Request number 3 is retrieving an image. It is the placeholder image for profile pictures in Hipchat.
GET /img/silhouette_125.png HTTP/1.1 Connection: Keep-Alive Accept-Encoding: gzip, deflate Accept-Language: en-US,* User-Agent: Mozilla/5.0 Host: www.hipchat.com
Why are we retrieving this image from hipchat.com every time when it can be stored in the application and conserve bandwidth? I don't know but Paranoid Parsia tells me that it is an Atlassian tracking request. This way they will know where and when an instance has been executed. There is no identifying data sent with the request.
Request 4 is another GET request.
GET /release_notes/appcast/qtwindows?auth-uid=351&auth-token=JHAgpsxHVva3SMC HTTP/1.1 Cache-Control: no-cache Pragma: no-cache Connection: Keep-Alive Accept-Encoding: gzip, deflate Accept-Language: en-US,* User-Agent: Mozilla/5.0 Host: hipchat.com
But it gets redirected to https://www.hipchat.com/release_notes/appcast/qtwindows?auth-uid=351&auth-token=JHAgpsxHVva3SMC. Remember when we saw the application communicating with both
www.hipchat.com (sections 2.4 and 2.5 of part 1)? This is it.
HTTP/1.1 301 Moved Permanently Cache-control: no-cache="set-cookie" Content-Type: text/html Date: Mon, 07 Sep 2015 22:41:37 GMT Location: https://www.hipchat.com/release_notes/appcast/qtwindows?auth-uid=351&auth-token=JHAgpsxHVva3SMC Server: nginx Set-Cookie: AWSELB=05C1D11310299FE142D714774ABD93C5B09ED1734381C4F7DC691A8BCC5031E618740E2045508C8D72C034DD48A74BD4A2E439469DEA3BD63B536161358959E4151A965466;PATH=/ Strict-Transport-Security: max-age=31536000 X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Length: 178 Connection: keep-alive Response: <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html>
Which results in request 5.
GET /release_notes/appcast/qtwindows?auth-uid=351&auth-token=JHAgpsxHVva3SMC HTTP/1.1 Cache-Control: no-cache Pragma: no-cache Connection: Keep-Alive Accept-Encoding: gzip, deflate Accept-Language: en-US,* User-Agent: Mozilla/5.0 Host: www.hipchat.com
Response to request 5 is an RSS feed containing release versions of the Hipchat client for Windows. Click this link if you want to see it in action https://www.hipchat.com/release_notes/appcast/qtwindows.
HTTP/1.1 200 OK Cache-control: no-cache="set-cookie" Content-Type: application/xml Date: Mon, 07 Sep 2015 22:41:38 GMT Server: nginx Set-Cookie: AWSELB=05C1D11310299FE142D714774ABD93C5B09ED1734381C4F7DC691A8BCC5031E618740E204546FF579CEC855051CA268C2FEED4240DD3110178C6BD0BB2D00F1E409F9F4DA6;PATH=/ Strict-Transport-Security: max-age=31536000 X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Length: 21562 Connection: keep-alive <?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:hipchat="http://hipchat.com"> <channel> <title>HipChat Windows App Changelog</title> <link>https://www.hipchat.com/release_notes/appcast/qtwindows</link> <description>Appcast of updates.</description> <language>en</language> <item> <title>Version 2.2.1388 (1388)</title> <pubDate>Tue, 23 Jun 2015 00:00:00 +0000</pubDate> <sparkle:releaseNotesLink>https://www.hipchat.com/release_notes/client_embed/qtwindows?version_num=1373&auth-token=JHAgpsxHVva3SMC&auth-uid=351</sparkle:releaseNotesLink> <sparkle:minimumSystemVersion>10.8</sparkle:minimumSystemVersion> <enclosure url="https://s3.amazonaws.com/downloads.hipchat.com/windows/HipChat-2.2.1388-win32.msi" sparkle:version="1388" sparkle:shortVersionString="2.2.1388" length="43982848" type="application/octet-stream" /> <hipchat:required>0</hipchat:required> </item> ... </channel> </rss>
I think this RSS feed is used to check for updates.
5. GET request over HTTP
Now let's take a look at request one. It is loading an HTML page and displays it in the app. directly We can intercept the response in Burp and modify it. The request is to http://downloads.hipchat.com/blog_info.html and that page is not available over TLS.
That was easy. Now let's see if we can modify it to display something else.
This is not a serious vulnerability. The attacker needs to be on the same network or in the path and MitM the HTTP connection. But because it is HTTP, there are no certificate warnings. A number of Internet Service Providers also inject ads and other stuff in HTTP traffic. If injected they will appear here. I still do not know why even the emoticon is loaded over https but this latest news is not (
downloads.hipchat.com is not even available over HTTPs).
In my opinion the best strategy for an attacker is to inject links to phishing sites. Something along the lines of
Click to download the new version and serve infected files or
Click to verify your account and point to a phishing login screen. Doubly so because this is the Hipchat link box and users are expected to click these links. We should also remember that Hipchat is also used in non-corporate environments so the next person at Starbucks may be messing with your traffic.
5.1 The Container
In part three, we will talk about proxying Hipchat client's traffic with the Hipchat server that we skipped using Burp's SSL Pass Through and do more exciting stuff.
As usual if you have any questions/feedback/complaints or just want life advice from ancient Persian spirits, you know where to find me.