profile image

L o a d i n g . . .

article thumbnail image
Published 2021. 3. 31. 22:11

1. 문제

checksec을 통해 문제에 적용된 보호기법을 확인한다.

NX 비트가 걸려있음을 알 수 있다.

 

ida를 통해서 까본 결과이다.

처음에 gets 함수를 통해 입력을 받는데, 입력받은 것을 check_passcode() 인자로 넘겨서 반환되는 값이 hashcode와 같을 경우 core() 함수를 실행한다.

 

hashcode의 값 : 0xC0D9B0A7

 

check_passcode() 함수이다.

gets로 받은 인자(a1)를 반복문을 돌리는데,

for 문을 통해 a1에 4씩 더하면서 4바이트 포인터로 형변환을 해준다.

그래서 a1부터 a1+16까지의 값을 누적시킨 v2를 반환해준다.

(즉, for 문을 5번 반복하면서 전달받은 주소값을 기준으로 4bytes 씩 증가시켜 순차적으로 접근하여 해당 값들을 v2 변수에 더하여 반환한다.)

이때, v2는 hashcode의 값( 0xC0D9B0A7 ) 과 같아야 한다.

 

값을 같게 할 방법은 두 가지 정도 있다.

1) hashcode 값을 5로 나눠준 결과값을 모두 이어준다. 이때 5로 나눈 나머지가 2이기 때문에 마지막값에는 2만큼 더해준다. 따라서 다음과 같다. 0x2691f021*4 + 0x2691f023

 

2) 어차피 누적시킨 값이 hashcode 값과 같기만 하면 되기에 0xC0D9B0A7 + 0*4를 전달해도 무방하다.

 

 

다음은 core 함수의 모습이다.

printf 함수의 주소가 leak 되고 있다.

또한 read 함수를 통해 buf 에 입력을 받는데, 이때 overflow가 발생해 ret를 덮어쓸 수 있을 것으로 보인다.

이때 offset은 62이다. (buf가 ebp로부터 0x3E만큼 떨어져 있으므로)

 

 

2. 문제 의도 파악

위의 논리대로 만든 payload를 전달하면 다음과 같이 core 함수가 실행되며, printf 함수 주소가 leak 됨을 알 수 있다.

파일을 실행할 때마다 printf의 주소값이 달라진다. -> ASLR이 걸려있음을 알 수 있다.

 

그럼 NX bit와 ASLR이 걸려있는 상황에서 어떻게 하면 쉘을 획득할 수 있을까?

아마 system 함수를 통해 binsh를 실행하면 될 것 이다.

그런데 ASLR 때문에 주소값이 바뀌므로 문제에서 leak 되는 printf를 가지고 system 함수와 binsh 주소값을 구해서 문제를 해결할 수 있다.

 

이때, 문제에서 libc.so.6을 문제 파일과 같이 주었다.

서버 환경에선 libc.so.6 파일을 통해 라이브러리를 참조한다.

따라서 로컬에서 offset을 구하면 서버에서 익스가 안된다... (로컬에서는 기본적으로 설정되어 있는 라이브러리를 참조하기 때문이다)

 

 

3. 익스플로잇

 

위의 논리대로 exploit 코드를 작성해보았다.

여기서 또 한 가지 주의할 점이 있는데, python3를 사용하는 경우 "/bin/sh" 의 offset을 구할 때 앞에 b를 붙어 byte 형태로 바꿔주어야 한다.

그렇게 해주지 않으면 요런 오류가 뜬다.

 

 

성공적으로 쉘을 획득한 모습이다!!

이 문제에서 딱히 특별한 건 없었다.

문제에서 같이 준 libc.so.6 라이브러리 파일을 참조해서 주소값을 구해야 된다는 점을 빼고는 다른 RTL 문제와 비슷했다.

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] BOF_FIE  (0) 2021.04.15
[HackCTF] Offset  (0) 2021.04.15
[HackCTF] RTL_World  (0) 2021.03.20
[HackCTF] x64 Simple_size_BOF  (0) 2021.03.19
[HackCTF] Basic_FSB  (0) 2021.03.19
복사했습니다!