
사용자 친화적인 Thrift 인코더/디코더
Readable Thrift는 바이너리 Thrift 프로토콜 메시지를 사람이 읽기 쉬운 형식으로 변환하거나 그 반대로 변환하여 쉽게 작업할 수 있게 해줍니다. 이를 통해 바이너리 형식 Thrift 메시지의 수동 분석 및 변조가 HTTP와 같은 평문 프로토콜을 작업하는 것만큼 쉬워집니다.
이 라이브러리는 Java로 구현되어 JVM에서 실행되는 Burp 및 ZAP과 같은 인기 있는 웹 애플리케이션 테스트 도구용 확장 기능과 통합할 수 있습니다. 분석 또는 변조 도구를 실행하려면 적절한 바이트를 파싱하여 코덱에 전달하기만 하면 됩니다.
readablethrift 라이브러리는 다른 프로젝트에 의존성으로 설치 및 포함할 수 있는 Gradle 기반 Maven 패키지입니다. 원시 바이너리 또는 Base64 인코딩 형식의 인코딩 및 디코딩을 위한 네 가지 간단한 메서드를 제공합니다.
참고: 현재 표준 바이너리 형식 프로토콜만 지원됩니다. 컴팩트 바이너리 및 JSON(코덱이 생성하는 읽기 가능한 JSON과 다름)은 아직 지원되지 않습니다.
ThriftCodec::decode 메서드는 바이너리 Thrift 메시지를 포함하는 원시 바이트 버퍼에서 직접 설명적인 org.json.JSONObject 인스턴스를 생성합니다.ThriftCodec::decodeB64String 정적 메서드는 Base64 문자열을 디코딩한 다음 decode를 호출합니다.ThriftCodec::encode 메서드는 설명적인 org.json.JSONObject 인스턴스를 동등한 Thrift 바이너리 메시지를 포함하는 원시 바이트 버퍼로 변환합니다.ThriftCodec::b64encodeJson 정적 메서드는 JSON 객체를 Thrift 바이너리 형식으로 변환하고 결과를 Base64로 인코딩합니다.ThriftCodec 클래스는 추가 바이너리 형식 헤더나 캡슐화와 같은 Thrift 바이너리 프로토콜 형식의 수정 또는 확장을 처리할 수 있도록 확장 가능하게 설계되었습니다.
라이브러리에 포함된 대화형 명령줄 인터페이스를 사용하려면 기본 Gradle 작업으로 JAR을 빌드한 다음 java -jar로 실행하세요:
$ ./gradlew
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
$ java -jar build/libs/readablethrift-1.0.0-all.jar
Enter Base64 encoded message or JSON object (or q to quit):
사람이 읽을 수 있는 JSON이 어떻게 보이는지 보여주기 위해, 일부 애플리케이션 트래픽에서 추출한 Base64로 인코딩된 바이너리 blob 예제를 살펴보겠습니다:
$ base64 -D | hexdump
gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAAIY29vbHVzZXILAAEAAAALcGFzc3dvcmQxMjMAAA==
00000000: 8001 0001 0000 0005 6c6f 6769 6e00 0000 ........login...
00000010: 000c 0000 0b00 0000 0000 0863 6f6f 6c75 ...........coolu
00000020: 7365 720b 0001 0000 000b 7061 7373 776f ser.......passwo
00000030: 7264 3132 3300 00 rd123..
"login", 사용자 이름 및 비밀번호 문자열은 이것이 인증 요청임을 암시합니다. 이 메시지를 즉석에서 변조하려면 Thrift 프로토콜 바이너리 형식 파서의 내부 세부 사항을 조회하고, 헥스 에디터로 메시지 구조를 파악한 다음 각 필드를 수동으로 업데이트해야 합니다. 사용자 이름과 비밀번호 문자열의 경우 문자열 자체 외에도 접두어 길이 값을 업데이트해야 합니다. 이는 지루하고 오류가 발생하기 쉬우며 시간이 많이 걸리는 작업입니다. Readable Thrift는 이 과정을 더 간단하게 만듭니다. 동일한 메시지를 전달한 결과는 다음과 같습니다:
Enter Base64 encoded message or JSON object (or q to quit): gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAAIY29vbHVzZXILAAEAAAALcGFzc3dvcmQxMjMAAA==
{"message": {
"name": "login",
"type": "call",
"fields": [{
"id": 0,
"type": "struct",
"value": [
{
"id": 0,
"type": "string",
"value": "cooluser"
},
{
"id": 1,
"type": "string",
"value": "password123"
}
]
}],
"seqid": 0
}}
이제 메시지가 두 개의 문자열 값을 인자로 포함하는 구조체와 함께 "login" 메서드에 대한 호출을 설명한다는 것을 쉽게 확인할 수 있습니다. 문자열 값을 업데이트하는 것은 value JSON 필드를 작성하거나 편집하고 새 JSON 텍스트를 코덱에 다시 전달하는 것만큼 간단합니다. 모든 길이 접두어 및 바이너리 형식의 기타 세부 사항은 자동으로 처리됩니다.
새 필드를 추가하여 가능한 선택적 매개변수를 테스트할 수도 있습니다. admin 또는 debug 부울 플래그가 있을까요? 아니면 권한 ID 목록이 있을까요? id, type, value를 사용하여 새 필드를 설명한 다음 fields 배열에 추가하세요:
Enter Base64 encoded message or JSON object (or q to quit): {"message": {
"name": "login",
"type": "call",
"fields": [{
"id": 0,
"type": "struct",
"value": [
{
"id": 0,
"type": "string",
"value": "differentuser"
},
{
"id": 1,
"type": "string",
"value": "differentpassword!"
}
]
},
{"id": 1, "type": "bool", "value": true},
{"id": 2, "type": "list", "value":
{
"elemType": "i32",
"list": [1, 2, 3]
}
},
{"id": 3, "type": "map", "value":
{
"keyType": "string",
"valueType": "string",
"map": {
"dog": "bark",
"cat": "meow"
}
}
}],
"seqid": 0
}}
gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAANZGlmZmVyZW50dXNlcgsAAQAAABJkaWZmZXJlbnRwYXNzd29yZCEAAgABAQ8AAggAAAADAAAAAQAAAAIAAAADDQADCwsAAAACAAAAA2NhdAAAAARtZW93AAAAA2RvZwAAAARiYXJrAA==
다음은 Thrift 바이너리 프로토콜로 다시 변환된 업데이트된 메시지입니다:
$ base64 -D | hexdump
gAEAAQAAAAVsb2dpbgAAAAAMAAALAAAAAAANZGlmZmVyZW50dXNlcgsAAQAAABJkaWZmZXJlbnRwYXNzd29yZCEAAgABAQ8AAggAAAADAAAAAQAAAAIAAAADDQADCwsAAAACAAAAA2NhdAAAAARtZW93AAAAA2RvZwAAAARiYXJrAA==
00000000: 8001 0001 0000 0005 6c6f 6769 6e00 0000 ........login...
00000010: 000c 0000 0b00 0000 0000 0d64 6966 6665 ...........diffe
00000020: 7265 6e74 7573 6572 0b00 0100 0000 1264 rentuser.......d
00000030: 6966 6665 7265 6e74 7061 7373 776f 7264 ifferentpassword
00000040: 2100 0200 0101 0f00 0208 0000 0003 0000 !...............
00000050: 0001 0000 0002 0000 0003 0d00 030b 0b00 ................
00000060: 0000 0200 0000 0363 6174 0000 0004 6d65 .......cat....me
00000070: 6f77 0000 0003 646f 6700 0000 0462 6172 ow....dog....bar
00000080: 6b00