반응형
반응형
반응형

  InCTF 2021 Forensic 문제의 write up보고 다시 푼 내용을 정리하였습니다.

 

https://blog.bi0s.in/2021/08/16/Forensics/Ermittlung-InCTF-Internationals-2021/

1. chat application program 찾기

2. userassist로 마지막 실행시각 확인

3. NTUSER.DAT에서 unread 메세지 개수와 프로그램 버전 확인

4. procdump, strings로 프로그램 버전 확인

 

 


ermitting.raw파일이 주어지는데, 용량은 0.99GB로, 메모리 덤프파일로 추측된다.

 

volatility를 사용하여 분석을 진행한다.

먼저 imageinfo로 프로필을 확인한다.

WinXPSP2x86

 

 

 

pstree에서 firefox.exe와 msimn.exe가 실행중이었음을 확인할 수 있다.

 

msimn.exe는 Outlook Express의 프로세스이다.

 

firefox를 사용하였으므로 firfoxhistory를 확인해보았지만, 의미있는 정보는 없다.

 


 

확인한 프로세스들 중에서 chat application program라고 할만한 것은 msimn.exe밖에 없다.

 

cmdline 플러그인을 사용하면 Outlook Express가 실행되는 부분을 찾을 수 있다.

따라서 1번 질문에 대한 답은 Outlook_Express 이다.

 


 

2번 질문, 해당 프로그램을 마지막을 이용한 시각은 pslist, pstree에서 확인할 수 있다.

 

아니면 userassist 플러그인을 사용하여 확인하는 방법도 있다.

실행횟수도 확인 가능하다.


outlook express 의 unread 메세지 개수는 NTUSER.DAT 레지스트리에서 찾을 수 있다.

 

hivelist로 NTUSER.DAT의 주소값을 찾고

 

dumpregistry로 해당 hive파일을 추출한다.

 

Software\Microsoft\Windows\CurrentVersion\UnreadMail\

REGA등으로 확인하면 된다.

해당 계정의 email주소도 확인할 수 있다.

 

volatility에서 printkey 플러그인을 사용하여 printkey -o 0xe1aa5b60 -K "Software\Microsoft\Windows\CurrentVersion\UnreadMail\" 로 확인할 수도 있다.


4번 질문, 채팅 프로그램의 버전 구하기.

프로그램의 버전을 찾는 방법에는 2가지가 있다. 1. NTUSER.DAT hive에서 찾기 2. 해당 프로세스를 dump떠서 찾기 

 

1. 레지스트리에서..

Software\Microsoft\Outlook Express\5.0\Shared Settings\Setup

 

2. 프로세스 dump에서...

volatility     procdump -p 2132 -D ./

리눅스 strings 명령어 사용해서 FileVersion을 찾을 수 있다.

 


https://blog.bi0s.in/2021/08/16/Forensics/Heist-InCTF-Internationals-2021/

 

1. NTUSER.DAT 레지스트리에서 default browser 찾기

2. top-visited website 확인

3. TeamViewer 아티팩트 분석

4. TeamViewer 아티팩트 분석


Heist.E01 ~ Heist.E10 10개로 분할된 이미지 파일(, disk dump)이 주어진다.

Autopsy를 사용하여 분석을 시작하자.

 

원래는 FTK Imager를 사용했었다가 이번에 autopsy를 사용해봤는데 autopsy가 분석하기에 더 편한 것 같다.

앞으로 Autopsy를 사용해야겠다.

 

1번 질문, 기본 브라우저.

 

NTUSER.DAT: Software\Microsoft\Windows\Shell\Associations\UrlAssociations\{http|https}\UserChoice

에서 기본 브라우저로 설정된 브라우저를 찾을 수 있다.

Chrome

 


2번 질문, top-visited 웹사이트 url 찾기

크롬 방문기록을 확인하기 위해 추출하는 History 파일이 있는 위치에 Top Sites라는 파일이 있다.

역시나 sqlite db파일인데

autopsy에서는 바로 데이터를 볼 수 있다.

 

top_sites 테이블에서 url_rank 값이 낮을 수록 가장 많이 방문한 사이트이다.

따라서 ebay.com

 


3번 질문, 가장 최근에 팀뷰어에서 파일 전송 세션이 시작된 시각

 

TeamViewer는 유저 데이터를 두 곳에 저장한다.

1. C:\Program Files\TeamViewer\
2. C:\Users\<User Profile>\AppData\Roaming\TeamViewer\

그리고 확인해야할 주요 파일은 1번 경로에 Connection_incoming.txt와 2번 경로에 Connections.txt 이다.

 

connection_incoming.txt example, Img src:  mii-cybersec

 

Connection_incoming.txt에서 filetransfer 세션 기록을 찾을 수 있었다.

해당 세션의 시작시간인 20-07-2021 07:48:50 이다.


4번 질문, 파일 전송 세션에서의 id와 hostname

3번에서 사용한 파일에서 찾을 수 있다.

920981533 & DESKTOP-S34NLCJ

 


반응형

 

 

https://blog.bi0s.in/2021/08/16/Forensics/Heist-Continues-InCTF-Internationals-2021/

1. Slack user id와 workspace id 찾기

2. remote connected PC의 배경화면 확인하기

3. 연결된적 있었던 2개의 USB의 파일시스템 확인하기

4. 윈도우10 타임라인에서 voice modulator 사용 시간 확인하기

 

문제파일은 위 heist 문제와 동일하다.

 


Slack user log는 Users\Danial Benjamin\AppData\Roaming\Slack에 있다.

주요 파일은 .\Local Storage\leveldb\000004.log 와 .\storage\root-state.json이다.

 

000004.log 에는 workspace에 대한 metadata(workspace name, user id, workspace id, icons 등)가 포함되어 있다. 

root-stat.json에는 workspace에서 다운받은 파일들에 대한 정보와 workspacedp 대한 metadata 일부가 있다.

root-stat.json

root-stat.json에서 domain, workspace id, user id, workspace name을 확인할 수 있으며

domain - heistplanning.slack.com
Workspace Name - Heist Planning
User ID - U027XK55WCT
Workspace ID - T027GM97WJ3

 

000004.log

000004.log에서 한 번 더 확인이 가능하다.

 


2번 질문, 원격으로 연결된 PC의 배경화면에 있는 글자 확인하기

 

이 문제 파일에서는 2개의 원격 프로그램 TeamViewer와 AnyDesk를 찾을 수 있다.

AnyDesk에서는 Remote PC의 배경화면을 썸네일로 사용하며,

해당 섬네일은 Users\Danial Benjamin\AppData\Roaming\AnyDesk\thumbnails 에서 찾을 수 있다.

 

 


3번 질문, 연결된 적이 있는 2개의 USB의 파일시스템 알아내기

3. Team restored 2 USB devices (Sandisk 3.2Gen1 & Toshiba External USB 3.0) at the leader’s place. What is the file system of these 2 USB devices?

 

SYSTEM레지스트리에서 해당 USB 2개 연결된 흔적을 찾을 수 있다.

 

이벤트 로그에 USB connection과 removal에 대한 detail들이 저장된다.

EVENT ID 1006번에서 찾아볼 수 있으며, 해당 ID는 Microsoft-Windows-Partition%4Diagnostic.evtx에서 찾을 수 있다.

 

해당 evtx를 파싱하여 CSV로 추출하기위해 Eric Zimmerman의 EvtxExplorer를 사용한다.

https://ericzimmerman.github.io/#!index.md

 

Eric Zimmerman's tools

 

ericzimmerman.github.io

사용 예제

 


Microsoft-Windows-Partition%4Diagnostic.evtx에서 얻을 수 있는 모든 아티팩트들에 대해서는https://dfir.pubpub.org/pub/h78di10n/release/2 (by Alexandros Vasilaras, Evangelos Dragonas, and Dimitrios Katsoulis)

 

USB Forensics – Recover more Volume Serial Numbers (VSNs) with the Windows 10 Partition/Diagnostic Event Log · DFIR Review

Synopsis Forensics Question: How many Volume Serial Numbers (VSNs) of previously connected devices can be recovered from a single Windows event log?OS Version: Microsoft Windows 10 Pro 2004 Build 19041 (Original Tests)Microsoft Windows 10 Pro 20H2 Build 19

dfir.pubpub.org

에 자세히 설명되어 있다고 한다. (나중에 정독해봐야겠다.)


해당되는 USB의 각 Payload에서

 

Vbr0값을 찾고 hex값을 ascii로 변환해주면

SanDisk 3.2Gen1 FileSystem - FAT32

파일시스템을 찾을 수 있다.

 

Toshiba USB 3.0 FileSystem - NTFS

 


4번 질문, 음성 변조 프로그램 사용 시간 구하기.

 

Windows10 1803버전 부터는 Timeline 기능이라는 것이 있다. http://www.forensic-artifacts.com/windows-forensics/timeline

 

디지털 포렌식 아티팩트 & 증거 분석 기법 공유 | 인섹시큐리티

[증거]테이블의 상단 칼럼 정보를 통해 응용프로그램 이름, 마지막 실행 시간 정보를 확인 할 수 있고 우측 [세부 정보]테이블을 통해서도 확인 가능

www.forensic-artifacts.com

 

C:\Users\<user>\AppData\Local\ConnectedDevicePlatform\L.<profile>\ActivitiesCache.db

 

추출하여 dbbrowser를 사용해서 열었다.

AppId에서 Voicemod Desktop을 찾고, ActivityType이 6인 것들 중에서 Payload에서 activeDurationSeconds 값을 확인한다.

해당 값을 모두 합치면 된다.

 

ActivitiyType == 6는 "App in focus"를 의미한다.

 


 

 

https://blog.bi0s.in/2021/08/16/Forensics/Heist-Ends-InCTF-Internationals-2021/

 

1. Google Keep Notes에서 note의 생성시각 추출

2 3 4. Slack Messages에서 장소와 일정 찾기

5. Google Tasks에서 completed tasks 개수 구하기

6. Google Docs cache에서 secret code 추출

7. Game 첫 실행 시각 찾기


./data

Android Device dump가 주어진다.

abrignoni의 ALEAPP를 사용하여 데이터를 파싱한다. (python3.9+가 필요하다.)

https://github.com/abrignoni/ALEAPP

 

GitHub - abrignoni/ALEAPP: Android Logs Events And Protobuf Parser

Android Logs Events And Protobuf Parser. Contribute to abrignoni/ALEAPP development by creating an account on GitHub.

github.com

 

ALEAPP을 돌려주면 이렇게 HTML 보고서를 확인할 수 있다.

안드로이드 10임을 확인할 수 있다.

 

1. When did the Professor create the note for Rio?

Google Keep에서 해당 노트를 찾을 수 있으며,  생성 시각도 확인할 수 있다.

 

Google Keep 아티팩트s https://g4rud4.gitlab.io/2021/Google-Keep-Notes-and-Lists-Mobile-Artifacts/

 

Google Keep - Notes and Lists: Mobile Artifacts | Nihith's Blog

Google Keep is one of the best notes storing app for Android from Google can be installed through Google Play store. In this blog post I am gonna explain about the Google Keep Mobile Artifacts, one can find in an android mobile dump. The Google Keep Notes

g4rud4.gitlab.io


2. Where did Professor and Rio, Plan to meet to plan the heist?

Slack 아티팩트 분석

https://abrignoni.blogspot.com/2018/09/finding-slack-messages-in-android-and.html

 

Finding Slack app messages in Android and using json_extract to do it.

Short version: The Slack app for Android keeps message related data in the TCJRXQD1B database located in the following directory: ...

abrignoni.blogspot.com

 

쿼리

https://github.com/abrignoni/DFIR-SQL-Query-Repo/tree/master/Android/SLACK

 

GitHub - abrignoni/DFIR-SQL-Query-Repo: Collection of SQL query templates for digital forensics use by platform and application.

Collection of SQL query templates for digital forensics use by platform and application. - GitHub - abrignoni/DFIR-SQL-Query-Repo: Collection of SQL query templates for digital forensics use by pla...

github.com

 

\data\data\com.Slack 경로에 유저 데이터가 있다.

SELECT datetime(ts , 'unixepoch') AS 'Time Sent', channel_id, user_id, json_extract(message_json, '$.text') AS 'Messages' FROM messages ORDER BY ts;

 

 

 


3. When did Rio plan to meet Professor?

 

 

 


4. How many members did Rio gathered for the heist?

 

 

 

 


5. How many tasks did Rio created in planning the heist, and how many did he complete?

 

 


6. There is a secret code present in a document shared between Rio & Professor, can you find out what it is?

 

문서를 공유한 것을 확인할 수 있고, 기기에 Google docs 앱이 설치되어 있는데 이 앱 캐시에서 해당 문서를 찾을 수 있다.

 

data\data\com.google.android.apps.docs\cache\docs_glide\data

png 파일이 존재한다.

 

시크릿 코드를 찾을 수 있다.

 

 

 


7. We found a game installed on the device. When did Rio first open this game?

dr. driving이라는 게임 하나가 깔려 있다.

data\data\com.ansangha.drdriving 에 유저 데이터가 있다.

.\shared_prefs\com.google.android.gms.measurement.prefs.xml 파일을 보면

first_open_time 값을 찾을 수 있다.


The Big Score

https://blog.bi0s.in/2021/08/20/Forensics/InCTFi21-TheBigScore/

Challenge Description


We sent Michael over to the Union Depository to collect data from one of their systems for the heist. We were able to retrieve the data, but it looks like they were able to read the message sent to us that Michael had typed from their system. Fortunately, he took the memory dump before escaping the building. Analyze the memory dump and find out how the message was compromised.

 

리눅스 메모리 덤프 파일 분석

 

리눅스 메모리 덤프인 lime 파일이 주어진다.

볼라티리티로 해당 메모리 덤프를 분석하기 위해서, 리눅스 프로파일을 빌드해주어야 한다. (기본 지원이 안되는 프로필인가 봄)

 

그래서 해당 파일의 프로필을 알아내야 하는데, 당연하겠지만 볼라티리티 imageinfo로는 안나온다.

대신 strings와 grep 명령어로 찾아낸다.

$ strings the_big_score.lime | grep 'Linux version'

Linux version 5.4.0-42-generic (buildd@lgw01-amd64-023) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #46~18.04.1-Ubuntu SMP Fri Jul 10 07:21:24 UTC 2020 (Ubuntu 5.4.0-42.46~18.04.1-generic 5.4.44)

 

그리고 동일한 버전의 vm을 구축하고 프로필을 빌드한다.

https://github.com/volatilityfoundation/volatility/wiki/Linux

 

GitHub - volatilityfoundation/volatility: An advanced memory forensics framework

An advanced memory forensics framework. Contribute to volatilityfoundation/volatility development by creating an account on GitHub.

github.com

 

https://github.com/volatilityfoundation/profiles/tree/master/Linux/Ubuntu/x64

 

GitHub - volatilityfoundation/profiles: Volatility profiles for Linux and Mac OS X

Volatility profiles for Linux and Mac OS X. Contribute to volatilityfoundation/profiles development by creating an account on GitHub.

github.com

여기 있는 것이라면 가져다 써도 되는데, 커널 버전이 안맞아서 오류가 난다.

 

http://old-releases.ubuntu.com/releases/18.04.1/

 

Index of /releases/18.04.1

Select an image Ubuntu is distributed on two types of images described below. Desktop image The desktop image allows you to try Ubuntu without changing your computer at all, and at your option to install it permanently later. This type of image is what mos

old-releases.ubuntu.com

 

 

$ apt-get install dwarfdump

$ apt-get install build-essential

$ cd volatility/tools/linux

$ make

$ head module.dwarf (module.dwarf 파일이 생성되었는지 확인)

 

$ sudo zip volatility/volatility/plugins/overlays/linux/Ubuntu1204.zip volatility/tools/linux/module.dwarf /boot/System.map-5.4.0-24-generic

 

vol.py --info

 

특이사항 하나를 찾을 수 있다.

 

링크로 들어가면, base64로 인코딩된 실행파일을 찾을 수 있다. 파일로 저장되지 않고 바로 메모리로 올라가 실행된다.

base64 디코딩해서 ida로 까보면 되는데, 기능은 간단하다.

git clone repo -> python 스크립트 실행 -> repo 제거

스크립트는 /dev/input/event2에서 데이터를 읽어와 hex로 인코딩해서 termbin에 업로드한다.

업로드한 경로는 hashed, reversed 되서 bin/log에 랜덤해시로 저장

 

bin/log를 추출하여 hash값을 얻기 위해, linux_enumerate_files 플러그인을 사용한다.

 

vol.py -f the_big_score.lime --profile=LinuxUbuntu18_04_1-5_4_0-42x64 linux_enumerate_files | findstr bin/log
vol.py -f the_big_score.lime --profile=LinuxUbuntu18_04_1-5_4_0-42x644 linux_find_file -i 0xffff8aa80573b890 -O ./

다음과정 생략.


Darkness

https://github.com/teambi0s/InCTFi/tree/master/2021/Forensics/Darkness

E01 파일 주어짐.

의심스러운 웹사이트 방문, 삭제된 중요한 키 파일

 

  1. The zip file is actually deleted from disk and can be recovered by extracting the Volume shadow copy from the .E01.키파일이 담긴 zip 복구 . 모르겠다.

 

방문기록 확인

 

pastebin.com 접속 기록을 확인할 수 있지만 그 이상은 없다. (흔적을 덮기 위해 방문기록을 지웠기 때문.)

 

윈도우에는 옵션으로 진단 데이터를 수집하는 기능이 있고 해당 데이터에는 MS edge 브라우저 방문기록 등이 있다.

 

C:\ProgramData\Microsoft\Diagnosis\EventTranscript\EventTranscript.db

 

Events_presisted 테이블에서  ogging_binary_name = msedge.exe 로 필터링 후 payload에서 navigationUrl값에서 url 찾기.

 

이게 오피셜 롸업이고,


방문기록에서 pastebin.com이 나온 것을 근거로 pastebin.com을 검색해서 찾아내면 된다.

해당 링크는 edge cache 폴더에 있는 파일에서 발견되었다.

 

해당 링크로 들어가면 패스워드를 요구하는데,

 

Archives에서 confidential.zip을 찾을 수 있고

 

해당 zip파일에서 패스워드를 찾을 수 있다.

반응형

'CTF Write Up' 카테고리의 다른 글

FIESTA 2021 Write up  (0) 2021.09.25
Fword CTF 2021 Forensics Write up  (0) 2021.09.25
SSTF 2021 write up  (0) 2021.08.16
RACTF 2021 Write up  (0) 2021.08.15
RCTS CERT CTF 2021 write up  (0) 2021.08.11
반응형

2020 Defenit CTF Write-up 6/5 09:00 ~ 6/7 09:00 (UTC, 48h)

 

 

 

Forensic

Baby Steganography

I heared you can find hide data in Audio Sub Bit. Do you want to look for it?

 

 

.wav 파일이 주어진다. 문제 지문을 보면 Audio Sub Bit에 데이터를 숨긴다고 한다.

 

Audio Sub Bit...

 

Sub Bit...

 

SB...

 

LSB?

 

LSB가 아닐까 생각을 해보고서 바로 구글링을 했다.

 

 

 

https://medium.com/@sumit.arora/audio-steganography-the-art-of-hiding-secrets-within-earshot-part-2-of-2-c76b1be719b3

 

Audio Steganography : The art of hiding secrets within earshot (part 2 of 2)

In this article we take a look at methods and tools along with code walk-through for performing Audio Steganography.

medium.com

Audio Steganography : LSB

 

 

포스트를 내리다보면 Python으로 작성된 Decode 코드가 있다. 바로 긁어다가 실행해 보았다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Use wave package (native to Python) for reading the received audio file
import wave
song = wave.open("problem", mode='rb')
# Convert audio to byte array
frame_bytes = bytearray(list(song.readframes(song.getnframes())))
 
# Extract the LSB of each byte
extracted = [frame_bytes[i] & 1 for i in range(len(frame_bytes))]
# Convert byte array back to string
string = "".join(chr(int("".join(map(str,extracted[i:i+8])),2)) for i in range(0,len(extracted),8))
# Cut off at the filler characters
decoded = string.split("###")[0]
 
# Print the extracted text
print("Sucessfully decoded: "+decoded)
song.close()
 
cs

 

Sucessfully decoded: Defenit{Y0u_knOw_tH3_@uD10_5t39@No9rAphy?!}

 

결과는 대성공.

 

 

 

 


Misc

QR Generator

Escape from QR devil!

 

nc 연결을 하자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Let's START!
 
< QR >
1 1 1 1 1 1 1 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 
1 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 
1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 0 1 1 0 1 0 1 1 1 0 1 
1 0 1 1 1 0 1 0 1 1 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1 1 1 0 1 
1 0 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 1 1 1 0 1 
1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 
1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 
0 1 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 0 1 1 0 1 1 0 1 1 1 1 1 
0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 0 0 0 1 1 0 1 0 0 1 1 0 1 1 
0 1 0 1 0 1 1 1 1 0 1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0 0 0 1 
1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 
0 0 0 0 1 0 1 1 1 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 
1 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 0 1 0 1 
0 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 0 1 0 1 0 1 1 
0 1 1 1 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 
1 0 0 1 1 0 1 1 1 1 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 0 0 1 
1 0 0 1 0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 
1 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 0 1 1 0 1 1 0 0 0 1 1 0 
0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 
1 0 0 0 1 0 1 0 1 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 0 1 0 
0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 0 0 
1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 1 0 1 0 0 0 1 
1 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 0 0 1 0 0 0 1 1 1 1 0 
1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 
1 0 1 1 1 0 1 0 1 0 1 1 1 1 1 1 0 0 0 1 1 0 0 1 0 1 1 1 0 
1 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 
1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 
1 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 
 
STAGE 1
>> Time Over!
 
cs

 

1과 0으로 된 qrcode를 보내준다.

 

하얀배경 이미지를 불러와서 값이 1이면 해당 위치의 픽셀의 값을 검정으로 바꾸도록 코드를 쓱-싹 작성해 준다.

하얀배경 이미지는 포토샵을 이용한다. 넉넉하게 200px*200px

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from pwn import *
from PIL import Image
 
= remote("qr-generator.ctf.defenit.kr"9000)
p.recvuntil('name?')
p.sendline('M4ndU')
img = Image.open('./200.png') #load white background 200*200 image
img = img.convert("RGB")
newData = []
 
qrbin = [0* 200
p.recvuntil('< QR >\n')
for i in range(200):
    data = str(p.recvline())
    data = data.replace("b'""")
    data = data.replace("\\n'""")
    data = data.replace(" """)
    if data == "":
        print(p.recvline())
        break
    qrbin[i] = data
 
for x in range(len(qrbin)):
    if qrbin[x] == 0:
        break
    for y in range(len(str(qrbin[x]))):
        if qrbin[x][y] == "1":
            img.putpixel( (x, y), (000)) #black
 
img.save("./dimg/TransparentImage"+str(n)+".png""PNG")
 
 
p.interactive()
 
cs

 

그러면 이러한 qrcode 이미지를 만들어 낼 수 있다.

(제공되는 qrcode 크기가 제각각 이어서 배경 이미지의 크기에 여유를 주었다. 인식하는데에는 문제가 없었다.)

 

 

이제 이 qrcode를 decoding해서 보내주기만 하면 된다. 그러나 이 과정에서 삽질이 있었다.

 

이 qrcode이미지를 디코딩하는 방법에는 여러가지가 있다.

qrcode를 디코딩해주는 사이트에 리퀘스트 날려서 크롤링하는 방법. (이미지 보내고 크롤링 해야되는 무조건 버리고)

파이썬 모듈을 이용해서 디코딩 하는 방법.

 

qrcode를 디코딩할 수 있는 파이썬 모듈에는 여러가지가 있었다.

 

먼저 qrtools.

 

$sudo pip3 install qrtools

 

      qr = qrtools.QR()

AttributeError: module 'qrtools' has no attribute 'QR'

 

음? (오류 1스택)

파이썬 2로 다시시도..

 

 

$sudo pip install qrtools

 

import qrtools
ImportError: No module named qrtools

 

??????? (오류 2스택)

 

다음 시도한 것이 qrcode

 

 d = qrcode.Decoder()
AttributeError: module 'qrcode' has no attribute 'Decoder'

 

문서에서는 이렇게 쓰라고 나와있었는데 뭐지..(오류 3스택)

 

 

pyzbar를 사용해볼까

>>> decode(img)
[]

 

도대체 되는게 뭡니까(오류 4스택)

 

 

$ sudo pip3 install pyqrcode

$ sudo apt-get install python-qrtools

 

>>> import pyqrcode
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named pyqrcode
(오류 5스택)

 

>>> import qrtools

>>> qr = qrtools.QR()

>>> qr.decode("./TransparentImage.png")
False

(오류 6스택)

 

AttributeError: module 'pyqrcode' has no attribute 'Decoder'

(오류 7스택)

 

 

...

 

웹으로 해결할까 생각이 들어서 테스트때 디코딩에 성공했던 ZXng Decode Online에 들어가봤다.

 

https://zxing.org/w/decode.jspx

 

ZXing Decoder Online

 

zxing.org

하단 내용을 보면 오픈소스 프로젝트라고 써있다.

 

혹시 파이썬 모듈도 있나 들어가봤다.

 

pyzxing Python wrapper to ZXing library

 

있다.

 

바로 설치.

 

>>> from pyzxing import BarCodeReader

>>> reader = BarCodeReader()

>>> results = reader.decode( './TransparentImage.png')

>>> results
[{'filename': 'file:///home/mandu/Desktop/p/./TransparentImage.png', 'format': 'QR_CODE', 'type': 'TEXT', 'raw': '0pXenF4L00pza6n9XO45WjUvM4RvBUuoQICQAraBTh1rJIBeYUpxxJFNFsGOQ7DFNZ67QzuP0fNzl8of6j3wfObKWkRuUO1xrn2iMLQl7KCBJ6waeBboITBQRPDYtZUmQmHHa85ll4J', 'parsed': '0pXenF4L00pza6n9XO45WjUvM4RvBUuoQICQAraBTh1rJIBeYUpxxJFNFsGOQ7DFNZ67QzuP0fNzl8of6j3wfObKWkRuUO1xrn2iMLQl7KCBJ6waeBboITBQRPDYtZUmQmHHa85ll4J', 'points': [(3.5, 49.5), (3.5, 3.5), (49.5, 3.5), (46.5, 46.5)]}]
>>> results[0]['raw']
'0pXenF4L00pza6n9XO45WjUvM4RvBUuoQICQAraBTh1rJIBeYUpxxJFNFsGOQ7DFNZ67QzuP0fNzl8of6j3wfObKWkRuUO1xrn2iMLQl7KCBJ6waeBboITBQRPDYtZUmQmHHa85ll4J'

 

성공.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from pwn import *
from PIL import Image
from pyzxing import BarCodeReader
 
= remote("qr-generator.ctf.defenit.kr"9000)
p.recvuntil('name?')
p.sendline('M4ndU')
for n in range(100):
    img = Image.open('./200.png')
    img = img.convert("RGB")
    newData = []
 
    qrbin = [0* 200
    p.recvuntil('< QR >\n')
    for i in range(200):
        data = str(p.recvline())
        data = data.replace("b'""")
        data = data.replace("\\n'""")
        data = data.replace(" """)
        if data == "":
            print(p.recvline())
            break
        qrbin[i] = data
 
    for x in range(len(qrbin)):
        if qrbin[x] == 0:
            break
        for y in range(len(str(qrbin[x]))):
            if qrbin[x][y] == "1":
                img.putpixel( (x, y), (000))
 
    img.save("./dimg/TransparentImage"+str(n)+".png""PNG")
 
 
    reader = BarCodeReader()
    results = reader.decode('./dimg/TransparentImage'+str(n)+'.png')
    print(results[0]['raw'])
 
    p.sendline(results[0]['raw'])
 
p.interactive()
 
cs

 

 

 

 

 

 

 


Minesweeper

Can you solve the minesweeper in one minute?

 

 

1분안에 지뢰찾기를 성공하면 되는 문제.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
     a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   
   -----------------------------------------------------------------
 1 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 2 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 3 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 4 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 5 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 6 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 7 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 8 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 9 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
10 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
11 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
12 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
13 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
14 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
15 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
16 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 
Type the column followed by the row (eg. a5). To put or remove a flag, add 'f' to the cell (eg. a5f). Type 'help' to show this message again.
 
Enter the cell (40 mines left): 
 
cs

 

이런식으로 칸이 주어지고, a1을 입력하면 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
     a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   
   -----------------------------------------------------------------
 1 | 0 | 0 | 0 | 0 | 0 | 1 |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 2 | 0 | 0 | 0 | 0 | 0 | 1 |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 3 | 0 | 1 | 2 | 2 | 1 | 1 |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 4 | 0 | 1 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 5 | 0 | 1 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 6 | 1 | 1 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 7 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 8 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 9 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
10 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
11 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
12 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
13 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
14 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
15 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
16 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   -----------------------------------------------------------------
 
cs

주변 3*3범위에 폭탄의 개수를 알려준다.

 

지뢰의 위치에는 깃발을 꽂아야 한다. 저기서는 C4자리에 폭탄이 있으니 c4f를 입력해주어야 한다.

다음으로 지뢰가 없는 c5를 입력하여 나아가도록 한다.

 

이 과정을 자동화 하자.

 

 

http://www.hakank.org/numberjack/minesweeper.py

구글링 해서 찾아낸 지뢰찾기 솔버.

 

사용을 위해서 Numberjack 모듈을 설치해준다.

https://github.com/eomahony/Numberjack

 

eomahony/Numberjack

Python Combinatorial Optimisation Platform. Contribute to eomahony/Numberjack development by creating an account on GitHub.

github.com

X = -1

default_game = [
            [2,3,X,2,2,X,2,1],
            [X,X,4,X,X,4,X,2],
            [X,X,X,X,X,X,4,X],
            [X,5,X,6,X,X,X,2],
            [2,X,X,X,5,5,X,2],
            [1,3,4,X,X,X,4,X],
            [0,1,X,4,X,X,X,3],
            [0,1,2,X,2,3,X,2]
            ]

이렇게 지뢰찾기 배열을 넘겨주면

0 0 1 0 0 1 0 0 
1 1 0 0 1 0 1 0 
0 0 1 1 0 1 0 1 
1 0 1 0 1 1 0 0 
0 1 1 1 0 0 1 0 
0 0 0 0 1 1 0 1 
0 0 1 0 1 0 1 0 
0 0 0 1 0 0 1 0 
Nodes: 3  Time: 0.0

 

0: 지뢰없음 1: 지뢰있음 으로 결과를 출력해준다. 확실하지 않은 곳은 확률을 반환해준다. 이것을 개조했다.

 

문제에 아무 위치 한곳을 입력해주고 그 출력값을 위 코드로 분석하여 확실한 지뢰가 아닌 곳(0)과 지뢰인 곳(1)을 구해낼 수 있다. 지뢰인 곳에는 flag를 세우고 지뢰가 아닌 곳은 입력해서 주변 값들도 알아낸다.

 

이제 다시 맵의 결과값을 바탕으로 위 루틴을 전체를 구해낼 때까지 돌린다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/python
"""
This Numberjack model was created by
Hakan Kjellerstrand (hakank@bonetmail.com)
 
See also my Numberjack page http://www.hakank.org/numberjack/
"""
import sys
from Numberjack import *
 
from pwn import *
 
colNum = "abcdefghijklmnop"
 
= -1
alreadyInput = [[0 for ccccc in range(16)] for ddddd in range(16)]
row = [['0' for cola in range(16)] for rowa in range(16)]
gamerow = [[-1 for colas in range(16)] for rowas in range(16)]
 
= remote("minesweeper.ctf.defenit.kr"3333)
p.recvuntil(':')
p.sendline('h7'#중앙을 파면 한 번에 많은 위치를 분석할 수 있지 않을까
 
default_game = gamerow
default_r = 16
default_c = 16
 
#
# Solve the Minesweeper problem
#
def minesweeper(libs, game="", r="", c=""):
 
    # Set default problem
    if game == "":
        game = default_game
        r = default_r
        c = default_c
    else:
        print "rows:", r, " cols:", c
 
    #
    # Decision variables
    # Note: Matrix is defined with cols,rows,...
    #
    mines = Matrix(c,r,0,1)
 
    S = [-1,0,1]  # for the neighbors of this cell
 
    model = Model()
 
    for i in range(r):
        for j in range(c):
            if game[i][j] >= 0:
                model.add(mines[i,j] == 0)
                # this cell is the sum of all the surrounding cells
                model.add(
                    game[i][j] == Sum([mines[i+a,j+b]
                                       for a in S for b in S
                                       if i+a>=0 and
                                          j+b>=0 and
                                          i+a<r  and
                                          j+b<c
                                       ])
                    )
            if game[i][j] > X:
                # This cell cannot be a mine
                model.add(mines[i,j] == 0)
 
    # print model
 
 
    for library in libs:
        solver = model.load(library)
        # print solver
        print ''
        if solver.solve():
            solver.printStatistics()
            print_mines(mines, r, c)
            print 'Nodes:', solver.getNodes(), ' Time:', solver.getTime()
            #while library == 'Mistral' and solver.getNextSolution():
            #    print_mines(mines, r, c)
            #    print 'Nodes:', solver.getNodes(), ' Time:', solver.getTime()
 
        else:
            print "No solution"
            p.interactive()
        print ''
 
#
# Print the mines
#
def print_mines(mines, rows, cols):
    for i in range(rows):
        print i+1,
        for j in range(cols): #이부분을 수정했다. 불확실한 곳은 ?표시
            if len(str(mines[i,j])) > 4:
                print "?",
            else : #확실
                print str(mines[i,j]),
                if str(mines[i,j]) == '1'#지뢰는 플래그를 세우자
                    if alreadyInput[i][j] == 0#중복 입력 방지
                        print(colNum[j]+str(i+1)+"f"+'\n')
                        try:
                            p.send(colNum[j]+str(i+1)+"f"+'\n')
                            p.recvuntil("):")
                        except Exception as e:
                            p.interactive()
                elif str(mines[i,j]) == '0'#지뢰가 아니면 주변을 더 알아내자
                    if alreadyInput[i][j] == 0#중복 입력 방지
                        print(colNum[j]+str(i+1)+'\n')
                        try:
                            p.send(colNum[j]+str(i+1)+'\n')
                            p.recvuntil("):")
                        except Exception as e:
                            p.interactive()
        print ''
 
def print_game(game, rows, cols):
    for i in range(rows):
        print i+1,
        for j in range(cols):
            if game[i][j] == -1:
                print "?"#모르거나 지뢰인 곳은 ?표시
            else :
                print game[i][j],
        print ''
 
 
# file = "minesweeper1.txt"
 
for aa in range(6): #루틴을 몇번 돌릴 것인지. 끝까지 돌리는게 최고지만 정확성이 떨어져서 적당히 맞춰줘야 했다.
    row = [['0' for cola in range(16)] for rowa in range(16)]
    gamerow = [[-1 for colas in range(16)] for rowas in range(16)]
 
    p.recvline()
    p.recvline()
    p.recvline()
    p.recvline()
    p.recvline()
    for i in range(16):
        data = p.recvline()
        row[i] = str(data).split('|')
        p.recvline()
        for j in range(117):
            try:
                if row[i][j] == '   ':
                    gamerow[i][j-1= -1;
                elif row[i][j] == ' F ':
                    alreadyInput[i][j-1= -1 #중복입력을 방지하기 위함. 깃발을 세웠다는건 여기를 더 이상 이 위치를 입력할 필요가 없다는 것
                else :
                    gamerow[i][j-1= int(row[i][j].strip());
                    alreadyInput[i][j-1= 1 #중복입력ㅇ르 방지하기 위함. 이곳의 값이 있다는건 더 이상 이 위치를 입력할 필요가 없다는
            except Exception as e:
                p.interactive()
 
 
    default_game = gamerow
    print_game(default_game, 1616)
    # minesweeper(['NumberjackSolver', 'Mistral'])
    minesweeper(['Mistral'])
    # minesweeper(['SCIP'])
    print "================================================="
    p.sendline("h7")
 
p.interactive()
 
cs

 

 

근데 solver가 완벽하지는 않다. 완벽한 지뢰 위치를 찾아주지 못한다. 그래서 중간에 game over가 나기도 한다.

그래서 약 6번의 루틴을 시도하게 하고, 코드를 수십번 돌려서 운좋게 165행 코드가 실행이 되면 약 3칸정도가 남는다. 이건 눈으로 보고 풀어서 flag를 받을 수 있었다.

 

 

It took you 0 minutes and 17 seconds.

You Win!!!
Defenit{min35w33p3r_i5_ezpz}

 

 

 

 

반응형

'CTF Write Up' 카테고리의 다른 글

CCE2020 Quals Write-up  (0) 2020.09.26
FIESTA 2020 Write up  (2) 2020.09.07
angstrom CTF 2020 write up  (0) 2020.03.14
UTCTF 2020 Write up  (0) 2020.03.07
RiceTeaCatPanda CTF 2020 Write up  (0) 2020.01.22
반응형

Forensics

 

I AM STEGO!!

50

hxd로 열어서 끝부분에서 패스워드를 찾을 수 있다.

 

openstegoflag.txt 추출

 

 

 

Thinking

100

 

.zip으로 바꾸고 ppt> mediaFLAG.PNG가 존재한다.

 

 

You are in me

100

 

jpgfooter 시그니쳐ff d9를 찾으면 다음에 MZ 시그니쳐가 보인다.

카빙해서 IDA로 보면 xor 연산을 하는 것을 알 수 있다.

간단히 코드 짜서 xor 돌리면 플래그 나온다.

 

 

 

Header Trick

150

I think the header of this flag is wrong...

 

라고 한다. 압축파일 내용을 보면, 파일이 두 개가 존재하는데, flag.txt는 암호가 걸려있고, 다른 하나는 걸려있지 않다.

 

그렇다는 것은 실제로 패스워드는 걸려있지 않지만, flag.txt만 헤더 조작을 통해 암호화가 걸린 것 처럼 만든 것이다.

 

hxd를 통해 해더를 분석해보면 헤더가 다른 것이 보인다.

 

 

 

flag.txt만 00 09 08 08 00 이고 나머지는 00 00 00 08 00임을 알 수 있다.

 

09 08을 00 00로 덮어주고 열면 된다.

 

 

 

 

Something is inside me?!

200

 

IDA로 까서 strigs에서 보이는 문자열 ascii 85로 디코딩 해주면 된다.

https://cryptii.com/pipes/ascii85-encoding

 

힌트라고 한다면,, <- Guess what it is! There's 85 possibilitys. 여기서 85가 힌트일 듯 하다.

 

 

 

 

 

All your base are belong to newbie

350

 

png footer 시그니쳐 뒤에 elf 시그니쳐가 있다.

카빙후 실행하면 문제를 풀어야 한다. 문제 답은 IDA로 까보면 찾을 수 있다.

반응형
반응형

http://52.79.224.215

 

Multimedia Forensic

 

Welcome Forensic World

30

 

hxd로 열어보면 된다.

 

 

Where_is_flag

50

 

jpg시그니쳐 9바이트 채워주면 된다.

 

 

 

 

Dark web

100

hint : base

 

힌트가 base이다. base32나 base64라고 생각하고, 패딩 문자열 ==hxd를 통해 검색하면, 바로 찾을 수 있다.

 

JYYDAYSDKRDHWZCAOJVV65ZTMJPUSNK7MRAG4OLFOIYHKUZBEF6Q====

 

이를 base32로 디코딩하면 된다.

 

 

 

 

What is docx?

100

찾기로 flag 가 하나 나오는데 그건 fake이다.

 

.zip으로 바꾸면 암호걸린 flag.zip이 나오는데 key는 media폴더에서 찾을 수 있다.

 

 

 

Please open steganography

200

 

문제의 제목에서 open 을 통해 open stego를 써야된다는 것을 알 수 있다.

 

패스워드는 해당 png파일을 hxd로 열어서 마지막쯤에 있는 OPENLOCK 을 사용하면 된다.

 

추출하면 flag.txt가 추출된다.

반응형
반응형

http://52.79.224.215

 

 

Disk Forensic

Emergency!! Leak my source code..

100

access.log를 먼저 봤다. 모든 접근 기록이 담겨 있어서 모든 것을 조사해 볼 수는 없었다. 범위를 좁히기 위해서 다른 파일들을 살펴 보았다.

 

 

 

sad파일에서 수상한 pid를 찾을 수 있다.

 

               pid    ppid

www-data  5230  5244  0 10:11 ?        00:00:00 php -f /var/www/upload/ws1004/image/hack.php
www-data  5244   814  0 10:11 ?        00:00:00 sh -c php -f /var/www/upload/ws1004/image/hack.php

 

 

hack.php와 관련이 있음을 구할 수 있다. hack.php와 관련한 로그만 찾으면 되기 때문에 access.log에서 hack.php를 검색해서 나오는 모든 로그들을 모았다.

 

 

 

 

[25/Oct/2019:17:18:51 +0900] cHdk
[25/Oct/2019:17:26:23 +0900] bHMgLWFsICAvdmFyL3d3dy91cGxvYWQvd3MxMDA0L2ltYWdlLw%3D%3D
[25/Oct/2019:17:21:12 +0900] dGFyIC1jdmYgL3Zhci93d3cvdXBsb2FkL3dzMTAwNC9pbWFnZS8xMjU5MTIzNzQ5IC92YXIvd3d3Lw%3D%3D
[25/Oct/2019:17:26:40 +0900] cGhwIC1mIC92YXIvd3d3L3VwbG9hZC93czEwMDQvaW1hZ2UvaGFjay5waHA%3D

 

시각과 쿼리로 넘어가는 명령어만 기록해봤다.

 

 

base64로 인코딩 되었는데, 4번째 명령어는 아래와 같다.

php -f /var/www/upload/ws1004/image/hack.php

 

해당 명령어를 실행하는 쉘의 pid는 5230이다.

 

따라서 플래그는 N00bCTF{2019-10-25_17:26:40&5244} 가 된다.

반응형
반응형

헐... ? 누군가가 장난을 쳐두었어 ! 3가지를 찾아줘 ! 플래그 포맷

HCAMP{삭제 된 유저_메모프로그램에 저장된 숫자_부팅 시 조작 된 프로세스명}

 

[+] 삭제 된 유저는 로그에서 찾을 수 있습니다.

[+] 메모 프로그램은 sticky note입니다.

[+] 부팅 시 로드 되는 화면은 레지스트리에서 관리합니다.

 

 

 

TEAM : 속4Four

대회때 느린 다운로드 속도 + 제한된 데이터량 때문에 이미지파일을 못 받았다가

다음날 와이파이로 접속해서 다운받아 풀었다.

 

vmware로 열려다가 부팅이 안되길레 그냥 FTK Imager로 열어서 풀었다.

 

삭제 된 유저는 로그에서 찾을 수 있다. -> 이벤트 로그

유저 관련 이벤트 로그는 Security.evtx다. 해당 로그파일을 추출해서 이벤트 뷰어로 보면되는데, 삭제로그 이벤트 ID는 4726이다. id로 정렬하면 id가 4726인 로그를 하나 찾을 수 있다.

 

로그 내용에서 '계정 이름: Bn312'을 찾을 수 있다.

 

 

 

 

 

 

 

메모프로그램 (sticky note)에 저장된 숫자 -> sticky note 세이브 파일을 찾으면 된다.

세이브 파일 경로를 검색했을 때

 

C:\Users\계정명\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\localstate

로 찾을 수 있었는데, 해당 경로가 존재하지 않아서, 다른 경로를 찾아 보았다.

 

https://tirtir.tistory.com/entry/%EC%8A%A4%ED%8B%B0%ED%82%A4%EB%85%B8%ED%8A%B8-%EA%B5%AC%EB%B2%84%EC%A0%84-%ED%8C%8C%EC%9D%BC-%EC%9D%BD%EA%B8%B0snt

 

스티키노트 구버전 파일 읽기(.snt)

C:\Users\계정이름\AppData\Roaming\Microsoft\Sticky Notes 안에 위치한 이 파일만 백업한 후 윈도우 업그레이드를 시작했는데.. 새 버전의 윈도우10에서는 아무리 찾아도 넣어야 할 폴더가 보이지 않는다. 업무..

tirtir.tistory.com

 

위 블로그 글을 참고했다. 이미지 파일에서 snt파일을 추출해서 내 컴퓨터에 덮어쓴 후에, sticky note를 실행해주면

저장된 메모가 나온다. 여기서 '저장된 숫자' = 589319235를 구할 수 있다.

 

 

 

 

 

 

 

 

부팅 시 조작 된 프로세스명은 레지스트리에서 찾을 수 있다고 한다.

역시 검색을 해보았다.

 

 

https://ploiu.tistory.com/30

 

[윈도우] 윈도우 구동시 자동시작프로그램 로드순서

[윈도우] 윈도우 구동시 자동시작프로그램 로드순서 얼렁뚱땅 2006.12.01 09:31 윈도우를 구동할시에는 윈도우가 자동적으로 로드를 하여 구동을 시키는 프로그램들이 있는데, 이를 (자동)시작프로그램 이라고 합..

ploiu.tistory.com

여기에서 관련된 레지스트리를 찾았다.

 

SOFTWARE 레지스트리 파일을 추출해서 분석하면 되는데, 

SOFTWARE > Microsoft > Windows > Run 에 shell이라는 이름으로 h33cxkqi1531 라는 값이 들어있었다.

 

 

해서 flag는 HCAMP{Bn312_589319235_h33cxkqi1531}가 된다.

반응형
반응형

처음 포렌식과 미슥만 풀 생각으로 시작했다. 근데 대부분 문제가 예선 300점짜리가 나왔고... (솔버0 미슥 300 리벤지!)

점수판이 1000 1000 1000 0 0 0 0 0 0 0 ...이 되버리는 사태가..

거의 대회 마지막까지도 점수판이 1000 0 0 0 0 0 ... 이어서 막판에 힌트가 터져나왔는데, 웹과 포너블만 힌트가 나오고 내가 풀던 포렌식은 힌트가 3개뿐...(그 중 2개는 아는거) 그래서 각 문제에서 솔버가 나온 것이다.

 

 

이번 포렌식 문제의 경우, 포렌식 + 리버싱 + 크립토가 아닌가 싶다.

 

이미지파일 분석해서 바이러스를 찾고, 바이러스 분석해서 암호화된 파일 복호화하기.

이렇게 과정이 2가지인데, 힌트 1번과 2번은 과정1에 대한 것이었고, 힌트 3번은 과정2에 대한 것이었다.

 

과정1의 경우 작년 예선 포렌식100을 풀었었다면 쉽게 풀 수 있다.

 

 

 

 

문제 내용은 대강 이렇다.

스피어 피싱을 당해서 바이러스을 실행시켰고, 그로 인해 파일이 암호화되었다. 바이러스를 찾고 암호화된 파일을 복호화하자!

 

스피어 피싱은 이메일을 통해 이루어진다고 한다. 그래서 이메일 관련 해서 분석을 해보면 된다.

하지만 난 바닥부터 차근차근 해보았다. (사실 처음에 스피어피싱을 제대로 보지 않아서..)

 

 

 

 

일단 \Users\Doctuments에 있는 hwp문서들이 .apworegin 확장자명으로 암호화되어있는 것을 확인한다.

엑세스된 시각은 오전 4:43:04(UTC) = 오후 1:43:04(KST)이다.

 

 

그리고 바이러스 프로그램이 실행되었을테니 프리패치파일을 확인했다.

\Windows\Prefetch

 

폴더 채로 추출해서 내 로컬 프리패치 폴더와 바꿔치기 해서 분석툴로 분석했다.

 

 

비슷한 시간대를 위주로 살펴보면, photoshopsetup.exe이 바이러스파일임을 알 수 있다.

그러나 해당 프로그램의 경로가 나와있지 않는다. 그래서 NTFS log를 분석했다.

 

NTFS Log Tracker을 사용했다. 필요한 파일들의 위치는 아래 블로그를 참고하자.

https://infosecguide.tistory.com/110

 

 

 

파일명으로 검색을 했다.

파일명이 변경되고 실행되고 삭제됨을 알 수 있다. 삭제되었는데 휴지통에서도 찾을 수는 없었다.

파일명이 변경되기 이전을 살펴보았다.

 

 

 

크롬으로 다운로드 되었다.

그래서 크롬 방문기록과 다운로드 기록을 확인하였는데, 해당 파일은 찾을 수 없었다.

여기서 문제를 다시 읽고, 스피어 피싱 = 메일임을 확인했다. 방문기록에 eM Client가 있음을 확인했고, 작년 예선에서 풀어보았기 때문에 해당 프로그램이 이메일 프로그램임을 알고 있었다. 먼저 내 컴퓨터에 eM Client를 설치하고, Appdata\Loaming\ 에 있는 eM Client 파일을 통채로 복사해서 내 컴에 그대로 덮어주고 프로그램을 실행하면 메일 내용을 확인 할 수 있다.

 

 

메일 내용에서 pdf첨부파일을 구할 수 있고, 열어보면 다운로드 링크를 준다.

다운로드 링크를 통해 photoshopsetup.exe을 다운로드 받을 수 있다.

 

 

여기까지 바이러스를 찾는 과정.

다음은 암호화된 파일을 복호화해야한다. 제공된 힌트 3번째 = "파일은 AES로 암호화되었다."

 

 

플래그 형식이 바이러스명_바이러스가 다운로드 된 시각_바이러스를 보낸사람의 이메일 아이디

뭐 이런거면 풀었는데.. 너무 쉽나?

반응형
반응형

Moving but not moved

75

[문제 설명] 움직이지 않는 오브젝트는?
[출제자] 정준영(Joon)

 

 

Hxd로 보면 맨 마지막 부분이 PNG의 푸터 시그니쳐다. 헤더 시그니쳐를 찾아서 추출해내면 flag가 나온다.

 

 

 

Archives

100

[문제 설명] 귀여운 아오바가 숨긴 비장의 플래그는 무엇일까?
[출제자] 정준영(Joon)

 

 

pptx파일 하나가 주어진다. 확장자명을 zip으로 바꿔서 ppt > media > image5.png을 열어보면 플래그가 나온다.

 

 

Inside the beat

100

[문제 설명] 비트를 타자
[출제자] 정준영(Joon)

 

 

osz파일이 주어진다. 근데 HxD로 열어보면 파일시그니쳐가 PK, 즉 ZIP파일과 구조가 같음을 알 수 있다.

그래서 zip으로 파일명을 바꿔주고 열어보면 된다.

 

 

그러면 mp3파일을 하나 찾을 수 있고, HxD로 열면 최하단에서 플래그를 찾을 수 있다. 근데 끊어져 있다.

 

그래서 해당 파일 헥스 처음부분을 확인하니 전체부분을 확인할 수 있었다.

 

 

 

Not compressed

100

[문제 설명] 어떻게 압축되었을까?
[출제자] 정준영(Joon)

 

 

 

Hxd로 보면 시그니쳐는 PK로 압축 파일인데 그 다음부분부터는 모두 PNG 부분같다.

 

그래서 헤더를 PNG헤더로 바꿔주었더니 flag을 얻을 수 있었다.

 

 

 

너의 비밀번호는

100

[문제 설명] 최고급 사전을 눈이 아닌 다른것으로 읽어보자.
[출제자] 정준영(Joon)

 

 

사전공격으로 패스워드를 찾아내면 된다.

 

 

 

Note graph

150

[문제 설명] 우리는 음표와 비슷한걸 읽어봐야합니다.
[출제자] 정준영(Joon)

 

 

sonic visualiser을 이용해서 Pane> add spectrugram

플래그!

 

 

 

CAN_YOU_FIND?

250

[문제 설명] 날 찾아줘
[출제자] 황수민

 

 

HxD로 열고 찾기 기능으로 A0V3R을 검색하니 플래그를 찾을 수 있었다.

 

 

 

Extend

300

[문제 설명] 뛰는놈위에 나는놈 있다.
[출제자] 정준영(Joon)

 

 

사진 열어보면 머리카락이라고 한다. 머리카락 = 높이

bmp구조를 봐서 높이 부분의 값을 조금씩 높이다 보면, 플래그가 보이기 시작한다.

 

 

 

카토의 눈은 정말 최고입니다

300

[문제 설명] 마음에 눈으로 보십시오.
[출제자] 황수민(Xixon)

 

 

mp3파일이 하나 주어진다. hxd로 열어서 플래그 찾으니 나온다. 왜????

 

 

 

LAST_SAEKANO

300

[문제 설명] kato_eyes_revenge
[출제자] 황수민

 

mp3파일인데 파일 썸네일을 보면 검을 글자같은게 보인다.

HXD로 열어서 jpg파일 추출해내면 플래그를 확인할 수 있다.

jpg 푸더 시그니쳐는 FF D9이다.

 

 

 

미술품 구매계획

400

[문제 설명] 고가의 미술품을 미리볼 수 있는 프리뷰이다. 한번 둘러보자.
[출제자] 정준영(Joon)

 

 

ppt파일이 주어지는데, 일단 zip으로 바꿔준다.

ppt\media\에 이미지 9개가 있다. 모두 openstego를 써준다.

 

image5.png에서 flag.png가 추출된다. 그런데 flag.png에 이미지가 표시되지 않는다.

hxd로 열어보면 시그니쳐가 png가 아닌 jpg로 되어있는 것을 확인할 수 있다.

시그니쳐를 png로 바꿔주고 다시 열어주면 플래그가 나온다.

Matryoshka Doll

500

[문제 설명] 옛날옛적에 러시아에 살던 어떤 사람이 마트료시카 인형에 중요한 깃발을 숨겨놓았다고 한다. 찾아보자.
[출제자] 정준영(Joon)

 

 

푸터부분을 보면 APNG assembler을 사용한 것을 알 수 있다.

그래서 APNG disassembler을 검색하니까 나오길레 설치해서 해봤다. 2개의 이미지가 나오게 되는데...

 

openstego를 사용하면 docx파일이 하나씩 나온다. (openstego 오랜만에 써본다.)

 

 

flags.docx에서 flag의 절반을 얻을 수 있다.

 

그리고 다시 zip으로 바꿔서 word\fonts.xml을 hxd로 열면 나머지 플래그가 있다.

 

 

정말 많을걸 해야하는 문제...

반응형
반응형

Welcome_Forensics

50

 

이미지 우클릭하고 새 탭에서 보기를 하면 플래그를 확인할 수 있다.

 

 

 

Question?

100

 

압축을 풀면 나오는 파일 이름이 Do_you_know_HxD 이다.

HxD로 깠는데, 앞 뒤에 플래그가 없었다.

그래서 다른 삽질을 하려다가 Hack을 검색해보니 플래그가 숨어있었다.

 

flag : HackCTF{P1e45e_find_m3}

 

 

 

So easy?

100

 

문제파일 이미지를 보면, 러시아 전통 인형이다. 파일안에 파일이 숨어있다는 뜻.

일단 hxd로 까봤는데 뒤에 플래그가 있어서 당황스러웠으나... 가짜 플래그다.

so easy? 그건 fake야.

 

PK가 있으므로 zip파일이 있음을 알 수 있다. 직접 추출하기 귀찮아서 foremost 이용해서 추출했다.

zip파일 하나 안에 txt파일이 하나 있고, 거기에 플래그가 있다.

FLAG : HackCTF{M4try0shka_do11}

 

 

 

Secret Document

150

 

와 기밀문서!

플래그 파일은 암호가 걸려있다.

 

힌트파일을 보자.

hint1 : Brute-Force NOOOOOOOOOOOO!

hint2 : Do you think the password exists?

 

암호화는 fake라는 소리다. 실제로 암호는 안걸려있는데 걸려있는 것처럼 위장한 것이다. hxd를 이용해 해당 헤더를 조작해주면 된다.

 

다른 파일의 flag bit가 00 08 인데 flag.txt의 flag bit는 09 08이다. 09 08을 00 08로 바꿔주면 flag.txt가 열린다.

 

 

 

세상에서 잊혀진 날 찾아줘!

150

 

flag == Ctrl+a & Ctrl+c & Ctrl+v

pdf열고 위 동작을 해보면 이미지 위에 안보이는 텍스트들이 있음을 알 수 있다.

 

 

 

나는 해귀다

150

 

이미지 보면 hex값을 뒤집어 놓았다고 했다.

정말이다.

다시 뒤집자.

 

< waytogo.png xxd -p -c1 | tac | xxd -p -r > file.png

 

이미지에 나와있는 플래그도 뒤집혀 있다.

 

 

Magic PNG

150

 

일단 png 파일임을 인식을 못한다. 왜 그런가 알기위해 hxd로 까보았다.

 

파일 시그니처가 맞지 않다.

PNG 시그니처는  89 50 4E 47 0D 0A 1A 0A 이다. 맞게 수정해주자.

 

수정하고 나면, 이미지가 위에서 나오다가 잘려버린다.

 

원인은 TweakPNG에서 찾을 수 있었다.

청크 중간에 IDAT이 아닌 idat이 있다.

HxD를 이용해서 idat부분을 IDAT으로 수정해주면 완벽한 이미지와 함께 플래그가 나오게 된다.

 

 

Terrorist

200

당신은 현장을 수사하여 범행과 관련된 단서를 찾았다!
단서를 분석하여 다음 범행장소를 알아내야한다.
플래그 포맷은 HackCTF{범행장소}로 적어야 한다.

 

파일이 하나 주어지는데 mp4 파일이다.

재생시켜보면 역재생된 말소리가 들린다.

동영상편집프로그램 같은거 사용해서 다시 역재생하면 된다.

 

잔상

250

 

용량이 같은 파일 2개가 주어진다.

 

oct to ascii

 

 

Let'S get it ! Boo*4

350

 

0xCDA90xBD840xD7880d.8AC000H.8CE580xC7880xB2940xC8740xC7AC0v.8C57C

아 앞에 B10C 빼먹었넹

 

끝.

반응형

'WAR GAME > HackCTF' 카테고리의 다른 글

HackCTF Reversing 카테고리 풀이  (0) 2019.08.29
HackCTF Pwnable [Basic_BOF #1] 풀이  (0) 2019.07.24
HackCTF Cryptography 카테고리 풀이  (2) 2019.07.18
HackCTF MISC 카테고리 풀이  (0) 2019.07.18
HackCTF Web 카테고리 풀이  (0) 2019.07.18
반응형

스테그



이미지 파일이 주어지는데, 플래그가 이미지 안에 있을 것처럼 생겼다.


그래서 stegsolve 를 돌려보았다.




역시나


FLAG IS {H1H1_H4H4_H0H0}

반응형

+ Recent posts