level17

해커스쿨 FTZ 2018. 4. 2. 18:51

level17은 지금까지 푼 BOF문제(level11~)중에 가장 빠르고 쉽게 풀었던 것 같다.


코드를 분석하자면 *call이 printit함수의 주소를 가리키고, fgets에서 입력을 받은뒤 call을 실행하는 구조이다.



main을 disassemble해보니 이번에도 역시 ebp-16이 보이는걸 알 수 있다.

이번에도 역시 40자리를 A로 채우고 그 뒤의 ret을 오버플로우 하면 되는 것으로 보인다.


이번엔 코드 내부에 /bin/sh를 실행하는 코드가 없으므로 쉘코드를 환경변수로 만들었다.



그리고 이 환경변수의 주소를 알아보기 위해 간단한 코드를 짰다.




gcc로 컴파일 한 후 실행해 보니



이 환경변수의 주소가 0xbffffc2e인것을 알 수 있었다.


따라서 40자를 채운 후 이 환경변수로 ret을 바꾸면 쉘을 얻을 수 있다.



'해커스쿨 FTZ' 카테고리의 다른 글

level19  (0) 2018.04.03
level18  (0) 2018.04.02
level16  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
level14  (0) 2018.03.28
블로그 이미지

천재보다는 범재

,

level16

해커스쿨 FTZ 2018. 4. 2. 17:32

이번문제의 힌트 또한 한 프로그램이다.


먼저 shell() 이라는 함수를 선언하는데 이 함수는 setreuid를 통해 level17의 권한으로 /bin/sh를 실행시켜주는 함수다.


딱 봐도 이 함수를 실행시키면 문제가 풀리도록 되어있따.


두번째 함수는 printit()이다. 이 함수는 "Hello there!"을 출력하고 종료하도록 되어있다.


main의 경우는 void (*call)()=printit; 이 뭘 의미하는지 확실히는 모르지만 맥락상 *call이 printit함수의 주소를 가리키도록 되어있는것 같다.


그 밑에 buf[20]이 선언되어 있고, fgets가 버퍼 이상을 입력받으므로 *call을 오버플로우 할 수 있을거라 예상했다.



이 경우에도 공간은 총 0x38, 즉 56이 할당되었고, main+16에서 ebp-16으로 값을 넣는걸 보니 40byte만큼 입력 후 shell() 함수의 주소를 넣으면 될 것 같았다.


gdb에서 shell의 주소를 보았더니


주소가 0x080483ec인것을 확인할 수 있었다.



따라서 코드를 (python -c 'print "A"*40 + "\xd0\x84\x04\x08"';cat)|./attackme 로 짜고 실행해서 쉘을 획득했다.




'해커스쿨 FTZ' 카테고리의 다른 글

level18  (0) 2018.04.02
level17  (0) 2018.04.02
LEVEL15  (0) 2018.03.29
level14  (0) 2018.03.28
level13  (0) 2018.03.28
블로그 이미지

천재보다는 범재

,

LEVEL15

해커스쿨 FTZ 2018. 3. 29. 21:58

 

먼저 hint파일을 열어보면 level14와 유사한 코드를 볼 수 있다.

 

 

코드가 완전 똑같은데 check앞에 *가 붙은 것을 볼 수 있다.

 

변수 앞에 *가 붙으면 포인터를 의미한다.

 

tmp로 코드를 복사한 후 컴파일 해 보았다.

 

 

gdb에서  intel형식으로 보면 level14와 아주 유사하지만 main+32에서 DWORD PTR [eax], 0xdeadbeef라고 바뀐것을 볼 수 있다.

 

이 어셈블리코드를 해석하자면 eax가 가리키는 주소에 있는 값고 0xdeadbeef를 비교하라는 뜻인데 바로 위 main+29를 보면

mov eax, DWORD PTR [ebp-16]을 볼 수 있다.

즉 EBP값의 16바이트 전의 주솟값을 의미한다.

 

level14와 같은 위치이므로

level14와 마찬가지로 A 40개를 넣고 0xdeadbeef를 입력하면 될 줄 알았다.

 

 

 

level14와 다른점은 포인터로 바뀌었다는 것 뿐인데 결과값이 달라서 포인터에 대해 다시 공부해 보았다.

 

이 코드에서 스택의 상태는

ret
sfp
crap
check
buf[20]

일 것이다

만약 check의 주소가 0x804123라고 하면

 

level14에서는
0x804123에 0xdeadbeef를 넣으면 해결되었지만 

*check의 경우  0xdeadbeef를 넣는다고 해결되지 않는다.

 

예를 들어보자

int a = 3;     //a가 0x8048af00에 할당되었다고 하자.
int *p = a;    // p는 a의 주솟값인 0x8048af00를 가질것이다

 

*p == 3     // 이 경우   0x8048af00이라는 주소에 3이 저장되어 잇으므로 

               //  3 == 3 true가 될 것이다.
p == 3      // 이 경우는 8048a00 == 3 이 되므로 false가 될 것이다.

 

 

따라서 이번문제는 check가 가리키는 주소값에 존재하는 값이 가리키는 주소에 있는 값과 0xdeadbeef가 같아야 하는 문제이다.

level14와 마찬가지로 환경변수로 0xdeadbeef를 넣고 주소값을 가져왔다.

 

환경변수가 저장된 값이 0xbffffc9e인것을 확인했다.

 

그리고 level14처럼 A40개와 환경변수의 주소를 입력하자 쉘을 얻을 수 있었다.

 

 

'해커스쿨 FTZ' 카테고리의 다른 글

level17  (0) 2018.04.02
level16  (0) 2018.04.02
level14  (0) 2018.03.28
level13  (0) 2018.03.28
level12  (0) 2018.03.28
블로그 이미지

천재보다는 범재

,