제리의 블로그

picoCTF 2018 quackme up Reversing 본문

CTF/reversing

picoCTF 2018 quackme up Reversing

j3rrry 2018. 10. 9. 20:40

quackme up - Points: 350 - (Solves: 323)


요약

주어진 바이너리를 실행시켜보니
문자열을 입력받아서 encrypt 된 ciphertext 를 보여주는 프로그램 이었습니다.

맞는 문자열을 넣었을 때 나오게 되는 ciphertext 는 "11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 45 20 35 05 70 20 95 50 C1" 입니다.

임의로 문자열을 넣어보니 몇가지 사실을 유추해볼 수 있는데요.
1. 입력 문자열과 출력 ciphertext 의 길이는 동일하다
2. encrypt 알고리즘은 입력 문자가 같으면 출력 문자도 같다.

plaintext 와 ciphertext 가 각각 문자마다 1 대 1 매칭임을 알았으므로
모든 문자를 1개씩 넣어본 결과를 토대로
플래그를 알아냈습니다.



Description

The duck puns continue.
Can you crack, I mean quack this program as well?
You can find the program in /problems/quackme-up_1_6511dc9aa02307b2cc53c5dd9fdfdc75 on the shell server.




Writeup

# file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=29975be87b2ffffa12286e5069470357dff7ab24, not stripped
주어진 파일은 32비트 바이너리였습니다.




# ./main
We're moving along swimmingly. Is this one too fowl for you?
Enter text to encrypt: j1rrry
Here's your ciphertext: B0 05 31 31 31 81
Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 45 20 35 05 70 20 95 50 C1
That's all folks.
문자를 입력받아서 encrypt 를 진행하고
Here's your ciphertext 라며 입력에 대한 결과를 보여줍니다.
그리고 Now quack it! 이라면서 목표 ciphertext 를 알려줍니다.



일단 입력 길이에 따라서 ciphertext 의 길이도 동일하게 나옵니다.
그리고 "r" 을 3번 입력했는데 "31" 로 똑같이 출력된 것으로 보아
앞 뒤의 문자와 연계되지 않고 문자 하나하나 동일하게 encrypt 되고 있다고 유추할 수 있습니다.





# ./main
We're moving along swimmingly. Is this one too fowl for you?
Enter text to encrypt: picoCTF{
Here's your ciphertext: 11 80 20 E0 22 53 72 A1
Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 45 20 35 05 70 20 95 50 C1
That's all folks.
플래그 값 포맷으로 입력을 해본 모습입니다.

역시 접근자체는 지금까지 아주 좋습니다.



저의 풀이 방법은 이렇습니다.
모든 문자(ascii code 0x20 ~ 0x7E)에 대하여 한번씩 문자를 넣어봐서
"11" "80" "20" "E0" "22" "53" "72" "A1" "01" "41" "55" "20" "A0" "C0" "25" "E3" "45" "35" "05" "70" "20" "95" "50" "C1" 에 대응하는 값을 찾을 것입니다.





# python a.py
('1', '05')
('2', '35')
('3', '25')
('4', '55')
('5', '45')
('8', '95')
('C', '22')
('F', '72')
('T', '53')
('_', 'E3')
('c', '20')
('d', '50')
('f', '70')
('i', '80')
('k', 'A0')
('m', 'C0')
('o', 'E0')
('p', '11')
('q', '01')
('u', '41')
('{', 'A1')
('}', 'C1')
0x20 ~ 0x7e 까지의 ascii code 를 돌려본 결과입니다.
왼쪽이 입력 문자이고 오른쪽이 ciphertext 입니다.
대문자 'CTF' 도 있고
띄어쓰기 대신 쓰이는 '_'(언더바) 도 보이고
플래그 포맷에 필요한 '{', '}' 괄호도 보입니다.



플래그

# python a.py
picoCTF{qu4ckm3_5c21fc8d}

코드

from pwn import *

context.log_level = 'error'

goal = '11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 45 20 35 05 70 20 95 50 C1'

# ascii code 0x20 ~ 0x7e
found = []                  # found table
for i in range(0x20, 0x7f):
    p = process('./main')
    #p.recvuntil(': ')
    p.sendline(chr(i))
    p.recvuntil('xt: ')
    ciphertext = p.recvline().strip()
    if ciphertext in goal.split():    # if matched
        found.append((chr(i), ciphertext))
    p.close()

# make FLAG
for f in found:
    goal = goal.replace(f[1], f[0])

print(goal.replace(' ', ''))


Comments