분류 전체보기
- SQL Injection Payload List 2019.11.21
- IDA 단축키 2019.11.09
- ECC calculator 2019.11.02
- RSA LSB Oracle Attack ( + 키 값 계속 바뀔 시도 가능) 2019.10.12
- [PIE & Full RELRO] PIE Leak 하기 2019.10.10
- [Leak Technology] Leak by stdout 2019.10.10
- _dl_fini exploit (_rtld_global) 2019.10.09
- z3 사용 2019.09.23 1
- [SEC-T CTF 2019] Trivial RSA 2019.09.22
- [Crypto] CTR 모드 공격 Break fixed-nonce CTR 2019.09.17
SQL Injection Payload List
'Web & Network' 카테고리의 다른 글
Cloud9 사용 (0) | 2019.05.21 |
---|---|
[WebHacking] Hydra 툴 (0) | 2019.02.04 |
[Web] 내장함수 사전(php.net) (0) | 2017.07.02 |
[Web] HTML entity (0) | 2017.07.02 |
SQL 인젝션 (0) | 2017.07.02 |
IDA 단축키
ECC calculator
RSA LSB Oracle Attack ( + 키 값 계속 바뀔 시도 가능)
RSA LSB Oracle Attack에서 키값이 바뀌거나 고정되어있을때 공격할 수 있는 방법이다.
이전과 다른 점은 N값이 계속 바뀐다는 점인데, 이는 한 비트씩 추출하는 방법으로 풀 수 있다.
2의 제곱들의 역원을 이용해서 한비트씩 추출해내는 방법으로 문제를 푸는 것인데,
기존의 LSB Attack 공격에 쓰이는 방법과 비교했을때, (기존에 이 블로그 writeup에 쓰인 방법들은 이진탐색 방법이였다.)
한 bit씩 추출하여 flag를 찾아낸다는 점에서 더 괜찮은 공격방법일 수 있다.
생각해보니 이 방법 자체가 엄청 좋은 것같다. ㅎㅎ...
example server
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 | from Crypto.PublicKey import RSA from Crypto.Util.number import long_to_bytes, bytes_to_long menu = """ 1. Get PublicKey 2. Encrypt 3. Decrypt 4. Print FLAG """ with open("./flag", "r") as f: flag = f.read().strip() privkey = RSA.generate(1024) N = privkey.n e = privkey.e d = privkey.d def encrypt(p): return pow(p, e, N) def decrypt(c): return pow(c, d, N)%2 def main(): global N,e,d print(menu.strip()) choice = int(input("> ")) if choice == 1: print("n is "+str(N)) print("e is "+str(e)) elif choice == 2: data = raw_input("msg : ") print("enc : "+str(encrypt(bytes_to_long(data)))) elif choice == 3: data = input("msg (demical number) : ") print("dec : "+str(decrypt(data))) privkey = RSA.generate(1024) N = privkey.n e = privkey.e d = privkey.d elif choice == 4: print(str(encrypt(bytes_to_long(flag)))) else: print("invalid menu") welcome = """ /$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$$ /$$$$$$$$ /$$ /$$ | $$__ $$ /$$__ $$ /$$__ $$ /$$__ $$| $$ /$$//$$__ $$|__ $$__/| $$_____/| $$$ /$$$ | $$ \ $$| $$ \__/| $$ \ $$ | $$ \__/ \ $$ /$$/| $$ \__/ | $$ | $$ | $$$$ /$$$$ | $$$$$$$/| $$$$$$ | $$$$$$$$ | $$$$$$ \ $$$$/ | $$$$$$ | $$ | $$$$$ | $$ $$/$$ $$ | $$__ $$ \____ $$| $$__ $$ \____ $$ \ $$/ \____ $$ | $$ | $$__/ | $$ $$$| $$ | $$ \ $$ /$$ \ $$| $$ | $$ /$$ \ $$ | $$ /$$ \ $$ | $$ | $$ | $$\ $ | $$ | $$ | $$| $$$$$$/| $$ | $$ | $$$$$$/ | $$ | $$$$$$/ | $$ | $$$$$$$$| $$ \/ | $$ |__/ |__/ \______/ |__/ |__/ \______/ |__/ \______/ |__/ |________/|__/ |__/ version 3.2.7 """ print(privkey.d) if __name__ == '__main__': print(welcome) while True: try: main() except: break | cs |
attack code
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 Crypto.Util.number import * from Crypto.PublicKey import RSA from pwn import * conn = process(["python", "server.py"]) def get_key(): conn.sendlineafter("4. Print FLAG", "1") conn.recvuntil("n is ") return int(conn.recvline().strip()) def get_flag(): conn.sendlineafter("4. Print FLAG", "4") conn.recvuntil("> ") return int(conn.recvline().strip()) def decrypt(ct): conn.sendlineafter("4. Print FLAG", "3") conn.sendline(str(ct)) conn.recvuntil("dec : ") result = int(conn.recvline().strip()) return result flag_enc = get_flag() init_N = get_key() # Public exponent e = 65537 bits = "1" flag = "" i = 1 while True: enc = get_flag() N = get_key() inv = inverse(2**i, N) chosen_ct = (enc*pow(inv, e, N))%N output = decrypt(chosen_ct) flag_char = (output - ((int(bits, 2)*inv) % N)) % 2 bits = str(flag_char) + bits if len(bits) % 8 == 0: flag = long_to_bytes(int(bits, 2)) print(flag) if flag_enc == pow(int(bits, 2), e,init_N): break i+=1 | cs |
'Crypto' 카테고리의 다른 글
오라클 패딩 공격 (Oracle Padding Attack) (0) | 2020.04.12 |
---|---|
ECC calculator (0) | 2019.11.02 |
[Crypto] CTR 모드 공격 Break fixed-nonce CTR (0) | 2019.09.17 |
JohnTheRipper Password 크랙 재시도가 안될시 해결법 (0) | 2018.11.27 |
배낭암호(Knapshot) (0) | 2018.11.26 |
[PIE & Full RELRO] PIE Leak 하기
[Leak Technology] Leak by stdout
_dl_fini exploit (_rtld_global)
참고 원문 : https://st4nw.github.io/2019-09-02/dlfini/
main -> libc_start_main -> exit -> run_exit_handlers
main의 리턴은 libc_start_main으로 향하고, libc_start_main은 exit을 호출하는데, 이 exit에서 __run_exit_handlers를 호출하여 소멸자를 호출하는 루틴에서 라이브러리의 특정 주소를 덮어쓸 수 있다면 _dl_fini 루틴에서 원하는 흐름으로 넘어갈 수 있는 익스 방법
void
exit (int status)
{
__run_exit_handlers (status, &__exit_funcs, true, true);
}
libc_hidden_def (exit)
_dl_fini
__run_exit_handler가 호출하는 _dl_fini가 실질적인 소멸자 호출을 담당하게된다. 서버환경과 사용하는 라이브러리에 따라 _dl_fini의 루틴도 다르기때문에 문제풀이 및 익스시에는 환경에 맞춰 분석을 해야한다.
0x7ffff7de7dc9 <_dl_fini+777>: mov r12,QWORD PTR [rax+0x8]
0x7ffff7de7dcd <_dl_fini+781>: mov rax,QWORD PTR [rbx+0x120]
0x7ffff7de7dd4 <_dl_fini+788>: add r12,QWORD PTR [rbx]
0x7ffff7de7dd7 <_dl_fini+791>: mov rdx,QWORD PTR [rax+0x8]
0x7ffff7de7ddb <_dl_fini+795>: shr rdx,0x3
0x7ffff7de7ddf <_dl_fini+799>: test edx,edx
0x7ffff7de7de1 <_dl_fini+801>: lea r13d,[rdx-0x1]
0x7ffff7de7de5 <_dl_fini+805>: je 0x7ffff7de7e00 <_dl_fini+832>
0x7ffff7de7de7 <_dl_fini+807>: nop WORD PTR [rax+rax*1+0x0]
0x7ffff7de7df0 <_dl_fini+816>: mov edx,r13d
0x7ffff7de7df3 <_dl_fini+819>: call QWORD PTR [r12+rdx*8]
위에서처럼 call을 통해 흐름을 바꿀 수 있는 부분이 있기때문에 위 부분이 가리키는 곳이 항상 같은지 동적으로 체크하여 해당 부분을 덮어서 exploit을 실행할 수 있다.
위 경우외에도 _dl_fini 루틴중 다음과 같은 부분이 있다면 _rtld_global+3840을 덮고, exit가 실행되면 원하는 흐름으로 바꿀 수 있다.
0x7ffff7de5a02 <_dl_fini+98>:
lea rdi,[rip+0x217f5f] # 0x7ffff7ffd968 <_rtld_global+2312>
0x7ffff7de5a09 <_dl_fini+105>:
call QWORD PTR [rip+0x218551] # 0x7ffff7ffdf60 <_rtld_global+3840>
0x7ffff7de5a0f <_dl_fini+111>: mov edx,DWORD PTR [rbx+0x8]
0x7ffff7de5a12 <_dl_fini+114>: test edx,edx
0x7ffff7de5a14 <_dl_fini+116>: je 0x7ffff7de59e0 <_dl_fini+64>
0x7ffff7de5a16 <_dl_fini+118>: mov rax,QWORD PTR [rbx]
0x7ffff7de5a19 <_dl_fini+121>: movzx r13d,BYTE PTR [rax+0x315]
동적으로 한줄씩 실행시키면서 분석하는 것이 제일 나은 방법인 것 같다.... 아니면 해당 부분에 breakpoint를 걸거나 해서 분석
'Pwnable!!' 카테고리의 다른 글
[PIE & Full RELRO] PIE Leak 하기 (0) | 2019.10.10 |
---|---|
[Leak Technology] Leak by stdout (0) | 2019.10.10 |
[ 19.04 ] glibc 2.29 heap exploit 관련 (0) | 2019.07.22 |
[Linux] gdb로 PIE 디버깅 (0) | 2019.07.22 |
[glibc] malloc - fastbin size check 분석 : malloc(): memory corruption (fast) (0) | 2019.07.13 |
z3 사용
from z3 import *s = Solver()x1 = Int('x1')x2 = Int('x2')x3 = Int('x3')x4 = Int('x4')x5 = Int('x5')s.add(x1 + x2 + x3 + x4 + x5 == x1*x2*x3*x4*x5)print s.check()print s.model()
123456789101112131415 from z3 import *s = Solver()# 변수들x1 = Int('x1')x2 = Int('x2')x3 = Int('x3')x4 = Int('x4')x5 = Int('x5')s.add(x1 + x2 + x3 + x4 + x5 == x1*x2*x3*x4*x5) # 조건식print s.check()print s.model()cs
'Reversing' 카테고리의 다른 글
Sage n차 방정식 해 구하기 (mod n) feat. whitehatcontest2022(suspicious_signature) (0) | 2022.10.18 |
---|---|
[rev] LazyKLEE / Symbolic Execution Engine (0) | 2022.10.18 |
angr이란 (1) | 2018.04.28 |
[SEC-T CTF 2019] Trivial RSA
[Crypto] CTR 모드 공격 Break fixed-nonce CTR
시간이 없어 암호 공부를 얼마간 못하다가 다시 시작하였습니다. 이번에는 CTR모드에 대해, 그리고 고정된 nonce를 사용하는 CTR모드
를 공격하는 방법에 대해 알아보겠습니다. 참고로 공격대상이 되는 데이터는 영어평문문장입니다.
먼저 CTR모드에 대해 알아보겠습니다.
CTR(Counter)
카운터(Counter, CTR) 방식은 블록 암호
를 스트림 암호
로 바꿔주는 구조를 가집니다. CTR모드에서는 각 블록마다 현재 블록이 몇 번째인지 값을 얻어, 그 숫자(count)와 nonce를 결합하여 블록 암호의 입력으로 사용합니다. 그렇게 각 암호화를 통해 연속적인 난수를 얻은 다음 암호화하려는 문자열과 XOR하는 방식입니다.
이렇게 되면 CTR모드는 각 블록의 암호화 및 복호화가 이전 블록에 의존하지 않으며, 따라서 병렬적으로 동작하는 것이 가능해집니다. 이것은 암호화 및 복호화의 속도가 타모드에 비해 매우 빠르다는 것을 의미합니다. 이전에 있던 모드들은(CBC, CFB, OFB와 같은) 블록의 암호화 및 복호화가 이전 블록에 의존되게 때문에 각 블록이 독립적으로 동작할 수 없고, 때문에 암호화와 복호화가 순차적으로 이루어져야했습니다. 또한 암호화된 문자열 중 원하는 부분만 골라 복호화하는 것이 불가능하였으나, CTF모드에서는 이것이 가능합니다.
* 정리
- 블록마다 1씩 증가하는 counter와 nonce를 결합하여 암호화하여 키 스트림을 만든다.
- 키 스트림과 평문 블록을 XOR한 결과가 암호문 블록이다.
- 블록 암호를 스트림 암호구조로 바꿔준다.
- 암호화와 복호화가 같은 구조다. (XOR암호)
- 병렬처리가 가능하다. (임의의 블록만 암/복호화가 가능하다)
- Error propagation : 각 블록이 독립적이므로, 에러가 다른 블록으로 전파되지않는다.
자. 이제 CTR모드에 대해 알아보았으니, 이 모드에서 고정된 nonce를 사용할 경우 어떻게 공격할 수 있는지에 대해 살펴보겠습니다.
먼저 위에서 살펴보았듯이 CTR모드를 사용하게되면 블록암호를 스트림암호방식으로 사용할 수 있습니다. 즉, 패딩이 불필요해지고, 키스트림을 생성하고 나면 XOR암호화 동일해집니다.
그럼 이제 남은 일은 이 XOR암호
를 공격하는 것입니다. 고정된 nonce인 경우, 여러개의 데이터를 암호화하게 되면 같은 counter값
을 가진 구간에 대해선 모두 같은 키스트림을 가지고 XOR암호화되게 됩니다.
위와 같이 여러개의 데이터가 있을 때, 각 데이터의 첫번째 블록은 고정된 nonce | counter
으로 만들어진 키스트림과 XOR을 통해 암호화되게 됩니다. 이 때 nonce
가 고정되어있고, counter
값은 블록의 인덱스를 나타내므로 각 데이터의 블록들은 모두 각각 같은 키스트림을 가지게됩니다.
그렇다면 각 데이터에서 같은 인덱스의 블록들을 모은다면, 같은 키스트림을 가지는 암호문 리스트를 얻을 수 있습니다.
키스트림의 길이는 블록길이와 같으므로, XOR암호
에서 키 사이즈는 BLOCKSIZE
입니다. 여기서는 블록암호로 AES-128
을 사용하였으므로, 키 사이즈는 16입니다. 이제 Muliple XOR Cipher
을 풀 차례입니다. 그러나 키 길이를 알 고 있으므로 저희는 이것을 Single XOR Cipher
로 바꿀 수 있습니다. 키길이가 16이면, XOR수행시 같은 바이트값, 즉 SingleXorByte
가 16byte마다 나타나는 것을 알 수 있습니다. 그러므로 이번에는 바이트단위로 암호문을 나누어 다시 새롭게 배열합니다.
아래는 만약 KEY가 XOR
인 keySize가 3일 때를 나타내는 예시입니다.
위의 같은 색으로 칠해진 부분은 같은 단일 KEYBYTE
에 의해 암호화됩니다. 그러므로 위 Ciphertext
를 아래와 같이 새롭게 정렬해줄 수 있습니다.
이제 새롭게 정렬된 Ciphertext
를 Single XOR Cipher
공격으로 풀면 됩니다. 공격은 기본 BruteForce
로 정확도를 높이기 위해 AlphabetScoring
방식으로 진행합니다.
이제 각각에 대해 AlphabetScoring
을 통해 KEYSTEAM을 알아낼 수 있습니다.
그럼 이제 실전으로 들어가보겠습니다. 먼저 AES-CTR
암호화에 사용할 데이터를 40개 준비합니다.
SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==
Q29taW5nIHdpdGggdml2aWQgZmFjZXM=
RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==
RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=
SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk
T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=
UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=
T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl
VG8gcGxlYXNlIGEgY29tcGFuaW9u
QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==
QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=
QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==
QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo=
QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA==
SW4gaWdub3JhbnQgZ29vZCB3aWxsLA==
SGVyIG5pZ2h0cyBpbiBhcmd1bWVudA==
VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==
V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==
V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==
U2hlIHJvZGUgdG8gaGFycmllcnM/
VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=
QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=
VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=
V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=
SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==
U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==
U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=
VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==
QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu
SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=
VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs
WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=
SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0
SW4gdGhlIGNhc3VhbCBjb21lZHk7
SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=
VHJhbnNmb3JtZWQgdXR0ZXJseTo=
QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
base64로 인코딩된 평문을 40개 준비하였습니다. 이제 base64로 디코딩하여 평문을 40개 리스트에 넣고, 이를 AES_CTR
로 암호화시켜 암호문 배열을 만들겠습니다.
plainlist = open("data.txt", "r").readlines()
plainlist = [b64decode(x) for x in plainlist]
cipherlist = [AES_CTR(x, KEY, nonce) for x in plainlist]
이제 암호문을 Coulumn
으로 나눠서 다시 정렬하여, 위에서 설명했던 대로 AlphabetScoring
을 통해 키를 구합니다.
def get_keyString(ciphers):
keyString = ""
for nColumnCipher in ciphers:
Max_score = 0.0
key = 0
for sbyte in range(0,256):
nomal_string = XOR_singleByte(nColumnCipher, sbyte)
score = alphabet_score(nomal_string)
if score > Max_score:
Max_score = score
key = sbyte
keyString += chr(key)
return keyString
maxLen = max([len(x) for x in cipherlist])
print("maxLen : %d " % maxLen)
nColumnCipher = []
for n in range(0, maxLen):
nColumn = ""
for c in cipherlist:
if len(c) > n:
nColumn += c[n]
nColumnCipher.append(nColumn)
keyString = get_keyString(nColumnCipher)
결과를 한번 확인해보겠습니다.
decrypt_list = [XOR_with_Key(ciph, keyString) for ciph in cipherlist]
for i, decrpyt in enumerate(decrypt_list):
print("%d : %s" %(i, decrpyt))
대체로 성공적으로 복호화 완료된 것을 볼 수 있습니다. 뒷 부분은 평문이 제대로 복호화가 되지않는 결과가 조금씩 보이는데, 이것은 각 Coulumn
으로 정렬하는데 있어 데이터가 부족하여 생긴 결과입니다. 이 부분은 어쩔 수 없이 수동으로 조금 씩 맞춰주거나, 아니면 단어를 가지고 Scoring
을 수행하던지 해야하는 부분입니다. 저는 이 부분을 Fix_keyString
이란 함수를 만들어 처리하였지만, 여기서는 설명하지않도록 하겠습니다.
이렇게 CTR
모드의 공격에 대한 설명을 마치겠습니다. 아래는 CTR
모드의 공격을 테스트하는 전체코드입니다.
* 전체코드
from pwn import p64
from base64 import b64decode
from Crypto.Cipher import AES
import os
#Letter Distribution - Exterior Memory http://www.macfreek.nl/memory/Letter_Distribution
freq = {
' ' : 18.28846265,
'E' : 10.26665037,
'T' : 7.51699827,
'A' : 6.53216702,
'O' : 6.15957725,
'N' : 5.71201113,
'I' : 5.66844326,
'S' : 5.31700534,
'R' : 4.98790855,
'H' : 4.97856396,
'L' : 3.31754796,
'D' : 3.28292310,
'U' : 2.27579536,
'C' : 2.23367596,
'M' : 2.02656783,
'F' : 1.98306716,
'W' : 1.70389377,
'G' : 1.62490441,
'P' : 1.50432428,
'Y' : 1.42766662,
'B' : 1.25888074,
'V' : 0.79611644,
'K' : 0.56096272,
'X' : 0.14092016,
'J' : 0.09752181,
'Q' : 0.08367550,
'Z' : 0.05128469,
}
def alphabet_score(stringA):
score = 0.0
for c in stringA:
c=c.upper()
if c in freq:
score+=freq[c]
return score
def XOR_singleByte(str1, sbyte):
str1 = str1.encode("hex")
result = ""
for i in range(0,len(str1),2):
h1 = int(str1[i:i+2],16)
h2 = sbyte
result+= '{:02x}'.format(h1^h2)
return result.decode("hex")
KEY = os.urandom(16)
nonce = p64(0)
BLOCK_SIZE = 16
def XOR_with_Key(str1, Key):
str1 = str1.encode("hex")
result = ""
for i in range(0,len(str1),2):
h1 = int(str1[i:i+2],16)
h2 = ord(Key[(i/2)%len(Key)])
result+= '{:02x}'.format(h1^h2)
return result.decode("hex")
def AES_ecb_encrypt(plain, key):
obj = AES.new(key, AES.MODE_ECB)
cipher = obj.encrypt(plain)
return cipher
def AES_CTR(data, key, nonce):
xor_data = ""
cnt = 0
for i in range(0, len(data), BLOCK_SIZE):
input = nonce + p64(cnt)
xor_data += AES_ecb_encrypt(input, key)
cnt+=1
processing_data = XOR_with_Key(data, xor_data)
return processing_data
def get_keyString(ciphers):
keyString = ""
for nColumnCipher in ciphers:
Max_score = 0.0
key = 0
for sbyte in range(0,256):
nomal_string = XOR_singleByte(nColumnCipher, sbyte)
score = alphabet_score(nomal_string)
if score > Max_score:
Max_score = score
key = sbyte
keyString += chr(key)
return keyString
def Fix_keyString(keyString, cipher, fix_plain):
decrypt = XOR_with_Key(cipher, keyString)
fix = XOR_with_Key(decrypt, fix_plain)
fix_keyString = XOR_with_Key(keyString, fix)
return fix_keyString
def main():
plainlist = open("data.txt", "r").readlines()
plainlist = [b64decode(x) for x in plainlist]
cipherlist = [AES_CTR(x, KEY, nonce) for x in plainlist]
maxLen = max([len(x) for x in cipherlist])
print("maxLen : %d " % maxLen)
nColumnCipher = []
for n in range(0, maxLen):
nColumn = ""
for c in cipherlist:
if len(c) > n:
nColumn += c[n]
nColumnCipher.append(nColumn)
keyString = get_keyString(nColumnCipher)
keyString = Fix_keyString(keyString, cipherlist[0], "I have met them at close of day")
keyString = Fix_keyString(keyString, cipherlist[25], "This other his helper and friend")
decrypt_list = [XOR_with_Key(ciph, keyString) for ciph in cipherlist]
for i, decrpyt in enumerate(decrypt_list):
print("%d : %s" %(i, decrpyt))
# compare to original_plain & decrypt_plain
for original, decrpyt in zip(plainlist, decrypt_list):
print("o : " + original)
print("d : " + decrpyt)
if __name__ == '__main__':
main()
'Crypto' 카테고리의 다른 글
ECC calculator (0) | 2019.11.02 |
---|---|
RSA LSB Oracle Attack ( + 키 값 계속 바뀔 시도 가능) (0) | 2019.10.12 |
JohnTheRipper Password 크랙 재시도가 안될시 해결법 (0) | 2018.11.27 |
배낭암호(Knapshot) (0) | 2018.11.26 |
An ECB/CBC Mode and ECB Attack (0) | 2018.08.10 |