Monday, July 6, 2015

Drive by multi-architecture examples of software breakpoint detection :D

; intel x86_64
 mov rcx, rsi ; move size argument into rcx for the loop
 mov rsi, rdi ; move the the text pointer to rsi for printing
 xor rax, rax ; clear out registers
 xor rdi, rdi
scan:    ; scan for breakpoints
 cmp byte [rsi], 0xCC
 je fuck_you
 inc rsi
loop scan
 xor rdi, rdi
 ret
fuck_you:
 xor rdi, rdi
 mov al, 1
 ret



@ ARM
scan:
        .code 32
        ldr r3, =0xE7F00000     @ load breakpoint constant
        ldr r4, =0xFFFF0000     @ mask
loop:
        ldr r2, [r0]    @ load byte code into r2
        and r2, r4      @ clear out extra data in bytecode with mask
        cmp r2, r3      @ is it a breakpoint?
        beq fuck        @ if so FUCK
        cmp r1, #0      @ are we at the end?
        beq safe        @ if so we are safe
        sub r1, #1      @ decrement the counter
        add r0, #1      @ increment our pointer
        bne loop        @ if we are still looping, loop
safe:
        mov r0, #0      @ return false
        mov r1, r0
        bx lr
fuck:
        mov r0, #0x1    @ return true
        mov r1, #0
        bx lr



# MIPS
scan:
        li $t0, 0x5000D                 # breakpoint constant
loop:
        lw $t3, ($a0)                   # load bytecode
        beq $t3, $t0, fuck              # if this is a breakpoint fucked
        beq $t3, 0, safe                # if the counter is 0 we are safe
        subu $a1, 1                     # decrement counter
        addu $a0, 1                     # increment our pointer
        j loop                          # if we are looping loop
 
safe:
        li $v0, 0x0     # return false
        li $v1, 0x0
        jr $ra
 
fuck:
        li $v0, 0x1     # return true
        li $v1, 0x0
        jr $ra

The stosb detection method for qemu lives AGAIN, only my version checks for a segfault because they patched this, but they patched it DIRTY xD

This is technically a new vulnerability found by myself that checks for BOTH mine and the original vulnerability that would fail to write over the memory location directly below what would be a jmp to say we were in fact in the matrix.
// ------------------------------------------------------------------------------
// THE BEER-WARE LICENSE (Revision 43):
// <aaronryool@gmail.com> wrote this file. As long as you retain this notice you
// can do whatever you want with this stuff. If we meet some day, and you think
// this stuff is worth it, you can buy me a beer in return
// ------------------------------------------------------------------------------

#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/mman.h>

int main(unsigned a);

__sighandler_t handler(int sig)  // our signal handler function
{
 switch(sig)
 {
  case SIGSEGV:  // when segfaults happen
   main(0xC0DE); // assume they have to be because of the bug and tell us we are in the matrix
  break;
 }
}
unsigned qemu(void)
{
 void *page =(void *) ((unsigned long) (&&assembly) &~(getpagesize() - 1)); // get the page the assembly is on
 mprotect(page, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC); // mark that shit as RWE for self modification
assembly: asm volatile(
".intel_syntax noprefix\n"
 "mov eax, 0x90\n" // move a nop into eax for copying
 "mov ecx, 9\n"  // move 9 into ecx for the number of bytes the byte code is from the offset to the jmp
 "mov edi, offset $\n" // mov the address of the start of this instruction into edi for rep
 "rep stosb\n"  // finally, repeat that byte over the memory region
 "jmp _qemu\n"  // this should be overwritten, if it isnt, some naughty child is running an old version of qemu lol, and they are in the matrix
 "jecxz noqemu\n"  // if ecx is 0, we are not in the matrix by definition lol, if it is not 0, then
"_qemu:\n"   // this is the matrix
 "mov eax, 1\n"  // follow cdecl calling convention and return 1 in eax
 "ret\n"
"noqemu:\n"   // this is not the matrix
 "xor eax, eax\n"); // return 0 according to cdecl calling convention
}


int main(unsigned a)
{
 if(a==0xC0DE) goto matrix; // if this shit is from a segfault, we are matrix status
 signal(SIGSEGV, &handler); // register the segfault signal to be caught by our handler
 
 if(qemu()) goto matrix;  // if this is an old version of qemu, and the standard vulnerability is present, MATRIX (upgrade yo shit foo)
 puts("Isn't real life boring?"); // if we get here, this is boring reality :( no cool ninja moves today bro lol
 exit(0);

matrix:
 puts("The Matrix haz you Neo..."); // this is where you would put ninja moves, jack in or jack off, your choice ;)
 exit(1);
}

Quick POC on detecting hyper-visors using redundant rep prefixes

// ------------------------------------------------------------------------------
// THE BEER-WARE LICENSE (Revision 43):
// <aaronryool@gmail.com> wrote this file. As long as you retain this notice you
// can do whatever you want with this stuff. If we meet some day, and you think
// this stuff is worth it, you can buy me a beer in return
// ------------------------------------------------------------------------------

#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/mman.h>

int main(unsigned a);

__sighandler_t handler(int sig)  // our signal handler function
{
 switch(sig)
 {
  case SIGSEGV:  // when segfaults happen
   main(0xC0DE); // assume they have to be because of the bug and tell us we are in the matrix
  break;
 }
}

int main(unsigned a)
{
 if(a==0xC0DE) goto irl;  // if this shit is from a segfault, we are in real life :(
 signal(SIGSEGV, &handler); // register the segfault signal to be caught by our handler
 
asm(
        ".intel_syntax noprefix\n"
        "xor ecx, ecx\n" // we arent actually copying anything, so the counter is zero
        ".byte 0xf3, 0xf3, 0xf3, 0xf3, 0xf3\n" // redundant rep prefixes
        ".byte 0xf3, 0xf3, 0xf3, 0xf3, 0xf3\n" // ...
        ".byte 0xf3, 0xf3, 0xf3, 0xf3, 0xf3\n" // ...
        ".byte  0xa4\n" // movsb
);
 puts("The Matrix haz you Neo..."); // this is where you would put ninja moves, jack in or jack off, your choice ;)
 exit(1);
irl:
 puts("Isn't real life boring?"); // if we get here, this is boring reality :( no cool ninja moves today bro lol
 exit(0);
}
Think you are man enough to solve this baby? ;)

Simple Example of time based detection of hypervisors

Well the theory behind this is simple lol. Time the execution of a series of instructions in a statistically diverse range of test cases under rest conditions, and then do this in a few hyper-visors. When you analyze the data from the hyper-visors, you will notice large peaks that happen intermittently. Find the average of those peaks, then find out the frequency of these in the normal operating environment. The code below does just that, although i was limited in the number of test cases as i did this on a single machine lol. Also, please note that in order to implement this into something more robust, you need to add code that detects the base state of the machine it is on before it tests for the existence of a hyper-visor, as this will throw LOTS of false positives under heavy load. This is common with any kind of time based detection method.
Running in the real world


Running inside a hypervisor





12 byte code cave inside an elf header

So I was playing around with minimalism, and I like to get pretty dirty when this happens. So i started seeing what i could corrupt in an elf header until Linux refused the binary. I found that I could corrupt the twelve bytes directly following the magic sequence. This has some interesting side effects. The first being that all debugging software I attempted to run this in refused to acknowledge that it was even an executable lol. readelf was able to see that there was in fact an elf header, but gave back false information. The GNU file command can see that it is in fact an elf, but doesn't recognize anything other than that, given that most of that information was defaced. The incredibly scary bit is that Linux is able to in fact run this file without any issue lol.

Saturday, July 4, 2015

Obfuscation: a comic strip series, episode: 0










Why yes, this is in fact a comic made out of code lol. think you can solve the challenge? Here is the code.

Hint: the comic code is a hint, and I gave you every letter of the alphabet ;)

Stay tuned for more :D