틀린 부분이 있다면 언제든지 댓글 남겨주세요!
CodeEngn_Challenges Basic RCE L07
L07. 컴퓨터 C 드라이브의 이름이 CodeEngn 일경우 시리얼이 생성될때 CodeEngn은 'ß어떤것'으로 변경되는가
string검색해서 시리얼 번호를 비교하는 것으로 추측되는 부분으로 이동한다.
비교 코드의 시작부분으로 추측되는 코드에 BP를 걸고 실행시켜본다.
메시지 박스에 시리얼 문자열을 입력하고 check버튼을 누르면 BP를 건 부분으로 이동한다.
GetDlgItemText함수에서 사용자가 입력한 문자열을 가져온다. 'Ente'를 입력했다.
VolumeName매개변수가 가리키는 주소(40225C)로 지정된 볼륨의 이름을 받아온다.
현재 분석 환경의 C드라이브 이름이 없기 때문에 빈 문자열이다.
그래서 임의로 40225C주소에 'ABCD' 문자열을 입력했다.
이후 lstrca함수에서 '4562-ABEX'문자열과 받아온 볼륨의 이름을 합친다.
드라이브명이 기존의 문자열 앞에 더해지는 것을 확인할 수 있다.
다음 연산 루틴 반복 후 문자열은 'FEDC4562-ABEX'가 된다.
연산은 드라이브명의 앞 4자리 문자열 ASCII + 2이다.
lstrca함수로 'L2C-5781'문자열을 402000주소의 문자열과 붙이는데 402000문자열은 비어있다.
4023FD='L2C-5781' + 402000='' >> 'L2C-5781'
40225C='FEDC4562-ABEX' + 402000='L2C-5781' >> 'L2C-5781FEDC4562-ABEX'
402324='Ente' 와 402000='L2C-5781FEDC4562-ABEX' 를 비교하면 같지 않기 때문에 EAX=1을 반환한다.
EAX=1이므로 CMP결과 같지 않아 JE분기하지 않고 'Error' MessageBox를 출력한다.
- GetDIgItemTextA: 메시지박스의 컨트롤과 연결된 문자열 가져옴.
- GetVolumeInformation: 지정된 루트 디렉터리와 연결된 파일 시스템 및 볼륨에 대한 정보를 검색.
- lstrcatA: 한 문자열을 다른 문자열에 추가.
- lstrcmpiA: 대소문자를 구분하지 않고 두 문자열을 비교.
따라서 문제의 답을 유추해보면 C드라이브명이 'CodeEngn'인 경우
C+2, o+2, d+2, e+2 => E, q, f, g로 변경되어 'EqfgEngn'이 된다.
_Challenges Basic RCE L08
L08. OEP를 구하시오 Ex) 00400000
파일을 실행해보면 일반적인 계산기 프로그램이다.
파일 정보를 확인하기 위해 ExeinfoPE 프로그램을 이용하여 열었다.
UPX로 패킹되어 있는 걸을 확인할 수 있다.
앞선 문제에서 이용했던 것과 같은 방법으로 UPX 언패킹을 하여 OEP를 찾는다.
하드웨어 BP 방식을 사용했다.
BP건 부분까지 실행해 POPAD이후로 JMP OEP하는 부분을 찾는다.
1012475가 OEP임을 찾았다. EP가 12475, image base가1000000이다.
_Challenges Basic RCE L09
L09. StolenByte를 구하시오 Ex) 75156A0068352040
StolenByte란
안티 디버깅의 일종으로 훔친 바이트. 즉 어떤 부분의 코드를 다른 부분으로 이동시킨 코드를 의미한다.
패킹을 방해하기 위해 일부 영역을 다른 영역에서 실행되게 하여 OEP를 다른 위치로 가장해 덤프가 어렵도록 구현한 기법이다.
StolenByte는 주로 EP의 윗부분 몇 줄 이며, OEP주소로 JMP하기 전에 PUSH로 삽입된다.
이 코드들은 할당된 메모리 공간에서 실행되기 때문에 언패킹시 StolenByte와 함께 덤프해야 파일이 성공적으로 덤프된다.
파일을 실행시키면 다음과 같은 메시지박스가 나온다.
ExeinfoPE로 패킹된 파일임을 확인했다.
앞선 문제와 같은 방법으로 OEP를 구했다.
OEP는 40100C이며 StealByte의 특성을 통해 JMP이전에 PUSH 코드 3줄이 StealByte임을 추측할 수 있다.
이 3줄이 StealByte라는 것을 확인하기 위해 OEP 코드를 보면,
MessageBox API를 호출하는데 이 API는 다음과 같이 4개의 파라미터를 필요로 한다.
int MessageBoxA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
);
하지만 현재 OEP에는 PUSH 0 하나의 파라미터만 입력되어 있다.
StealByte로 추정되는 주소에는 OEP 코드의 MessageBox API에서 사용될 문자열이 들어있다.
따라서 이 코드 3줄이 StealByte임이 확인되었다.
만약 StealByte를 복구하지 않고 dump를 하게 되면 다음과 같이 문자열이 제대로 나오지 않는다.
이제 해당 코드를 원래 자리에 입력하고 저장하여 정상적으로 실행되는지 확인해본다.
[ctrl+e]단축키로 코드를 입력하고 dump를 뜬다. 이때 OEP를 1000으로 지정해준다.
저장 후 다시 열어보면 다음과 같이 정상적으로 실행되는 것을 볼 수 있다.
따라서 정답은 6A0068002040006812204000 이다.
'Security > Reversing' 카테고리의 다른 글
[CodeEngn] Challenges Basic RCE L13, L14, L15, L16 (0) | 2021.08.22 |
---|---|
[CodeEngn] Challenges Basic RCE L10, L11, L12 (0) | 2021.08.15 |
[CodeEngn] Challenges Basic RCE L04, L05, L06 (0) | 2021.08.06 |
[CodeEngn] Challenges Basic RCE L01, L02, L03 (0) | 2021.08.05 |
GDB 실습 1 (0) | 2021.05.16 |
댓글