Deserialization
기본 정보
직렬화는 객체를 보존할 수 있는 형식으로 변환하는 방법으로 이해됩니다. 객체를 저장하거나 통신 프로세스의 일부로 전송하기 위한 목적으로 사용됩니다. 이 기술은 객체가 나중에 재생성될 수 있도록 보장하기 위해 일반적으로 사용됩니다.
역직렬화는 직렬화의 반대 과정입니다. 특정 형식으로 구조화된 데이터를 가져와 객체로 다시 구성하는 과정을 포함합니다.
역직렬화는 잠재적으로 공격자가 직렬화된 데이터를 조작하여 해로운 코드를 실행하거나 객체 재구성 프로세스 중에 응용 프로그램에서 예기치 않은 동작을 유발할 수 있기 때문에 위험할 수 있습니다.
PHP
PHP에서는 직렬화 및 역직렬화 프로세스 중에 특정 매직 메서드가 사용됩니다:
__sleep
: 객체가 직렬화될 때 호출됩니다. 이 메서드는 직렬화해야 하는 객체의 모든 속성 이름으로 구성된 배열을 반환해야 합니다. 보류 중인 데이터를 커밋하거나 유사한 정리 작업을 수행하는 데 일반적으로 사용됩니다.__wakeup
: 객체가 역직렬화될 때 호출됩니다. 직렬화 중에 손실된 데이터베이스 연결을 다시 설정하고 다른 초기화 작업을 수행하는 데 사용됩니다.__unserialize
: 객체가 역직렬화될 때 (존재하는 경우)__wakeup
대신 호출됩니다.__wakeup
에 비해 역직렬화 프로세스에 대해 더 많은 제어를 제공합니다.__destruct
: 객체가 소멸되거나 스크립트가 종료될 때 호출됩니다. 파일 핸들을 닫거나 데이터베이스 연결을 종료하는 등 정리 작업에 일반적으로 사용됩니다.__toString
: 객체를 문자열로 처리할 수 있게 합니다. 파일을 읽거나 해당 내부의 함수 호출에 기반한 기타 작업에 사용될 수 있으며 객체의 텍스트 표현을 제공합니다.
만약 결과를 살펴보면 객체가 역직렬화될 때 함수 **__wakeup
**과 **__destruct
**가 호출된다는 것을 알 수 있습니다. 여러 튜토리얼에서는 어떤 속성을 출력하려고 할 때 __toString
함수가 호출된다고 설명되어 있지만, 현재는 그렇지 않은 것으로 보입니다.
클래스에 구현된 경우 __unserialize(array $data)
메소드가 __wakeup()
대신 호출됩니다. 이 메소드를 사용하여 직렬화된 데이터를 배열로 제공하여 객체를 역직렬화할 수 있습니다. 이 메소드를 사용하여 속성을 역직렬화하고 역직렬화 시 필요한 작업을 수행할 수 있습니다.
PHP 예제를 여기에서 설명을 볼 수 있습니다: https://www.notsosecure.com/remote-code-execution-via-php-unserialize/, 여기 https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf 또는 여기 https://securitycafe.ro/2015/01/05/understanding-php-object-injection/
PHP Deserial + Autoload Classes
PHP autoload 기능을 악용하여 임의의 php 파일을 로드하고 더 많은 작업을 수행할 수 있습니다:
pagePHP - Deserialization + Autoload Classes참조 값 직렬화
어떤 이유로든 값이 다른 값에 대한 참조로 직렬화되길 원한다면:
PHPGGC (PHP용 ysoserial)
PHPGGC은 PHP 직렬화를 악용하기 위한 payload를 생성하는 데 도움이 될 수 있습니다.
여러 경우에는 응용 프로그램의 소스 코드에서 직렬화를 악용할 방법을 찾을 수 없을 수 있지만 외부 PHP 확장 프로그램의 코드를 악용할 수도 있습니다.
따라서 가능하다면 서버의 phpinfo()
를 확인하고 인터넷에서 (또는 PHPGGC의 가젯에서) 악용할 수 있는 가능한 가젯을 찾아보세요.
phar:// 메타데이터 직렬화
파일을 읽고 그 안에 있는 PHP 코드를 실행하지 않는 LFI를 발견했다면, 예를 들어 _file_get_contents(), fopen(), file() 또는 file_exists(), md5_file(), filemtime() 또는 filesize()_와 같은 함수를 사용하는 경우입니다. 파일을 읽을 때 발생하는 직렬화를 악용해 볼 수 있습니다. 자세한 정보는 다음 게시물을 참조하세요:
pagephar:// deserializationPython
Pickle
객체가 언피클될 때 함수 ___reduce___가 실행됩니다. 악용되면 서버가 오류를 반환할 수 있습니다.
Pickle jails로부터 탈출하는 더 많은 정보를 확인하려면:
pageBypass Python sandboxesYaml & jsonpickle
다음 페이지는 yamls 파이썬 라이브러리에서의 안전하지 않은 역직렬화를 남용하는 기술을 소개하고, Pickle, PyYAML, jsonpickle 및 ruamel.yaml에 대한 RCE 역직렬화 페이로드를 생성하는 데 사용할 수 있는 도구로 마무리됩니다:
pagePython Yaml DeserializationClass Pollution (Python Prototype Pollution)
pageClass Pollution (Python's Prototype Pollution)NodeJS
JS Magic Functions
JS에는 PHP나 Python과 같이 "매직" 함수가 없습니다. 이 함수들은 객체를 생성할 때 실행됩니다. 그러나 toString
, valueOf
, **toJSON
**과 같이 직접 호출하지 않아도 자주 사용되는 함수가 있습니다.
역직렬화를 남용하면 이러한 함수들을 타 코드를 실행하도록 손상시킬 수 있으며(원형 오염을 남용할 수 있음), 호출될 때 임의의 코드를 실행할 수 있습니다.
다른 함수를 직접 호출하지 않고 호출하는 "매직" 방법은 비동기 함수(프로미스)에서 반환된 객체를 손상시키는 것입니다. 왜냐하면, 그 반환 객체를 다른 프로미스로 변환하면 **함수 유형의 "then"**이라는 속성을 가진 프로미스가 다른 프로미스에 의해 반환되었기 때문에 실행될 것입니다. 자세한 정보는 이 링크 를 참조하십시오.
__proto__
및 prototype
오염
__proto__
및 prototype
오염만약 이 기술에 대해 알고 싶다면 다음 튜토리얼을 확인하세요:
pageNodeJS - __proto__ & prototype Pollution이 라이브러리는 함수를 직렬화할 수 있게 합니다. 예시:
직렬화된 객체는 다음과 같이 보일 것입니다:
예제에서 함수가 직렬화될 때 _$$ND_FUNC$$_
플래그가 직렬화된 객체에 추가된다는 것을 볼 수 있습니다.
node-serialize/lib/serialize.js
파일 내부에서 동일한 플래그와 코드가 어떻게 사용되는지 확인할 수 있습니다.
마지막 코드 청크에서 볼 수 있듯이, 플래그가 발견되면 eval
이 사용되어 함수를 역직렬화하므로 기본적으로 사용자 입력이 eval
함수 내부에서 사용됩니다.
그러나 함수를 단순히 직렬화하는 것만으로는 실행되지 않습니다. 예를 들어 코드의 일부가 y.rce
를 호출해야 하며, 이는 매우 가능성이 낮습니다.
어쨌든, 직렬화된 객체를 수정하여 괄호를 추가하여 객체가 역직렬화될 때 직렬화된 함수가 자동으로 실행되도록 할 수 있습니다.
다음 코드 청크에서 마지막 괄호를 주목하고 unserialize
함수가 코드를 자동으로 실행하는 방법을 확인하세요:
위에서 언급했듯이, 이 라이브러리는 _$$ND_FUNC$$_
이후의 코드를 가져와서 eval
을 사용하여 실행합니다. 따라서 코드를 자동으로 실행하기 위해 함수 생성 부분을 삭제하고 마지막 괄호를 삭제하고 다음 예제와 같이 JS 원라이너를 실행할 수 있습니다:
다음에서 이 취약점을 어떻게 악용하는지에 대한 추가 정보를 찾을 수 있습니다: 여기.
funcster의 주목할만한 측면은 표준 내장 객체에 대한 접근 불가능; 이들은 접근 가능한 범위를 벗어납니다. 이 제한으로 인해 내장 객체의 메소드를 호출하려는 코드 실행이 방지되어 console.log()
또는 require(something)
과 같은 명령을 사용할 때 "ReferenceError: console is not defined"
과 같은 예외가 발생합니다.
그러나 이 제한을 우회하는 것이 가능합니다. 특정 접근 방식을 통해 전역 컨텍스트로의 완전한 액세스 복원이 가능합니다. 전역 컨텍스트를 직접 활용하여 이 제한을 우회할 수 있습니다. 예를 들어, 다음 스니펫을 사용하여 액세스를 다시 설정할 수 있습니다:
더 많은 정보를 원하시면 이 소스를 읽어보세요.
serialize-javascript 패키지는 오로지 직렬화 목적으로 설계되었으며 내장 역직렬화 기능이 없습니다. 사용자는 자체 역직렬화 방법을 구현해야 합니다. 직렬화된 데이터를 역직렬화하는 공식 예제에서는 eval
의 직접적인 사용이 제안됩니다:
만약 이 함수가 객체를 역직렬화하는 데 사용된다면, 쉽게 악용할 수 있습니다:
더 많은 정보를 원하시면 이 소스를 읽어보세요.
Cryo 라이브러리
다음 페이지에서는 이 라이브러리를 남용하여 임의의 명령을 실행하는 방법에 대한 정보를 찾을 수 있습니다:
Java - HTTP
Java에서는 역직렬화 콜백이 역직렬화 과정 중에 실행됩니다. 이 실행은 악의적인 페이로드를 조작하여 이러한 콜백을 트리거하는 악용자에 의해 악의적인 작업의 실행으로 이어질 수 있습니다.
Fingerprints
White Box
코드베이스에서 잠재적인 직렬화 취약점을 식별하려면 다음을 검색하십시오:
Serializable
인터페이스를 구현하는 클래스.java.io.ObjectInputStream
,readObject
,readUnshare
함수의 사용.
특히 주의를 기울여야 할 사항:
외부 사용자가 정의한 매개변수로 사용된
XMLDecoder
.특히 XStream 버전이 1.46 이하인 경우
XStream
의fromXML
메서드는 직렬화 문제에 취약합니다.ObjectInputStream
이readObject
메서드와 결합된 경우.readObject
,readObjectNodData
,readResolve
, 또는readExternal
과 같은 메서드의 구현.ObjectInputStream.readUnshared
.Serializable
의 일반적인 사용.
Black Box
블랙 박스 테스트를 위해 특정 **서명 또는 "매직 바이트"**를 찾아보십시오. 이는 자바 직렬화된 객체를 나타냅니다 (ObjectInputStream
에서 유래):
16진수 패턴:
AC ED 00 05
.Base64 패턴:
rO0
.Content-type
이application/x-java-serialized-object
로 설정된 HTTP 응답 헤더.압축 전 16진수 패턴:
1F 8B 08 00
.압축 전 Base64 패턴:
H4sIA
..faces
확장자와faces.ViewState
매개변수가 있는 웹 파일. 웹 응용 프로그램에서 이러한 패턴을 발견하면 Java JSF ViewState Deserialization에 대한 게시물에 자세히 기술된 조사를 유도해야 합니다.
취약 여부 확인
만약 Java 역직렬화 exploit이 어떻게 작동하는지 배우고 싶다면, 기본 Java 역직렬화, Java DNS 역직렬화, 그리고 CommonsCollection1 Payload를 살펴보세요.
화이트박스 테스트
알려진 취약점이 있는 어플리케이션이 설치되어 있는지 확인할 수 있습니다.
당신은 알려진 취약점이 있는 모든 라이브러리를 확인하고 Ysoserial이 악용할 수 있는 취약점을 제공하는 라이브러리를 확인할 수 있습니다. 또는 Java-Deserialization-Cheat-Sheet에서 지정된 라이브러리를 확인할 수도 있습니다. 가능한 악용할 수 있는 가젯 체인을 검색하기 위해 gadgetinspector를 사용할 수도 있습니다. gadgetinspector를 실행할 때 (빌드 후) 경고/오류 메시지가 표시되더라도 신경 쓰지 마시고 완료될 때까지 기다리십시오. 발견된 모든 내용은 _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_에 기록됩니다. gadgetinspector는 악용 코드를 생성하지 않으며 잘못된 양성 결과를 나타낼 수 있습니다.
블랙박스 테스트
Burp 확장 프로그램 gadgetprobe를 사용하여 사용 가능한 라이브러리(버전 포함)를 식별할 수 있습니다. 이 정보를 통해 취약점을 악용할 payload를 선택하는 것이 더 쉬워질 수 있습니다.
GadgetProbe에 대해 더 알아보려면 이 문서를 읽어보세요.
GadgetProbe는 ObjectInputStream
역직렬화에 중점을 둡니다.
Burp 확장 프로그램 Java Deserialization Scanner를 사용하여 ysoserial로 악용 가능한 취약한 라이브러리를 식별하고 악용할 수 있습니다.
Java Deserialization Scanner에 대해 더 알아보려면 이 문서를 읽어보세요
Java Deserialization Scanner는 ObjectInputStream
역직렬화에 중점을 둡니다.
Freddy를 사용하여 Burp에서 역직렬화 취약점을 감지할 수 있습니다. 이 플러그인은 ObjectInputStream
관련 취약점 뿐만 아니라 Json 및 Yml 역직렬화 라이브러리의 취약점도 감지합니다. 활성 모드에서는 sleep 또는 DNS 페이로드를 사용하여 확인을 시도합니다.
Freddy에 대한 자세한 정보는 여기에서 확인할 수 있습니다.
직렬화 테스트
서버에서 사용 중인 취약한 라이브러리를 확인하는 것만큼 중요한 것은 아닙니다. 때로는 직렬화된 객체 내부의 데이터를 변경하고 일부 확인을 우회할 수도 있습니다(웹 애플리케이션 내에서 관리자 권한을 부여할 수도 있음). 웹 애플리케이션으로 전송되는 Java 직렬화된 객체를 발견하면 SerializationDumper를 사용하여 전송된 직렬화 객체를 더 읽기 쉬운 형식으로 출력할 수 있습니다. 보내는 데이터를 알면 수정하여 일부 확인을 우회하는 것이 더 쉬워집니다.
악용
ysoserial
Java 역직렬화를 악용하는 주요 도구는 ysoserial입니다 (여기에서 다운로드). 복잡한 명령(예: 파이프 사용)을 사용할 수 있도록 하는 ysoseral-modified도 고려할 수 있습니다.
이 도구는 **ObjectInputStream
**을 악용하는 데 중점을 두고 있습니다.
주입이 가능한지 테스트하기 위해 RCE 페이로드보다 "URLDNS" 페이로드를 먼저 사용하는 것이 좋습니다. 그래도 "URLDNS" 페이로드가 작동하지 않을 수 있지만 다른 RCE 페이로드는 작동할 수 있습니다.
**java.lang.Runtime.exec()**에 대한 페이로드를 생성할 때는 ">" 또는 "|"와 같은 특수 문자를 사용할 수 없으며, "$()"를 사용하여 명령을 실행하거나 명령에 공백으로 구분된 인수를 전달할 수 없습니다 (echo -n "hello world"
는 가능하지만 python2 -c 'print "Hello world"'
는 불가능합니다). 페이로드를 올바르게 인코딩하려면 이 웹페이지를 사용할 수 있습니다.
취약한 웹 페이지에서 Windows 및 Linux에 대한 모든 가능한 코드 실행 페이로드를 생성하고 테스트하기 위해 다음 스크립트를 자유롭게 사용하십시오:
시리얼킬러바이패스가젯
https://github.com/pwntester/SerialKillerBypassGadgetCollection을 사용하여 ysoserial과 함께 더 많은 익스플로잇을 생성할 수 있습니다. 이 도구에 대한 자세한 정보는 도구가 소개된 발표 자료에서 확인할 수 있습니다: https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1
marshalsec
marshalsec은 Java에서 다양한 Json 및 Yml 직렬화 라이브러리를 악용하기 위한 페이로드를 생성하는 데 사용할 수 있습니다.
프로젝트를 컴파일하려면 pom.xml
에 다음 의존성을 추가해야 했습니다:
Maven을 설치하고 프로젝트를 컴파일하세요:
FastJSON
이 Java JSON 라이브러리에 대해 더 읽어보세요: https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html
Labs
일부 ysoserial 페이로드를 테스트하려면 이 웹앱을 실행할 수 있습니다: https://github.com/hvqzao/java-deserialize-webapp
Why
Java는 다음과 같은 다양한 목적으로 직렬화를 많이 사용합니다:
HTTP 요청: 직렬화는 매개변수, ViewState, 쿠키 관리 등에서 널리 사용됩니다.
RMI (원격 메서드 호출): 직렬화에 완전히 의존하는 Java RMI 프로토콜은 Java 애플리케이션에서 원격 통신의 중추 역할을 합니다.
HTTP를 통한 RMI: 이 방법은 Java 기반의 두꺼운 클라이언트 웹 애플리케이션에서 일반적으로 사용되며 모든 객체 통신에 대해 직렬화를 사용합니다.
JMX (Java 관리 확장): JMX는 네트워크를 통해 객체를 전송하기 위해 직렬화를 사용합니다.
사용자 정의 프로토콜: Java에서는 원시 Java 객체의 전송이 일반적이며 이는 다가오는 악용 예제에서 설명될 것입니다.
Prevention
일시적 객체
Serializable
을 구현하는 클래스는 직렬화되지 말아야 하는 클래스 내의 모든 객체를 transient
로 구현할 수 있습니다. 예를 들어:
Serializable
를 구현해야 하는 클래스의 직렬화 방지
Serializable
를 구현해야 하는 클래스의 직렬화 방지특정 객체가 클래스 계층 구조로 인해 Serializable
인터페이스를 구현해야 하는 상황에서는, 의도하지 않은 역직렬화의 위험이 있습니다. 이를 방지하기 위해 아래와 같이 항상 예외를 throw하는 final
readObject()
메서드를 정의하여 이러한 객체가 역직렬화되지 않도록 해야 합니다:
Java에서 역직렬화 보안 강화
java.io.ObjectInputStream
을 사용자 정의하는 것은 역직렬화 프로세스를 보호하는 실용적인 방법입니다. 이 방법은 다음 경우에 적합합니다:
역직렬화 코드가 당신의 통제 아래에 있는 경우.
역직렬화를 위해 예상되는 클래스가 알려진 경우.
resolveClass()
메소드를 오버라이드하여 허용된 클래스로의 역직렬화를 제한합니다. 이를 통해 명시적으로 허용된 클래스인 Bicycle
클래스로의 역직렬화만 허용하는 다음 예제와 같이 어떤 클래스의 역직렬화도 방지할 수 있습니다:
보안 향상을 위한 Java 에이전트 사용은 코드 수정이 불가능할 때 대안적인 해결책을 제공합니다. 이 방법은 주로 해로운 클래스를 블랙리스트에 등록하여 JVM 매개변수를 사용합니다:
동적으로 직렬화를 보호하는 방법을 제공하여 즉시 코드 변경이 어려운 환경에 이상적입니다.
rO0 by Contrast Security에서 예제를 확인하세요.
직렬화 필터 구현: Java 9에서 ObjectInputFilter
인터페이스를 통해 직렬화 필터를 도입하여 직렬화된 객체가 역직렬화되기 전에 충족해야 하는 기준을 지정할 수 있는 강력한 메커니즘을 제공했습니다. 이러한 필터는 전역적으로 적용하거나 스트림별로 적용하여 역직렬화 프로세스를 세밀하게 제어할 수 있습니다.
직렬화 필터를 활용하기 위해 모든 역직렬화 작업에 적용되는 전역 필터를 설정하거나 특정 스트림에 동적으로 구성할 수 있습니다. 예를 들어:
향상된 보안을 위한 외부 라이브러리 활용: NotSoSerial, jdeserialize, Kryo와 같은 라이브러리는 Java 역직렬화를 제어하고 모니터링하는 고급 기능을 제공합니다. 이러한 라이브러리는 클래스 화이트리스트 또는 블랙리스트, 역직렬화 전 직렬화된 객체 분석, 사용자 정의 직렬화 전략 구현 등 추가적인 보안 계층을 제공할 수 있습니다.
NotSoSerial은 신뢰할 수 없는 코드 실행을 방지하기 위해 역직렬화 프로세스를 가로챕니다.
jdeserialize은 역직렬화하지 않고 직렬화된 Java 객체를 분석할 수 있어 잠재적으로 악의적인 콘텐츠를 식별하는 데 도움이 됩니다.
Kryo는 속도와 효율성을 강조하는 대체 직렬화 프레임워크로, 보안을 강화할 수 있는 구성 가능한 직렬화 전략을 제공합니다.
참고 자료
역직렬화 및 ysoserial 토크: http://frohoff.github.io/appseccali-marshalling-pickles/
역직렬화 CVEs: https://paper.seebug.org/123/
JNDI Injection & log4Shell
JNDI Injection이 무엇인지, RMI, CORBA & LDAP를 통해 어떻게 남용되며 log4shell을 어떻게 악용하는지 (이 취약점의 예시)를 다음 페이지에서 찾을 수 있습니다:
pageJNDI - Java Naming and Directory Interface & Log4ShellJMS - Java Message Service
Java Message Service (JMS) API는 두 개 이상의 클라이언트 간에 메시지를 보내기 위한 Java 메시지 지향 미들웨어 API입니다. 이는 생산자-소비자 문제를 처리하기 위한 구현체입니다. JMS는 Java Platform, Enterprise Edition (Java EE)의 일부이며 Sun Microsystems에서 개발된 명세에 따라 개발되었지만 현재는 Java Community Process에 의해 이끌리고 있습니다. Java EE를 기반으로 하는 응용 프로그램 구성 요소가 메시지를 생성, 전송, 수신 및 읽을 수 있도록 하는 메시징 표준입니다. 분산 응용 프로그램의 다른 구성 요소 간 통신을 느슨하게 결합되고 신뢰성 있게 비동기적으로 만들어줍니다. (출처: 위키피디아).
제품
이 미들웨어를 사용하여 메시지를 보내는 여러 제품이 있습니다:
악용
따라서 기본적으로 위험한 방식으로 JMS를 사용하는 서비스들이 많이 있습니다. 따라서 이러한 서비스로 메시지를 보낼 권한이 충분하다면 (보통 유효한 자격 증명이 필요합니다) 직렬화된 악의적 객체를 전송하여 소비자/구독자가 역직렬화할 수 있도록 할 수 있습니다. 이는 이 악용에서 모든 메시지를 사용할 클라이언트가 감염될 수 있다는 것을 의미합니다.
서비스가 취약하더라도 (사용자 입력을 안전하게 역직렬화하지 않았기 때문에) 여전히 취약한 애플리케이션 내에 사용할 수 있는 유효한 가젯을 찾아야 합니다.
도구 JMET은 알려진 가젯을 사용하여 직렬화된 여러 악의적 객체를 보내는 방식으로 이 서비스에 연결하고 공격하는 데 사용됩니다. 이러한 악용은 서비스가 여전히 취약하고 사용된 가젯 중 하나가 취약한 애플리케이션 내에 있을 경우에만 작동합니다.
참고 자료
.Net
.Net의 맥락에서, 역직렬화 악용은 Java에서 발견된 것과 유사하게 작동하며, 가젯이 객체의 역직렬화 중에 특정 코드를 실행하도록 악용됩니다.
지문
WhiteBox
소스 코드를 검사하여 다음 사항을 확인해야 합니다:
TypeNameHandling
JavaScriptTypeResolver
집중해야 할 부분은 사용자가 제어하는 변수에 따라 유형을 결정할 수 있는 직렬화 프로그램입니다.
BlackBox
검색 대상은 서버 측에서 역직렬화될 수 있는 Base64로 인코딩된 문자열 AAEAAAD///// 또는 유사한 패턴입니다. 이는 TypeObject
또는 $type
을 특징으로 하는 JSON 또는 XML 구조를 포함할 수 있습니다.
ysoserial.net
이 경우 ysoserial.net 도구를 사용하여 역직렬화 exploit을 생성할 수 있습니다. 깃 리포지토리를 다운로드한 후 Visual Studio와 같은 도구를 사용하여 도구를 컴파일해야 합니다.
ysoserial.net의 주요 옵션은 --gadget
, --formatter
, --output
, **--plugin
**입니다.
**
--gadget
**은 악용할 가젯을 지정하는 데 사용됩니다 (역직렬화 중 명령을 실행하기 위해 악용될 클래스/함수를 지정).**
--formatter
**는 exploit을 직렬화하는 방법을 지정하는 데 사용됩니다 (페이로드를 역직렬화하는 백엔드가 사용하는 라이브러리를 알아야 하며, 동일한 라이브러리를 사용하여 직렬화해야 합니다).--output
은 exploit을 raw 또는 base64로 인코딩할지를 지정하는 데 사용됩니다. _ysoserial.net은 페이로드를 UTF-16LE로 인코딩할 것이므로 (Windows에서 기본적으로 사용되는 인코딩) 리눅스 콘솔에서 인코딩만 하면 인코딩 호환성 문제가 발생할 수 있어서 제대로 작동하지 않을 수 있습니다 (HTB JSON 상자에서 페이로드는 UTF-16LE 및 ASCII에서 모두 작동했지만 항상 작동한다는 의미는 아님)._--plugin
ysoserial.net은 ViewState와 같은 특정 프레임워크에 대한 exploit을 만들기 위한 플러그인을 지원합니다.
추가 ysoserial.net 매개변수
--minify
는 더 작은 페이로드를 제공합니다 (가능한 경우)--raf -f Json.Net -c "anything"
이것은 제공된 포매터(Json.Net
이 경우)와 함께 사용할 수 있는 모든 가젯을 나타냅니다.--sf xml
는 가젯을 지정할 수 있고 ysoserial.net은 "xml"을 포함하는 포매터를 검색합니다 (대소문자 구분 없음).
ysoserial 예제를 만들어보세요:
ysoserial.net에는 각 exploit이 어떻게 작동하는지 더 잘 이해할 수 있도록 도와주는 매우 흥미로운 매개변수인 --test
가 있습니다. 이 매개변수를 지정하면 ysoserial.net이 로컬에서 exploit을 시도하여 페이로드가 올바르게 작동하는지 테스트할 수 있습니다. 이 매개변수는 유용한데, 코드를 검토하면 다음과 같은 코드 청크를 찾을 수 있습니다 (ObjectDataProviderGenerator.cs에서).
이는 exploit을 테스트하기 위해 코드가 serializersHelper.JsonNet_deserialize를 호출할 것을 의미합니다.
이전 코드는 생성된 악용에 취약합니다. 따라서 .Net 애플리케이션에서 유사한 것을 찾으면 해당 애플리케이션이 취약할 가능성이 높습니다.
따라서 --test
매개변수를 사용하여 ysoserial.net이 생성할 수 있는 직렬화 악용에 취약한 어떤 코드 청크인지 이해할 수 있습니다.
ViewState
.Net의 __ViewState 매개변수를 악용하는 방법에 대한 POST을 살펴보고 임의의 코드를 실행해보세요. 피해자 머신에서 사용된 비밀을 이미 알고 있다면, 이 게시물을 읽어 코드를 실행하는 방법을 알아보세요.
예방
.Net에서 직렬화와 관련된 위험을 줄이려면 다음을 수행하세요:
데이터 스트림이 객체 유형을 정의하지 못하도록합니다. 가능한 경우
DataContractSerializer
또는XmlSerializer
를 사용합니다.JSON.Net
의 경우TypeNameHandling
을None
으로 설정: %%%TypeNameHandling = TypeNameHandling.None%%%JavaScriptSerializer
와JavaScriptTypeResolver
를 함께 사용하지 않습니다.직렬화할 수 있는 유형을 제한하여 .Net 유형과 관련된 잠재적 위험을 이해합니다. 예를 들어
System.IO.FileInfo
와 같은 유형은 서버 파일 속성을 수정할 수 있어 거부 서비스 공격으로 이어질 수 있습니다.위험한 속성을 가진 유형에 주의를 기울입니다.
System.ComponentModel.DataAnnotations.ValidationException
의Value
속성과 같이 악용할 수 있는 속성이 있는 경우입니다.타입 인스턴스화를 안전하게 제어하여 공격자가 직렬화 프로세스에 영향을 미치지 못하도록 합니다. 심지어
DataContractSerializer
또는XmlSerializer
도 취약해질 수 있습니다.BinaryFormatter
및JSON.Net
에 대해 사용자 정의SerializationBinder
를 사용하여 화이트리스트 컨트롤을 구현합니다..Net 내에서 알려진 불안전한 직렬화 가젯에 대해 정보를 받아들이고 직렬화기가 이러한 유형을 인스턴스화하지 않도록 합니다.
알려진 가젯 노출을 피하기 위해 잠재적으로 위험한 코드를 격리합니다. 예를 들어 WPF 애플리케이션에서
System.Windows.Data.ObjectDataProvider
를 신뢰할 수 없는 데이터 소스에 노출하지 않도록 합니다.
참고 자료
루비
루비에서 직렬화는 marshal 라이브러리 내의 두 가지 메서드로 수행됩니다. 첫 번째 메서드인 dump는 객체를 바이트 스트림으로 변환하는 데 사용됩니다. 이 프로세스를 직렬화라고 합니다. 반대로 두 번째 메서드인 load는 바이트 스트림을 객체로 되돌리는 데 사용되며, 이 프로세스를 역직렬화라고 합니다.
직렬화된 객체를 안전하게 보호하기 위해 **루비는 HMAC(해시 기반 메시지 인증 코드)**를 사용하여 데이터의 무결성과 신뢰성을 보장합니다. 이를 위해 사용되는 키는 다음 중 하나의 위치에 저장됩니다:
config/environment.rb
config/initializers/secret_token.rb
config/secrets.yml
/proc/self/environ
루비 2.X 일반 직렬화를 RCE 가젯 체인으로 변환 (자세한 정보는 https://www.elttam.com/blog/ruby-deserialization/):
다른 RCE 체인은 루비 온 레일즈 취약점을 악용합니다: https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/
Last updated