안녕하세요. 오늘은 codeengn level 10을 풀어보겠습니다.

홈페이지로 들어가 basic level 10을 눌러주세요.

OEP를 구한 후 등록성공으로 가는 분기점의 OPCODE를 구하라네요. OEP는 앞서 설명한 시작위치를 말합니다. 그러면 파일을 받아 봅시다.

실행시키면 위와 같은 창이 뜹니다. 그런데 입력칸에 아무것도 입력이 안되어지네요. 그리고 빨간글씨로 등록되지 않았다며 다시 시도하라고 적혀있습니다. 일단 올리디버그로 열어봅시다.

여기서 재생버튼을 함 눌러봅시다.

실행화면이 달라졌습니다. 일단 OEP를 찾아보겠습니다.

아무데나 브레이커를 걸고 해보았습니다.

그런데 맨 첫번째 문장에 브레이크를 걸고 실행시켰는데도 실행이 되더군요. 게다가 프로그램조차 제대로 실행이 되지 않습니다. 그리고 실행시키자마자 또 실행화면이 달라지는 것을 볼 수 있습니다.

그래서 아래와 같이 브레이커를 걸고 다시프로그램을 열어 실행시켰습니다. 다시 프로그램을 실행시켜도 브레이커는 남아있으니까요.

그런데 브레이크를 걸고 다시 실행시켜보니 브레이커가 없어졌습니다. 이러면 곤란합니다...

OEP를 찾아야 하는데 실행된 위치를 못찾으니 찾을 수가 없습니다.

그래서 프로그램을 다시 열었습니다.

그런데 프로그램을 열때마다 계속 이런 창이 뜨는군요. 처음에는 무시해도 파일이 열려서 별 대수롭지 않게 생각했지만 지금 보니까 의미심장합니다.

그래서 이 에러가 뜨는 이유를 알아보았습니다.

이유는 두가지가 나왔습니다.

1. 올리디버그가 64bit와 잘 호환이 되지 않기 때문

2. 이 파일이 패킹되어있기 때문입니다.

패킹이란 쉽게 말하면 압축입니다. 그런데 그냥파일을 압축하는 것이 아닌 실행파일을 압축하는 것을 의미합니다. 게다가 일반 파일을 압축하면 확장자가 zip으로 바뀌는 것에 비해 패킹은 압축을 해도 확장자가 그대로이고 또 바로 실행이 가능합니다. 일반압축이 용량을 줄이는데에 의의가 있다면 패킹은 용량도 줄이고 또 보호목적으로 암호화도 시킨답니다.

만약 이 오류가 뜨는 이유가 2번인 경우라고 봤을 경우 우리는 패킹을 푸는 작업 즉 언패킹을 해야 하는데 귀찮으니까 우리는 간단하게 풀어봅시다.

맨 첫줄을 보시면 PUSHAD라고 나와있습니다. 즉 패킹의 시작인 것입니다. 그런데 말입니다. PUSHAD로 패킹된 프로그램은 대부분 POPAD로 패킹을 풉니다. 즉 우리는 POPAD를 찾아줍시다. 아래와 같이 들어갑시다.

그리고 POPAD를 입력합니다.

FInd를 눌러주시면

정말 많이 나옵니다. 첫번째 것을 더블클릭해봅시다.

제일 먼저 나온 POPAD를 찾았습니다만

조금만 움직이니 바로 바껴버리는군요. 다시 들어가 두번째 POPAD를 눌러줍시다.

더블클릭

이번엔 맍는 것 같습니다. 움직여도 없어지지 않네요. 즉 저 POPAD이후로 패킹이 풀렸을 가능성이 있습니다. POPAD부터 브레이크를 걸고 실행시켜 봅시다.

위 사진은 실행시킨 사진입니다. 실행전과의 차이를 찾으셨나요?

밑에서 두번째 줄을 보시면 PUSH가 있습니다 이것이 처음엔 0이었는데 실행을 시키니 00445834라고 뜨는군요. 암튼 계속 실행해봅시다.

00445834가 스택에 입력되었습니다. 계속 실행시켜 봅시다.

놀랍게도 retn함수가 실행된 후 프로그램이 실행되는 것을 볼 수 있습니다.

retn은 그냥 되돌아가는 함수이니 별 상관은 없습니다. 그러면? 가장 최근에 스택을 입력한 00445834가 시작주소 즉 OEP임을 알 수 있습니다.

이제 OEP는 찾았는데 등록성공으로 가는 분기점의 OPCODE를 구하라는군요.

일단 OEP로 가봅시다.

도착했습니다만 조금만 움직이니 또 바뀌는군요.... 암튼 이번엔 문자열을 찾아봅시다.

성공의 문자열을 말입니다.

들어가셔서 맨 밑으로 내리시면

Registered... well done이 보이는군요. 등록이 성공되었다는 뜻입니다.

더블클릭을 해봅시다.

제대로 찾아온것 같군요. 우리는 여기서 OPCODE를 찾아야 합니다. OPCODE는 명령어를 뜻합니다. 즉 성공과 실패를 가르는 분기점에서 쓰인 명령어를 찾아야 된다는 것입니다.

제법 가까운데 있습니다.

Jnz short 10,0044552B 라고 적혀있네요.

Jnz는 조건점프입니다. zero flag의 값이 0이 아니면 점프하라는 소리입니다. zero flag란 두값을 비교했을 때 두값이 같으면 1이고 다르면 0을 반환합니다. 저기서는 10과 0044552B를 비교하겠군요. 0044552B주소에 있는 xor구문의 값이 10이 아니기 때문에 zero flag의 값은 0을 반환할 것이고 0이기 때문에 jnz는 점프를 하지 않고 그냥 넘어가 등록성공이란 문구를 출력하는것입니다. 만약 값이 1이 된다면 0044552B로 점프합니다. 0044552B가 비교 겸 점프위치가 되는 것이지요.

아무튼 OPCODE는 Jnz였습니다. 그런데 문제에 보시면 예시가 숫자로 되어있습니다.

그래서 주소로 적겠습니다.

OEP + OPCODE이므로

00445834 + 004454D4 인 00445834004454D4 가 되겠네요. 입력해봅시다.

.... 아니라네요.. 분명 OEP는 맞습니다. 그러면 OPCODE가 잘못되었다는건데...

주소값이 아닌 바이트값 7555를 넣어보겠습니다.

004458347555를 입력해봅시다.

인증해줍시다.

네 이것으로 문제풀이를 마치겠습니다.









'codeengn' 카테고리의 다른 글

codeengn - basic rce level 12  (0) 2015.08.12
codeengn - basic rce level 11  (0) 2015.08.12
codeengn - basic rce level9  (0) 2015.08.05
codeengn - basic rce level 8  (0) 2015.08.05
codeengn - basic rce level 7  (0) 2015.08.03
Posted by englishmath
,