Peepdf
소개[편집]
Peepdf는 Jose Miguel Esparza에서 무료로 제공하는 유틸리티이다. 최신 버전은 0.3이고, 본 항에서는 최신버전인 0.3을 기반으로 보고서를 작성하였다. Peepdf는 Windows와 Unix에서 콘솔로 동작한다. 파이썬(Python) 기반의 유틸리티이기 때문에 이용하기 전에 파이썬을 반드시 설치해야한다. 지원하는 문서의 종류는 Adobe의 PDF파일이다.
사용법[편집]
유틸리티를 개발한 개발자가 자체적으로 제작한 PyV8 와 Pylibemu를 추가로 설치해야 Peepdf가 추가로 지원하는 기능을 사용할 수 있다. 그러나 추가로 설치를 하지 않아도 기본적인 정보를 출력하는 동작은 한다. 추가 설치 파일은 모두 파이썬 기반의 추가 설치파일이다. 2개의 파일은 Peepdf의 공식홈페이지의 링크를 통해서 다운 받을 수 있다. PyV8 와 Pylibemu의 설치를 바친 후, Peepdf를 실행하면 [그림 1]와 같이 Peepdf에서 사용 할 수 있는 명령어들이 화면에 출력된다.
명령어 –i를 이용하여 콘솔 모드로 진입을 하여 PDF파일을 분석해도 되고, 콘솔모드로 진입하지 않고 직접 명령어들을 일일이 입력하여 분석할 수 있다. 기본 명령어는 다음과 같다.
peepdf.py pdf_file |
도구 기능[편집]
peepdf에서 제공하는 명령어를 통해 입력한 PDF파일에 대한 상세 분석이 가능하다. -f 명령어를 이용하면 입력한 PDF파일에 대해 기본적인 정보를 [그림 2]와 [그림 3]와 같이 출력해준다.
PDF파일의 파일명, MD5, SHA1, 크기, 버전 등 기본적인 정보에 대해서 화면에 출력해주고, 에러, 스트림, 인코딩 오브젝트에 대해서도 화면에 출력해준다.
-c 명령어를 이용하면 입력한 PDF파일을 바이러스토탈(VirusTotal) 사이트에 PDF파일을 자동으로 입력하고, 그 분석 결과를 [그림4]화면에 출력해준다.
그 외에는 peepdf의 업데이트, 버전 확인, 콘솔모드로 진입 등의 기능이 있다. 콘솔모드로 진입을 하면 입력한 PDF파일에 대해 더 자세한 분석이 가능하다. [그림 5]은 콘솔모드에서 사용 가능한 명령어를 보여주는 화면이다.
콘솔 모드에서 사용 할 수 있는 명령어를 정리하면 [표 2]와 같다.
명령어 | 명령어 형태 | 설명 |
bytes | bytes $offset $num_bytes [$file] | Shows or stores in the specified file $num_bytes of the file beginning from $offset |
changelog | change log files | |
create | (open_action_js [$js_file]) | Creates a new simple PDF file or one with Javascript code to be executed when opening the file. It's possible to specify the file where the Javascript code is stored or do it manually. |
create object_stream [$version] | Creates an object stream choosing the objects to be compressed. | |
decode | decode variable $var_name $filter1 [$filter2 ...] | Decodes the content of the specified variable, file or raw bytes using the following filters or algorithms: |
* base64,b64: Base64 | ||
* asciihex,ahx: /ASCIIHexDecode | ||
* ascii85,a85: /ASCII85Decode | ||
* lzw: /LZWDecode | ||
* flatedecode,fl: /FlateDecode | ||
* runlength,rl: /RunLengthDecode | ||
* ccittfax,ccf: /CCITTFaxDecode | ||
* jbig2: /JBIG2Decode (Not * implemented) | ||
decode file $file_name $filter1 [$filter2 ...] | * dct: /DCTDecode (Not * implemented) | |
decode raw $offset $num_bytes $filter1 [$filter2 ...] | * jpx: /JPXDecode (Not implemented) | |
decrypt | decrypt $password | Decrypts the file with the specified password |
embed | Usage: embed [-x] $filename [$file_type] | Embeds the specified file in the actual PDF file. The default type is "application/pdf". |
* Options: | ||
-x: The file is executed when the actual PDF file is opened | ||
encode | encode variable $var_name $filter1 [$filter2 ...] | Encodes the content of the specified variable, file or raw bytes using the following filters or algorithms: |
* base64,b64: Base64 | ||
* asciihex,ahx: /ASCIIHexDecode | ||
* ascii85,a85: /ASCII85Decode (Not implemented) | ||
* lzw: /LZWDecode | ||
* flatedecode,fl: /FlateDecode | ||
* runlength,rl: /RunLengthDecode (Not implemented) | ||
* ccittfax,ccf: /CCITTFaxDecode (Not implemented) | ||
* jbig2: /JBIG2Decode (Not implemented) | ||
encode file $file_name $filter1 [$filter2 ...] | * dct: /DCTDecode (Not implemented) | |
encode raw $offset $num_bytes $filter1 [$filter2 ...] | * jpx: /JPXDecode (Not implemented) | |
encode_strings | encoding strings | |
encrypt | encrypt file | |
errors | check error | |
exit | exit peepdf | |
filters | filters $object_id [$version] [$filter1 [$filter2 ...]] | Shows the filters found in the stream object or set the filters in the object (first filter is used first). The valid values for filters are the following: |
* none: No filters | ||
* asciihex,ahx: /ASCIIHexDecode | ||
* ascii85,a85: /ASCII85Decode (Not implemented) | ||
* lzw: /LZWDecode | ||
* flatedecode,fl: /FlateDecode | ||
* runlength,rl: /RunLengthDecode (Not implemented) | ||
* ccittfax,ccf: /CCITTFaxDecode (Not implemented) | ||
* jbig2: /JBIG2Decode (Not implemented) | ||
* dct: /DCTDecode (Not implemented) | ||
* jpx: /JPXDecode (Not implemented) | ||
hash | rawobject|stream|rawstream $object_id [$version] | Generates the hash (MD5/SHA1/SHA256) of the specified source: raw bytes of the file, objects and streams, and the content of files or variables |
hash raw $offset $num_bytes | ||
hash file $file_name | ||
hash variable $var_name | ||
help | output command | |
info | output PDF file informations | |
js_analyse | js_analyse variable $var_name | Analyses the Javascript code stored in the specified variable, file, objaw code |
js_analyse file $file_name | ||
js_analyse object $object_id [$version] | ||
js_analyse code $javascript_code | ||
js_beautify | js_beautify variable $var_name | Beautifies the Javascript code stored in the specified variable, file or object |
js_beautify file $file_name | ||
js_beautify object $object_id [$version] | ||
js_code | js_code $object_id [$version] | Shows the Javascript code found in the object |
js_eval | js_eval variable $var_name | Evaluates the Javascript code stored in the specified variable, file, object or raw code in a global context |
js_eval file $file_name | ||
js_eval object $object_id [$version] | ||
js_eval code $javascript_code | ||
js_jjdecode | js_jjdecode variable $var_name | Decodes the Javascript code stored in the specified variable, file or object using the jjencode/decode algorithm by Yosuke Hasegawa (http://utf-8.jp/public/jjen |
js_jjdecode file $file_name | code.html) | |
js_jjdecode object $object_id [$version] | ||
js_join | js_join variable $var_name | Joins some strings separated by quotes and stored in the specified variable or file in a unique one |
js_join file $file_name | ||
js_unescape | js_unescape variable $var_name | Unescapes the escaped characters stored in the specified variable or file |
js_unescape file $file_name | ||
js_vars | ||
malformed_output | ||
metadata | output metadata | |
modify | modify object|stream $object_id [$version] [$file] | Modifies the object or stream specified. It's possible to use a file to retrieve |
the stream content (ONLY for stream content). | ||
object | object $object_id [$version] | Shows the content of the object after being decoded and decrypted. |
offsets | 제대로 동작 안함 | |
open | open [-fl] $file_name | Opens and parses the specified file |
Options: | ||
* -f: Sets force parsing mode to ignore errors | ||
* -l: Sets loose parsing mode for problematic files | ||
quit | quit console mode | |
rawobject | xref|trailer [$version]] | Shows the content of the object without being decoded or decrypted (object_id, xref, trailer) |
rawstream | rawstream $object_id [$version] | Shows the stream content of the specified document version before being decoded and decrypted |
references | in $object_id [$version] | Shows the references in the object or to the object in the specified version of the document |
replace | replace all $string1 $string2 | Replaces $string1 with $string2 in the whole PDF file |
replace variable $var_name $string1 $string2 | Replaces $string1 with $string2 in the content of the specified variable or file | |
replace file $file_name $string1 $string2 | ||
reset | clear | |
save | save file | |
save_version | save_version $version $file_name | Saves the selected file version to disk |
sctest | ||
search | search [hex] $string | Search the specified string or hexadecimal string in the objects (decoded and en |
crypted streams included) | ||
set | output malformed_options, vt_key, output_limit, header_file | |
show | show $var_name | Special variables: |
* header_file | ||
* malformed_options | ||
* output | ||
* output_limit | ||
* vt_key | ||
stream | stream $object_id [$version] | Shows the object stream content of the specified version after being decoded an decrypted (if necessary) |
tree | output tree structure | |
vtcheck | check VirusTotal | |
xor | rawstream $object_id [$version] [$key] | Performs an XOR operation using the specified key with the content of the speciied file or variable, raw bytes of the file or stream/rawstream. |
xor raw $offset $num_bytes $key | If the key is not specified then a bruteforcing XOR is performed. | |
xor file $file_name $key | ||
xor variable $var_name $key | ||
xor_search | rawstream $object_id [$version] $string_to_search | Searches for the specified string in the result of an XOR brute forcing operation with the content of the specified file or variable, raw bytes of the file or stream/rawstream. The output shows the offset/s where the string is found. It's a case sensitive search but it's possible to make it insensitive using -i. |
xor_search [-i] raw $offset $num_bytes $string_to_search | ||
xor_search [-i] file $file_name $string_to_search | ||
xor_search [-i] variable $var_name $string_to_search |
[그림 6]은 set 명령어를 실행한 결과이다. malformed option과 vt key, output limit, header file에 대해서 출력한다.
[그림 7]은 edcode_strings 명령어를 실행한 결과이다. 입력한 PDF파일의 스트링을 인코딩한다.
[그림 8]은 명령어 metadata를 통해 입력한 PDF파일의 메타데이터 정보가 출력된 화면이다.
[그림 9]은 입력한 PDF파일을 암호화한 결과 화면이다.
제한사항[편집]
Windows 환경에서는 Pylibemu가 제대로 설치가 되지 않았고, Linux 환경에서는 PyV8와 Pylibemu 둘 다 설치가 제대로 되지 않는다. 그렇기 때문에 Pylibemu를 설치해야 PDF파일 안의 자바 코드를 분석 할 수 있는 기능이 제대로 동작하지 않는다.
수사 활용 방안[편집]
peepdf는 입력한 PDF파일이 정상인지, 악성코드와 같은 수상한 코드들이 파일에 삽입이 되어 있는지, 암호화되어 있는지 등에 대해 분석해야할 경우에 적합한 도구로 보인다.