HackCTF 내 버퍼가 흘러넘친다!!!

image

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+0h] [ebp-14h]

  setvbuf(stdout, 0, 2, 0);
  printf("Name : ");
  read(0, &name, 50u);
  printf("input : ");
  gets(&s);
  return 0;
}

IDA를 통해 까본 prob1 소스이다.
read 함수를 이용하여 name 변수에 50byte만큼 이름을 입력을 받고 변수 s를 통해 입력값을 입력받는다. gets함수를 이용하고 최대 byte수를 정해주지 않았기 때문에 BOF가 일어난다.


풀이

처음에 생각했던건 gets함수에 입력제한이 없으니 dummy[24]를 주고 ret를 shellcode 주소로 준다음 그 뒤에 추가해서 shellcode를 넣는 방법을 생각했다. 하지만 local에서의 주소와 네트워크 상에서에 주소가 다른지 쉘이 따지지 않드라.... 그리고 또 이용할 수 있는 것이 name 이었는데 name은 선언이 안되있어서 뭐지? 싶었는데 더블 클릭을 하니 .bss 영역에 할당되어 있는 것으로 보아 전역변수로 선언되어있는것 같았다. 따라서 여기다 쉘코드를 삽입하고 ret을 이 .bss 주소로 변조해주면 될 것 같다.

.bss:0804A060 name            db    ? ;               ; DATA XREF: main+29↑o
.bss:0804A061                 db    ? ;
.bss:0804A062                 db    ? ;
.bss:0804A063                 db    ? ;
.bss:0804A064                 db    ? ;
.bss:0804A065                 db    ? ;
~~~
.bss:0804A093 _bss            ends

일단 gdb로 분석을 해보자

image

음 ida로 보는 것과 별반 차이는 없는 것 같다. 정보를 종합하고 payload를 짜주러 가보자.

  1. read 함수의 버퍼(name) 주소는 0x0804a060
  2. gets() 부터 ret 까지의 길이는 24byte

image

payload.py

image