
Offset 문제
[실행 화면]

무슨 함수를 실행시킬지 물어봤는데? 아무 단어나 입력하면 아무것도 출력을 하지 않는다.
[사전조사]
어떤 공격기법이 통할지 조사해봤다.

Full RELRO : 저번에 함수의 진짜 주소를 다른 함수로 덮어씌우는(got 덮어쓰기) 기법이 불가능해진다.
NX enabled : 데이터가 저장되는 영역에 실행 방지가 걸려 쉘코드 삽입이 불가능하다.
PIE : 실행파일의 위치가 변하기 때문에 함수들의 절대주소는 알 수 없고, 상대적인 위치만 알 수 있다.
[흐름 분석]
원하는 함수라.. 함수의 목록을 살펴봐야겠다.
one 함수, two 함수, print_flag 함수가 있다.

print_flag 함수를 실행시키는 것이 목적인것 같다.

우선 ebx에 offset _GLOBAL_OFFSET_TABLE이라는게 저장되는데, (got overwrite에서 got가 이것임) 이 상대 위치를 알아내보면

1FB8이다.
소괄호, 대괄호가 연달아 있을 경우에는 대괄호에 있는 값에서 소괄호에 있는 값을 더한다는 의미가 된다.
예를들어 저 lea eax, 구문에서는 ebx에서 (aWhichFunctionW - 1FB8h)를 빼게 되므로 1FB8 + aWhichFunctionW - 1FB8h 가 되어서 문자열 aWhichFunctionW를 정확하게 가리키게 된다.
뒤에서도 저 형태는 자주 등장한다.
저 문자열을 puts한뒤 gets를 수행하고, select_func를 수행한다.
select_func를 뜯어봐야겠다.

1에서 eax는 two 함수를 가리키면서 var_c에 주소값을 저장하고, 2에서 인자로 넘어온 문자열을 var_2a에 복사한다.(main에서 gets로 입력한 함수가 인자로 넘어오는것). 3에서 one 문자열과 비교하고 있으며 만약 비교 결과가 0(=같다)이 되면 4번으로 넘어가 var_c에는 one 함수가 저장된 뒤 5에서 실행되고, 만약 비교 결과가 0이 아니면 var_C에는 그대로 two 함수의 위치가 저장되기 때문에 two 함수가 실행된다.

one을 입력하면 "This is function one!"이 출력될 것이고,

one 이외의 문자열은 "This is function two!" 라고 출력하도록 되어 있다.
(그런데 왜 one을 입력하면 정상적으로 출력되는데 two라고 입력하면 아무것도 안나오는지 모르겠다...)
[해결 전략]
비록 got overwrite는 불가능하더라도 코드 내에서는 상대적인 위치를 받아서 해당 함수로 이동하는 코드가 있기 때문에(PIE가 무의미할것), 함수의 주소를 담고있는 var_C를 변조한다면 print_flag 함수를 실행하게 해서 flag를 얻을 수 있을 것이다.
필요한 것은 print_flag 함수의 상대 주소, var_2a 부터 var_C까지의 거리 정도가 될것이다.
[필요한것들 구하기]
gets를 통해 입력된 문자는 arg0을 거쳐 최종적으로 var_2a로 복사되기 때문에 var_2a로부터의 거리를 구하는 것이다.
한가지 문제가 뭐냐면 strncpy 함수를 사용한다는것인데, 최대 0x1F만큼의 글자 수만큼만 옮길 수 있다.

즉, 아무 문자 30바이트 + 1바이트 주소만큼 옮길 수 있다는 얘기인데, print_flag, two, one의 주소는 모두 2바이트로 이루어져있다.(물론 상대주소)
하지만, 다행히도 two와 print_flag 함수의 경우 상위 1바이트 주소는 같기 때문에 1바이크만큼 덮어써도 two 함수 대신 print_flag 함수를 실행하도록 할 수 있다. 06AD는 실제로 \xAD\x06 이런식으로 저장되어 있는데, 입력값으로 byte 형태의 입력값을 그대로 준다면 입력한 순서대로 메모리에 쓰여지기 때문에(그동안 문제풀면서 관찰한 결과, 틀렸으면 바로 정정할 예정) 아무문자 30바이트 + '\D8' 형태로 입력을 주면 될것같다.
[실행으로 옮겨보기]
from pwn import *
p = remote('ctf.j0n9hyun.xyz',3007)
data = b'A'*30
data += b'\xD8'
p.sendline(data)
[결과]


휴.. 스택에 대한 본질적인 탐구가 필요할것 같다.
'정보보안' 카테고리의 다른 글
| [정보보안] Return to Libc 씹어먹기 (0) | 2022.01.20 |
|---|---|
| [문제해결] BOF_PIE 해결과정 (0) | 2022.01.18 |
| [정보보안] Simple_Overflow_ver_2 해결과정 (0) | 2022.01.16 |
| [문제해결] x64 Simple_size_BOF 해결과정 (0) | 2022.01.14 |
| [문제해결] x64 Buffer Overflow 해결과정 (0) | 2022.01.14 |