Basic RCE L20

hoon·2023년 6월 11일
0

CodeEngn

목록 보기
20/21

문제

이 프로그램은 Key파일을 필요로 하는 프로그램이다.
'Cracked by: CodeEngn!' 문구가 출력 되도록 하려면 crackme3.key 파일안의 데이터는 무엇이 되어야 하는가
Ex) 41424344454647
(정답이 여러개 있는 문제로 인증시 맞지 않다고 나올 경우 Contact로 연락주시면 확인 해드리겠습니다)

실행화면

PEiD

MASM32TASM32는 x86 아키텍처의 어셈블리 언어를 사용하여 Windows 운영 체제에서 실행되는 프로그램을 개발하기 위해 사용되는 개발 도구

IDA 분석

CRACKME3.KEY 파일을 읽어 조건 충족시 성공문자열을 보여준다.


if ( FileA != (HANDLE)-1
    && (hFile = FileA, ReadFile(FileA, byte_402008, 0x12u, &NumberOfBytesRead, 0), NumberOfBytesRead == 0x12)
    && (sub_401311(byte_402008), dword_4020F9 ^= 0x12345678u, v2 = sub_40133C(byte_402008) == dword_4020F9) )
  {
    sub_401346((int)WindowName);
  }
  else
  {
    sub_4012F5(WindowName);
  }

crakeme3.key에서 18byte를 읽어와 sub401311(읽은 문자열) == (dword_4020F9^=0x12345678)가 되어야
sub_401346을 실행시켜준다. 실패 시 sub_4012F5를 실행한다.

문자열의 앞에서 14바이트만큼을 가져와 연산진행 0x41(65)부터 0x4f(79)까지 문자열마다 XOR를 해준다.

x86dbg

이 부분이 앞에서 부터 14바이트 문자열을 0x41~0x4f까지 XOR한 값들의 합^0x12345678한 값과 key값을 비교하는 부분이다.
즉 b'CodeEngn\x00'+ ????? 를 0x41~0x4f까지 각각 XOR 한 합^0x12345678 == key인데 이 key값은 4020F9에 저장되어있다.

4020F9에 저장된 값은 0x1234557B이다.

따라서 key값에 들어갈 데이터는
XOR(CodeEngn\x00) + ????? + b'7b553412' 가 된다.

정답

def sub_401311(string):
    v4 = 0x41
    new = []
    dword_4020F9 = 0
    for i in range(14):
        v2 = v4^string[i]
        v4 += 1
        new.append(hex(v2))
        dword_4020F9 += v2
    return new, dword_4020F9


import itertools

# ASCII 내의 알파벳과 숫자 범위
characters =  [chr(i) for i in range(128)]

# 18바이트 문자열 생성
combinations = itertools.product(characters, repeat=5)

# 모든 조합 출력


for combo in combinations:
    str1 = ''.join(combo)
    string=b"CodeEngn\x00" # 뒤의 5문자는 단순히 key를 맞추기 위해 사용됨
    string += str1.encode()
    v2, key = sub_401311(string)
    key ^= 0x12345678
    if key == 0x1234557b:
        print(combo)
        break


#key=0x1234557b
byte_list = [int(x,16).to_bytes(1,'little') for x in v2]

key= key.to_bytes(4, 'little')
bytestr = b''.join(byte_list) +key

p = ""
for b in bytestr:
    p += hex(b)[2:].zfill(2)
print(p)

f = open('CRACKME3.KEY','wb')
f.write(bytestr)
f.close()
    

('\x00', '\x00', '\x00', '0', '9')
022d272100282026494a4b4c7d777b553412

인증을 하기 위해서는 중간의 ?????값이 00 00 00 00 00이 되야한다고 한다.
사실 앞의 9바이트와 뒤의 4바이트 key만 맞춰줘도 정상적으로 정답이 된다.

#인증용
def sub_401311(string):
    v4 = 0x41
    new = []
    for i in range(9):
        v2 = v4^string[i]
        v4 += 1
        new.append(hex(v2))
    return new


string=b"CodeEngn\x00"
v2 = sub_401311(string)
byte_list = [int(x,16).to_bytes(1,'little') for x in v2]
key=0x1234557b
#key^=0x12345678
key= key.to_bytes(4, 'little')
bytestr = b''.join(byte_list) + b'\x00\x00\x00\x00\x00'+key
p = ""
for b in bytestr:
    p += hex(b)[2:].zfill(2)
print(p)
print(bytestr)
f = open('CRACKME3.KEY','wb')
f.write(bytestr)
f.close()
    

0개의 댓글