728x90
반응형
728x90
반응형
728x90
반응형

ctfd같은걸 사용하지 않고 디스코드와 디스코드 봇을 사용하여 운영된 신기한 대회였다.

open pcap file with wireshark

search filter "http"

run script

 


주어진 바이너리에서 jpg 이미지들을 뽑아내면 된다

시그니쳐 ffd8로 검색하면 3개가 나오는데, ffd8기준으로 jpg 파일 3개 뽑아내주면 된다.

플래그 일부가 그려진 이미지들을 얻을 수 있으며

플래그들을 합쳐주면 된다.

 

반응형

elf core 파일과 플래그가 암호화된 enc 파일이 주어진다.

core파일을 ida에 올려보면

flag.txt가 압축된 bz2 파일을 password.txt를 패스워드로 사용해서 암호화한것을 유추할 수 있다.

 

그리고 strings에서 password로 보이는 문자열을 찾을 수 있다.

 

이 문제의 카테고리가 포렌식인데, 리버싱에 진심으로 문제를 제작하지 않았을 거 같아서

이런 리버싱처럼 보이는 포렌식 문제에는 xor이 많이 사용된다는 경험을 이용해서

xor을 때려봤다.

bz2의 헤더 시그니쳐와 enc 파일을 xor해봤다.

맞는거 같다.

https://cryptii.com/
https://gchq.github.io/CyberChef/

bz2 압출풀면 flag가 있다.

728x90
반응형

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

San Diego CTF 2022 Forensics write up  (0) 2022.05.09
RITSEC CTF 2022 Write up  (0) 2022.04.02
LINE CTF 2022 write up  (0) 2022.03.27
UTCTF 2022 Write up  (0) 2022.03.13
Codegate 2021 Quals Write Up  (0) 2022.02.28
ASCTF 2021 문제 풀이 및 출제 후기 - Forensic(5), Misc(1)  (0) 2021.11.24

728x90
반응형

Forensics

 

Bad C2

c2서버랑 통신하는 패킷 주어지는데, /get/secret에 post로 json 보내는 거 있음 간단한 조건 맞춰서 서버에 보내면 플래그 줌


oreo

./Default/Cookies

open with DB browser

base64 decode

 


cyber survey

tcp 패킷들 있는데, 포트스캐닝 마냥 여러 포트들 찌르는데, 열린포트에 6761.. 데이터를 push함. push한 포트 번호 끝 3자리 순서대로 가져오면 됨 (패킷 길이 73만 보면 됨)

length of packet == 73, get port number (last 3 digits)

dec to ascii


Death, Taxes, TCP

tcp패킷들만 있는데, 패킷길이 87짜리들이 데이터 1바이트씩 보냄. 순서대로 가져오면 됨.

 

length of packet == 87, get 1byte data

hex to ascii

728x90
반응형

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

San Diego CTF 2022 Forensics write up  (0) 2022.05.09
RITSEC CTF 2022 Write up  (0) 2022.04.02
LINE CTF 2022 write up  (0) 2022.03.27
UTCTF 2022 Write up  (0) 2022.03.13
Codegate 2021 Quals Write Up  (0) 2022.02.28
ASCTF 2021 문제 풀이 및 출제 후기 - Forensic(5), Misc(1)  (0) 2021.11.24
728x90
반응형

Whois_Ajou 팀으로 참여했다.

Crypto

ss-puzzle

단순 xor 역연산이다. 알고 있는 값들을 토대로 하나씩 xor 역연산 해가면서 찾아나아가면 된다.
참고로 S[0] = "LINECTF{" 임을 알고 있으면 된다.

X Factor


rsa blind signature attack 같은 느낌인데 sign을 해주는 기능을 제공해주지는 않는다.
대신 plain -> signature pair들을 제공해주기 때문에 이 값들을 sign함수 대신 사용하는 느낌으로 가야된다.
0x686178656c696f6e 값의 signature를 구하는 문제이다.

문제 제목이 힌트라고 볼 수 있는데, 각 plain 값들을 소인수분해한다. 이는 factordb 사이트를 이용하면 된다.
a ~ g의 값들을 사용하여 Z를 만들어내려면 ( f * b * g * d * g * d ) / ( c * e * a ) 가 된다.

http://the2702.com/2015/09/07/RSA-Blinding-Attack.html

The 2702 - Computer Security and CTF Writeups

We are given two ports on a server, Sign and Verify. Sign will sign an integer using the RSA signature scheme and Verify asks us to sign an integer providing the the public modulus and exponent. Sign it correctly and the server will give us the flag. The t

the2702.com

http://the2702.com/2015/09/07/RSA-Blinding-Attack.html


plain a ~ g, Z의 signature 값을 Sa ~ Sg, SZ 라고 하면,
위 사진의 식에서
M=Z = ( f * b * g * d * g * d ) / ( c * e * a ) ,
r= Sc * Se * Sa
r^e mod N = c * e * a
이므로 M' = ( f * b * g * d * g * d ) / ( c * e * a ) * (c * e * a) mod N = ( f * b * g * d * g * d )

S' = M'^d mod N = ( f * b * g * d * g * d )^d mod N = ( Sf * Sb * Sg * Sd * Sg * Sd ) mod N

우리가 원하는 S = S'/r mod N = ( ( Sf * Sb * Sg * Sd * Sg * Sd ) / ( Sc * Se * Sa ) ) mod N 이다.

https://ohgym.tistory.com/13, 모듈로 나눗셈 성질

( Sc * Se * Sa ) 의 역원을 구해야 한다.

https://ohgym.tistory.com/13

( Sc * Se * Sa ) 와 N 은 서로소이므로 확장된 유클리드 호제법을 사용하여 역원 x를 구한다.

역원을 얻었다.

S를 연산하고, 검증했다.
클리어.

728x90
반응형

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

San Diego CTF 2022 Forensics write up  (0) 2022.05.09
RITSEC CTF 2022 Write up  (0) 2022.04.02
LINE CTF 2022 write up  (0) 2022.03.27
UTCTF 2022 Write up  (0) 2022.03.13
Codegate 2021 Quals Write Up  (0) 2022.02.28
ASCTF 2021 문제 풀이 및 출제 후기 - Forensic(5), Misc(1)  (0) 2021.11.24
728x90
반응형

 

Forensics

Sounds Familiar

 

dtmf

이건 너무 부정확해서 다른 도구를 사용했다.

 

http://www.polar-electric.com/DTMF/Index.html

 

DTMF Decoder / Encoder

DTMF Decoder is a very easy to use program to decode DTMF dial tones found on telephone lines with touch tone phones. DTMF Decoder is also used for receiving data transmissions over the air in amateur radio frequency bands.   The following are the frequen

www.polar-electric.com

result

0과 1이 많아서 키패드 알파벳 변환은 아니다.

띄어서 입력되는 부분을 고려하면

100 88 82 106 100 71 90 55 78 87 86 106 99 109 86 48 88 50 89 120 81 68 108 102 90 71 57 102 98 109 57 48 88 122 86 111 81 72 74 108 102 81 61 61

이 되고, 이를 ascii로 변환한 뒤에 base64로 디코딩해주면 플래그가 나온다.

 

dtmf decode -> ascii -> base 64

 

 


Forensics

IRC

 

memdump.lime.z 파일이 주어진다.

zlib compreesed data이므로 압축을 풀어주자.

 

 

압축을 풀고 strings와 grep을 사용해서 프로필 정보를 알아냈다.

debian 10.2.1-6 에 linux version 5.10.0-11-amd64이다.

 

volatility2 사용을 위한 profile을 create해야한다. 

환경 구성의 편의를 위해서 커널버전 5.10.0-11에 가장 근접하는 데비안 버전을 사용했다.

 

debian 11.0.0 amd64 iso 파일을 다운받아서 가상환경을 구축해준다.

https://ftp.cae.tntech.edu/debian-cd/dvd/

 

Index of /debian-cd/dvd/

 

ftp.cae.tntech.edu

 

apt install linux-headers-5.10.0-11-amd64

apt install linux-headers-5.10.0-11-common

apt install linux-image-5.10.0-11-amd64

apt install linux-image-5.10.0-11-amd64-dbg

디스크 용량은 15GB 이상 확보하자.

 

기존에 설치되어 있는 커널 버전은 remove 해준다.

 

 

 

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

 

/boot/System.map-<uname -r> 파일을 보면 

The real System.map is in the linux-image-<version>-dbg package

이렇게 되어 있다. apt install linux-image-5.10.0-11-amd64-dbg 를 한 이유가 real System.map 파일을 얻기 위해서다.

real System.map 파일은 usr/lib/debug/boot/ 경로에 있다.

 

생성된 프로필 zip 파일을 볼라티리티 overlays linux 폴더에 옮겨 넣는다.

hexchat이라는 irc 프로그램을 설치한 기록을 확인할 수 있다.

 

 

pslist에서 hexchat이 확인된다.

 

이제 irc password를 찾기 위해서 log 파일을 확인하면 password를 찾을 수 있을 것이라고 생각했다.

그런데 log파일들이 있는 경로는 알지만 정확한 로그 파일을 봐야하고 그 파일의 이름이 뭔지를 알 수 없었으므로

(linux는 filescan이 안된다. 정확한 파일의 절대 경로를 알고 있어야 한다.)

여기서부터는 게싱을 했다.

 

 

HxD로 메모리 덤프 파일을 열어서 hexchat과 utctf를 검색했고, P=blabla 문자열을 확인할 수 있었다.

utctf.live는 irc 주소, P 값은 irc password로 추측되었다.

 

해당 P값을 flag로 제출했다.

 


WEB

Websockets

어드민 로그인 페이지가 있는데 username은 admin이고 pw는 숫자 3자리라고 한다.

웹소켓으로 id와 pw를 전달한다.

 

파이썬으로 쓰윽


 

WEB

pdf로 변환을 해준다.

 

<h1 id='test2'>a</h1><script>x = new XMLHttpRequest();
x.open('GET','file:///etc/passwd',false);
x.send();
document.getElementById('test2').innerHTML= x.responseText+location.href;
</script>

 

이렇게 파일을 읽어올 수 있고

+location.href로 현재 경로를 알아냈다.

 

<h1 id='test2'>a</h1><script>x = new XMLHttpRequest();
x.open('GET','file:///usr/src/app/app.py',false);
x.send();
document.getElementById('test2').innerHTML= x.responseText;
</script>

 

약간의 게싱으로 app.py의 소스를 가져온다.

 

flag가 환경변수에 있는데, /proc/environ을 못읽도록 하고 있다. 그런데 필터링 우회해서 해당 파일에 접근해도 결과가 안나왔다. (언인텐이라서 이쪽으로는 못풀게 아에 막은 듯 싶다.)

 

/admin 페이지 로그인으로 플래그를 얻어야 하는데 unix계정 로그인을 하면 된다.

 

아까 passwd파일을 확인했을 때 WeakPasswordAdmin 이라는 계정이 있었다. 해당 계정의 패스워드를 구해서 로그인하면 될 것으로 보인다.

 

/etc/shadow 파일도 가져온다.

 

클리어.


Misc

https://ropsten.etherscan.io/tx/0xca78d2d51101fda93f3f8c62f4349dd23a7e5692cef667ab834c3611601f068f

 

Ropsten Transaction Hash (Txhash) Details | Etherscan

Ropsten (ETH) detailed transaction info for txhash 0xca78d2d51101fda93f3f8c62f4349dd23a7e5692cef667ab834c3611601f068f. The transaction status, block confirmation, gas fee, Ether (ETH), and token transfer are shown.

ropsten.etherscan.io

 

그냥 이더스캔으로 컨트랙트 생성 트랜젝션의 인풋값 보면 된다.

728x90
반응형

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

RITSEC CTF 2022 Write up  (0) 2022.04.02
LINE CTF 2022 write up  (0) 2022.03.27
UTCTF 2022 Write up  (0) 2022.03.13
Codegate 2021 Quals Write Up  (0) 2022.02.28
ASCTF 2021 문제 풀이 및 출제 후기 - Forensic(5), Misc(1)  (0) 2021.11.24
Killer Queen CTF 2021 write up  (0) 2021.10.31
728x90
반응형

올해에는 대학부로 참여했다. 분야별 난이도 차이가 좀 큰 편이었다.

처음에 크립토 잡고 풀다가 하루 다 보내버리고 뒤늦게 웹에 합류하여 문제를 풀었다. 좀 더 빨리 웹을 잡고 풀었으면 좀 더 점수를 낼 수 있었을 텐데 아쉬웠다. 그리고 예선전은 인원 제한이 없는걸 몰랐어서 처음엔 4명 모아서 할려고 했다가 대회 시작 직전에 뒤늦게 사람 2명밖에 못 데려온 것도 좀 아쉬었다. 내년에는 소학회원들 많이 데리고 하면 좋을 거 같다.

 

코게에도 포렌식이나 네트워크 문제 나왔으면 좋겠다. 예전엔 그래도 한 두개씩 나왔던거 같은데..

 

WEB - superbee

golang으로 작성되어 있고

 

beego 라는 프레임워크를 사용하고 있다.

 

 

플래그는 app.conf에 정의되어 있고 (물론 주어진 파일에서는 REDEACTED)

 

main.go

http://[IP]/main/index 경로로 접속하면 flag를 확인할 수 있도록 되어 있지만

 

main.go

쿠키값을 비교하여 admin이 아니면 플래그를 확인할 수 없고, login 페이지로 redirect된다.

 

 

먼저 어드민 패스워드를 획득하여 어드민계정으로 로그인 하는 방법은

패스워드를 알아낼 방법이 없으므로 불가능하고

 

SSTI일까 생각해봤지만,

main.go

사용자가 입력한 값으로 render하는 곳이 없고, 애초에 beego에서는 값을 직접 때려주기 때문에 불가능하다.

 

어떻게 풀어야 될까 생각을 해보다가

main.go

/admin/authkey 페이지로 접근해서 encrypted_auth_key를 얻고

aes 복호화를 해서 평문 auth_key를 얻어서 sess 쿠키 값을 설정해서 main/index로 접근하여 flag를 얻는 루트같았다.

 

main.go

그러지 않고서야 aesencrypt함수를 넣어두고 admin페이지를 만들어둘 이유가 없다고 생각했다.

 

main.go

그런데 admin/authkey에 접근할려면 domain이 localhost가 되어야 한다.

아니 ssrf때릴 곳도 없는거 같은데 어떻게 domain명을 localhost로 만들지 고민을 하다가

Ctx.Input.Domain()이 사실 처음 보는 함수였기 때문에 정확히 어떻게 동작하는 지 알 필요가 있었다.

 

 

https://github.com/beego/beego/blob/develop/server/web/context/input.go

코드를 살펴보니 request의 host가 공백이면 localhost를 return해주고 있었다. (.....이게 맞나?)

 

 

그래서 burp suite로 리퀘 잡아서 Host 부분을 공백으로 바꿔주었더니

 

00fb3dcf5ecaad607aeb0c91e9b194d9f9f9e263cebd55cdf1ec2a327d033be657c2582de2ef1ba6d77fd22784011607

encrypted_auth_key값을 얻을 수 있었다.

 

해당 값을 복호화하기 위해서는 key값에 사용되는 auth_crypt_key값을 알아야하는데

 

main.go

키값이 공백일 수는 없는데.. 라고 생각을 하다가 

 

Padding 함수를 보면

main.go

Padding(key, 16)ciphertext가 [] 이더라도

16 - 0 % 16 = 16

16을 16번 반복 => [16] * 16 이 된다

즉 auth_crypt_key값이 공백이어도 된다.

 

main.go

aes cbc이고, iv와 key값이 동일하다

 

​복호화하여 auth_key를 구할 수 있다.

 

Md5("sess") = f5b338d6bca36d47ee04d93d08c57861

Md5(admin_id + auth_key) = Md5("admin" + "Th15_sup3r_s3cr3t_K3y_N3v3r_B3_L34k3d") = e52f118374179d24fa20ebcceb95c2af

 

 

Cookie: f5b338d6bca36d47ee04d93d08c57861=e52f118374179d24fa20ebcceb95c2af

이렇게 쿠키를 설정해주고, /main/index로 접근하면 flag를 확인할 수 있다.


WEB - babyfirst

로그인하고, 메모 작성하고, 메모를 읽는 간단한 서비스이다.

 

flag는 /flag에 있다.

 

memoServiet.class를 디컴파일해서 살펴봐야한다.

메모를 읽어오는 getMemo 함수를 보면 db에서 가져온 memo데이터를 가지고 lookupImg 함수를 돌리는데

 

lookupImg함수는 memo 내용에서 [URL] 패턴을 찾아서 해당 url 데이터가져와서 base64로 인코딩해서 <img>에 담아준다.

[file:///flag]가 되면 좋겠지만 file로 시작하는 건 필터링해버린다.


종료 30분 남은 시점에셔 여기서 막혀서 못 풀었다.

[url:file:///flag] 로 하면 된다.

https://github.com/openjdk/jdk11/blob/master/src/java.base/share/classes/java/net/URL.java#L575

 

GitHub - openjdk/jdk11: Read-only mirror of https://hg.openjdk.java.net/jdk/jdk11/

Read-only mirror of https://hg.openjdk.java.net/jdk/jdk11/ - GitHub - openjdk/jdk11: Read-only mirror of https://hg.openjdk.java.net/jdk/jdk11/

github.com

ㅠㅠ 아쉽


CRYPTO - dark-arts

 

챌린지 1,2,3,4를 모두 통과해야 플래그를 얻을 수 있다.

 

 

CHAL1은 GUESS_MODE()를 64번 통과해야 한다.

 

 

GENERATOR1에서 랜덤으로 func_gen 과 func_random 둘 중 하나로 고정되서 리턴한다.

gess_mode에서 x에 값을 직접 넣어서 그 결과를 알 수 있고, 그 값들을 가지고  mode가 0일지 1일지 (func_gen을 통과한 결과인지 func_random을 통괗나 결과인지)를 맞춰야 한다.

func_gen과 func_random 둘다 결과는 무조건 0 또는 1이 나온다.

 

func_gen은 랜덤 seed와 x의 각 bit를 내적한 값으로 66행의 식을 계산한 값이 결과가 된다.

x가 0 [0]이라면 prod가 0이 되고 66행의 계산 결과는 0이 된다.

x가 1 [1]이라면 prod는 1 또는 0이 되고, 1이라면 66행의 결과는 (1 % 2 + 1 % 3 ) %2 = 0

x가 2 [0,1]이라면 prod는 1 또는 0이 되고, 결과는 0

x가 3 [1,1]이라면 prod는 2 또는 1 또는 0이 되고 2라면 (2 % 2 + 2 % 3 ) % 2 = 0

x가 4, 5, 6, 8, 9, 10, 11 일 때에도 (bit 중 1인 bit의 개수가 3개 미만인 수들) 모두 결과는 0이 된다.

x가 7 [1,1,1] 이라면 prod가 3이 될 수도 있는데 (3 % 2 + 3 % 3) % 2 = 1이다.

따라서 x에  0,1,2,3,4,5,6,8,9,10,11 넣어서 결과가 1 나오면 무조건 mode=1

모두 0이 나오면 mode = 0 으로 판단하도록 코드를 작성하여 돌렸다.

 

 

 

 

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
from pwn import *
context.log_level = 'debug'
 
 
= remote("13.209.188.120"9003)
p.recvuntil("Challenge 1\n")
= 0
for _ in range(64):
    print(_)
    for i in range(13):
        if(i==7 or i==11):
            continue
        p.sendline("0")
        p.sendline(str(i))
        if(1 == int(p.recv())):
            p.sendline("1")
            p.sendline("1")
            f = 1
            break
    if(f):
        f = 0
        continue
    p.sendline("1")
    p.sendline("0")
p.interactive()
 
cs

 

 

chal2도 guess_mode()를 64회 통과해야하는데

 

이제는 리턴 값이 0,1,2,3,4 총 5개 이며

func_gen에서 x를 sha256을 돌려서 사용한다.

일단 x에는 int만 들어가고 x를 0부터 1씩 증가시켜 넣어서 결과를 확인했을 때 규칙을 찾을 수 없었고

sha256(x) 의 결과들 중에서 bit중 1의 개수가 작아봐야 80-90개 사이였기 때문에

chal1처럼 풀 수 없었다.

 

다르게 풀어야 되는 거 같은데..

728x90
반응형

728x90
반응형

https://dfir.pubpub.org/pub/h78di10n/release/2

 

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

저자: Alexandros Vasilaras 1 , Evangelos Dragonas 2 , Dimitrios Katsoulis 3

vasilaras@digitalforensics.gr , dragonas@digitalforensics.gr , katsulis@digitalforensics.gr

라이선스:  Creative Commons Attribution 4.0 국제 라이선스(CC-BY 4.0)

 

 

- 개요

질문 : Windows 이벤트 로그에서 이전에 연결된 장치의 VSN을 몇 개나 복구할 수 있는가

OS 버전 : Windows 10 Pro 2004 build 19041

도구 : JLECmd 1.4.0.0, LECmd 1.4.0.0, AXIOM 4.7, Partition-4DiagnosticParser

 

 

- 배경

윈도우 10에 파티션/진단 이벤트 로그가 처음 도입됨.

C:\Windows\System32\winevt\Logs\ Microsoft-Windows-Partition%4Diagnostic.evtx

이 로그에서 여러 볼륨이 있는 장치의 최대 3개의 VSN을 찾을 수 있음.

해당 로그를 분석해서 VSN을 추출하는 도구를 개발함.

 

해당 이벤트 로그에는 이동식 디스크 (USB 스틱, SD카드, 외장 하드 등)과 컴퓨터 내부 디스크에 대한 정보가 저장됨.

 

- 이벤트 로그 필드 일부 설명

[시스템 섹션]

  • EventID: 항상 1006
  • TimeCreated [SystemTime]: 타임스탬프
  • EventRecordId: 로그 파일 내의 각 기록에 할당된 고유 번호
  • Computer: 컴퓨터 이름
  • Security [UserID]: 유저의 SID값. 항상 S-1-5-18임 (User SYSTEM).

 

[이벤트 데이터 섹션]

  • DiskNumber: In our analysis, we found this number varying in a range between 0-3, with 0 being assigned to the disk running the operating system (OS).
  • IsSystemCritical: This value is usually false, apart from when DiskNumber was 0.
  • BytesPerSector: Bytes per sector (usually 512-defined by the manufacturer) of the device.
  • Capacity: The total capacity of the device (in bytes).
  • Manufacter: The manufacturer of the device. Not always accurate.
  • Model: Model of the device. Not always accurate.
  • SerialNumber: Serial number of the device.
  • ParentId: Information about the device, including Vendor ID, Product ID, Serial Number (potential correlation with registry files).
  • PartitionStyle: The partition scheme of the device. MBR is 0. GPT (GUID Partition Table) is 1.
  • PartitionCount: Number of partitions of the device. Not to be trusted.
  • Mbr: Raw dump of the first 512 bytes of the Master Boot Record of the device. Contains device’s Disk Signature and Master Partition Table.
  • Vbr0: Raw dump of the Volume Boot Record of the device’s 1st partition. Contains the VSN of this partition.
  • Vbr1: Raw dump of the Volume Boot Record of the device’s 2nd partition. Contains the VSN of this partition.
  • Vbr2: Raw dump of the Volume Boot Record of the device’s 3rd partition. Contains the VSN of this partition.
  • Vbr3: In our analysis, we found that this field is not populated with the raw dump of the Volume Boot Record of the device’s 4th partition. If someone wants to determine the existence of a 4th partition, he should examine the Master Partition Table.

 

위에서 볼 수 있듯 한 장치의 두 번째 및 세 번째 파티션의 VSN도 저장한다. 사용자가 자신의 장치를 포맷하더라도(할당된 VSN 손실) 이벤트 로그에서 이전 VSN을 검색할 수 있다.

 

- 조건 및 한계점

이 연구는 Microsoft-Windows-Partition%4Diagnostic.evtx 이벤트 로그에 대한 포렌식 분석에만 중점을 둠. 레지스트리 등의 다른 아티팩트를 조사하지 않는다.

이 연구는 할당되지않음 또는 MBR 파티션이 있는 장치로 제한됨. GPT 파티션 장치는 이 이벤트 로글르 다른 방식으로 기록함. 또한 4번째 파티션이 존재할 경우 4번째 파티션에 대한 정보는 저장되지 않음.

이 연구는 FAT32, NTFS, exFAT, EXT3 파일 시스템을 사용하는 장치만을 대상으로함. 다른 파일시스템을 사용하는 장치는 이 이벤트 로그를 다른 방식으로 기록함.

해당 이벤트 로그의 수명은 짧음. 주요한 윈도우 10 업데이트될 때 이벤트 로그가 지워짐. 다만, 19041에서 19042로의 업데이트와 같이 사소한 업데이트로는 지워지지 않음.

장치유형(SSD), 연결유형 (USB <- SATA 디스크)는 이벤트 로그를 다른 방식으로 기록함.

 

- 방법론

VSN은 파티션의 고유하게 하는 한 가지 기능임.

VSN은 VBR 내부에 있으며, 오프셋과 길이는 파일시스템에 따라 다름.

VSN은 LNK파일 및 점프 모곩에서 대상 파일이 있는 볼륨을 가리키는데 사용됨.

 

MBR 파티션 테이블이 있는 장치를 식별하는 다른 기능은 디스크 서명임.

디스크 서명은 MBR의 offset 0x1b8(4byte, little endian)에 있으며 파티션이 만들어질 때 할당 됨.

 

--- 직접 시연을 하기 위해서 사용된 환경 및 장비가 다릅니다. ---

OS : Windows 10 home 21H2 19044.1415
usb device : A(unknown) 64GB(MBR, 4 NTFS partition), B(unknown) 8GB (MBR, 1 FAT32 partition & 1 EXT3 partiton)
software : JLECmd 1.4.0.0, LECmd 1.4.0.0, AXIOM 4.7

 

 

  • 1단계 : 이 단계에서 A 64GB USB 장치는 테스트 컴퓨터에 여러 번 연결/해제되었습니다. 장치가 연결되어 있는 동안 LNK 파일과 점프 목록을 생성하기 위해 여러 파일(4개 파티션 모두에 위치)에 액세스했습니다. 일정량의 데이터가 생성된 후 이벤트 로그, LNK 파일 및 점프 목록에 대한 포렌식 검사를 진행했습니다.
  • 2단계 : 이 단계에서 A 64GB USB 장치의 모든 파티션을 삭제하고 3개의 새로운 NTFS 파티션을 생성했습니다. 1단계(연결/연결 해제, 모든 파티션의 파일 액세스)와 동일한 과정을 반복했습니다. 일정량의 데이터가 생성된 후 이벤트 로그, LNK 파일 및 점프 목록에 대한 포렌식 검사를 진행했습니다.
  • 3단계 : 이 단계에서 B 8GB USB 장치는 테스트 컴퓨터에 여러 번 연결/해제되었습니다. 잠시 후 우리는 이벤트 로그에 대한 포렌식 조사를 진행했습니다.
  • 4단계 : 이 단계에서 B 8GB USB 장치의 FAT32 파티션을 삭제하고 새로운 exFAT 파티션을 생성했습니다. 3단계(연결/연결 해제)와 동일한 과정을 반복했습니다. 잠시 후 우리는 이벤트 로그에 대한 포렌식 조사를 진행했습니다.

A usb의 환경 구성에 실패. 처음에 NTFS 파티션 4개로 나누고 각 파티션에 테스트용 파일까지 넣고 usb 재인식하니까 위 사진처럼 파티션 구성이 바뀌어서 인식됨. usb 자체 문제인지 특성인지 파악 못함.

B USB의 경우 FAT32와 EXT3 파티션 구성이 유지되었음.

그러나 FAT32 파티션을 exFAT 파티션으로 포맷하고 재인식하니 exFAT 파티션이 RAW로 인식되버림.

첫번째 파티션을 exFAT 대신 NTFS로 다시 포맷하여 진행함.

따라서 3~4단계만 진행.


 

1단계

그냥 위 사진 상태의 usb를 연결하고 파일에 접근한 뒤 로그를 확인해 보았다.

NTFS로 정상적으로 인식되는 첫 번째 파티션은 vbr이 제대로 기록되었고, 나머지는 vbr이 0000으로 기록되었지만 이를 통해 최소 4개의 파티션이 존재했음을 알 수 있다.

 

2단계

 

3단계

USB를 연결하고 FAT32 파티션 내에 있는 테스트 파일을 열어본 이후 Microsoft-Windows-Partition%4Diagnostic.evtx 해당 이벤트 로그를 확인한 내용이다.

FAT32 파티션의 vbr은 기록되었지만 EXT3 파티션은 인식할 수 없는 포맷이므로 vbr이 기록되지 않았다.

그래도 2개의 파티션이 있는 것을 확인할 수 있다.

 

4단계

역시 2개의 파티션이 존재함을 알 수 있고, 두 번째 EXT3 파티션은 여전히 0000으로 기록되어있으며

첫번째 파티션이 새로 포맷되었기 때문에 vbr값이 변경된 것을 알 수 있다.

mbr값은 동일하다.

 

- 결론

이 게시물에서 우리는 특히 장치 속성이 필요한 경우 "Microsoft-Windows-Partition%4Diagnostic.evtx" 검사의 중요성에 대해 설명했습니다. 이 유물이 몇 년 전에 발견되었지만 우리는 아직 그 풍부한 정보를 완전히 탐색하지 못했습니다. 그럼에도 불구하고 우리는 저장되어 있는 사용 가능한 모든 VSN을 수동으로 추출하는 방법과 이 프로세스를 자동화하는 도구를 개발하는 방법을 보여주었습니다. 이 이벤트 로그에 대한 추가 연구의 여지가 있지만 독자가 이 이벤트 로그에서 찾을 수 있는 주요 아티팩트 중 일부에서 가치를 찾을 수 있기를 바랍니다.

https://github.com/theAtropos4n6/Partition-4DiagnosticParser

 

 

- 앞으로

해당 이벤트 로그가 GPT 파티션을 사용하는 장치를 처리하는 방법과 다양한 파일 시스템을 처리하는 방법을 분석할 예정.

 

- DFIR 리뷰

 USB 드라이브에는 여러 볼륨이 포함될 수 있으며, 동일한 물리적인 USB 드라이브에서 여러 볼륨을 나올 수 있다는 사실을 간과할 수 있따는 점을 중요하게 지적함.

 

 

 

 

728x90
반응형

'Project > 논문리뷰' 카테고리의 다른 글

DFRWS 포스트 요약 정리 리뷰1  (0) 2022.01.15

728x90
반응형

ASCTF에 출제한 리눅스 메모리 포렌식 문제 제작에  12시간 이상 소요된 것 같다. 사전 계획 빼고 문제 제작 자체만.

순조롭게 진행되었다면 절반도 안걸렸을테지만.. 처음 만들다보니 헤메는 것이 많았다.

그리고 만들고 보니 왜 CTF들에 리눅스 메모리 문제는 거의 없는지도 느낄 수 있었다.

 


리눅스 메모리 포렌식 문제 제작은 처음이지만, 최근에 한 번 풀어 본 적이 있다.

리눅스 메모리 포렌식의 특징은 분석 자체는 볼라티리티로 하면 되므로

윈도우랑 별 차이가 없기 때문에 쉽다.

그런데 이 볼라티리티를 사용하기 위한 환경 구성에 시간이 많이 소요된다.

 

프로필을 생성하는 방법은 쉽게 찾을 수 있다.

https://github.com/volatilityfoundation/volatility/wiki/Linux#creating-a-new-profile

이 과정에 비교적 많은 시간이 소요된다. 리눅스를 가상머신에 깔고 커널버전을 맞춰줘야 하니까..

 

 

리눅스 종류랑 리눅스 커널 버전이 매우 다양해서, 볼라티리티에서 모든 종류의 프로필을 배포할 수 없고

많은 프로필들을 한 번에 볼라티리티에 적용할 경우 볼라티리티의 성능이 매우 나빠진다.

 

https://github.com/volatilityfoundation/profiles

 

따라서 필요한 프로필만 그때 그때 만들어서 적용을 해서 사용을 해야한다.

 

이 부분을 노리고 문제 제작을 계획했다.


 

리눅스에서 메모리를 덤프할 때 사용할 수 있는 소프트웨어들에는 여러가지가 있다.

그 중에서 나는 들어본 적 있는 lime을 사용하기로 했고 관련 포스트를 찾아보았다,

 

https://lastcard.tistory.com/68

위 포스트를 찾아서, 문제 시나리오대로 구성을 한 뒤에 덤프를 위해 사용방법을 따라했다.

근데 사용 예시에 format이 raw로 설정되어있다. 밑에 옵션은 처다보지도 않고, 당연히 메모리 덤프는 raw지! 하고 raw로 덤프를 떴다.

 

그리고 볼라티리티를 돌렸는데 여기서 문제가 발생했다.

예시자료&nbsp;https://cpuu.postype.com/post/665132

이런 식으로 no base address space가 떴다. (사용했던 볼라티리티 버전은 2.6.1 최신이었다.)

문제 제작한 환경이 ubuntu 18.04.1 x64 linux version 5.4.0-42-generic 이었고, 동일한 환경에서 제작된 문제를 이전에 풀어본 적이 있었기 때문에 전혀 이해가 가지 않은 상황이었다.

반응형

그래서 좀 찾아보니까 

https://cpuu.postype.com/post/665132

리눅스 커널 4.8 부터는 KASLR이 적용되어 있어서 저런 현상이 발생되고 분석을 진행할 수 없다는 내용이었다.

추가로 kaslr이 적용된 4.8에서 사용할 수 있는 볼라티리티 버전이 있다는 내용도 있었다.

https://github.com/volatilityfoundation/volatility/pull/385

 

이 시점에서 의문이 들었다.

내가 풀었었던 동일한 환경의 문제는 어떻게 제작이 되었던 것일까?

1. 나랑 다른 방식으로 메모리를 덤프하였다.

2. kaslr을 해제하고 문제를 제작하였다.

 

2번 같은 경우 kaslr을 해제할 수 있다는 내용을 보고 선택지를 추가하게 되었다.

https://wogh8732.tistory.com/323

난 여기서 1번에 의심을 가졌으면 금방 해결되었을 문제였지만 나는 4.8 kaslr 버전용 볼라티리티가 따로 있어? 에 흥미를 느끼고 4.8 환경에서 문제를 제작해서 해당 볼라티리티 버전만을 사용하게 해서 문제를 풀게 하면 재밌겠다는 생각이 들었다. 그리고 이게 안되면 kaslr을 해제해서 만들자로 plan b를 세웠다.

 

(아무 의미가 없는 행동이었다. bneuburg가 제작한 4.8 kaslr 지원 버전에는 2개가 있는데, 모두 2017년에 올라온 것이고 지금은 이미 최신버전 볼라티리티에 기본 탑재되어 있는 기능이다. 근데 난 몰랐다. (아니 나 2017년도 내용임을 확인안하고 뭐했냐..))


 

기존에 사용하던 18.04.1에서는 커널 버전을 4.8로 내릴 수 없어서 4.8로 탑재되어 있는 16.10을 다운받아 환경을 구성하였다.

 

https://ko.wikipedia.org/wiki/%EC%9A%B0%EB%B6%84%ED%88%AC_%EB%B2%84%EC%A0%84_%EC%97%AD%EC%82%AC

 

그리고 똑같은 짓을 하고

똑같이 raw로 덤프를 떠서

볼라티리티를 돌렸고

똑같은 결과가 나왔다. No base address.

 

왜 안되지 하고 깃헙 페이지를 자세히 봤다. 이전엔 자세히 안보고 걍 지원되는 버전 정도만 확인 했었다.

이걸 딱 읽고 아 라임 포멧이어야 하는구나를 알게 되었다.

 

그리고 이전에 읽었던 lime 사용방법 블로그로 돌아와서

https://lastcard.tistory.com/68

방법2-1에는 포멧을 lime으로 써두셨더라..

그래서 처음부터 다 잘못됐음을 깨닳고 처음 환경에서 lime으로 뽑아내서 최신버전 볼라티리티를 돌렸고

분석에 성공했다.

 

이렇게 메모리 덤프를 볼라티리티에 인식하게 하는 것에 성공했다.


728x90

다음 두번째 문제가 있었다.

처음 계획했던 시나리오는 크롬이나 파이어폭스 검색 기록을 확인해서 특정 시간에 검색한 키워드를 찾아내는 것이었다.

 

근데 문제는 일단 chromehistory firefoxhistory 플러그인이 리눅스에서는 지원되지 않았다.

 

그러면 히스토리 파일을 뽑아내야하는데, 파일을 추출 할때 윈도우처럼 filescan 같은 플러그인이 없고 find_file 플러그인 하나로 파일의 메모리 주소 뽑아내고 파일 추출을 다 해야한다.

find_file로 파일의 메모리 주소를 뽑아내려면 파일의 full 절대 경로를 알아야 한다. 크롬은 기본 설치 경로를 생각하고 히스토리 파일을 뽑아낼 수 있겠지만 파이어폭스는 랜덤 문자열의 profile 이름으로 생성된 폴더에 있기 때문에 해당 폴더명을 알아내야하는 과정이 필요한데, lime 포멧은 R-Studio 같은거에서도 분석이 안되서 파일 구조를 확인할 수 없고

bash에서 해당 파일명을 주고자 bash로 직접 해당 폴더까지 접근하는 것을 시나리오 넣기엔 너무 부자연스러웠다. 문제 제작을 위해 고의로 넣은 내용 느낌. 개인적으로 이런거 안 좋아한다.

뭐 어떻게 해서 풀 절대경로를 줘서 파일을 추출하더라도 내용이 제대로 들어있지 않았다.

그래서 히스토리 파일을 뽑아내는 것은 의미가 없었다.


그래서 크롬/파이어폭스 프로세스를 덤프를 떠서 찾아내야 하는데,

yarascan으로 http 뽑아내서 링크들을 뽑아내는 것은 가능한데, 시간 값을 뽑아내려면 뭐 어떻게 잘 해서 뽑아내야할건데 난 모른다.

 

그래서 문제 지문에 구글 검색으로 첫 번째로 검색한 내용은? 같은걸 할까 했지만 이 경우 구글 검색 링크 "https://www.google.com/search?q=" 로 yarascan 돌리면 바로 나와버리기 때문에 난이도가 매우 낮았다. 이건 볼라티리티 안쓰고 그냥 grep으로도 뽑아낼 수 있으므로 

브라우저 검색 기록을 찾아내는 것은 포기하고

 

어디서 많이 본 프로세스 뽑아내서 실행하기가 되었다.

근데 또 문제가 있었다. bash에 입력한 명령어는 볼라티리티 플러그인으로 확인할 수 있지만, 출력된 내용은 플러그인으로 확인할 수 없는 것으로 알고 있다.

하지만 그냥 raw로 출력 내용이 남아 있기 때문에 strings랑 grep으로 다 뽑아낼 수 있다.

grep에 키워드가 최대한 걸리지 않도록 플래그를 base64 이중으로 인코딩하는 등의 노력을 했지만

"ASCTF"가 키워드에 걸렸다. "ASCTF{"만 생각하고 이건 생각 못했다. 이건 롸업에도 써놨다.

 

이걸 롸업 작성하면서 알아서 해당 프로세스의 pid값을 플래그에 추가하는 걸로 문제를 수정하였다.

pid값은 볼라티리티로만 뽑아낼 수 있으니까..


혀튼 리눅스 메모리 포렌식 문제를 제작해보고 다시 풀어보면서 

리눅스 메모리 분석은 윈도우 메모리 분석이랑 비슷하거나 할 수 있는게 더 적었고

실제 분석보다 환경 구성의 비중이 크고 오래걸리고 어렵고 귀찮고 짜증나기 때문에

CTF에서 리눅스 메모리 문제를 보기 어려웠던 이유를 알 수 있었다.

 

분석 자체만 가지고 어렵게 만들 수만 있다면 프로필 파일은 같이 제공해줘도 되긴 하는데

 

 

 

응애

나 뉴비

728x90
반응형

'Project' 카테고리의 다른 글

리눅스 메모리 포렌식 문제 제작 삽질  (0) 2021.11.30

+ Recent posts