힌트에는 소스코드가 나와 있다.
버퍼 오버 플로우를 이용한 문제이며, bu2[10]의 처음 두 인덱스에 go가 들어가면 성공한다.
버퍼오버플로우 문제이므로, gdb로 프로그램을 뜯어보려 했으나, 권한 문제로 막혀있다.
하지만 소스를 가지고 있으니 새로 프로그램을 만들면 된다.
vi로 test.c를 만들어 소스코드를 복사하고, gcc로 컴파일하는 과정을 거친다.
제대로 작동하는 것 같다. 위의 사진은 실행 후 아무 값이나 던져본 상황이다.
이제 gdb로 test 프로그램을 디버깅해보자.
disassembly main을 통해, 프로그램의 main함수를 디스어셈블리로 만들었다.
이를 해석해서 프로그램이 어떤 동작을 하는지를 확인할 수 있다.
main+43 부분인 0x0804844b 부분인 lea eax,[ebp-40] 명령에서 문자열을 입력받는 것 같다.
EBP에서 40바이트(0x28바이트)만큼 떨어진 곳의 주소를 EAX레지스터에 입력한다.
또한, main+65부분인 0x08048461 부분인 lea eax,[ebp-24] 명령에서도 문자열을 입력받는다.
EBP에서 24바이트(0x18바이트)만큼 떨어진 곳의 주소를 EAX레지스터에 입력한다.
이 두 부분에 브레이크 포인트를 걸고,
EBP레지스터 값의 변화에 주의하며 살펴보도록 하자.
우선, 각각의 브레이크 포인트를 통과할 때 나타나는 변화는 다음과 같다.
1. 첫 번째 브레이크 포인트를 통과할 때, EBP-40의 주소가 EAX에 들어감을 알 수 있다.
2. 두 번째 브레이크 포인트를 통과할 때, EBP-24의 주소가 EAX에 들어감을 알 수 있다.
초기 EBP의 주소는 0xbfffdce8이다.
첫 번째 브레이크 포인트를 통과한 뒤 EAX의 주소 값은
EBP주소에서 0x28을 뺀 값인 0xbfffdcc0이 된다.
이후 continue를 통해 진행하면, fgets()에서 문자열을 입력받아 bof[10]에 저장하는데,
여기서 A를 14번 정도 입력해보자.
이후 두 번째 브레이크 포인트를 지나면 EAX 주소값에 변화가 생기는데,
EBP주소에서 0x18을 뺀 값인 0xbfffdcd0이 된다.
이 주소값은 bof2[10]을 가리킨다.
두 버퍼의 주소 값의 상대적인 차는 0x10바이트이다.
이제 이 둘 사이에 쌓인 dummy를 확인하고 버퍼오버플로우를 위한 정확한 계산을 할 수 있다.
x/12wx $ebp-0x28 명령을 통해,
ebp에서 -0x28바이트 떨어진 곳을 기준으로 값을 확인할 수 있다.
우선, EBP-0X28(bof[10]부분)부터 A값을 14개 입력해주었는데,
한 필드에 A가 4개씩 들어감을 확인할 수 있다.
bof[10]에 할당된 공간은 10바이트 이므로, 나머지 부분은 dummy부분이다.
버퍼오버플로우를 만들어 EBP-0X18(bof2[10]부분)까지 침범하려면
bof[10]부분과 dummy부분을 합쳐서 어떤 값이든 16바이트 채워져야 한다.
따라서 위와 같이 16바이트를 아무 값이나 넣어 채우고,
그 후 go를 입력해 bof2[10]에 입력되도록 하면 level10권한의 bash 명령이 호출되고
my-pass를 통해 level10의 패스워드를 얻을 수 있다.
'System Hacking' 카테고리의 다른 글
[해커스쿨FTZ] Level7 (0) | 2020.01.06 |
---|---|
[해커스쿨FTZ] Level8 (0) | 2020.01.06 |
[해커스쿨FTZ] Level10 (0) | 2020.01.06 |
[해커스쿨FTZ] Level11 (0) | 2020.01.06 |
[해커스쿨FTZ] Level12 (0) | 2020.01.06 |