argv hunter + 파일명위치 찌꺼기 이용 문제
'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글
LoB golem (3) | 2016.09.28 |
---|---|
LoB skeleton (1) | 2016.09.23 |
LoB troll (0) | 2016.09.22 |
LoB orge (0) | 2016.09.22 |
LoB darkelf (0) | 2016.09.22 |
document.onkeypress = getKey;
argv hunter + 파일명위치 찌꺼기 이용 문제
LoB golem (3) | 2016.09.28 |
---|---|
LoB skeleton (1) | 2016.09.23 |
LoB troll (0) | 2016.09.22 |
LoB orge (0) | 2016.09.22 |
LoB darkelf (0) | 2016.09.22 |
대부분 버퍼오버플로우를 일으키고 RET 주소를 덮을 때
아무 일도 일으키지 말라는 Nop Sled와 권한 상승(privilege escalation)을 위해 사용되는 쉘코드가 있는 주소를 주입시켜준다.
이때 이 Nop Sled와 쉘코드를 어디다가 저장해둘까? 에 대한 방법이다.
exploit의 종류 중 가장 기본적이고 쉬운 환경변수를 통한 공격 방법을 설명해주겠다.
환경변수를 통한 공격은 "에그쉘"이라고 불린다.
FTZ 11번 문제를 예시로 설명해주겠다.
버퍼오버플로우를 일으킬 수 있는 취약한 함수인 strcpy 함수를 확인해 보자.
길이를 체크하지 않고 copy 하는 함수이기 때문에 우리가 조금만 더 작성하면 RET 값을 덮어버릴 수 있다.
우리는 환경변수 안에다가 쉘코드를 저장해둘꺼고, 나중에 RET 주소에다가 이 쉘코드를 저장한 환경변수의 위치를 작성해 줄 것이다.
그러니 일단 환경변수에 쉘코드를 저장해보자...!!
리눅스에서 환경변수 설정은 이렇게 한다.
export 변수명=`python -c 'print "\x90"*100+"쉘코드"
(여기서 변수명뒤=을 붙여쓰라)
그럼 이 환경변수가 저장된 위치를 알려주는 프로그램을 짜야한다.
c언어의 getenv 함수를 이용하면 된다!
getenv.c 를 짜서 gcc -o getenv getenv.c 명령어를 통해 컴파일 해준다.
첫번째 인자에 환경변수명을 넣어주면 그게 저장된 위치를 알려준다.
이런식으로
이제 우리는 이 주소를 그냥 RET 주소에다가 덮어 주면 된다.
물론 Little Endian으로!!
버퍼크기(256) + 더미갯수 (8) + SFP (4) + RET (4) <이부분은 gdb로 까봐야 안다! 필자는 생략한다>
이므로 버퍼+더미+SFP 까지 268개를 덮은 후 우리의 쉘코드가 있는 주소를 RET 부분에 작성해준다.
아래처럼 말이다!!!
peda에서 개꿀팁 (2) | 2017.03.31 |
---|---|
rop를 위한 objdump 옵션들 확인 (0) | 2017.01.22 |
pop pop ret 헷갈리지 않기 (0) | 2017.01.22 |
보호기법 끄는 컴파일 옵션 (0) | 2017.01.20 |
xinetd 사용해보기! (0) | 2017.01.20 |
Big NOP Sled for changing address 문제
원래 우리가 항상 RET으로 보내던 주소는 0xbfff~~~ 꼴로 이루어져있다.
근데 0xbf는 괜찮은데 0xbfff꼴이면 안된다.
생각해본 아이디어는 argv[2]를 이용해 버퍼를 크게크게 늘려놓는 것이다. 그럼 0xbfff 에서 0xbffe로 갈 것이다. (스텍은 -로 자란다)
동일하게 argv[2]의 0x위치를 알려주는 printf를 짜놓고 컴파일 한다.
0xbffe 로 바뀌려면 적어도 9만개의 nop 슬레드를 생각해보자는 의미가 된다!!
9만개나 이쓰면
LoB skeleton (1) | 2016.09.23 |
---|---|
LoB vampire (0) | 2016.09.23 |
LoB orge (0) | 2016.09.22 |
LoB darkelf (0) | 2016.09.22 |
LoB wolfman (0) | 2016.09.21 |
argv[0] 사용 문제
문제가 점점 제약을 두고 있다.
여태까지 argv[2]의 위치를 알아서 쉘코드를 주입했었는데...
1. argc 갯수를 2개로 제한했고,
2. Egghunter 와 버퍼갯수 48이상 제한
3. 버퍼와 argv[1] memset 초기화
거의 다 막아 두었다.
그래서!!!!!!!
argv[0]은 파일명이다.
이 파일명을 긴 파이썬 쉘코드로 만들면 짜증나지만 쉘코드를 주입시킬 수 있는 유일한 방법이다.
주요한 점이 있는데
실행시 파일명에 / 가 사용되면 안되기 때문에 \x2f는 없는 쉘코드를 사용해야된다.
\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81
mv troll `python -c 'print "\x90" *100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"'`
물론 gdb 확인을 위해서 원본을 복사해서 코어를 떠보자.(이름은 다르게 했다.)
코어를 확인해보자
코어를 떠서 확인할때 0x90909090이 뜨면 가슴이 설렌다... NOP Sled를 봤을때
이 주소를 RET 하면 답이 될 가능성이 매우 높다.
답은 이렇게 된다.
LoB vampire (0) | 2016.09.23 |
---|---|
LoB troll (0) | 2016.09.22 |
LoB darkelf (0) | 2016.09.22 |
LoB wolfman (0) | 2016.09.21 |
LoB orc (0) | 2016.09.21 |
argv[0] check 문제
이전 문제들과 똑같지만
argv[0]를 체크해버린다. bash2 꼭 하자
공격방법은 첫 글자 수가 75자가 되어야 한다. ( 쩜 슬래쉬 ./ 도 포함해야 되서 2글자 뺴라...)
mv orge `python -c 'print "A"*75'` 로 공격할 orge 프로그램의 이름을 바꾸라
그리고 당근 파일명이 75자인 BBBBBBB...BBBBBBB를 만들어서 gdb 코어 덤프를 뜬다.
x/100x $esp 로 내리다 보면 주입했던 NOP SLED 가 보인다.
0x90909090 의 아무 위치나 잡아서 AAAAAA..AAAAAAAA에 공격을 시도한다. (필자는 0xbffff7f0을 선택함)
LoB troll (0) | 2016.09.22 |
---|---|
LoB orge (0) | 2016.09.22 |
LoB wolfman (0) | 2016.09.21 |
LoB orc (0) | 2016.09.21 |
LoB goblin (0) | 2016.09.18 |
argv[1] Length Check 문제
전 문제와 동일하게 argv[2]의 위치를 알려주는 코드를 작성했다. (파일이름길이도 abcdefg로 같게)
뒤에 쉘코드 짤려있다..
이상하게 argv[2]의 위치가 나오지가 않는다...
그럼 코어를 확인해 보자.
코어를 보면 어디서부터 argv[2]의 \x90 이 쌓이는지 알 수가 있다.
이 위치 아무거나 선택을 해주어서 주소로 입력을 해주면... (필자는 0xbffff090 을 선택했다)
답이 뙇
교훈이 있다.
항상 bash2 하자. 너무 화난다.
그리고 이제 코어보는 법을 익혔다. $esp를 확인해보면 되니까,...
gdb -q 파일명 core
LoB orge (0) | 2016.09.22 |
---|---|
LoB darkelf (0) | 2016.09.22 |
LoB orc (0) | 2016.09.21 |
LoB goblin (0) | 2016.09.18 |
LoB cobolt (0) | 2016.09.18 |
Egghunter & Buffer Hunter Detour 문제
일단 bash2 그리고 쉘코드
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
문제가
버퍼와 환경변수를 지운다.
우회하는 방법은 다양하다.
RET 주소 뒤에 아무 주소에 쉘코드와 NOP 썰매를 태워준다든지
argv[2] 인자의 주소를 알아내서 여기에다가 쉘코드를 주입시켜준다.
필자는 후자를 선택하겠다.
일단 같은 이름크기의 abcdefg.c 파일을 만들어서 argv[2]의 주소값을 뿌려주는 코드를 더 작성해준다.
그렇다면 이를 컴파일해서 실행시켜보자.
일단 bash2를 꼭 키고...
당빠 인자 두개를 작성해줘야겠지 (뒤에 짤린건 그냥 쉘코드다)
argv[2]의 주소는 bfffd54c 이다.
이거를 이제 wolfman 한테 주소를 넣어서 해보자. (뒤에 또 쉘코드 짤렸다)
답이 나온다.
LoB darkelf (0) | 2016.09.22 |
---|---|
LoB wolfman (0) | 2016.09.21 |
LoB goblin (0) | 2016.09.18 |
LoB cobolt (0) | 2016.09.18 |
LoB gremlin (0) | 2016.09.18 |
Egghunter & Canary Detour 문제
두 가지 보호기법이 있었다.
1. 환경변수를 이용하지 못하게 egghunter를 사용했다.
egghunter는 memset을 통해 환경변수를 다 0으로 초기화시켜버렸다.
2. Canary를 이용했다.
특정 RET 주소위치에 \xbf가 꼭 있어야 된다고 한다.
이 두개를 우회하면 된다.
간단하다 환경변수를 안 쓰고 \xbf를 넣어주면 된다.
사실 우리 항상 처음 버퍼의 주소를 선택해 넣어줄 때 \xbf가 있지 않았나!!!
일단 실행시켜보자...
당연히 카나리 때문에 if 문에 걸려서 프로그램이 끝나버리고 만다.
아 그러면 47개 덮고 마지막만 \xbf로 채워보자
Segmentation fault는 정말 긍정적인 결과이다!
버퍼오버플로우가 일어날 수 있다는 이야기이다.
일단 두 가지 시나리오를 생각해보자.
1. 버퍼 위치를 캐서 그 안에다가 쉘코드와 RET주소를 이쁘게 덮어 공격
2. 두 번째 인자가 argv[2] 위치를 알아내서 ./orc 실행시킬 때 페이로드 인자를 두 개 더 붙이자
난 다할꺼다...ㅎ
---------------------------------------------------1번 시나리오----------------------------------------------------
일단 gdb로 까보는 것도 해보고 뭐 다 해봤지만 안된다. (까봐도 된다. 하지만 직접 실행시키는 경우 주소가 바뀐다고 한다.)
그래서 orc.c를 복사해서 printf("%s\n", buffer); 였던 거를
%p 로 바꿔 버퍼 시작 주소로 만들었다. (코드길이도 크게 달라지지 않고 뭐여튼)
이거 컴파일 할때 orc랑 이름 길이 똑같게 abc 로 했다.
버퍼 주소는 떴다.. 어효 힘들다
페이로드는 44개 덮고 RET에 버퍼시작주소를 두고 nop sled 이후 쉘코드를 주입시킨다.
음.. 되긴 되는데 이게 주소가 정확하게 이렇게 하면 되는건지 궁금하다. 사실 이거 약간 주소가 운으로 맞은거 같다.
LoB wolfman (0) | 2016.09.21 |
---|---|
LoB orc (0) | 2016.09.21 |
LoB cobolt (0) | 2016.09.18 |
LoB gremlin (0) | 2016.09.18 |
LoB gate (0) | 2016.09.14 |
Small buffer & stdin 문제
FTZ랑 똑같이 stdin은 파이프 형태로 받아주면 된다.
small buffer는 에그쉘 환경변수를 이용하면 되고!!
gdb로 까보지도 않아도 문제가 너무 쉽다.
환경변수로 담은 위치 저장해 두고 (꼭 bash2를 한 다음에 환경변수를 설정하자!!!!!!!!!!!)
LoB wolfman (0) | 2016.09.21 |
---|---|
LoB orc (0) | 2016.09.21 |
LoB goblin (0) | 2016.09.18 |
LoB gremlin (0) | 2016.09.18 |
LoB gate (0) | 2016.09.14 |
Small Buffer 문제
버퍼의 크기가 작을 때 버퍼오버플로우를 일으키자.
내가 막 생각나는 방법은 역시 쉘코드를 환경변수 등록으로 해서...
저번에 썼던 쉘코드를 그대로 불러올께요.
gdb로 까보시면 아시겠지만 gcc가 전 버전이라 더미가 없이 이쁘게 16개 이후 sfp 4바이트까지 포함해서 20바이트를 채워 준 후 RET 가 존재합니다.
넘나 쉽다
LoB wolfman (0) | 2016.09.21 |
---|---|
LoB orc (0) | 2016.09.21 |
LoB goblin (0) | 2016.09.18 |
LoB cobolt (0) | 2016.09.18 |
LoB gate (0) | 2016.09.14 |