[LOB] bugbear -> giant
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 | /* The Lord of the BOF : The Fellowship of the BOF - giant - RTL2 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> main(int argc, char *argv[]) { char buffer[40]; FILE *fp; char *lib_addr, *execve_offset, *execve_addr; char *ret; if(argc < 2){ printf("argv error\n"); exit(0); } // gain address of execve fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r"); fgets(buffer, 255, fp); sscanf(buffer, "(%x)", &lib_addr); fclose(fp); fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r"); fgets(buffer, 255, fp); sscanf(buffer, "%x", &execve_offset); fclose(fp); execve_addr = lib_addr + (int)execve_offset; // end memcpy(&ret, &(argv[1][44]), 4); if(ret != execve_addr) { printf("You must use execve!\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); } | cs |
코드가 복잡해졌다. execve의 주소를 구하고 ret를 execve함수의 주소로 덮어쓰지 않으면 프로그램이 종료된다
execve는 호출한 프로세스를 새로운 프로세스로 변경한다. 이때 환경변수 정보를 추가 가능하다
프로토타입
execve (const char *filename, char *const argv[], char *const envp[])
첫번째 인자 : 실행시킬 파일명
두번째 인자 : 전달할 인자값 (포인터배열)
세번째 인자 : 환경변수 (NULL을 주면됨)
ret에 execve의 주소를 덮으면
(lower address) [execve()][execve의 ret][인자1][인자2][인자3] (higher addess)
[execve()][system()][exit()]["bin/sh"][NULL]
execve함수로 exit함수를 실행하면 바로 종료해버리면서 ret에있는 system함수를 실행하고 두번째 인자로 전달한 /bin/sh이 실행된다.
system() : 0x40058ae0
execve() : 0x400a9d48
exit() : 0x400391e0
NULL : 0xbffffffc (스택끝부분에 있는걸 씀)
/bin/sh : 0x400fbff9 ( darkknight에서 구한 주소)
페이로드와 Password
*exit주소를 쓰지 않고 dummy로 채워도 쉘을 딸 수 있지만 dummy로 채웠을 경우 쉘을 나가면 세폴 오류가 뜬다는 차이점이 있다
'System > LOB' 카테고리의 다른 글
[LOB] assassin -> zombie_assassin (0) | 2015.04.18 |
---|---|
[LOB] giant -> assassin (0) | 2015.04.14 |
[LOB] darkknight -> bugbear (0) | 2015.04.12 |
[LOB] golem -> darkknight (0) | 2015.04.11 |
함수의 프롤로그(prologue) 및 에필로그(epilogue) (0) | 2015.04.10 |