Blog Content

    티스토리 뷰

    [Google CTF 2017] [MISC] - Secret Notes


    이 문제에서는 다음과 같은 풀이과정이 필요하다.

    1. 계정 가입했을 때 얻는 토큰의 형태 이해

    2. apk 파일을 분석하여 동작방식 이해

    3. index.pyc를 찾아 웹 동작방식 이해

    4. 계정에 따른 해쉬값의 패턴을 찾아 추측

    5. DB를 다운로드하여 디코딩 후 FLAG 획득



    먼저 링크를 따라가면 위와 같은 간단한 가입 페이지를 볼 수 있다.

    여기서는 계정을 생성하여 토큰을 얻을 수 있는데 토큰의 형식은 계정의 hex값 - hash 이다.

    ex) testAccount = 746573744163636f756e74-51bd5ae127bffb3f



    dex2jar로 APK를 분석해보면 /private로 접근하면 DB를 다운로드 할 수 있는 것을 알 수있다.


    Fiddler를 이용하여 웹 사이트를 돌아다녀보면 /static/ 이라는 경로안에 파일이 존재하는 것과

    Response header에 X-Served-By: index.py이 있음을 알 수 있고 여기에 힌트 pyc를 종합해보면

    https://notes-server-m8tv5txzzohwiznk.web.ctfcompetition.com/static/index.pyc 으로 

    접근하면 index.pyc 파일을 얻을 수 있다는 것을 추측 할 수 있다.

    index.pyc 파일을 uncompyle6를 이용하여 위와 같은 py파일로 보면 웹 페이지가 동작하는 구조를 파악할 수 있다.

    142번째 줄을 보면 locked_id를 볼 수 있다. 이를 hex 디코드하면 Corg1l0ver99<3!! 라는 문자열이 나오며 

    이 id를 이용하여 DB파일을 빼내야 한다는 것을 알 수 있다. 

    하지만 DB파일을 가져오기 위해서는 id에 대한 해시 값을 알아야 하는데 4번째 줄에 있는 hasher 모듈을 사용하는 것을 알 수 있다.

    이 모듈을 출제자가 문제를 위해 개인적으로 제작한 모듈이었으며 여러번의 추측끝에 

    https://notes-server-m8tv5txzzohwiznk.web.ctfcompetition.com/static/hasher.pyc 로 접근하여 hasher.pyc 파일을 얻을 수 있었다.

    마찬가지로 디컴파일을 통해 py파일을 추출하여 보면 해시가 생성되는 과정을 볼 수 있다.

    하지만 해시값을 얻기 위해서는 key1key2가 필요한데 이것은 서버에서 생성되는 것으로 얻을 수가 없었다.

    물론 역연산을 통해 key값을 구하는 방법도 있겠지만 나는 웹 사이트에서 id를 가입하여 나오는 해시에 대한 패턴을 찾아 풀었다.

    패턴을 찾을때에는 0 패딩이 들어가는 것을 보고 hex로 10의 배수인 값을 이용하여 쉽게 찾았다.


     가입 ID

     토큰의 Hash 값

     Corg1l0ver99<3!!P

     62e77228f277ba31

     Corg1l0ver99<3!!PP

     62b77228f277ba31

     Corg1l0ver99<3!!PPP

     62b72228f277ba31

     Corg1l0ver99<3!!PPPP 62b72278f277ba31
     Corg1l0ver99<3!!PPPPP 62b72278a277ba31


    위 표를 보면 웹페이지에서 가입을 했을때 토큰의 hash들을 보면 특정패턴이 보이는 것을 알 수 있다.

    62e77228f277ba31 -> 62b77228f277ba31 (3번째 자리 e -> b)

    62b77228f277ba31 -> 62b72228f277ba31 (5번째 자리 7 -> 2)

    62b72228f277ba31 -> 62b72278f277ba31 (7번째 자리 2 -> 7)

    62b72278f277ba31 -> 62b72278a277ba31 (9번째 자리 f -> a)


    패턴은 P를 붙힐때마다 홀수번째 인덱스 값이 5만큼 작아지며 인덱스의 값이 5보다 작으면 5만큼 더 플러스를 한다는 것인데

    이것을 보면 해시값이 크게 변화하지 않는다는 것을 알 수 있고 1번재 자리의 값만 대입하면 locked_id의 값을 알아낼수 있다.


    몇번 대입하다 436f7267316c3076657239393c332121-32e77228f277ba31이라는 토큰으로 DB파일을 성공적으로 다운로드 할 수 있었다.



    DB파일을 다운로드 받으면 파일이 base64로 암호화 되있는것을 볼 수 있는데

    base64 디코딩을 한 후 SQLite 뷰어를 통해 FLAG 테이블을 확인하면 플래그를 확인할 수 있다.


    Google CTF Write-up


    Comments