ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python의 PIL 라이브러리를 이용한 Binary Data Visualizer 만들기
    프로그래밍/개발 2018. 2. 5. 18:15

    최근에 VELES(CodiSec)라는 바이너리 분석 툴을 알고 깜짝 놀랐던 적이 있다.

    스크린샷 출처: https://codisec.com/binary-data-visualization/ 

    위 스크린샷에서처럼 바이너리 데이터를 시각화해줘서 분석하기 쉽게 만들어주는 툴이다.

    실제로 개발팀은 이 툴을 사용하는 CTF 팀도 만들어서 활동하고 있다고 한다. 

    그런데 왜 시각화를 할까?

    진화심리학자 행크 데이비스는 인간은 무슨 일이든지 패턴을 발견하고 인과관계를 찾으려고 노력하는 존재라고 했다.

    비슷한 말 하나 기억나서 구글에 치면서 안 사실 처음 뵙겠습니다 행크 데이비스 씨^^7

    게임 로딩창에서 와 이걸 계속 터치하고 있으면 로딩이 빨리 될거야 그딴거 없어요 그런 느낌일까... 

    로딩창 말고도 게임 자체가 인간이 '패턴'을 찾는다는 것을 좋아한다는 특징을 이용한다는 말을 넥슨 어쩌고 하는 책에서 본 것 같다.

    또 관상, (인간에게 걸맞는 예시일진 모르겠지만) 빅데이터나 기계학습(얘네도 데이터에서 패턴을 찾으니까?) 같은 예시가 있을 것이다. 

    그래서일까? 인간은 숫자의 연속적인 조합(헥스에디터로 바이너리 파일을 열면 보이는 16진수 헬파티라던가)보다

    패턴에서 더 의미있는 데이터들을 더 빠르게 얻을 수 있다고 한다.

    실제로 이런 류(바이너리를 시각화해주는)의 툴은 파일에서 악성코드 같은 것들을 빠르게 찾을 수 있도록 사용한다던

    한 외국인 보안전문가의 트윗을 본 기억이 있다. 

    ~인지는 몰라도 그냥 멋있고 이쁘고 만들어보면 재미있을 것 같으니까 한번 해보자! 내가 이 위에 대체 뭐라고 쓴 거지

    VELES처럼 3D로 구현은 어려울 것 같고 그냥 2D로라도 만들어 보기로 하고, 구현 방법에 대해서 찾아봤다.

    공식 사이트에 원리를 설명하는 페이지가 있었다. 참고로 VELES는 오픈소스다.

    스크린샷 출처: https://codisec.com/binary-visualization-explained/

    저렇게 바이너리 데이터의 한 바이트와 그 다음 바이트를 그래프 위의 한 점의 좌표로 잡고 좌표계에 표시하고 하는 것이 기본적인 개념 같다.

    더 아래로 내려보면 점이 몇 번 표시되는지나 데이터의 위치나 그런 것에 따라서 또 세부적으로 명암이나 컬러링을 조절하는데 

    일단은 그 전 부분까지만 해봤다. 

    구현을 위해서는 이미지 파일을 다뤄야 하는데, 어떻게 해야 할지 막막하기만 했었는데

    작년 UBUNTU CTF에 Flag가 써있는 이미지를 이루는 RGB 값만으로 이루어진 텍스트 파일을 줬던 문제가 떠올랐다.

    물론 우리팀은 못 풀었지만 당시 1등 "이걸이렇게푼다..." 팀 분들께서 작성하신 WriteUp에 픽셀을 하나씩 찍는 코드가 있었던 것으로 기억했다.

    해당 WriteUp을 페북에서 찾아서 다시 읽어보면서 Python의 Image 모듈에 대해서 배우고 아래처럼 짜봤다.

    1. import sys  
    2. try:  
    3.     from PIL import Image  
    4. except ImportError:  
    5.     print("Install Python module Pillow by running \'pip install pillow\' on terminal")  
    6.     sys.exit()  
    7. image=Image.new("RGB", (256256))  
    8. filename=input("file name : ")  
    9. try:  
    10.     f=open(filename, "rb")  
    11. except IOError:  
    12.     print("No file with such name :(")  
    13.     sys.exit()  
    14. filedata=f.read()  
    15. for data in filedata:  
    16.     data=data&0xFF  
    17. f.close()  
    18. for i in range(0, len(filedata)-1):  
    19.     image.putpixel((filedata[i+1], filedata[i]), (255255255))  
    20. image.save("visualized_"+filename+".png")  

    따로 파이썬 이미징 라이브러리 Pillow를 설치해야 하기에 사용자의 시스템에 해당 라이브러리가 없을 경우까지 대비해서 친절하게(?) 예외처리까지...

    뭐튼 그리하여 프로그램이 완성되었고 결과를 봐도 앵간히 나온 것 같드아!

    Windows Executable(.exe) 파일을 대상으로 한 실행결과

    ELF 파일을 대상으로 한 실행결과

    PNG 파일을 대상으로 한 실행결과

    텍스트 파일을 대상으로 한 실행결과

    WAV 파일을 대상으로 한 실행결과

    ZIP 압축 파일을 대상으로 한 실행결과

    pcap 패킷 파일을 대상으로 한 실행결과

    또 문제가 입력으로 pdf 파일이나 mp3 파일처럼 용량이 크고 찍히는 점의 종류가 많은(?) 방대한 바이너리는 왠만해선 출력결과가 걍 하얗게 나와버린다.

    VELES 공식 사이트에 나온 데로 샘플링을 한다던가, 아니면 파일 데이터를 분할하고 시각화해서 여러 개의 출력을 내논다던가 해야겠다.

    앞으로 컬러링도 해보고 싶드아!! 알랴죠에 넣어서 돌아오는걸루(?)

    댓글

Designed by Tistory