© Digital Security
Юшкевич Иван
Опасная
сериализация
© Digital Security 2
Опасная сериализация
Ohw ma i?
© Digital Security 3
Опасная сериализация
Agenda
• Что такое сериализация
 Зачем, для чего, почему
• Уязвимости (calc.exe time)
• Как искать
• Как защититься
• …
• Profit(?)
© Digital Security 4
Опасная сериализация
Сериализация
Сериализация - это процесс сохранения состояния объекта в последовательность байт.
Десериализация - это процесс восстановления объекта, из этих байт. Обратный процесс
сериализация(!)
Формат представления:
Бинарный: Java Serialization, Ruby Marshal, Protobuf, Thrift, Avro, MS-NRBF, Android
Binder/Parcel, IIOP
Смешанный: PHP Serialization, Python pickle, Binary XML/JSON
«Читаемый»: XML, JSON, YAML
© Digital Security 5
Опасная сериализация
Сериализация
• Протоколы передачи данных:
RMI (Remote Method Invocation)
JMX (Java Management Extension)
JMS (Java Messaging System)
• Обмен «объектами» между двумя приложениями
• Кэширование
• Cookie, API-токены
• Сохранение и восстановление объекта
© Digital Security 6
Опасная сериализация
Сериализация
© Digital Security 7
Опасная сериализация
Сериализация
© Digital Security 8
Опасная сериализация
Сериализация
• readObject()
• readResolve()
• validateObject()
• readObjectNoData()
• readExternal()
• finalize()
© Digital Security 9
Опасная сериализация
Сериализация
public class Gadget0
{
public String command;
protected void readObject(java.io.ObjectInputStream
stream) throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
Runtime.getRuntime().exec(command);
}
}
© Digital Security 10
Опасная сериализация
Сериализация
public class Gadget0
{
public String command;
protected void readObject(java.io.ObjectInputStream
stream) throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
Runtime.getRuntime().exec(command);
}
}
© Digital Security 11
Опасная сериализация
Как это сделано?
© Digital Security 12
Опасная сериализация
Как это сделано?
public static void main(String[] args) {
User user = new User();
user.name = "steph"; user.isAdmin=false;
FileOutputStream fos = new
FileOutputStream("object.ser");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(user); os.close();
FileInputStream fis = new FileInputStream("object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
User objectFromDisk = (User)ois.readObject();
System.out.println(objectFromDisk.name); ois.close();
}
public class User implements Serializable{
public String name;
public boolean isAdmin;
public String picture;
public User() {
}
}
© Digital Security 13
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
© Digital Security 14
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
© Digital Security 15
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
0x73: TC_OBJECT. – новый объект
© Digital Security 16
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
0x73: TC_OBJECT. – новый объект
0x72: TC_CLASSDESC. Обозначение нового класса.
© Digital Security 17
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
0x73: TC_OBJECT. – новый объект
0x72: TC_CLASSDESC. Обозначение нового класса.
00 08 – длина имени класса
© Digital Security 18
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
0x73: TC_OBJECT. – новый объект
0x72: TC_CLASSDESC. Обозначение нового класса.
00 08 – длина имени класса
Имя класса
UID класса
© Digital Security 19
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
0x73: TC_OBJECT. – новый объект
0x72: TC_CLASSDESC. Обозначение нового класса.
00 08 – длина имени класса
Имя класса
UID класса
02 – поддерживает сериализацию
00 03 – количество полей
© Digital Security 20
Опасная сериализация
Как это сделано?
AC ED: STREAM_MAGIC – указание , что это сериализованные данные
00 05: STREAM_VERSION. – версия
0x73: TC_OBJECT. – новый объект
0x72: TC_CLASSDESC. Обозначение нового класса.
00 08 – длина имени класса
Имя класса
UID класса
02 – поддерживает сериализацию
00 03 – количество полей
5A – тип поля
00 07 - Длина имени поля
© Digital Security 21
Опасная сериализация
Уязвимости?
© Digital Security 22
Опасная сериализация
Уязвимости
1) Нарушение логики работы программы
2) Ошибки связанные с валидацией пользовательских данных
3) RCE
• Даже когда её не ждешь…
А все почему?
Данные приходят из НЕ ДОВЕРЕННОГО источника.
© Digital Security 23
Опасная сериализация
Уязвимости
Date Type Product Researcher(s)
Apr 2005 DOS JRE Marc Schönefeld
Aug 2008 Applet->RCE JRE Sami Koivu
Apr 2010 Applet->RCE JRE Sami Koivu
Mar 2010 DOS Sun Java Web Console Luca Carettoni
Sept 2011 RCE Spring Framework Wouter Coekaerts
Oct 2012 RCE IBM Cognos BI Pierre Ernst
Feb 2013 File Write->RCE Apache OpenJPA Pierre Ernst
Mar 2013 File Write->RCE Apache Tomcat Pierre Ernst
July 2015 RCE Apache Groovy "cpnrodzc7"
Aug 2015 Buffer Overflow->RCE Android Or Peles & Roee Hay
Nov 2015 RCE Apache Commons Collections Chris Frohoff & Gabriel Lawrence
Nov 2015 DOS JRE Wouter Coekaerts
© Digital Security 24
Опасная сериализация
Уязвимости
Date Type Product Researcher(s)
Apr 2005 DOS JRE Marc Schönefeld
Aug 2008 Applet->RCE JRE Sami Koivu
Apr 2010 Applet->RCE JRE Sami Koivu
Mar 2010 DOS Sun Java Web Console Luca Carettoni
Sept 2011 RCE Spring Framework Wouter Coekaerts
Oct 2012 RCE IBM Cognos BI Pierre Ernst
Feb 2013 File Write->RCE Apache OpenJPA Pierre Ernst
Mar 2013 File Write->RCE Apache Tomcat Pierre Ernst
July 2015 RCE Apache Groovy "cpnrodzc7"
Aug 2015 Buffer Overflow->RCE Android Or Peles & Roee Hay
Nov 2015 RCE Apache Commons Collections Chris Frohoff & Gabriel Lawrence
Nov 2015 DOS JRE Wouter Coekaerts
© Digital Security 25
Опасная сериализация
Почему так?
Может ввести в заблуждение из-за
необычного формата:
• Хранение и передача данных - безопасны
• Бинарный формат непонятен, сложно
подделать
• Сериализация безопасна
Это всего лишь формат представления
данных
© Digital Security 26
Опасная сериализация
Пример
Cookie: user=base64(serialized(User.class))
© Digital Security 27
Опасная сериализация
Пример
Cookie: user=base64(serialized(User.class))
© Digital Security 28
Опасная сериализация
Пример
© Digital Security 29
Опасная сериализация
Пример
© Digital Security 30
Опасная сериализация
IRL sample
© Digital Security 31
Опасная сериализация
IRL
1) Cookie подписывается с помощью md5, по следующей схеме  md5(cookie.key)
2) Шифруется с помощью AES
3) Если AES не доступен, шифруется с помощью XOR(!)
https://www.dionach.com/blog/codeigniter-session-decoding-
vulnerability
© Digital Security 32
Опасная сериализация
UNTRUSTED INPUT
© Digital Security 33
Опасная сериализация
Untrusted input
USER
Permissions
UserInfo
Statistics
Name
Surname
Email
Type
Picture
String path=“/var/www/”
byte[] getPicture()
{
File file = new File(path, picture);
} return Files.readAllBytes(file.getPath());
Query =“select * from usersPermissions
where type=“+userType;
© Digital Security 34
Опасная сериализация
Untrusted input
USER
Permissions
UserInfo
Statistics
Name
Surname
Email
Type
Picture
String path=“/var/www/”
byte[] getPicture()
{
File file = new File(path, picture);
} return Files.readAllBytes(file.getPath());
Query =“select * from usersPermissions
where type=“+userType;
© Digital Security 35
Опасная сериализация
Untrusted input
USER
Permissions
UserInfo
Statistics
Name
Surname
Email
Type
Picture
String path=“/var/www/”
byte[] getPicture()
{
File file = new File(path, picture);
} return Files.readAllBytes(file.getPath());
Query =“select * from usersPermissions
where type=“+userType;
© Digital Security 36
Опасная сериализация
Untrusted input
USER
Permissions
UserInfo
Statistics
Name
Surname
Email
Type
Picture
String path=“/var/www/”
byte[] getPicture()
{
File file = new File(path, picture);
} return Files.readAllBytes(file.getPath());
Query =“select * from usersPermissions
where type=“+userType;
© Digital Security 37
Опасная сериализация
Untrusted input
USER
Permissions
UserInfo
Statistics
Name
Surname
Email
Type
Picture
String path=“/var/www/”
byte[] getPicture()
{
File file = new File(path, picture);
} return Files.readAllBytes(file.getPath());
Query =“select * from usersPermissions
where type=“+userType;
© Digital Security 38
Опасная сериализация
Untrusted input
USER
Permissions
UserInfo
Statistics
Name
Surname
Email
Type
Picture
String path=“/var/www/”
byte[] getPicture()
{
File file = new File(path, picture);
} return Files.readAllBytes(file.getPath());
Query =“select * from usersPermissions
where type=“+userType;
© Digital Security 39
Опасная сериализация
Untrusted input
Необходимо контролировать и обрабатывать те
данные которые пришли от пользователя!
Они получены из не доверенного источника.
Cериализация не поможет вам справиться с SQL/XSS
И т.д.
© Digital Security 40
Опасная сериализация
Gadget
© Digital Security 41
Опасная сериализация
Gadget
© Digital Security 42
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
© Digital Security 43
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
CacheManager
readObject()
© Digital Security 44
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
CacheManager
readObject()
© Digital Security 45
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
CacheManager
readObject()
© Digital Security 46
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
CacheManager
readObject() CommandTask
run()
© Digital Security 47
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
CacheManager
readObject() CommandTask
run()
Runtime
exec()
“calc.exe”
© Digital Security 48
Опасная сериализация
Gadget
ObjectInputStream
readObject()
defaultReadObject()
CacheManager
readObject() CommandTask
run()
Runtime
exec()
“calc.exe”
© Digital Security 49
Опасная сериализация
YaS
© Digital Security 50
Опасная сериализация
YaS
© Digital Security 51
Опасная сериализация
YaS
public class Gadget1 {
public Map map;
public String key;
protected void
readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
String foo = (String) map.get(key);
}
}
© Digital Security 52
Опасная сериализация
YaS
public class Handler0 implements InvocationHandler, Serializable
{
Object invoke(Object proxy, Method method, Object[] args)
{
Runtime.getRuntime().exec(args[0]);
}
}
© Digital Security 53
Опасная сериализация
YaS
© Digital Security 54
Опасная сериализация
YaS
Java-машина во время исполнения может сгенерировать прокси-класс для данного класса
A, т.е. такой класс, который реализует все интерфейсы класса A, но заменяет вызов всех
методов этих интерфейсов на вызов метода InvocationHandler#invoke, где
InvocationHandler - интерфейс JVM, для которого можно определять свои реализации.
Handler0 h = new Handler0();
Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h);
Gadget1 g = new Gadget1();
g.map = proxy;
g.key = “<MALICIOUS COMMAND>”;
byte[] bytes = serialize(g);
© Digital Security 55
Опасная сериализация
YaS
readObject()
Handler0 h = new Handler0();
Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h);
Gadget1 g = new Gadget1();
g.map = proxy;
g.key = “<MALICIOUS COMMAND>”;
byte[] bytes = serialize(g);
© Digital Security 56
Опасная сериализация
YaS
readObject()
Handler0 h = new Handler0();
Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h);
Gadget1 g = new Gadget1();
g.map = proxy;
g.key = “<MALICIOUS COMMAND>”;
byte[] bytes = serialize(g);
map.get() Proxy
© Digital Security 57
Опасная сериализация
YaS
readObject()
Handler0 h = new Handler0();
Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h);
Gadget1 g = new Gadget1();
g.map = proxy;
g.key = “<MALICIOUS COMMAND>”;
byte[] bytes = serialize(g);
map.get() Proxy
Gadget0
© Digital Security 58
Опасная сериализация
YaS
readObject()
Handler0 h = new Handler0();
Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h);
Gadget1 g = new Gadget1();
g.map = proxy;
g.key = “<MALICIOUS COMMAND>”;
byte[] bytes = serialize(g);
map.get() Proxy
Gadget0 invoke exec
© Digital Security 59
Опасная сериализация
© Digital Security 60
Опасная сериализация
Библиотеки
© Digital Security 61
Опасная сериализация
Библиотеки
© Digital Security 62
Опасная сериализация
Библиотеки
© Digital Security 63
Опасная сериализация
Библиотеки
• Большое количество
библиотек
• Сложно обновлять
© Digital Security 64
Опасная сериализация
И не только Java
© Digital Security 65
Опасная сериализация
PHP
Basic types:
• <type specifier>:<data>;
Arrays:
• a:<count>:{<key>:<value>,…}
Two ways for Objects:
• “O” just like array
• Custom defined by developer
© Digital Security 66
Опасная сериализация
PHP
0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s:
0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0;
0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19:
0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan
0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern
0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe";
0000060: 7d0a }.
© Digital Security 67
Опасная сериализация
PHP
0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s:
0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0;
0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19:
0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan
0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern
0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe";
0000060: 7d0a }.
© Digital Security 68
Опасная сериализация
PHP
0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s:
0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0;
0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19:
0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan
0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern
0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe";
0000060: 7d0a }.
© Digital Security 69
Опасная сериализация
PHP
0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s:
0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0;
0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19:
0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan
0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern
0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe";
0000060: 7d0a }.
© Digital Security 70
Опасная сериализация
PHP
0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s:
0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0;
0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19:
0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan
0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern
0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe";
0000060: 7d0a }.
© Digital Security 71
Опасная сериализация
Memcached
MEM(e)cached!
© Digital Security 72
Опасная сериализация
Memcached
MEM(e)cached!
© Digital Security 73
Опасная сериализация
Memcached
© Digital Security 74
Опасная сериализация
Memcached
© Digital Security 75
Опасная сериализация
Как искать?
© Digital Security 76
Опасная сериализация
Как искать?
В коде
• ObjectInputStream.readObject
• ObjectInputStream.readUnshared
Find Security Bugs
Serianalyzer
Паттерны:
• Magic bytes 'ac ed 00 05' bytes
• 'rO0' for Base64
• 'application/x-java-serialized-object' for Content-Type header
© Digital Security 77
Опасная сериализация
Что дальше? Ysoserial!
© Digital Security 78
Опасная сериализация
Как можно защититься?
© Digital Security 79
Опасная сериализация
Sandbox
Sandbox – все можно контролировать
• File R/W access
• Process creation
• Network access
• …
Недостатки
«Сложна, сложна, непонятно» - что
есть легитимное действие
• Были найдены уязвимости и
возможности обхода
© Digital Security 80
Опасная сериализация
Проверка имен классов
Проверка имен классов перед десерилизацией
• SerialKiller
• contrast-rO0
Можно использовать готовый парсер или написать свой(!)
© Digital Security 81
Опасная сериализация
Проверка имен классов
public class LookAheadObjectInputStream extends
ObjectInputStream {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) {
if ( ! desc.getName().equals(“Application.User”) ) {
throw new InvalidClassException(
"Unauthorized deserialization attempt",
desc.getName());
}
return super.resolveClass(desc);
}
}
Получить имя класса
Сравнить с каким-то значением
Profit?
© Digital Security 82
Опасная сериализация
План
Black List
• method1
• method2
Magic methods?
Class x.y.z
accept
reject
blacklisted methods?
yes yes
no no
Called methods
• methodA
• methodB
Analyze
Magic method
© Digital Security 83
Опасная сериализация
Whitelist vs Blacklist
Не использовать десеарилизацию данных из не доверенных
источников(!!!!)
Whitelist
Определить все классы, которые могут быть десериализованными
BlackList
Определить список классов, которые нельзя десериализовать
• Возможно обойти
© Digital Security 84
Опасная сериализация
Спасибо!

Опасная сериализация / Иван Юшкевич (Digital Security)

  • 1.
    © Digital Security ЮшкевичИван Опасная сериализация
  • 2.
    © Digital Security2 Опасная сериализация Ohw ma i?
  • 3.
    © Digital Security3 Опасная сериализация Agenda • Что такое сериализация  Зачем, для чего, почему • Уязвимости (calc.exe time) • Как искать • Как защититься • … • Profit(?)
  • 4.
    © Digital Security4 Опасная сериализация Сериализация Сериализация - это процесс сохранения состояния объекта в последовательность байт. Десериализация - это процесс восстановления объекта, из этих байт. Обратный процесс сериализация(!) Формат представления: Бинарный: Java Serialization, Ruby Marshal, Protobuf, Thrift, Avro, MS-NRBF, Android Binder/Parcel, IIOP Смешанный: PHP Serialization, Python pickle, Binary XML/JSON «Читаемый»: XML, JSON, YAML
  • 5.
    © Digital Security5 Опасная сериализация Сериализация • Протоколы передачи данных: RMI (Remote Method Invocation) JMX (Java Management Extension) JMS (Java Messaging System) • Обмен «объектами» между двумя приложениями • Кэширование • Cookie, API-токены • Сохранение и восстановление объекта
  • 6.
    © Digital Security6 Опасная сериализация Сериализация
  • 7.
    © Digital Security7 Опасная сериализация Сериализация
  • 8.
    © Digital Security8 Опасная сериализация Сериализация • readObject() • readResolve() • validateObject() • readObjectNoData() • readExternal() • finalize()
  • 9.
    © Digital Security9 Опасная сериализация Сериализация public class Gadget0 { public String command; protected void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); Runtime.getRuntime().exec(command); } }
  • 10.
    © Digital Security10 Опасная сериализация Сериализация public class Gadget0 { public String command; protected void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); Runtime.getRuntime().exec(command); } }
  • 11.
    © Digital Security11 Опасная сериализация Как это сделано?
  • 12.
    © Digital Security12 Опасная сериализация Как это сделано? public static void main(String[] args) { User user = new User(); user.name = "steph"; user.isAdmin=false; FileOutputStream fos = new FileOutputStream("object.ser"); ObjectOutputStream os = new ObjectOutputStream(fos); os.writeObject(user); os.close(); FileInputStream fis = new FileInputStream("object.ser"); ObjectInputStream ois = new ObjectInputStream(fis); User objectFromDisk = (User)ois.readObject(); System.out.println(objectFromDisk.name); ois.close(); } public class User implements Serializable{ public String name; public boolean isAdmin; public String picture; public User() { } }
  • 13.
    © Digital Security13 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные
  • 14.
    © Digital Security14 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия
  • 15.
    © Digital Security15 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия 0x73: TC_OBJECT. – новый объект
  • 16.
    © Digital Security16 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия 0x73: TC_OBJECT. – новый объект 0x72: TC_CLASSDESC. Обозначение нового класса.
  • 17.
    © Digital Security17 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия 0x73: TC_OBJECT. – новый объект 0x72: TC_CLASSDESC. Обозначение нового класса. 00 08 – длина имени класса
  • 18.
    © Digital Security18 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия 0x73: TC_OBJECT. – новый объект 0x72: TC_CLASSDESC. Обозначение нового класса. 00 08 – длина имени класса Имя класса UID класса
  • 19.
    © Digital Security19 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия 0x73: TC_OBJECT. – новый объект 0x72: TC_CLASSDESC. Обозначение нового класса. 00 08 – длина имени класса Имя класса UID класса 02 – поддерживает сериализацию 00 03 – количество полей
  • 20.
    © Digital Security20 Опасная сериализация Как это сделано? AC ED: STREAM_MAGIC – указание , что это сериализованные данные 00 05: STREAM_VERSION. – версия 0x73: TC_OBJECT. – новый объект 0x72: TC_CLASSDESC. Обозначение нового класса. 00 08 – длина имени класса Имя класса UID класса 02 – поддерживает сериализацию 00 03 – количество полей 5A – тип поля 00 07 - Длина имени поля
  • 21.
    © Digital Security21 Опасная сериализация Уязвимости?
  • 22.
    © Digital Security22 Опасная сериализация Уязвимости 1) Нарушение логики работы программы 2) Ошибки связанные с валидацией пользовательских данных 3) RCE • Даже когда её не ждешь… А все почему? Данные приходят из НЕ ДОВЕРЕННОГО источника.
  • 23.
    © Digital Security23 Опасная сериализация Уязвимости Date Type Product Researcher(s) Apr 2005 DOS JRE Marc Schönefeld Aug 2008 Applet->RCE JRE Sami Koivu Apr 2010 Applet->RCE JRE Sami Koivu Mar 2010 DOS Sun Java Web Console Luca Carettoni Sept 2011 RCE Spring Framework Wouter Coekaerts Oct 2012 RCE IBM Cognos BI Pierre Ernst Feb 2013 File Write->RCE Apache OpenJPA Pierre Ernst Mar 2013 File Write->RCE Apache Tomcat Pierre Ernst July 2015 RCE Apache Groovy "cpnrodzc7" Aug 2015 Buffer Overflow->RCE Android Or Peles & Roee Hay Nov 2015 RCE Apache Commons Collections Chris Frohoff & Gabriel Lawrence Nov 2015 DOS JRE Wouter Coekaerts
  • 24.
    © Digital Security24 Опасная сериализация Уязвимости Date Type Product Researcher(s) Apr 2005 DOS JRE Marc Schönefeld Aug 2008 Applet->RCE JRE Sami Koivu Apr 2010 Applet->RCE JRE Sami Koivu Mar 2010 DOS Sun Java Web Console Luca Carettoni Sept 2011 RCE Spring Framework Wouter Coekaerts Oct 2012 RCE IBM Cognos BI Pierre Ernst Feb 2013 File Write->RCE Apache OpenJPA Pierre Ernst Mar 2013 File Write->RCE Apache Tomcat Pierre Ernst July 2015 RCE Apache Groovy "cpnrodzc7" Aug 2015 Buffer Overflow->RCE Android Or Peles & Roee Hay Nov 2015 RCE Apache Commons Collections Chris Frohoff & Gabriel Lawrence Nov 2015 DOS JRE Wouter Coekaerts
  • 25.
    © Digital Security25 Опасная сериализация Почему так? Может ввести в заблуждение из-за необычного формата: • Хранение и передача данных - безопасны • Бинарный формат непонятен, сложно подделать • Сериализация безопасна Это всего лишь формат представления данных
  • 26.
    © Digital Security26 Опасная сериализация Пример Cookie: user=base64(serialized(User.class))
  • 27.
    © Digital Security27 Опасная сериализация Пример Cookie: user=base64(serialized(User.class))
  • 28.
    © Digital Security28 Опасная сериализация Пример
  • 29.
    © Digital Security29 Опасная сериализация Пример
  • 30.
    © Digital Security30 Опасная сериализация IRL sample
  • 31.
    © Digital Security31 Опасная сериализация IRL 1) Cookie подписывается с помощью md5, по следующей схеме  md5(cookie.key) 2) Шифруется с помощью AES 3) Если AES не доступен, шифруется с помощью XOR(!) https://www.dionach.com/blog/codeigniter-session-decoding- vulnerability
  • 32.
    © Digital Security32 Опасная сериализация UNTRUSTED INPUT
  • 33.
    © Digital Security33 Опасная сериализация Untrusted input USER Permissions UserInfo Statistics Name Surname Email Type Picture String path=“/var/www/” byte[] getPicture() { File file = new File(path, picture); } return Files.readAllBytes(file.getPath()); Query =“select * from usersPermissions where type=“+userType;
  • 34.
    © Digital Security34 Опасная сериализация Untrusted input USER Permissions UserInfo Statistics Name Surname Email Type Picture String path=“/var/www/” byte[] getPicture() { File file = new File(path, picture); } return Files.readAllBytes(file.getPath()); Query =“select * from usersPermissions where type=“+userType;
  • 35.
    © Digital Security35 Опасная сериализация Untrusted input USER Permissions UserInfo Statistics Name Surname Email Type Picture String path=“/var/www/” byte[] getPicture() { File file = new File(path, picture); } return Files.readAllBytes(file.getPath()); Query =“select * from usersPermissions where type=“+userType;
  • 36.
    © Digital Security36 Опасная сериализация Untrusted input USER Permissions UserInfo Statistics Name Surname Email Type Picture String path=“/var/www/” byte[] getPicture() { File file = new File(path, picture); } return Files.readAllBytes(file.getPath()); Query =“select * from usersPermissions where type=“+userType;
  • 37.
    © Digital Security37 Опасная сериализация Untrusted input USER Permissions UserInfo Statistics Name Surname Email Type Picture String path=“/var/www/” byte[] getPicture() { File file = new File(path, picture); } return Files.readAllBytes(file.getPath()); Query =“select * from usersPermissions where type=“+userType;
  • 38.
    © Digital Security38 Опасная сериализация Untrusted input USER Permissions UserInfo Statistics Name Surname Email Type Picture String path=“/var/www/” byte[] getPicture() { File file = new File(path, picture); } return Files.readAllBytes(file.getPath()); Query =“select * from usersPermissions where type=“+userType;
  • 39.
    © Digital Security39 Опасная сериализация Untrusted input Необходимо контролировать и обрабатывать те данные которые пришли от пользователя! Они получены из не доверенного источника. Cериализация не поможет вам справиться с SQL/XSS И т.д.
  • 40.
    © Digital Security40 Опасная сериализация Gadget
  • 41.
    © Digital Security41 Опасная сериализация Gadget
  • 42.
    © Digital Security42 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject()
  • 43.
    © Digital Security43 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject() CacheManager readObject()
  • 44.
    © Digital Security44 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject() CacheManager readObject()
  • 45.
    © Digital Security45 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject() CacheManager readObject()
  • 46.
    © Digital Security46 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject() CacheManager readObject() CommandTask run()
  • 47.
    © Digital Security47 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject() CacheManager readObject() CommandTask run() Runtime exec() “calc.exe”
  • 48.
    © Digital Security48 Опасная сериализация Gadget ObjectInputStream readObject() defaultReadObject() CacheManager readObject() CommandTask run() Runtime exec() “calc.exe”
  • 49.
    © Digital Security49 Опасная сериализация YaS
  • 50.
    © Digital Security50 Опасная сериализация YaS
  • 51.
    © Digital Security51 Опасная сериализация YaS public class Gadget1 { public Map map; public String key; protected void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); String foo = (String) map.get(key); } }
  • 52.
    © Digital Security52 Опасная сериализация YaS public class Handler0 implements InvocationHandler, Serializable { Object invoke(Object proxy, Method method, Object[] args) { Runtime.getRuntime().exec(args[0]); } }
  • 53.
    © Digital Security53 Опасная сериализация YaS
  • 54.
    © Digital Security54 Опасная сериализация YaS Java-машина во время исполнения может сгенерировать прокси-класс для данного класса A, т.е. такой класс, который реализует все интерфейсы класса A, но заменяет вызов всех методов этих интерфейсов на вызов метода InvocationHandler#invoke, где InvocationHandler - интерфейс JVM, для которого можно определять свои реализации. Handler0 h = new Handler0(); Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h); Gadget1 g = new Gadget1(); g.map = proxy; g.key = “<MALICIOUS COMMAND>”; byte[] bytes = serialize(g);
  • 55.
    © Digital Security55 Опасная сериализация YaS readObject() Handler0 h = new Handler0(); Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h); Gadget1 g = new Gadget1(); g.map = proxy; g.key = “<MALICIOUS COMMAND>”; byte[] bytes = serialize(g);
  • 56.
    © Digital Security56 Опасная сериализация YaS readObject() Handler0 h = new Handler0(); Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h); Gadget1 g = new Gadget1(); g.map = proxy; g.key = “<MALICIOUS COMMAND>”; byte[] bytes = serialize(g); map.get() Proxy
  • 57.
    © Digital Security57 Опасная сериализация YaS readObject() Handler0 h = new Handler0(); Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h); Gadget1 g = new Gadget1(); g.map = proxy; g.key = “<MALICIOUS COMMAND>”; byte[] bytes = serialize(g); map.get() Proxy Gadget0
  • 58.
    © Digital Security58 Опасная сериализация YaS readObject() Handler0 h = new Handler0(); Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h); Gadget1 g = new Gadget1(); g.map = proxy; g.key = “<MALICIOUS COMMAND>”; byte[] bytes = serialize(g); map.get() Proxy Gadget0 invoke exec
  • 59.
    © Digital Security59 Опасная сериализация
  • 60.
    © Digital Security60 Опасная сериализация Библиотеки
  • 61.
    © Digital Security61 Опасная сериализация Библиотеки
  • 62.
    © Digital Security62 Опасная сериализация Библиотеки
  • 63.
    © Digital Security63 Опасная сериализация Библиотеки • Большое количество библиотек • Сложно обновлять
  • 64.
    © Digital Security64 Опасная сериализация И не только Java
  • 65.
    © Digital Security65 Опасная сериализация PHP Basic types: • <type specifier>:<data>; Arrays: • a:<count>:{<key>:<value>,…} Two ways for Objects: • “O” just like array • Custom defined by developer
  • 66.
    © Digital Security66 Опасная сериализация PHP 0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s: 0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0; 0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19: 0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan 0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern 0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe"; 0000060: 7d0a }.
  • 67.
    © Digital Security67 Опасная сериализация PHP 0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s: 0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0; 0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19: 0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan 0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern 0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe"; 0000060: 7d0a }.
  • 68.
    © Digital Security68 Опасная сериализация PHP 0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s: 0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0; 0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19: 0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan 0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern 0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe"; 0000060: 7d0a }.
  • 69.
    © Digital Security69 Опасная сериализация PHP 0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s: 0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0; 0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19: 0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan 0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern 0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe"; 0000060: 7d0a }.
  • 70.
    © Digital Security70 Опасная сериализация PHP 0000000: 4f3a 343a 2255 7365 7222 3a33 3a7b 733a O:4:"User":3:{s: 0000010: 373a 2269 7361 646d 696e 223b 623a 303b 7:"isadmin";b:0; 0000020: 733a 343a 2270 6c61 6e22 3b73 3a31 393a s:4:"plan";s:19: 0000030: 222f 7661 722f 7777 772f 6e6f 706c 616e "/var/www/noplan 0000040: 2e74 7874 223b 733a 383a 2275 7365 726e .txt";s:8:"usern 0000050: 616d 6522 3b73 3a34 3a22 6761 6265 223b ame";s:4:"gabe"; 0000060: 7d0a }.
  • 71.
    © Digital Security71 Опасная сериализация Memcached MEM(e)cached!
  • 72.
    © Digital Security72 Опасная сериализация Memcached MEM(e)cached!
  • 73.
    © Digital Security73 Опасная сериализация Memcached
  • 74.
    © Digital Security74 Опасная сериализация Memcached
  • 75.
    © Digital Security75 Опасная сериализация Как искать?
  • 76.
    © Digital Security76 Опасная сериализация Как искать? В коде • ObjectInputStream.readObject • ObjectInputStream.readUnshared Find Security Bugs Serianalyzer Паттерны: • Magic bytes 'ac ed 00 05' bytes • 'rO0' for Base64 • 'application/x-java-serialized-object' for Content-Type header
  • 77.
    © Digital Security77 Опасная сериализация Что дальше? Ysoserial!
  • 78.
    © Digital Security78 Опасная сериализация Как можно защититься?
  • 79.
    © Digital Security79 Опасная сериализация Sandbox Sandbox – все можно контролировать • File R/W access • Process creation • Network access • … Недостатки «Сложна, сложна, непонятно» - что есть легитимное действие • Были найдены уязвимости и возможности обхода
  • 80.
    © Digital Security80 Опасная сериализация Проверка имен классов Проверка имен классов перед десерилизацией • SerialKiller • contrast-rO0 Можно использовать готовый парсер или написать свой(!)
  • 81.
    © Digital Security81 Опасная сериализация Проверка имен классов public class LookAheadObjectInputStream extends ObjectInputStream { @Override protected Class<?> resolveClass(ObjectStreamClass desc) { if ( ! desc.getName().equals(“Application.User”) ) { throw new InvalidClassException( "Unauthorized deserialization attempt", desc.getName()); } return super.resolveClass(desc); } } Получить имя класса Сравнить с каким-то значением Profit?
  • 82.
    © Digital Security82 Опасная сериализация План Black List • method1 • method2 Magic methods? Class x.y.z accept reject blacklisted methods? yes yes no no Called methods • methodA • methodB Analyze Magic method
  • 83.
    © Digital Security83 Опасная сериализация Whitelist vs Blacklist Не использовать десеарилизацию данных из не доверенных источников(!!!!) Whitelist Определить все классы, которые могут быть десериализованными BlackList Определить список классов, которые нельзя десериализовать • Возможно обойти
  • 84.
    © Digital Security84 Опасная сериализация Спасибо!

Editor's Notes

  • #5 Теория. Прочитать. Сериализация -  это процесс сохранения состояния объекта в последовательность байт. Десериализация - это процесс восстановления объекта, из этих байт. Обратный процесс сериализация(!) Сериализация объекта это способность объекта сохранять полную копию его и любых других объектов на которые он ссылается, используя поток вывода(например, во внешний файл). Таким образом, объект может быть воссоздан из сериализованной(сохраненной) копии немного позже, когда это потребуется.
  • #6 В сегодняшнем мире типичное промышленное приложение будет иметь множество компонентов и будет распространено через различные системы и сети. Если двум компонентам Java необходимо общаться друг с другом, то им необходим механизм для обмена данными. Есть несколько способов реализовать этот механизм. Первый способ это разработать собственный протокол и передать объект. В Java всё представлено в виде объектов; Это означает, что получатель должен знать протокол, используемый отправителем для воссоздания объекта, что усложняет разработку сторонних компонентов. Следовательно, должен быть универсальный и эффективный протокол передачи объектов между компонентами. Сериализация создана для этого, и компоненты Java используют этот протокол для передачи объектов.
  • #7 Процесс десиреализации начинается с момента когда объект считывается с ObjectInputStream, в который поступает данные, которые пришли от атакующего. Процесс начинает считывать сериализоанные данные и начинает цикличный процесс, в котором имя класса, который будет десиарилизован передается в метод ObjectInputStream.resolveClass(). Это необходимо для того, чтобы получить информацию и метаданные о классе. Это важный этап, поскольку на нем проверяется, что существует данный класс в classpath или нет. Стоит отметить, что уже на этом этапе, можно проверять класс, который будет сериализован с точки зрения безопасносити и можно еще все остановить. После того, как класс загружен ObjectInputStream, проверяет, содержит-ли он такие функции как readObject() и/или readResolve – если да, то вызывает их. readObject служит для того , чтобы устновить значения полей класса. В некоторых случаях могут вызываться и другие функции, такие как validateObject и другие. Этот процесс будет повторяться до самого конца, когда сам объект и все вложенные в него объекты не будут полностью десеарилизованны.
  • #8 Важно отметить, что перед тем , как быть скастованным до определенного объекта, некоторые методы будут вызваны, такие как readObject, readObjectNoData, readResolve и validateObject у десиарилизрованного класса. То есть если атакующий, сможешь каким-либо образом проэксплуатировать эти функции, то он сможет получить возможность выполнения произврольного кода. Иными словами, те действия, которые будут произходить в этим функциях с данными атакующего и крайне важны
  • #51 Пытаясь найти необходимые функции и классы, атакующий может быть не только ограничен данным методами. Он может использовать перехват вызовов, и с одной стороны метод readobject может передать управление на c. JDK и другие библиотеки, позволяет разработчикам писать проки классы , которые реализуют или расширяют определенный набор классов или интерфейсов. Любой метод который вызывается в этих проксях перехватывается и передается в invocation handler для выполнения дополнительного кода.
  • #53 И класс invocation handler. Как видно, если бы мы попытались его сериализовать стырм путем, то него нет методов и необходимы параметоров, которые можно было бы перезаписать
  • #55 Сначала атакующий создает экземпляр класса Handler0 Создает прокси на объект map, где в качестве F pfntv