본문 바로가기

wargame/reversing.kr

[Revesing.kr]Easy Keygen 풀이

반응형

Easy Keygen 풀이입니다.

더보기

문제 파일을 받아서 열어보니 실행 파일과 텍스트 파일이 있습니다.

텍스트 파일을 보니 시리얼을 주고 이때 맞는 이름을 찾는것 같네요

문제명처럼 키젠을 만들라는 것 같습니다!

정석적인 리버싱 문제네요

Peid로 까보니까 뭐 특별히 이상한건 없는 일반 32비트 실행파일입니다.

실행해보니까 이름과 시리얼을 입력받고 별다른 동작없이 종료합니다.

텍스트 파일 내용을 생각해보면 시리얼에 맞는 이름을 넣어주면 뭔가 동작을 할것같네요

만능인 리버서의 친구 IDA로 까줍니다.

main 함수를 보니 바로 aCorrect랑 aWrong이라는게 눈에 들어오네요 v9 변수와 v13으로 비교해서 분기를 가르고 있는게 보입니다.

위쪽에서는 v13을 손보는 알고리즘이 보이고 그위에 29라인을 보면 사용자 입력은 v9에 저장되는게 보입니다.

========================================================================

다시 순서대로 정리해보면 아래와 같습니다.

1.Name을 입력받는다.

2.입력받은 Name으로 Serial을 생성한다.

3.Serial을 입력받는다.

4. 2에서 생성한 Serial과 3에서 입력받은 Serial을 비교해서 sub_4011B9 함수에 적당한 인자를 전달한다.

그럼 우리가 할 건 무엇이냐?

Serial을 알고 있기 때문에 이때 맞는 Name을 찾아주면 됩니다.

그러면 2번 Serial을 생성하는 부분을 자세히 봅시다.

알고 있는 정보들을 넣어서 보기 쉽게 바꿔줍시다.

보기 한결 수월해졌네요

sprinf의 원형은 다음과 같습니다.

따라서 sprintf(&serial,"%s%02x",&serial, 값2)으로 정리가 가능합니다.

내용을 생각하면 serial 문자열에 '값2'의 16진수값을 문자열로 더해주는 내용입니다

그럼 값2 가 어떻게 생성되는지 알아봅시다. 

값2에 사용되는 변수는 name,v3, v6, i 가 사용되는것으로 보입니다.

 i의 경우 3이상이 되면 0으로 초기화됩니다.

따라서 i는 0,1,2가 반복됨을 알 수 있습니다.

v3의 경우 for 반복문이 돌아갈 때마다 1씩 증가하고 for문 자체가 Name의 길이와 v3를 비교해주기때문에

0,1... ,len(name)-1,len(name) 과 같음을 알 수있습니다.

그럼 *(&Name+v3++)의 해석이 가능해졌습니다.

Name[v3]와 같음을 알수 있습니다.

그럼 이제 이 부분만 알면 사실상끝나네요

주소를 보면 쉽게 나오네요 각 한자리씩 차이가 남이 보입니다. 내부 값은 위와 같이 되어있구요

i가 0,1,2가 반복되기때문에

는 16,32,48이 반복 됨을 알 수 있습니다.

따라서 시리얼은 Name[v3] 와 16,32,48을 xor 연산한 값으로 생성함을 알 수 있습니다.

name = input()
v6 = [16,32,48]
serial = ""
for v3 in range(len(name)):
    serial += str(format(ord(name[v3])^(v6[v3%3]),'x'))  
print(serial)

파이썬 코드로 알기 쉽게 구현하면 다음과 같습니다.

이런식으로 동작합니다.

이제 Name으로 Serial값을 구하는것은 구현이 되었습니다.

그럼 Serial로 Name을 구하려면 어떻게 해야 할까요?

답은 XOR 연산에 있습니다.

XOR연산의 특징중 하나가 XOR한 값으로 다시 XOR연산해주면 원래의 값을 나타내는 특성이 있습니다.

A XOR B = C 라고 하면 C XOR B = A 가 되게 됩니다.

따라서 Serial XOR v6 해주면 Name의 값을 얻을 수 있을 것입니다.

serial = input()
v6 = [16,32,48]
name = ""
for v3 in range(int(len(serial)/2)):
    name += str(chr(int(serial[v3*2:v3*2+2],16)^(v6[v3%3])))
print(name)

파이썬 코드로 짜주면 위와 같습니다.

ㅋㅋㅋ 플래그가 나왔습니다.

원래 실행파일에 입력해주면 정상적으로 Correct가 출력됩니다!

풀이 끝~