Write-up
- [UIUCTF 2018] xoracle (250) 2018.04.18
- [WriteUP] Byte Bandits CTF 2018 2018.04.10
- [WriteUp] UIUCTF 2018 Writeup 2018.04.10
- [TyokoWesterns] My Simple Cipher[75] 2017.09.02
- 난해한 프로그래밍 언어 2017.08.01
- [anstromCTF 2017] USB Encryption 2017.04.26
- [anstromCTF 2017] Document 2017.04.26
- [anstromCTF 2017] IMAGE TRICKERY 2017.04.26
- [anstromCTF 2017] Knock Knock 2017.04.25
- [anstromCTF 2017] Descriptions 2017.04.25 2
[UIUCTF 2018] xoracle (250)
이번 UIUCTF에서 못다푼 xoracle을 이번에 다시 한번 풀어보기로 했다.
이미 서버가 닫혀버렸으므로 가상서버에서 구축하여서 다시 풀어보기로 하였다.
(서버구축에 관한 내용은 이쪽 참고)
참고로 파이썬은 이렇게 추가해줘야한다.
service xoracle { disable = no flags = REUSE socket_type = stream protocol = tcp wait = no user = sherlock server = /usr/bin/python3 server_args = /home/sherlock/workstation/2018_CTF/UIUCTF/xoracle/xoracle.py } | cs |
xoracle ● Crypto ● 250 Points
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/env python3 from random import randint from base64 import b64encode def xor(data, key): out = b'' for n in range(len(data)): out += bytes([data[n] ^ key[n % len(key)]]) return out def randkey(): key = b'' for n in range(randint(128, 255)): key += bytes([randint(0, 255)]) return key if __name__ == "__main__": with open('flag', 'rb') as f: data = f.read() print(b64encode(xor(data, randkey())).decode("utf-8")) | cs |
두사람 writeup에 차이가 나는 이유를 알았다.
writeup1에서는 주어진 암호문의 해독한 길이를 1536으로 보았다. (실제로 서버에서 1536의 길이만 받은것같다.) 1
writeup2에서는 주어진 암호문을 해독하여 나온 길이를 2039로 본다.(나도 복호화한 결과 길이가 2039였다.)
그래서 결과적으로 w1과 w2에서 서로 조금씩 다른 파일들을 해독하였고... w2에 있는 분이 더 정확한 파일을 얻게된것이다.
나는 w1의 것을 w2의 2039를 받는것으로 해서 writeup을 재구성해보겠다.
먼저 이론을 다시 한번 정리하면 아래와 같다.
Solution
- 먼저 키를 모르고 암호문인 C만 알고 있을 때, 여기서 키만 남기고 이 키의 길이를 어떻게 정의하느냐를 알아야한다.
nc를 통해서 받게 되는 암호문 C를 base64로 복호화해보면 길이가 2039인것을 알 수 있다. 그리고 중요한 키 K의 길이는 128~255의 범위에 있고 만약 우리가 같은 길이를 가진 키 k1과 k2가 반복되어 얻어진 OTP인 K1와 K2로 암호화된 C1, C2를 가지고 있다면 키 길이를 유추할 수 가 있다.(키값은 서로 다르다, 같은것은 길이 뿐)
K1 XOR K2
은 2039길이를 가지고 있고, 이 안에는 128-255
의 길이를 가지는 k1 XOR k2가 반복되어지고 있을 것이다.
그러므로 우리는 다음 파이썬 코드를 가지고 키길이가 각각 128-255인 암호문을 128개 얻을 수 있다.
from base64 import b64decode from socket import socket ADDR = 'localhost', 7777 KEY_LEN = 128 def get_msg(): while True: with socket() as s: s.connect(ADDR) msg = b64decode(s.recv(3000)) if len(msg) == 2039: return msg def xor_bytetrings(a, b): return bytes((x^y for x,y in zip(a,b))) def find_msgs(): msgs ={get_msg()} needed = set(range(128)) while needed: print(len(msgs), needed) new_msg = get_msg() for msg in list(msgs): xor_key = xor_bytetrings(new_msg, msg) good_part, last_part = xor_key[:KEY_LEN], xor_key[KEY_LEN:] if good_part in last_part: i = last_part.index(good_part) print('\t', i) if i in needed: yield (i+KEY_LEN, new_msg) needed -= {i} msgs -= {msg} continue msgs.add(new_msg) if __name__ == "__main__": ### STEP 1. find key_length and Save for i, text in find_msgs(): with open('key_{0:0>3}_c'.format(i), 'wb') as f: f.write(text) # yeild : http://kkamikoon.tistory.com/90 , https://dojang.io/mod/page/view.php?id=1119 | cs |
- 자 이제 우리는 암호문 C와 그 암호화에 쓰인 키 K의 길이를 알고 있다. 키 길이를 len이라고 할 때 암호문 C를 len길이씩 짤라서 n개의 블록과 M을 len으로 나눈 n개의 블록 다음과 같이 표시 할 수 있다.
그리고 이 연산 c1 xor c2를 통해 키 K를 암호문에서 제거하여 평문 m블록의 연산으로만 바꿀수 있다. 이것이 키 길이를 알 때, 바로 암호문의 자신들끼리 곱하여 암호문에서 키를 소거하는 방법이다.
- 이제 키 길이가 서로 1차이가 나는 암호문
C1
과C2
를 가져오자. 이 들의 키를 각각K1,
K2
[|K1-K2|=1
이다. 여기서 기억할 것은 우리가 XOR할 것은M
의 블록이란 것이다.
위와 같이 계산되는 것이다! 키 길이가 1다른 것을 이용하여
M[1]^M[4]인 부분을 키길이가 3인 H1에서 가져오고, M[0]^M[4]인 부분을 키길이가 4인 H2에서 가져와
그 둘의 XOR결과로 M[0]^M[1]을 구할 수 있는 것이다.
이 계산을 키 길이 128인 C1을 base로 두고 키길이가 각각 1,2,3,4,5씩 차이나는 C들을 가져와 위와 같은 계산을 하면 우리는 결국 M[0] XOR M[i]
for all i
in [1,128]
을 계산할 수 있다. (M[1]~M[127])
- 이제 첫 평문 바이트 M[0]를 BruteForce를 통해 나머지 M[1]~M[127]을 구할 수 있고, 이 값을 이용해 키 길이가 128인 암호문과 XOR을 통해 128길이 키 K를 복구하여 평문메세지를 복호화할 수 있다.
import os KEY_LEN = 128 FILE_LEN = 2039 def xor_bytetrings(a, b): return bytes((x^y for x,y in zip(a,b))) def key2039_gen(key): key = key*(FILE_LEN // KEY_LEN) key += key[:FILE_LEN % KEY_LEN] return key if __name__ == "__main__": ### STEP 2. Xor M1, M2 AND Genearte M[0]^M[i] (i=range(1,128) res = [0] with open('key_128_c', 'rb') as f: original = f.read() for i in range(1,128): idx=i+KEY_LEN with open('key_{0:0>3}_c'.format(idx), 'rb') as f: shifted = f.read() or_blocks = [original[KEY_LEN*x:KEY_LEN*(x+1)] for x in range(0,2)] sh_blocks = [shifted[(KEY_LEN+i)*x:(KEY_LEN+i)*(x+1)] for x in range(0,2)] H1 = xor_bytetrings(*or_blocks) H2 = xor_bytetrings(*sh_blocks) res.append(H1[i] ^ H2[0]) ### STEP 3. Bruteforce M[0] for m0 in range(256): msg_first = [m0^x for x in res] key = xor_bytetrings(msg_first, original) key = key2039_gen(key); flag = xor_bytetrings(key, original) with open('flag_{0:0>3}'.format(m0), 'wb') as f: f.write(flag) ### STEP 4. file operation AND Find Real FLAG! for m0 in range(256): os.system('file flag_{0:0>3} | grep -v ": data"'.format(m0)) | cs |
flag_number에서 number은 M[0], 즉 첫바이트를 저값으로 하였을 때 나온 키값으로 복호화했을 때
파일 시그니처로 이렇다는 것이다.
만일 flag가 텍스트 파일이라면 아래와 같이 나온다.
sherlock@ubuntu:~/workstation/2018_CTF/UIUCTF/xoracle/my_writeup$ echo "hello world" > test sherlock@ubuntu:~/workstation/2018_CTF/UIUCTF/xoracle/my_writeup$ file test test: ASCII text | cs |
다른 파일들은 다 쓰레기값인것 같지만 flag_080은 뭔가 제대로된 파일헤더가 보인다. PK가 보이니 압축파일이겠고 또 f.bmp라는 문구도 보인다.
한번 unzip해보겠다.
- writeup1에서 풀이해주신분이 실수하신게 있다. 소스를 확인해보니 서버로 부터 recv(2<<10)를 하는데, 서버가 주는 문자열은 2800자 정도된다. 물론 그 문자열이 base64인코딩되어있어 이를 디코딩하게 되면 2039자가 나온다. 아마 여기서 헷갈리셔서 2<<10=2048자만 받으신거같다. 그래서 서버가 주는 문자열 2800자중에 2048만 받아가게 되어 파일크기가 1536이 된것같다. [본문으로]
'Write-up > Crypto' 카테고리의 다른 글
[0ctf 2017] integrity - 75p (0) | 2018.05.02 |
---|---|
[Byte Bandits CTF 2018] R u Ronald Rivest? 70p (0) | 2018.04.27 |
[TyokoWesterns] My Simple Cipher[75] (0) | 2017.09.02 |
[anstromCTF 2017] Knock Knock (0) | 2017.04.25 |
[anstromCTF 2017] Descriptions (2) | 2017.04.25 |
[WriteUP] Byte Bandits CTF 2018
UIUCTF보다 늦게 시작된 CTF이다.
문제는 UIUCTF보다 풍부해보인다... 어째
[Misc]Greetings 1p
1점짜리다....
안녕하세요! <3 란다...
룰을 읽어보면 freenode irc로 접속하는게 있다. 접속해보자.
최근에 irc 문제를 풀어서 그런가;; 데자뷰가...
[Crypto]R u Ronald Rivest? 70p
http://xerxes-break.tistory.com/316
[Forensics]Eating_that_ponegr 100p
어우야.... 뭔가 힌트가 될만한 문구를 나열해주는데; 봐도 잘... 아니 잠깐만 방금 깨달았네 ㄷㄷ;
PONEGR-du! GRINFO-du! 를 2글자씩 뛰어가며 읽어보자.
PNG OER GIF RNO를 말하는것 같다.
OER RNO는 모르겟지만 PNG GIF는 이미지 확장자다.
아래가 주어진 grinfo.png라는 확장자다.
그냥 평범한 그림파일이다... gif로 바꿔도 뭐 별거 없어보인다.
딱히 에러가 있지는 않다.
dma..음... 모르겠다
------- 2018. 04.13 추가 ---------
writeup이 올라왔다.
- https://ctftime.org/writeup/9666
내용이 매우 간단하다.
zsteg grinfo.png -E b1,b,lsb,xy > step1.gif
convert -verbose -coalesce step1.gif step2.png
montage step2-* -tile x1 -geometry '1x1+0+0<' final.png
By https://twitter.com/diofeher and https://twitter.com/K4L1_FS
이걸로 설명을 다하다니... 한번 차례로 해보겠다.
zsteg툴은 png & bmp 파일에서 숨겨진 데이터가 있는지 감지해주는 툴이다.
(https://github.com/zed-0xff/zsteg)
Description
detect stegano-hidden data in PNG & BMP
Detects:
- LSB steganography in PNG & BMP
- zlib-compressed data
- OpenStego
- Camouflage 1.2.1
- LSB with The Eratosthenes set
꽤나 유용한 툴 같다. 먼저 zsteg grinfo.png 를 실행하면 아래와 같이 나온다.
GIF가 있는 것을 b1,b,lsb, xy 항목을 보면 알 수 있다. 이제 저 GIF를 추출하자.
-E옵션을 이용해서 추출해줄수 있다.
.zsteg grinfo.png -E b1,b,lsb,xy > step1.gif 를 실행
gif가 추출되었고, 이제 convert를 통해 -verbose -coalesce 옵션을 주어 실행하면 gif파일이 png파일 450개정도로 나뉘어서 나온다.
이제 이 png들을 다 모아서 합쳐주면 된다.
montage step2-* -tile x1 -geometry '1x1+0+0<' final.png
이렇게 플래그가 나오는 것을 알 수있다.
나중에 시간나면 좀 더 분석해보겠다.
[Crypto]almost almost xor 150p
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/python3 import sys import os def encrypt(message, key): message = list(message) key = list(key) for i, kb in enumerate(key): step = (kb % len(key)) + 1 for j in range(i, len(message), step): message[j] ^= kb return bytes(message) with open(sys.argv[2], "wb") as f: f.write(encrypt(open(sys.argv[1], 'rb').read(), os.urandom(16))) | cs |
끝나버림 ㅠ;
'Write-up > CTF _ Write UP' 카테고리의 다른 글
[HITCON-Training] lab12 : secretgarden (0) | 2019.07.13 |
---|---|
RCTF 2018 Writeup (cpushop / babyre / Misc+) (0) | 2018.05.21 |
DEFCON CTF Quals 2018 Writeup (0) | 2018.05.14 |
[WriteUp] UIUCTF 2018 Writeup (0) | 2018.04.10 |
[WriteUp] UIUCTF 2018 Writeup
오랜만에 CFT나 해야겠다.
ROT180 ● oʇdʎɹƆ ● 1 Points ● Solved
위의 Crypto를 180도 돌려놓은 문자표시가 보이는가....
어떻게 이런걸 찾앗는지 ㄷㄷ;
영어는 알아서 해석하자 !
중요한건 중간에 보이는 저 {uoɔǝɹ‾ʇou‾sʇᴉ‾ʇsɐǝl‾ʇɐ}ƃɐlɟ 이다 처음에는 진짜.. 외계어인줄 알았다 ;; 어느 나라에서 쓰는 언어인가 싶었는데;
180도 돌려보니 플래그가 보였다.
돌려보자!
굿!
irc ● other ● 1 Points
https://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:IRC_%EB%8C%80%ED%99%94%EB%B0%A9
키위IRC 를 이용했음
1점... 그럼에도 꽤 헷갈림 ㅠ
위와같이 irc로 접속하면 클리어됨
Hastad ● Crypto ● 200 Points
sorry wrong chat라고 하고..
ciphertexts.txt 와 moduli.txt가 주어진다.
일단 한번 보자.
이게 ciphertexts.txt이고 아래가 moduli.txt이다.
RSA암호화로 ciphertexts.txt를 보낸것이라 생각한다. 여기서 e=3이라고 하는데...
e값이 매우 작고 평문이 길이가 짧을 경우, n(=p*q)값이 매우 크기때문에.. 암호화된 평문 C=P^e(% n) 에서 n이 너무커서 C가 모듈러 연산에 몇번 걸리지 않는 경우가 있다. 이 경우 C값을 그냥 e 거듭제곱근을 구해서 평문을 복호화해 낼 수가 있다고 한다. 그래서 일단 e제곱근한 값이 나오나 보기로 했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | c_list = [0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65] e = 3.00 for idx, c in enumerate(c_list): c_list[idx]=c**(1.00/e) print("%x " % c_list[idx]) for c in c_list: #c = c**(1.00/e) c=format(int(c), 'x') print("%s " % (c.decode("hex"))) | cs |
이런 파이썬 코드를 짜서... 출력해보았다.
코드는 해당 ciphertexts.txt의 값들을 각각 세제곱근한 값을 hex값으로 두고, 이를 decode해 평문으로 출력하는 것이다.
위와 같이 출력되었고... 666c61677b757000000000000000000000000000000000000000000000 와 flag{up 를 볼때...
모듈러연산에 걸려 평문값이 짤려 손실된것으로 보인다.
....
아닛.... 엄청난걸 찾았다. 위키백과 굿
https://en.wikipedia.org/wiki/Coppersmith%27s_attack#RSA_basics
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import gmpy c_list = [0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa86ddbee1409ac7ac327a0c848081ee6e3b110867085f1074755785b0a5a6a2343b791695c3e91fdb370d5b26be3b6d2fc449c7788bbb1ab67ddc361b4115010618e39c883449b757fc1624369b440236ee65, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa875a9ac01e472ea5896c1d460410508b9a7c723b5ba904fb5b64d68a1e96254ba04b08c92d51f1fe6c3d6bb426e1ee8c61c8a6ff1eeab9e07f51d8057f2f0c54b27c7006539f7148484ff26a02e4cb1d3165, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8ab16290cf92bacf31b23d6a0ea95c2ebd6eb8afe4f038d852a7f17e98f965f299b4d00126611d403c5208a145157ed1d71079fc558eaa888e993360fac35c7a816ad183190867b1b7580a2677cd6871aa65, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65, 0x10652cdfaa8210601d22f4a15aa380233420f9ee9a276d3ac8e05cfc4f6f515f78331e8e74484e8533221e88f78671dd08622e78233e458978a35036680d1c5caaba2fa3bce3b914ad48501a276d6a88adc16db282e065, 0x10652cdfaa8c9ef24fc044b5fed749888632ad132bd412f22d9d905e6ffd27b288c22884b24fe130d83aaab9c2dc6e942418dff89d2b66a66e40900db9456813d70eb63d0c38697f89ff387969d3d40163376416270965, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8ab162128a955a58d3b780f2656800796eb70c345c56d7b8523d614ef4ca920471f56493c83ca48500033a0c0b31988ca6e66a76e0ed559b38616688941558b127260cdf70261822929efa0aa6b6d79d1665, 0x10652cdfaa8c2701b8bb7c11fc3218cc2d97cd4707f6de55637bc093f474d231b4d4fe8635261b8e4f772d0e51a25f8e713777a137be6f04e0d28ddd6ec0b852aaf357d33e08aed23e034fcd1ced38542fbeb5aa0eee65] e = 3.00 for idx, c in enumerate(c_list): c_list[idx], perfect = gmpy.root(c, 3) print("%x %d " % (c_list[idx], perfect)) for c in c_list: #c = c**(1.00/e) c=format(int(c), 'x') print("%s " % (c.decode("hex"))) | cs |
하... 이렇게 잘나오는걸 삽질을 그렇게 하다니 ㅡㅡ;
Iterator | Arguments | Results |
---|---|---|
p, q, … [repeat=1] | cartesian product, equivalent to a nested for-loop | |
p[, r] | r-length tuples, all possible orderings, no repeated elements |
triptych ● Reversing ● 100 Points
리버싱 문제다!
triptych 라는 파일을 하나 준다. 일단 hxd로 열어보았다.
함수들이 여러개 보인다.
중요할거 같은 함수로는 main, the_first, the_third가 중요해보인다. 하나하나 살펴보자.
main이다. *MK_FP(__FS__, 40LL)은 뭔지 잘 모르겠으나, 마지막에 가서 원래값과 xor하여 변조됫는지 확인하는 것을 보니 canary 같은 것같다.
코드의 내용으로는 fgets으로 사용자로부터 25만큼 버퍼를 읽어들이고, mprotect를 이용해 0x400000부터 0x401000까지 권한을 rwx(7)로 설정해준다.
0x400000~0x401000은 main과 the_fisrt~the_third의 영역이고... 이 영역에 rwx권한을 모두 주는 것을 보니, 이 영역에 무엇을 할 것인가보다.
그리고 마지막으로 the_first에 사용자로 받은 입력값을 인자로 넣어준다. 이제 the first를 한번 보자.
the_first이다. v3~v7까지의 값을 문자값으로 바꿔보면 이상한 문자열이 나온다. 아마 String값이거나 배열이 저렇게 나온거같다.
C언어라면 원래 이렇게 표현됬을 것 같다. char arr[]="~~문자열~~";
다음으로 for문을 실행해 245만큼 반복하는데, 안의 연산이 좀 이상하다.
&the_second의 주소에 1씩더하면서 그 주소에 있는 값을 위에 있는 배열의 값과 XOR연산해 저장한다.
이렇게하면 the_second 함수에 적힌 명령들이 바뀌게 될것이다.
그럼 한번 the_second함수를 보자.
the_second함수를 보려했으나... 제대로 x-ray되지않는다... C언어로 보고싶엇으나 저렇게 표시되고
명령도 이상하게 보이는걸 보니; the_first의 for문 수행이 the_second의 값을 바꾸어 실행가능하게 해주는 것 같다.
일단 더이상 해석할게 없으니 the_third로 넘어가겠다.
the_third의 값은 또 잘 보인다. 하지만 내용이 제대로 파악이 안된다.
the_second의 내용을 알기위해 gdb로 실행해보겠다.
gdb로 disass해서보니... 엉망인것을 알 수잇다.
역시 for문을 수행하고 나서 정리되는 것 같다.
그래서 the_second함수를 콜하기전에 break를 걸고 disass 해보았다.
값이 제대로 보인다.
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 | (gdb) disass the_second Dump of assembler code for function the_second: 0x00000000004008fd <+0>: push rbp 0x00000000004008fe <+1>: mov rbp,rsp 0x0000000000400901 <+4>: sub rsp,0x60 0x0000000000400905 <+8>: mov QWORD PTR [rbp-0x58],rdi 0x0000000000400909 <+12>: mov rax,QWORD PTR fs:0x28 0x0000000000400912 <+21>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400916 <+25>: xor eax,eax 0x0000000000400918 <+27>: movabs rax,0x736a647361686868 0x0000000000400922 <+37>: mov QWORD PTR [rbp-0x40],rax 0x0000000000400926 <+41>: movabs rax,0x6873696f6a636f6a 0x0000000000400930 <+51>: mov QWORD PTR [rbp-0x38],rax 0x0000000000400934 <+55>: movabs rax,0x6a7662206b777661 0x000000000040093e <+65>: mov QWORD PTR [rbp-0x30],rax 0x0000000000400942 <+69>: movabs rax,0x76626b647361626b 0x000000000040094c <+79>: mov QWORD PTR [rbp-0x28],rax 0x0000000000400950 <+83>: movabs rax,0x7c7c276638393233 0x000000000040095a <+93>: mov QWORD PTR [rbp-0x20],rax 0x000000000040095e <+97>: mov WORD PTR [rbp-0x18],0x3b3e 0x0000000000400964 <+103>: mov QWORD PTR [rbp-0x48],0x400807 0x000000000040096c <+111>: mov DWORD PTR [rbp-0x4c],0xf5 0x0000000000400973 <+118>: mov DWORD PTR [rbp-0x50],0x0 0x000000000040097a <+125>: jmp 0x4009c8 <the_second+203> 0x000000000040097c <+127>: mov eax,DWORD PTR [rbp-0x50] 0x000000000040097f <+130>: movsxd rdx,eax 0x0000000000400982 <+133>: mov rax,QWORD PTR [rbp-0x48] 0x0000000000400986 <+137>: lea rsi,[rdx+rax*1] 0x000000000040098a <+141>: mov eax,DWORD PTR [rbp-0x50] 0x000000000040098d <+144>: movsxd rdx,eax 0x0000000000400990 <+147>: mov rax,QWORD PTR [rbp-0x48] 0x0000000000400994 <+151>: add rax,rdx 0x0000000000400997 <+154>: movzx edi,BYTE PTR [rax] 0x000000000040099a <+157>: mov ecx,DWORD PTR [rbp-0x50] 0x000000000040099d <+160>: mov edx,0x30c30c31 0x00000000004009a2 <+165>: mov eax,ecx 0x00000000004009a4 <+167>: imul edx 0x00000000004009a6 <+169>: sar edx,0x3 0x00000000004009a9 <+172>: mov eax,ecx 0x00000000004009ab <+174>: sar eax,0x1f 0x00000000004009ae <+177>: sub edx,eax 0x00000000004009b0 <+179>: mov eax,edx 0x00000000004009b2 <+181>: imul eax,eax,0x2a 0x00000000004009b5 <+184>: sub ecx,eax 0x00000000004009b7 <+186>: mov eax,ecx 0x00000000004009b9 <+188>: cdqe 0x00000000004009bb <+190>: movzx eax,BYTE PTR [rbp+rax*1-0x40] 0x00000000004009c0 <+195>: xor eax,edi 0x00000000004009c2 <+197>: mov BYTE PTR [rsi],al 0x00000000004009c4 <+199>: add DWORD PTR [rbp-0x50],0x1 0x00000000004009c8 <+203>: mov eax,DWORD PTR [rbp-0x50] 0x00000000004009cb <+206>: cmp eax,DWORD PTR [rbp-0x4c] 0x00000000004009ce <+209>: jl 0x40097c <the_second+127> 0x00000000004009d0 <+211>: mov rax,QWORD PTR [rbp-0x58] 0x00000000004009d4 <+215>: mov rdi,rax 0x00000000004009d7 <+218>: call 0x400807 <the_third> 0x00000000004009dc <+223>: nop 0x00000000004009dd <+224>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004009e1 <+228>: xor rax,QWORD PTR fs:0x28 0x00000000004009ea <+237>: je 0x4009f1 <the_second+244> 0x00000000004009ec <+239>: call 0x400550 <__stack_chk_fail@plt> 0x00000000004009f1 <+244>: leave 0x00000000004009f2 <+245>: ret End of assembler dump. | cs |
보아하니... the_third의 주소에도 the_second에 수행하는것과 비슷하게 수행하는 것같다.
the_third호출전에 break를 걸고 the_third를 보자.
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 | (gdb) disass the_third Dump of assembler code for function the_third: 0x0000000000400807 <+0>: push rbp 0x0000000000400808 <+1>: mov rbp,rsp 0x000000000040080b <+4>: sub rsp,0x60 0x000000000040080f <+8>: mov QWORD PTR [rbp-0x58],rdi 0x0000000000400813 <+12>: mov rax,QWORD PTR fs:0x28 0x000000000040081c <+21>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400820 <+25>: xor eax,eax 0x0000000000400822 <+27>: movabs rax,0x265e245e24736c61 0x000000000040082c <+37>: mov QWORD PTR [rbp-0x40],rax 0x0000000000400830 <+41>: movabs rax,0x69766467736b6720 0x000000000040083a <+51>: mov QWORD PTR [rbp-0x38],rax 0x000000000040083e <+55>: movabs rax,0x3332666972326967 0x0000000000400848 <+65>: mov QWORD PTR [rbp-0x30],rax 0x000000000040084c <+69>: movabs rax,0x6b676b647320282a 0x0000000000400856 <+79>: mov QWORD PTR [rbp-0x28],rax 0x000000000040085a <+83>: movabs rax,0x7a6f70607e202173 0x0000000000400864 <+93>: mov QWORD PTR [rbp-0x20],rax 0x0000000000400868 <+97>: mov WORD PTR [rbp-0x18],0x6961 0x000000000040086e <+103>: mov QWORD PTR [rbp-0x48],0x4006a6 0x0000000000400876 <+111>: mov DWORD PTR [rbp-0x4c],0x160 0x000000000040087d <+118>: mov DWORD PTR [rbp-0x50],0x0 0x0000000000400884 <+125>: jmp 0x4008d2 <the_third+203> 0x0000000000400886 <+127>: mov eax,DWORD PTR [rbp-0x50] 0x0000000000400889 <+130>: movsxd rdx,eax 0x000000000040088c <+133>: mov rax,QWORD PTR [rbp-0x48] 0x0000000000400890 <+137>: lea rsi,[rdx+rax*1] 0x0000000000400894 <+141>: mov eax,DWORD PTR [rbp-0x50] 0x0000000000400897 <+144>: movsxd rdx,eax 0x000000000040089a <+147>: mov rax,QWORD PTR [rbp-0x48] 0x000000000040089e <+151>: add rax,rdx 0x00000000004008a1 <+154>: movzx edi,BYTE PTR [rax] 0x00000000004008a4 <+157>: mov ecx,DWORD PTR [rbp-0x50] 0x00000000004008a7 <+160>: mov edx,0x30c30c31 0x00000000004008ac <+165>: mov eax,ecx 0x00000000004008ae <+167>: imul edx 0x00000000004008b0 <+169>: sar edx,0x3 0x00000000004008b3 <+172>: mov eax,ecx 0x00000000004008b5 <+174>: sar eax,0x1f 0x00000000004008b8 <+177>: sub edx,eax 0x00000000004008ba <+179>: mov eax,edx 0x00000000004008bc <+181>: imul eax,eax,0x2a 0x00000000004008bf <+184>: sub ecx,eax 0x00000000004008c1 <+186>: mov eax,ecx 0x00000000004008c3 <+188>: cdqe 0x00000000004008c5 <+190>: movzx eax,BYTE PTR [rbp+rax*1-0x40] 0x00000000004008ca <+195>: xor eax,edi 0x00000000004008cc <+197>: mov BYTE PTR [rsi],al 0x00000000004008ce <+199>: add DWORD PTR [rbp-0x50],0x1 0x00000000004008d2 <+203>: mov eax,DWORD PTR [rbp-0x50] 0x00000000004008d5 <+206>: cmp eax,DWORD PTR [rbp-0x4c] 0x00000000004008d8 <+209>: jl 0x400886 <the_third+127> 0x00000000004008da <+211>: mov rax,QWORD PTR [rbp-0x58] 0x00000000004008de <+215>: mov rdi,rax 0x00000000004008e1 <+218>: call 0x4006a6 <validate> 0x00000000004008e6 <+223>: nop 0x00000000004008e7 <+224>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004008eb <+228>: xor rax,QWORD PTR fs:0x28 0x00000000004008f4 <+237>: je 0x4008fb <the_third+244> 0x00000000004008f6 <+239>: call 0x400550 <__stack_chk_fail@plt> 0x00000000004008fb <+244>: leave 0x00000000004008fc <+245>: ret | cs |
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 | (gdb) disass validate Dump of assembler code for function validate: 0x00000000004006a6 <+0>: push rbp 0x00000000004006a7 <+1>: mov rbp,rsp 0x00000000004006aa <+4>: sub rsp,0x70 0x00000000004006ae <+8>: mov QWORD PTR [rbp-0x68],rdi 0x00000000004006b2 <+12>: mov rax,QWORD PTR fs:0x28 0x00000000004006bb <+21>: mov QWORD PTR [rbp-0x8],rax 0x00000000004006bf <+25>: xor eax,eax 0x00000000004006c1 <+27>: movabs rax,0x797472657771275f 0x00000000004006cb <+37>: mov QWORD PTR [rbp-0x30],rax 0x00000000004006cf <+41>: movabs rax,0x73617d7b706f6975 0x00000000004006d9 <+51>: mov QWORD PTR [rbp-0x28],rax 0x00000000004006dd <+55>: movabs rax,0x7a6c6b6a68676664 0x00000000004006e7 <+65>: mov QWORD PTR [rbp-0x20],rax 0x00000000004006eb <+69>: movabs rax,0x7c6d6e62766378 0x00000000004006f5 <+79>: mov QWORD PTR [rbp-0x18],rax 0x00000000004006f9 <+83>: mov DWORD PTR [rbp-0x5c],0x0 0x0000000000400700 <+90>: jmp 0x400777 <validate+209> 0x0000000000400702 <+92>: mov eax,DWORD PTR [rbp-0x5c] 0x0000000000400705 <+95>: movsxd rdx,eax 0x0000000000400708 <+98>: mov rax,QWORD PTR [rbp-0x68] 0x000000000040070c <+102>: add rax,rdx 0x000000000040070f <+105>: movzx eax,BYTE PTR [rax] 0x0000000000400712 <+108>: cmp al,0x5e 0x0000000000400714 <+110>: jle 0x40072a <validate+132> 0x0000000000400716 <+112>: mov eax,DWORD PTR [rbp-0x5c] 0x0000000000400719 <+115>: movsxd rdx,eax 0x000000000040071c <+118>: mov rax,QWORD PTR [rbp-0x68] ---Type <return> to continue, or q <return> to quit--- 0x0000000000400720 <+122>: add rax,rdx 0x0000000000400723 <+125>: movzx eax,BYTE PTR [rax] 0x0000000000400726 <+128>: cmp al,0x7d 0x0000000000400728 <+130>: jle 0x400734 <validate+142> 0x000000000040072a <+132>: mov edi,0x0 0x000000000040072f <+137>: call 0x400590 <exit@plt> 0x0000000000400734 <+142>: mov DWORD PTR [rbp-0x58],0x0 0x000000000040073b <+149>: jmp 0x40076d <validate+199> 0x000000000040073d <+151>: mov eax,DWORD PTR [rbp-0x58] 0x0000000000400740 <+154>: movsxd rdx,eax 0x0000000000400743 <+157>: mov rax,QWORD PTR [rbp-0x68] 0x0000000000400747 <+161>: add rdx,rax 0x000000000040074a <+164>: mov eax,DWORD PTR [rbp-0x58] 0x000000000040074d <+167>: movsxd rcx,eax 0x0000000000400750 <+170>: mov rax,QWORD PTR [rbp-0x68] 0x0000000000400754 <+174>: add rax,rcx 0x0000000000400757 <+177>: movzx eax,BYTE PTR [rax] 0x000000000040075a <+180>: movsx eax,al 0x000000000040075d <+183>: sub eax,0x5f 0x0000000000400760 <+186>: cdqe 0x0000000000400762 <+188>: movzx eax,BYTE PTR [rbp+rax*1-0x30] 0x0000000000400767 <+193>: mov BYTE PTR [rdx],al 0x0000000000400769 <+195>: add DWORD PTR [rbp-0x58],0x1 0x000000000040076d <+199>: cmp DWORD PTR [rbp-0x58],0x17 0x0000000000400771 <+203>: jle 0x40073d <validate+151> 0x0000000000400773 <+205>: add DWORD PTR [rbp-0x5c],0x1 0x0000000000400777 <+209>: cmp DWORD PTR [rbp-0x5c],0x2 0x000000000040077b <+213>: jle 0x400702 <validate+92> ---Type <return> to continue, or q <return> to quit--- 0x000000000040077d <+215>: movabs rax,0x7b646e6a7d756d7a 0x0000000000400787 <+225>: mov QWORD PTR [rbp-0x50],rax 0x000000000040078b <+229>: movabs rax,0x7b6f646e5f667b6f 0x0000000000400795 <+239>: mov QWORD PTR [rbp-0x48],rax 0x0000000000400799 <+243>: movabs rax,0x61677b5f7a685f7b 0x00000000004007a3 <+253>: mov QWORD PTR [rbp-0x40],rax 0x00000000004007a7 <+257>: mov BYTE PTR [rbp-0x38],0x0 0x00000000004007ab <+261>: mov DWORD PTR [rbp-0x54],0x0 0x00000000004007b2 <+268>: jmp 0x4007e0 <validate+314> 0x00000000004007b4 <+270>: mov eax,DWORD PTR [rbp-0x54] 0x00000000004007b7 <+273>: movsxd rdx,eax 0x00000000004007ba <+276>: mov rax,QWORD PTR [rbp-0x68] 0x00000000004007be <+280>: add rax,rdx 0x00000000004007c1 <+283>: movzx edx,BYTE PTR [rax] 0x00000000004007c4 <+286>: mov eax,DWORD PTR [rbp-0x54] 0x00000000004007c7 <+289>: cdqe 0x00000000004007c9 <+291>: movzx eax,BYTE PTR [rbp+rax*1-0x50] 0x00000000004007ce <+296>: cmp dl,al 0x00000000004007d0 <+298>: je 0x4007dc <validate+310> 0x00000000004007d2 <+300>: mov edi,0x0 0x00000000004007d7 <+305>: call 0x400590 <exit@plt> 0x00000000004007dc <+310>: add DWORD PTR [rbp-0x54],0x1 0x00000000004007e0 <+314>: cmp DWORD PTR [rbp-0x54],0x18 0x00000000004007e4 <+318>: jle 0x4007b4 <validate+270> 0x00000000004007e6 <+320>: mov edi,0x400be4 0x00000000004007eb <+325>: call 0x400540 <puts@plt> 0x00000000004007f0 <+330>: nop 0x00000000004007f1 <+331>: mov rax,QWORD PTR [rbp-0x8] ---Type <return> to continue, or q <return> to quit--- 0x00000000004007f5 <+335>: xor rax,QWORD PTR fs:0x28 0x00000000004007fe <+344>: je 0x400805 <validate+351> 0x0000000000400800 <+346>: call 0x400550 <__stack_chk_fail@plt> 0x0000000000400805 <+351>: leave 0x0000000000400806 <+352>: ret End of assembler dump. | cs |
10. 64-Bit Mode Instructions (64비트 모드 명령)
다음 명령은 64비트 모드에서 소개된 명령이다. 이 모드는 IA-32e 모드의 서브 모드이다.
CDQE - Convert doubleword to quadword
CMPSQ - Compare string operands
CMPXCHG16B - Compare RDX:RAX with m128
LODSQ - Load qword at address (R)SI into RAX
MOVSQ - Move qword from address (R)SI to (R)DI
MOVZX (64-bits) - Move doubleword to quadword, zero-extension
STOSQ - Store RAX at address RDI
SWAPGS - Exchanges current GS base register value with value in MSR address C0000102H
SYSCALL - Fast call to privilege level 0 system procedures
SYSRET - Return from fast system call
굿
C코드로 바꿔보았다.
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 | #include <stdio.h> int validate(char* s) { char str[]="_\'qwertyuiop{}asdfghjklzxcvbnm|"; char str2[]="zmu}jnd{o{f_ndo{{_hz_{ga"; int i,j; for(i=0; i<=2; i++) { if(s[i]<=94 || s[i]>125) // exit(0); for(j=0; j<=23; j++) { s[j]=str[s[j]-95]; } } for(i=0; i<=24; i++) { if(s[i] != str2[i]) exit(0); } printf("haha nice!"); } | cs |
분석은 알아서 하시게... 이제 풀면된다. 참 긴 여정이였다.
이제 역으로 돌려서 무엇을 넣어야 haha nice! 가 출력되는 지 알아보자...
쉽게하기위해 str2를 역으로 돌리는 코드를 짜보겟다.
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 | #include <stdio.h> #include <string.h> int main() { char str[]="_\'qwertyuiop{}asdfghjklzxcvbnm|"; char str2[]="zmu}jnd{o{f_ndo{{_hz_{ga"; int i,j,cnt; for(cnt=0; cnt<3; cnt++){ for(i=0; i<strlen(str2); i++) { for(j=0; j<strlen(str); j++){ if(str2[i]==str[j]){ str2[i]=j+95; break; } } } } printf("%s\n",str2); return 0; } | cs |
후... 굿굿!
titan ● Reversing ● 200 Points
HxD로 열어본 모습
Bin > ASC로 바꾸어본것.. 하지만 아무런 성과가 없다.
참고한 사이트 : https://www.hpcalc.org/hp48/docs/faq/48faq-6.html
Kermit의 일부 버전은 ASCII 파일과 이진 파일을 구별하기 때문에 연결의 양쪽 끝 (HP48 SX 끝과 컴퓨터 끝)에서 전송 모드에 대해 걱정해야합니다. 예를 들어, ASCII 파일을받을 때 Unix Kermit은 CR / LF 쌍을 LF로 변환해야합니다. HP48 SX가 이진 파일을 전송하지만 Unix Kermit이 ASCII를 예상하면 이진 파일의 모든 CR / LF 쌍이 LF로 변환되어 이진 파일이 손상됩니다. 불행히도, 당신은 단순히 전송을 되돌리고 Kermit이 LF를 CR / LF로 번역 할 것을 기대함으로써 손상된 이진 파일을 "uncorrupt"할 수 없습니다. 이것은 바이너리 파일이 원래 CR / LF 시퀀스의 일부가 아닌 LF의 발생을 포함 할 수 있기 때문입니다. 이진 파일이 손상되면 스택에 문자 "HPHP48-"로 시작하여 문자열로 표시되고 잔뜩 쓰레기가 계속됩니다. |
열심히 썻는데 다 날라갔네;; 하;;.... 이것도 5~6시간썻는데 결국 못품
나중에 writeup봐야겠다.
xoracle ● Crypto ● 250 Points
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/env python3 from random import randint from base64 import b64encode def xor(data, key): out = b'' for n in range(len(data)): out += bytes([data[n] ^ key[n % len(key)]]) return out def randkey(): key = b'' for n in range(randint(128, 255)): key += bytes([randint(0, 255)]) return key if __name__ == "__main__": with open('flag', 'rb') as f: data = f.read() print(b64encode(xor(data, randkey())).decode("utf-8")) | cs |
어케 푸는지 모르겠다ㅏㅏㅏㅏ
쉘스크립트를 통해 암호문을 모은다.
꽤 많이 모였다. 이제 저 중에 같은 키길이를 가지는 두 암호문을 찾아보자.
코딩은 알아서 해서... 찾았다.
1.enc와 44,90,95가 같은 키 길이를 가진다.
1.enc의 키의 길이는 172이다. 이제 키 길이는 알았으니, 비제네르 암호와 동일한 방법으로 공격하면 될 것같다.
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
ctf가 끝나버려서.. writeup을 참고
- Repeated XOR - 70 (Cryptography)
- Cracking repeating XOR key crypto
나 나름대로 정리해보겠다...고 생각하였으나; 개념은 이해가 가는데 코드짜기가 어렵다 + (이미 종료된 문제여서 더이상 암호문을 얻을수가 없다)
또... C의 길이가 1536이라는데에서 의문이 생기는데 이걸 이해할수가 없다.
'Write-up > CTF _ Write UP' 카테고리의 다른 글
[HITCON-Training] lab12 : secretgarden (0) | 2019.07.13 |
---|---|
RCTF 2018 Writeup (cpushop / babyre / Misc+) (0) | 2018.05.21 |
DEFCON CTF Quals 2018 Writeup (0) | 2018.05.14 |
[WriteUP] Byte Bandits CTF 2018 (0) | 2018.04.10 |
[TyokoWesterns] My Simple Cipher[75]
My Simple CipherProblemThis my first cipher system. Can you break it? |
cipher.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/usr/bin/python2 import sys import random key = sys.argv[1] flag = '**CENSORED**' assert len(key) == 13 assert max([ord(char) for char in key]) < 128 assert max([ord(char) for char in flag]) < 128 message = flag + "|" + key encrypted = chr(random.randint(0, 128)) for i in range(0, len(message)): encrypted += chr((ord(message[i]) + ord(key[i % len(key)]) + ord(encrypted[i])) % 128) print(encrypted.encode('hex')) | cs |
encrypted.txt 내용 7c153a474b6a2d3f7d3f7328703e6c2d243a083e2e773c45547748667c1511333f4f745e
message | key
랜덤한 0~128 사이의 아스키문자 하나를 뽑아내고 그것을 이용해 (message | key)의 첫글자를 암호화한다. 이제 암호화한걸 encrypted 문자 뒤에 덧붙이면서 간다. random.randint = encrypted[0]이고, 실제 encrypted.txt에서 가져와서 보면 "|"로 int값은 124이다.이걸... 와... 너무 설명이 귀찮고 어려워;대충 말하자면 Message = FLAG | KEY 로 구성되어 암호화에 KEY가 두번 더해지고 있음, 그걸 이용해서 풀면됨먼저 Message에 항상 "|"가 들어가므로 이걸 이용해서 Key[8]을 구하고 나머지를 순차적으로 구하면됨. 아래는 답을 구하는 소스코드를 실행하면 플래그가 나온다. key : ENJ0YHOLIDAY! TWCTF{Crypto-is-fun!}|ENJ0YHOLIDAY! 플래그 획득
123456789101112131415161718192021222324252627282930313233 #!/usr/bin/python2import sysimport randomkey = [0,0,0,0,0,0,0,0,0,0,0,0,0]encrypted_flag = '7c153a474b6a2d3f7d3f7328703e6c2d243a083e2e773c45547748667c1511333f4f745e'enc = encrypted_flag.decode('hex')key[8]=(ord(enc[22])-ord(enc[21])-ord(enc[0]))%128for j in range(0,13):for i in range(0, 13):if(key[(i+9)%13]!=0 and key[i]==0):key[i]=(ord(enc[i+23])-ord(enc[i+22])-key[(i+9)%13])%128skey=''for i in range(0,13):skey+=chr(key[i])print("key : "+skey)#deciphermessage = ''for i in range(1, len(enc)):message += chr((ord(enc[i])-ord(enc[i-1])-ord(skey[(i-1)%13])) % 128)#encrypted += chr((ord(message[i]) + ord(key[i % len(key)]) + ord(encrypted[i])) % 128)print(message)
'Write-up > Crypto' 카테고리의 다른 글
[Byte Bandits CTF 2018] R u Ronald Rivest? 70p (0) | 2018.04.27 |
---|---|
[UIUCTF 2018] xoracle (250) (0) | 2018.04.18 |
[anstromCTF 2017] Knock Knock (0) | 2017.04.25 |
[anstromCTF 2017] Descriptions (2) | 2017.04.25 |
[anstromCTF 2017] Substitution Cipher (0) | 2017.04.25 |
난해한 프로그래밍 언어
나무위키에 나온 난해한 프로그래밍 언어...
https://namu.wiki/w/%EB%82%9C%ED%95%B4%ED%95%9C%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%20%EC%96%B8%EC%96%B4
Bugs_BunnyCTF에서 나온 문제 중 하나
Crypto-20 Decode the message ! |
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>----. >+++++++++++++++++. --------------. ++++++++++++. --------------------. <. >++++++++++++++++++++++. -------. . +++++++++++. ++. <. >---------. <--------------. ---. +++++++++++++++++++++++++++++. +++++++++++++++++. -------------------------. >+++. <<++++++++++++. . >>++++++++. |
브레인퍽이란 언어...
https://namu.wiki/w/BrainFuck?from=%EB%B8%8C%EB%A0%88%EC%9D%B8%ED%8D%BD
브레인퍽 인터프리터
https://sange.fi/esoteric/brainfuck/impl/interp/i.html
답 : Bugs_Bunny{Br41N_Fu**}
'Write-up > Misc (+ Forensic, Stegano)' 카테고리의 다른 글
[MeePwnCTF 2018] White Snow, Black Shadow (0) | 2018.07.16 |
---|---|
RCTF 2018 Number Game, Bulls and Cows Solver (0) | 2018.05.21 |
[anstromCTF 2017] USB Encryption (0) | 2017.04.26 |
[anstromCTF 2017] Document (0) | 2017.04.26 |
[anstromCTF 2017] IMAGE TRICKERY (0) | 2017.04.26 |
[anstromCTF 2017] USB Encryption
USB ENCRYPTIONFORENSICS, 30We've made a copy of defund's flash drive, which seems to be protected by a usb encryption software. Retrieve the flag. Not really a hint, but this is an actual software. |
위 문제에서 DEFUND.dmg라는 파일을 제공해준다.
AccessData FTK Imager 을 이용하여 dmg 파일을 열어보았다.
뭔가 많다.
그 USB encryption software라는건 USBSecurity.exe 라는 걸로.. 진짜 있는 프로그램이다...(!???)
뭐;; 알바없고
열어서 [root]/Thumbs.us/com1.{~~~}/~~/~~/flag.txt를 발견
actf{not_quite_usb_encryption}
와~ 끝;;
'Write-up > Misc (+ Forensic, Stegano)' 카테고리의 다른 글
RCTF 2018 Number Game, Bulls and Cows Solver (0) | 2018.05.21 |
---|---|
난해한 프로그래밍 언어 (0) | 2017.08.01 |
[anstromCTF 2017] Document (0) | 2017.04.26 |
[anstromCTF 2017] IMAGE TRICKERY (0) | 2017.04.26 |
[ch4n3] Stegano_Dark (Steganography) (스테가노그래피 더 설명해줘) (0) | 2017.03.08 |
[anstromCTF 2017] Document
DOCUMENTFORENSICS, 60Defund wrecked his essay in a text editor to pretend that his file got corrupted. No hint. |
docx 파일 복구!
자세한건 귀찮으니 생략;
뭐 대충 hxd로 열어서 헤더파일 만들어 넣고
어짜피 여기서 해서 뭐 얼마나 더 괜찮게 되겠으...
zip파일로 열어서 document.xml로 걍 찾아봄 ㅇㅇ.. 결과는 굿.. 있었음
actf{too_bad_for_zip_recovery}
'Write-up > Misc (+ Forensic, Stegano)' 카테고리의 다른 글
난해한 프로그래밍 언어 (0) | 2017.08.01 |
---|---|
[anstromCTF 2017] USB Encryption (0) | 2017.04.26 |
[anstromCTF 2017] IMAGE TRICKERY (0) | 2017.04.26 |
[ch4n3] Stegano_Dark (Steganography) (스테가노그래피 더 설명해줘) (0) | 2017.03.08 |
[ch4n3] 나잡아봐라~~ (Steganography) (0) | 2017.03.08 |
[anstromCTF 2017] IMAGE TRICKERY
IMAGE TRICKERYFORENSICS, 50What do Twitch emotes have to do with a CTF? No idea, but there's a flag in here somewhere. *kappa* The colours in this image are just stunning. |
IMAGE TRICKERY
문제
이미지가 하얀색으로만 덮여있는것처럼 보이지만 픽셀값을 살펴보면 아님 ㅇㅇ...
귀찮아서... 툴도 없고 해서 그냥 일단 그림판으로 대충 칠함
그러니까 QR코드가 나옴
https://webqr.com/index.html
여기서 QR코드 올려서 어떤거 나오는지 봄
=> 결과
http://pastebin.com/S9De6WYA
라는 값이 나옴.. QR코드 해석한 결과임
안에 들어가봄
base64값으로 보이는 RAW값이 있음
base64 디코딩해봄
RAW => 디코딩
data:image/svg+xml;base64, (base64값)
뭔가 또 나옴...
또 디코딩해보니까 svg+xml이 나옴 ㅇㅇ
xml로 저장해서 열어서 보면
왠 북극봄이 꼬깔콘같은 그거 뒤집어쓰고 PARTY HARD하면서
actf{fa1L_F15H} 라고 그림판으로 글씨쓴거처럼 되있음
'Write-up > Misc (+ Forensic, Stegano)' 카테고리의 다른 글
[anstromCTF 2017] USB Encryption (0) | 2017.04.26 |
---|---|
[anstromCTF 2017] Document (0) | 2017.04.26 |
[ch4n3] Stegano_Dark (Steganography) (스테가노그래피 더 설명해줘) (0) | 2017.03.08 |
[ch4n3] 나잡아봐라~~ (Steganography) (0) | 2017.03.08 |
[ch4n3] Brute-Force (Misc) (0) | 2017.03.08 |
[anstromCTF 2017] Knock Knock
KNOCK KNOCKCRYPTO, 30You have come across a strange audio recording. Can you recover the flag? Note: The flag is not in the actf{} format. Google is your friend. |
... 망할 힌트있는줄 몰랐는데 방금 알음;;
Tap code 라 불리는 암호임...
참조 : https://en.wikipedia.org/wiki/Tap_code
GoldWave나 등등의 툴로 열어보든 아니면 직접 들어보든해서 들어보면
한번당 Knock 소리를 기록할수 있음
Roman alphabet tap code | |||||
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | A | B | C/K | D | E |
2 | F | G | H | I | J |
3 | L | M | N | O | P |
4 | Q | R | S | T | U |
5 | V | W | X | Y | Z |
The tap code table |
2 3 1 5 3 1 3 5 3 2 1 5 3 5 3 1 1 5 1 1 4 3 1 5 임...
이걸 2개씩 묶음 그리고 옆 표대로 하면 됨
(2, 3) h
(1, 5) e
(3, 1) l
(3, 5) p
(3, 2) m
(1, 5) e
(3, 5) p
(3, 1) l
(1, 5) e
(1, 1) a
(4, 3) s
(1, 5) e
flag : helpmeplease
'Write-up > Crypto' 카테고리의 다른 글
[UIUCTF 2018] xoracle (250) (0) | 2018.04.18 |
---|---|
[TyokoWesterns] My Simple Cipher[75] (0) | 2017.09.02 |
[anstromCTF 2017] Descriptions (2) | 2017.04.25 |
[anstromCTF 2017] Substitution Cipher (0) | 2017.04.25 |
[ch4n3] How are you? I'm XOR XOR.. (Crypto) (0) | 2017.03.08 |
[anstromCTF 2017] Descriptions
DESCRIPTIONSCRYPTO, 50We have found what appear to be nonsensical phrases. However, we believe that the author likes to hide secret messages using nonsensical phrases about animals. Please help us find what the secret message is. The writer seems obsessed with categorizing words. |
The horse was a small falcon runner.
The horse was a huge goat pitcher.
The pig is a quick falcon singer.
The goat was a quick sheep speaker.
The sheep is the big goat pitcher.
The sheep was a slow sheep hitter.
The horse is a tiny goat dancer.
A cow is the huge bluejay dancer.
The falcon is the fast sheep pitcher.
The pig was a speedy falcon pitcher.
The pig was the speedy goat singer.
The goat was a huge sheep hitter.
The horse was the speedy sheep runner.
The cow was a speedy bluejay singer.
A sheep is a small falcon catcher.
The cow was the fast cow singer.
The goat was a sluggish sheep catcher.
The goat is the slow robin catcher.
단어가 반복되고 같은 종류의 말들이 사용되는 것으로 보아 아마 같은 단어(종류)들은 같은 정보(비트)를 가질것이다.
또 한 문장이 7개의 단어들로 나누어져있음을 알 수 있다.
분류 시작
----------------------
The : 1
A : 0
----------------------
네발 동물(육지) : 1
horse, pig, goat, sheep, cow
----------------------
두발 동물(공중) : 0
falcon, bluejay, robin
----------------------
is : 1
was : 0
----------------------
크기 : 0
big, huge, small, tiny
----------------------
속도 : 1
speedy, fast. slow, sluggish
----------------------
야구 : 1
runner, catcher, pitcher, hitter
----------------------
노래 : 0
singer, dancer, speaker
----------------------
The horse was a small falcon runner.
1 1 0 0 0 0 1
....
....
....
1100001 a
1100011 c
1110100 t
1100110 f
1111011 {
1100111 g
1110010 r
0111000 8
1011111 _
1100101 e
1101110 n
1100011 c
1101111 o
1100100 d
0110001 1
1101110 n
1100111 g
1111101 }
actf{gr8_encod1ng}
'Write-up > Crypto' 카테고리의 다른 글
[TyokoWesterns] My Simple Cipher[75] (0) | 2017.09.02 |
---|---|
[anstromCTF 2017] Knock Knock (0) | 2017.04.25 |
[anstromCTF 2017] Substitution Cipher (0) | 2017.04.25 |
[ch4n3] How are you? I'm XOR XOR.. (Crypto) (0) | 2017.03.08 |
[ch4n3] King Sejong (Crypto) (0) | 2017.03.08 |