Page tree
Skip to end of metadata
Go to start of metadata

https://hitbxctf2018.xctf.org.cn/7b6d737a-a55e-48a0-9fde-cdda99c6b403/login/

함께 하시죠



1. Misc

  • Problem: IRC checkin
    irc client로 hitbxctf2018.freenode.irc 접속, /join hitbxctf2018 입장하면 Flags Get.


  • Problem: tpyx
    Simple picture steganography 
    https://hitbxctf2018.xctf.org.cn/media/task/e47c7307-b54c-4316-9894-5a8daec738b4.png

    스테가노그래피 문제로 PNG 파일이 주어진다, 아래와 같이 오탁후스러운 그림이 나옴.


    스테가노그래피 분석 사이트 몇군데를 돌려보았느데 성과 없음.
    1) Digital Image Forensic Analyzer - imageforensic.org
    2) http://stylesuxx.github.io/steganography/
    3) http://www.jpeg-repair.org/vg-jpeg-repair/
    4) tweakpng-1.4.6

    뭔가 내포된것이 있는지 binwalk로 확인 했는데 일반 PNG랑 비교 했을때 특별한게 안보임... 그리 쉬울리가 없지..

    root@Juwon1405:~/z/CTF/2018/hitbxctf2018/steganography# binwalk e47c7307-b54c-4316-9894-5a8daec738b4.png
    
    DECIMAL       HEXADECIMAL     DESCRIPTION
    --------------------------------------------------------------------------------
    0             0x0             PNG image, 1024 x 653, 8-bit/color RGBA, non-interlaced
    41            0x29            Zlib compressed data, default compression
    2747          0xABB           LZMA compressed data, properties: 0xC7, dictionary size: 17629184 bytes, uncompressed size: 564116269818626 bytes
    7399          0x1CE7          LZMA compressed data, properties: 0x89, dictionary size: 1749155840 bytes, uncompressed size: 2226797330053640880 bytes
    8453          0x2105          LZMA compressed data, properties: 0xA3, dictionary size: 42532864 bytes, uncompressed size: 2363042167456256480 bytes
    8755          0x2233          LZMA compressed data, properties: 0x92, dictionary size: 17104896 bytes, uncompressed size: 5654336402406536386 bytes
    8841          0x2289          LZMA compressed data, properties: 0x5C, dictionary size: 2028666880 bytes, uncompressed size: 1187824461394739226 bytes
    11664         0x2D90          LZMA compressed data, properties: 0x92, dictionary size: -6750208 bytes, uncompressed size: 5089269877972990409 bytes
    13376         0x3440          LZMA compressed data, properties: 0xB6, dictionary size: 2116681728 bytes, uncompressed size: 1258534629648183174 bytes
    18844         0x499C          LZMA compressed data, properties: 0x92, dictionary size: -1800601600 bytes, uncompressed size: 4711838334337024013 bytes
    23925         0x5D75          LZMA compressed data, properties: 0x93, dictionary size: 1620639744 bytes, uncompressed size: 2447307085072310094 bytes
    29959         0x7507          LZMA compressed data, properties: 0x91, dictionary size: -30408704 bytes, uncompressed size: 5504946975723080848 bytes
    31655         0x7BA7          LZMA compressed data, properties: 0x64, dictionary size: -1049034752 bytes, uncompressed size: 6260289902948521843 bytes
    39231         0x993F          LZMA compressed data, properties: 0xB8, dictionary size: -574160896 bytes, uncompressed size: 7061410741363752976 bytes
    40486         0x9E26          LZMA compressed data, properties: 0xBF, dictionary size: -446103552 bytes, uncompressed size: 363949681333449935 bytes
    42801         0xA731          LZMA compressed data, properties: 0x5A, dictionary size: 329515008 bytes, uncompressed size: 103600418035026752 bytes
    46495         0xB59F          LZMA compressed data, properties: 0x51, dictionary size: 1941897216 bytes, uncompressed size: 7349833221898761908 bytes
    47342         0xB8EE          LZMA compressed data, properties: 0x88, dictionary size: -1247150080 bytes, uncompressed size: 2901375546847713559 bytes
    49547         0xC18B          LZMA compressed data, properties: 0xCF, dictionary size: 27459584 bytes, uncompressed size: 5504915316123753562 bytes
    50115         0xC3C3          LZMA compressed data, properties: 0x7E, dictionary size: -1610088448 bytes, uncompressed size: 864741550019018216 bytes
    90968         0x16358         LZMA compressed data, properties: 0x91, dictionary size: -2072313856 bytes, uncompressed size: 2148850342028290981 bytes
    92204         0x1682C         LZMA compressed data, properties: 0x87, dictionary size: -1152385024 bytes, uncompressed size: 4895412928778185300 bytes
    97605         0x17D45         LZMA compressed data, properties: 0xB8, dictionary size: 2140864512 bytes, uncompressed size: 145268781718745189 bytes
    100220        0x1877C         LZMA compressed data, properties: 0xA2, dictionary size: 1545142272 bytes, uncompressed size: 18155136063701122 bytes
    100647        0x18927         LZMA compressed data, properties: 0x99, dictionary size: -437256192 bytes, uncompressed size: 3523327336774852554 bytes
    106125        0x19E8D         LZMA compressed data, properties: 0xBF, dictionary size: 1417347072 bytes, uncompressed size: 2005821249054206240 bytes
    107061        0x1A235         LZMA compressed data, properties: 0xBF, dictionary size: 1838546944 bytes, uncompressed size: 1358890821980526530 bytes
    110133        0x1AE35         LZMA compressed data, properties: 0xCF, dictionary size: 74907648 bytes, uncompressed size: 32783339350293512 bytes
    111083        0x1B1EB         LZMA compressed data, properties: 0xB8, dictionary size: 921108480 bytes, uncompressed size: 2444114911468346624 bytes
    127336        0x1F168         LZMA compressed data, properties: 0x90, dictionary size: -1104609280 bytes, uncompressed size: 5989013497571902034 bytes

    해당 PNG파일에 pngcheck / pngchunks 테스트 결과, CRC error in chunk IDAT (computed ecfb2a19, expected ba3de214), Unknown chunk type error가 확인됨.



    다시말해 CRC error in chunk IDAT (computed ecfb2a19, expected ba3de214) 는 IDAT chunk 무결성 값이, ecfb2a19로 계산되는데 실제 ba3de214로 계산되었다는 이야기다. IDAT chunk가 조작된 것일까.... 하... 어쨋든 파일이 망가졌으니 복구하는 방법은 파일 구조를 이해하고 포맷에 맞게 수정해 주어보자... (시바 이걸 스테가노그라피라고 ... 하... )




    참고로, PNG파일 구조는 아래 링크를 참고하자.. (이걸 왜 알아야하는지 정말 모르겠다.-,.-)
    https://www.w3.org/TR/PNG/#4Concepts.FormatTypes





    위 그림처럼 Chunk(청크)는 길이,청크타입명,청크데이터(보조청크는생략),무결성값(CRC)로 구성된다.
    PNG파일 포멧에는 반드시 PNG 헤더 + IHDR+IDAT+IEND 청크들(IDAT 청크 데이터안에 그림데이터 값이 들어감)이 들어가고
    헤더는 파일의 식별, IHDR는 컬러와 사이즈 및 기타 사진에 대한 메타정보, IDAT는 사진 메터데이터에서 정의한 방식의 그림 데이터, IEND는 PNG파일 포맷의 끝을 알려준다. 그 외에 PLTE청크 및 기타 보조 청크들도 함께 있는경우도 존재함.


    자 그럼 문제의 PNG파일은 어디서 부터 접근해야 할지, PNG의 헤더와 푸터를 보자.
    PNG File 헤더는, 89 50 4E 47 0D 0A 1A 0A 이다.
    헌데 푸터는 아래 그림에서 위(정상)와 아래(문제파일)의 HEX마지막 값에 00 이 붙는다. 일단 00부터 지우고 시작함.

    (정상)

    (문제파일: 끝에 00이 붙음)


    그리고 기본 Chunk를 보니, PNG헤더(매직시그니처)는 정상 인데, 청크가 깨진것 같다.

    위 그림과 같이 청크[0]은 IHDR이고, 해당 값 Length, IHDR에 내포된 값들 또한 정상이다..
    반면 IDAT 청크[1]은 0x21 offset이고, length가 1162839 byte 다. crc값은 기재된 length대비 자동 offset이 잡혀 기재되어 있는데,
    IDAT 청크[2]에서 보면 청크 Type명이 없다. 그리고 length값 또한 length의 일반적인 범위(65536) 를 넘는 3224620939 byte로 보이고,
    마지막으로, IEND 청크가 없다.

    해볼 수 있는 방법은,
    1) IDAT length 값을 IEND 전 까지로 수정해주고, CRC값을 구해 기재해 준다.
    2) 아니면, IDAT를 65536 byte단위로 쪼개면서 분할해주고, IDAT 청크 단위별로 CRC를 구해 기재 해봐야겠다.. (하..... 귀찮..)
    아래는 인터넷에 찾을 수 있는 코드이고..

    CRC-32 출력 예제
    스크립트 파일명: example.py
    
    #!/usr/bin/python
    # -*- coding: cp949 -*-
    # 32비트 unsigned 형으로 변환하는 함수 정의
    def unsigned32(n):
      return n & 0xFFFFFFFFL
    # 지정한 파일의 CRC-32 값 반환 함수
    import zlib
    def getCRC32(filename):
      try:
        crc = zlib.crc32(file(filename, 'rb').read())
        return unsigned32(crc)
      except IOError:
        print "그런 파일이 없거나, 읽기 에러입니다."
        return -1  # 에러 나면 -1 (-0000001) 반환
    # 본격적인 프로그램 시작
    import sys
    if len(sys.argv) == 1:  # 옵션 없으면 도움말 출력하고 종료
      print "CRC를 검사할 파일명을 입력해 주세요"
      exit(1)
    # CRC-32 값 출력
    print "%08X" % getCRC32(sys.argv[1])

    더 간단하게는 TweakPNG를 사용하면, chunk의 crc 값 체크, 기타 PNG청크 타입 오류를 확인시켜 준다.
    http://entropymine.com/jason/tweakpng/




    위 그림처럼, 우리는 "첫번째 IDAT 청크길이"가 잘못 기록되어, 실제보다 짧은 잘못된 길이로 인해 CRC값이 잘못 구해지고,
    IDAT 청크 타입명은 해당 파일내 1개만 존재한다. 따라서 삭제되지 않았다고 가정하고 1개의 IDAT 청크로 length를 재 계산한다.

    계산: IEND 청크 시작 값 (0x11C4E3) - IDAT Data offset (0x29) = IDAT length (0x11C4BA) 으로 계산하였다.


    위와 같이 저장한 length 값으로 수정하여 PNG 파일을 저장하고, CRC값 을 확인하여 수정한다.


    아래와 같이 최종적으로 PNG 고쳐 놓음...


    처음 다운받았을 때와 다르게, 손상없는 PNG파일 확인함.




    근데 똑같아... 키값이고 뭐고 안보인다.

    e47c7307-b54c-4316-9894-5a8daec738b4.png

    그 외에도 여러 각도에서 스테가노그래피가 있는지 확인했다.

    샤오 스테가노그래피, 이미지 스테가노그래피, 스테그하이드, 크립처, 스테가노그래프X 플러스, r스테그, 에스수트 픽셀, 아워 시크릿, 카무플라주, 오픈스테고, 스테간PEG, 하이드’N’센드
    외에도 픽셀 변화, 명암 색 등을 변화시켜 의미있는 문자등이 나오는지 확인함. ....








    그래서!!!! 일단, 처음 부터 다시해보자! 으아아아앍!!!

    첨부터 다시 시작하니까 ... 한 30분 정도 만에 풀렷다. !?!?
    (과정에서 "e47c7307-b54c-4316-9894-5a8daec738b4.png" 파일명이 32글자라서 md5 hash로 킬링해보고.. 저 hex값을 IDAT다른 헤더와 비교/삽입 삽질)

    처음에 했던 binwalk 부터 다시 돌아가서 해보자.
    일단 아래와 같이 내포된 파일 시그니처를 기반으로 카빙한다.



    아래와 같이 파일들이 풀리고, 확장자 7z은 hex값을 보니 IDAT 헤더와 일치해서 실제 7z 압축은 아니라서 패스, Zlib compressed 된 파일을 확인하자.



    29 이라는 추출된 파일을 보니, Zlib 압축이다. 그럼 binwalk로 다시한번 추출 진행!



    위 에서 풀어서 _29.extracted 폴더에 들어가서 28D28D 라는 파일을 보니, 뭔가 있는것 같다!! hex값이 나왓는데.. 제발!!



    hex 값을 ascii 바꿔 로 보니!!
    - 파일 헤더는 7z 이고
    - 합축 파일내 flag 파일이 있다.
    - 끝에 ascii ==로 페딩 붙은거 보니 base64값도 있는것 같다.




    다음과 같이 28D28D내 HEX Ascii 값을, result.7z으로 생성 해 준다.

     echo 377abcaf271c000382f96c91300000000000000073000000000000003c0e24409c429fdb08f31ebc2361b3016f04a79a070830334c68dd47db383e4b7246acad87460cd00ba62cfae68508182a69527a0104060001093000070b0100022406f107010a5307cb7afbfaec5aa07623030101055d0000010001000c2c2700080a01c35b933000000501110b0066006c00610067000000120a010000844bf3571cd101130a010000e669e866d1d301140a010080ffcdd963d1d301150601008000000000001800345172634f556d365761752b5675425838672b4950673d3d | xxd -r -p > result.7z



    result.7z 암호를 풀어보려 하니... 헐퀴.. 압축을 해제 하려고 보니, 암호가있단다. 주 패고싶네 진짜..-_-
    그래서 이것저것 넣어보다 아까 봣던 base64값(4QrcOUm6Wau+VuBX8g+IPg== 이건 디코딩 해도 깨지더라)을 넣으니 풀렷다.





    알고보니 zlib 압축 내, 파일을 다시 zlib압축하고 그 안에 .7z 압축파일 내 flag가 있엇고, 그 7z 트레일러에 base64로 암호를 동봉한 문제였다.
    이게 정말 스테가노그래피 문제인가... 암걸릴뻔.... (갠히!? PNG 공부만 했네...)

    Flag: HITB{0c88d56694c2fb3bcc416e122c1072eb}






2. Web

 2.1 upload

| 문제

  • TIP : Get Shell !






3. Android

  • multicheck

+ 파일 다운로드

+ apk 폰에 설치해 작동 상태 보기
flag 입력후 check 버튼 누르면 “Sorry, you are wrong” 나옴.


+ 디컴파일 하여 소스코드 본 결과

플래그를 제대로 입력하면, 아래와 같이 “YES, you get it~” 이라고 출력될모양임.

 

+ 그럼 method.invoke 는 어디있는가?

겁나게 꼬아뒀음. dex파일로부터 class 파일을 풀어냄.

그리고, 그 클래스 파일을 로드하고, 지워버림.

 

로드된 클래스엔 아래 메소드가 있는모양.

com.a.Check.check 메소드.

이것을 알아내면 되는거임. 이라고 파악함.

 

+ 디컴파일된 내용을 가지고 claz.dex를 풀어내는 java 코드를 작성.

 

+ claz.dex아 풀어진 claz_out.dex를 얻어냄.

 

+ dex를 jar로 바꿔봄.

 

+ 산출된 jar파일을 jd-gui 로 열어봄.

 

+ 디컴파일된 내용이 나왔음. 여기서 문자열을 얻어내면 답이될거라 확신함.
소스코드를 보니.. 참 더럽다고 느낌. 왜? 어째서 이렇게 괴상하게 해놓은거야. 너무하자나. 귀찮아.
그냥 안해버릴까 5초정도 고민함.

 

+개뻘짓중…


+ ???? 꼬였다…미친.. 카악 퉷

 

+ 방법을 달리해야겠음. 그냥 소스에서 정렬하자…

 

 

+ 헥헥. 정렬 완료.

 

+ 문자열 나왔음.
HITB{this_is_certainly_not_the_flag}
영어를 보니.. 이것은 확실히 플래그가 아니란다…

 

+ ???? 답이 아니네??

 

뭐야.. 나 이런거 진짜 싫어…
나도 ctf때 이런문제 내놓고 확 잠수타버릴까…



+ 잠깐 일이 생겨 멈췄다가 다시 왔음.


+이거 또 개수작을 부리는 모양인데... 리소스좀 뒤져보니 .so 파일이 보임. ndk인가... 

java소스단엔 가져다 쓰질 않았음. 뭐하자는걸까...


+ 일단 ida가 필요하게됨. 노트패드로 단순히 열어선 뭐 보이는게 없음.

ida 설치중.. ... 아 열받아.. 아 열받아!!!!! 위에서 개뻘짓 했자나1!!!! 괜히 짜증나버렷!!!!!!! 카악 퉷

퉷!!! 카악~~! 퉷 이문제 낸녀석 코풀다가 코털 다 뽑혀버려라.!!!!!!!!


+ 일단 libcheck.so 파일 열어봄


+ ida로 열어서 봐도... 전혀 알지를 모르겠음. apk 와 연관되는 부분이라곤 그냥 load하는것뿐이여서
이정표가 전혀 없음. 뭐냐이건... 정말 이따위로 문제 낼래!!!

native 키워드도 없고, 함수명도 다 똥임.

어떻게 푼걸까... 이 인간들.....


+ 문제를 다시 생각해보는중.

Check!! Check!! Check!! 란다.. 확인하고. 또 확인하고. 그리고 또 확인하라는데..

여러번 확인했더니 블럭먹었다. 카악 퉷















  • No labels

2 Comments

  1. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ웃기네여 

  2. ㅋㅋㅋㅋㅋㅋㅋㅋ