document.onkeypress = getKey;


코드분석을 해보자.


argc 는 2개 (인자 하나) 그리고 인자값은 5개 이상이어야 한다.


버퍼에 argv[1]의 입력을 memcpy 해주고, memset으로 끝 4자리 빼고 다 0으로 초기화 해버린다.


functionpointer의 주소를 bad함수로 초기화해주는데

good 주소로 가면 쉘을 딸 수 있다.


기본적인 버퍼오버플로우로 functionpointer가 저장되어있는 메모리에 가서 good의 주소를 덮어써주면 된다.


bad와 good주소는 친절하게도 실행 시켜보면 안다. 인자 대충 5개이상 때려보자


memcpy 이후에 브레이크 포인트를 걸고 버퍼 크기만큼 50개를 덮어준다.


우리의 bad함수의 주소는 0x080484a4이였다.


A가 50개 덮어지고 저기 밑에 보면 빨간색으로 bad함수의 주소가 보인다.

이 부분을 good 주소로 바꿔주면 문제가 풀릴 것이다.



주소는 0xbffffc8c(0x080484a4인 bad함수가 초기화되었을때, 즉 functionpointer의 주소가 담겨있는 주소) - 0xbffffc40(버퍼시작주소) = 76



버퍼에 76개를 덮고 good주소를 덮어주자.


페이로드: ./level03 `python -c 'print "A"*76 + "\x74\x84\x04\x08"'`





인자는 3개, atoi 함수로 숫자로 받아온다.


signal(SIGFPE, catcher); 가 무슨 함수인지만 알면 된다.


시그널 함수는

SIGFPE가 일으키면 catcher를 실행시킨다는 것이다.


SIGFPE는 Erroneous arithmetic operation 일 때 생긴다고 한다.


0으로 나누거나 integer overflow를 생각해보았는데


0으로 나누는 것은 !atoi 때문인지 안되는 것 같다.





버퍼오버플로우 원정대를 끝내고

혁이형과 스터디에서 푸는 스매시더스택을 풀게 되었다. 유후


http://io.netgarage.org

이 주소를 통해서 xshell로 들어가면 된다.



문제 푸는법


cd /levels 에 가서

ls -las level01로 id 정보를 확인하자. 다음 쉘로 가는!!



그리고 프로그램 취약점을 분석해 쉘을 따면 된다!



level2가 걸려있다.


실행해보자


번호 맞추면 되는듯?



gdb 로 까보면

0x10f랑 cmp 한다.


271인데.. ㄱㄱㄱ




Calling Functions Continuously 문제 + /bin/sh인자 전달


문제 너무 길다...

쉽게 이해하면 

스텍은 RET 주소에는 도 함수의 주소를 저장해야하고,

RET 뒤 100개 정도만 사용할 수 있고,

LD_함수는 못쓰게 만들었다.


도 개 걸 윷 모 함수를 쭈욱 타서

MO함수의 인자인 char *cmd에 주소를 입력해주면 된다.




필자는 도개걸윷모의 주소를 알아낸 후 인자로 /bin/sh를 보내기 위해 /bin/sh를 뒤에다가 저장하고 그 주소를 향하게 만들었다.





'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB assassin  (0) 2016.10.08
LoB giant  (0) 2016.10.08
LoB bugbear  (0) 2016.09.29
LoB darkknight  (0) 2016.09.28
LoB golem  (3) 2016.09.28

Fake EBP (Shell 주입 or RTL) 문제




strcpy가 아닌 strncpy를 주어줘서 딱 RET 주소까지만 덮을 수가 있다.


FPO랑 RET Sled 를 풀었을 때와 비슷한 원리로 Fake EBP도 RET 어드레스에 LeaveRet 가젯을 넣어줘서 SFP 값을 통해 리턴을 조작하는 것이다.


일단 RTL도 쉘코드도 가능하지만 필자는 RTL로 풀어보겠다.


일단 RET 주소에 LeaveRet 주소를!!


버퍼의 위치로 가야하므로 버퍼-4의 주소를 SFP에 넣어준다. (나중에 push 때문에 4가 증가되므로)

그렇게 되면 버퍼 -4 + 4 한 위치에 담겨있는 주소를 가져온다.

그러니 그게 system 주소가 담겨 있으면 되고, 이에서 + 8 한 위치가 /bin/sh이면 된다.!!!


일단 버퍼의 주소도 알아냈다 printf("%p\n", buffer); 로 바꿔서 컴파일 해주었다.



시스템 주소와 /bin/sh 주소는 전 단계에서 구했던 거 알죠?



다시 한 방에 정리... (어떻게 주소들 구하는지 정리해주겠다.)


버퍼 주소 (0xbffffa70)

- %p 버퍼로 출력하게 리컴파일 했다. 우리는 Fake EBPㅏ사용하므로 버퍼 -4 의 주소를 페이로드에 넣을 것이다.


시스템 주소 (0x40058ae0)

int main(void) {

system();

}    으로 만들어서 컴파일해서 브포 main 걸고 r 누른 후 print system 한다.


/bin/sh 주소 (0x400fbff9)          

#include <stdio.h>

int main (int argc, char* argv[]) {
long shell;
shell = 0x40058ae0;
while(memcmp((void *) shell, "/bin/sh", 8)) {
shell++;
}

printf("\"/bin/sh\" is at 0x%x\n", shell);
printf("printf %s\n",shell);
return 0;
}

LeaveRet 주소(0x08484df)
이건 gdb 뒷부분 확인


-------------------------------------------------------------------------------------------------------------


print "시스템주소"       +        아무거나 4바이트        +  /bin/sh주소            +        아무거나 28바이트        +     Buffer주소-4        +  LeaveRet주소


BUUUUUUUUUUUUUUUUUUUFFFFFFFFFFF버퍼FFFEEEEEEEEEEEEEEEEEEEEEERRRRRRRRRRRRR           +     SFP                    +  RET



따라서 페이로드는 다음과 같다.




'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB zombie_assassin  (0) 2016.10.11
LoB giant  (0) 2016.10.08
LoB bugbear  (0) 2016.09.29
LoB darkknight  (0) 2016.09.28
LoB golem  (3) 2016.09.28

RET Sled 문제



RTL과 스텍을 사용하지 못하게

RET 주소에 \xbf와 \x40을 막아버렸다.


하지만 RET sled를 사용하면 한 번 (47번째에 두 주소를 우회) 사용하면 된다.


알다 싶이 RET (pop eip 와 jmp eip) 명령을 하게 되면 esp는 +4가 됩니다~


그렇기 때문에 ret 가젯의 주소를 return address에 넣어주고 그 다음주소에 쉘코드의 주소(\xbf 사용가능)를 넣어주게 되면 됩니다.


바로 ret 명령의 주소는 이것이다.


우린 0x804851e를 리턴 어드레스에 넣을 것이다.


그러니 첨에 쉘코드 주소는 \xbf\xbf\xbf\xbf로 아무렇게나 해주고 코어 덤프떠서 확인해보자.



0xbfffd3c4를 쉘코드 주소로 사용하자.



'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB zombie_assassin  (0) 2016.10.11
LoB assassin  (0) 2016.10.08
LoB bugbear  (0) 2016.09.29
LoB darkknight  (0) 2016.09.28
LoB golem  (3) 2016.09.28

RTL, execve 주소 사용 문제




코드가 길다...ㅠ


일단 맨 뒷부분 if문을 보면

ret 값에 execve의 주소를 알아서 넣어줘야되는 것 같다.


execve는 lib_addr + execve_offset 이므로



일단 주소는 0x400a9d48로 정해졌다.


사실 브레이크 포인트를 걸고 실행시켜보면 여러가지 함수들의 주소를 알 수 있다. 

execve함수 주소가 동일하다!!


RTL을 사용할 것이기 때문에 페이로드는


A*44개(버퍼와 SFP 덮고) +  execve 주소 (RET 부분) + system ( execve의 RET) + 더미(4바이트 아니 exit 주소 해도 됨) + "/bin/bash/"의 주소




0a 때문에 한번더 큰따옴표 "" 로 묶어주었다.

'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB assassin  (0) 2016.10.08
LoB giant  (0) 2016.10.08
LoB darkknight  (0) 2016.09.28
LoB golem  (3) 2016.09.28
LoB skeleton  (1) 2016.09.23

RTL 기본 문제


bugbear 로 가자!


코드를보니까 stack이 나를 배반한단다...

뭐 환경변수든 버퍼든 인자든 스택관련이기 때문에 \xbf로 시작한다. 그래서ㅠㅠ 스텍을 이용해서 공격할 수 가 없다.


특히 쉘코드를 이용하지 않고 /bin/sh 를 띄우는 방법을 고민하라고 한다.



필자는 http://m-youngzzang-for20.tistory.com/115 웹사이트 RTL에 대한 기본개념들이 적혀있는 블로그를 보고 작성하였다.

(따라하니까 되었다!! ㅎㅎㅎㅎ 이제 이해를 하면 되니까 이해를 시켜주겠다)


일단 

system 함수를 아무거나 만들어서 system 주소를 알아내보려고 했다.


가볍게 짜고 컴파일 한 후 gdb로 까준다

main에 브포를 걸구 실행시켜 system 주소를 알아낸다!!


ㅎㅎ 주소를 알아냈다!


이 주소를 이용해 코드를 작성해보자. (http://m-youngzzang-for20.tistory.com/115) 에 참고해보았습니다.

/bin/sh를 찾아주는 코드이다.


일단 shell = system 주소로 초기화해준다.

이걸 실행 시켜보면!


/bin/sh와 주소가 뜬다.


이걸

buf랑 sfp(40+4) + 시스템주소 + 더미(4) + /bin/sh의 주소

로 공격한다.


더미 4는 꼭 넣어야한다. 왜냐하면 system 함수나 execl 함수는 ebp+8 위치의 인자를 인식하기 때문에 dummy+4를 넣어서 /bin/sh를 불러옵니다! 라고 한다.





'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB giant  (0) 2016.10.08
LoB bugbear  (0) 2016.09.29
LoB golem  (3) 2016.09.28
LoB skeleton  (1) 2016.09.23
LoB vampire  (0) 2016.09.23

FPO 문제





메인 함수 이외의 함수가 있다...

이 문제는 FPO 를 찾아서 해보려 했지만 내가 진짜 너무 빠가라 동기의 도움도 받았다 헿


일단 나는 불친절하게 작성할꺼다.

Frame Pointer Overflow를 찾아봐라 그럼 SFP를 1바이트 조작해서 원하는 쉘코드에 들어간다.


일단 RET이 두 번 일어나야된다. 왜냐면 SFP 자체가 전에 어디에 있었는지 알려주기 때문이다.


내가 이해한(?) 루트는 이렇다.

SFP에는 전에 어디에 있었는지 주소를 담고 있다.

근데 이걸 1바이트 조작하면 내가 원래 있었던 공간으로 안가고 앰한데로 간다.

그러면 그 앰한데를 간 곳의 +4에 담긴 주소로 (leave ret 시 pop 때문에)  ret을 시킨다!!



우리의 시나리오

마지막 한바이트를 조작시켜 버퍼의 시작 주소로 두고

버퍼 안에는 뭐 argv[2]의 위치주소들로 40개를 이쁘게 채워준다. (뭐 아무거나 딱 얻어걸리겠지?)

그러면 그 버퍼 안에 4바이트를 읽어서 그 위치(argv[2])로 돌아가는데..

그 위치에는 우리가 쉘코드를 박아놓아준다.



브레이크포인트는 strncpy 를 실행시킨 이후에 걸어준다.

problem_child +24 에 걸어줬다.


일단 40개를 A로 채우고 argv[2]에 뭐 우리 nop sled 100이랑 쉘코드를 넣다고 가정하자. 


그럼 0xbffffa34에 A가 40개 이쁘게 박히고 다음에 0xbffffa00이다!!!!!!!!!

그리고 저어어 밑에 0xbffffbe4 근처에 우리 nop sled가 보인다 여기가 아마 argv[2]같은데...


그래도 확인해보자...


오 버퍼 주소는 일단 맞고!!

쭉 내려서 엔터 하면


저기 repeats 124번 이라는 거 보니까 우리의 쉘코드 주소 (argv[2] 주소) 같다!!



버퍼에 argv[2]주소 *10으로 40개를 박고 한 바이트를 버퍼의 주소로 (\x34)를 오버플로 해주고

argv[2] 에 쉘코드를 이쁘게 박아주면 된다.





'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB bugbear  (0) 2016.09.29
LoB darkknight  (0) 2016.09.28
LoB skeleton  (1) 2016.09.23
LoB vampire  (0) 2016.09.23
LoB troll  (0) 2016.09.22

Stack Destroyer & LD_PRELOAD 사용 문제




뭐 egghunter는 없다 쳐도

buffer 44개를 싹 지워버리고 RET이후부터 stack에 있는 모든 주소를 0으로 초기화시켜버린다.

딱 RET 주소 빼고 버퍼 이후의 스텍을 다 초기화해버린다ㅠ


스택 메모리에 쉘코드를 주입할 수는 없다는 것이다...

그럼 버퍼 시작 이전에 쉘코드를 주입시키고 이 위치를 RET에 넣어볼까????????


이런 방법을 고민하는 것이 LD_PRELOAD를 이용하는 것이다.


LD_PRELOAD 가 뭐지?


프로그램이 동작할 때 메모리에 실행한 프로그램만 로드하는 게 아니라

프로그램 내부 사용하는 함수들도 실행을 해야되서 전부 메모리에 로드한다.

내부 함수들은 외부 라이브러리에 존재(다른 메모리 영역!!!!!!!!!!!!!에 존재)

ex) strcpy, memset 이런 것들도 


근데 이제 등록되지 않은 함수들을 사용하고 싶다면!!

 메모리 상에 로드를 시키고 프로그램을 실행 시켜야 하니 먼저 메모리에 로드를 시켜야겠지?

메모리에 로드 시킬 수 있는 환경변수가 있는데 이게 LD_PRELOAD 이다!!


이 환경변수에 파일을 등록하면 (C 파일 컴파일한 파일) 프로그램이 메모리에 올라가기 전에 환경변수에 등록한 파일을 먼저 메모리에 올린다.


전 문제처럼 파일경로와 이름 찌꺼기가 남아있음을 이용하는 것!!!


----------------------------------------------------------------시작해보자...


일단 환경변수에 올리기 위해 파일을 생성한다.

a.c를 만들어 컴파일 한다.


단 이때 컴파일 시에는 gcc -fPIC -shared a.c -o `python -c 'print "\x90" * 100 + "파일이름으로 쓸 수 있는 쉘코드"'`


공유 라이브러리로 컴파일하는 이유는

이를 메모리에 올리면 여러 프로그램이 동시에 활용할 수 있어 디스크와 메모리를 절약하고 또 우리가 쓰는 golem에다가 직접 공격이 가능하다.



LD_PRELOAD 로 이 컴파일한 파일을 올려보자.



이제 환경변수로 올라갔으니 모든 프로그램이 스택 전의 메모리에 이 쉘코드가 적재되어 있을 것이다.


x/100x $esp-4000 정도로 확인해봐서

쭉 내리다 보면 우리의 NOP sled 가 보인다.



이 주소를 공격하자. (필자는 0xbffff580을 선택함)


페이로드와 답이 나온다.






'pwnable > LoB (Lord of Bufferoverflow)' 카테고리의 다른 글

LoB darkknight  (0) 2016.09.28
LoB golem  (3) 2016.09.28
LoB vampire  (0) 2016.09.23
LoB troll  (0) 2016.09.22
LoB orge  (0) 2016.09.22

+ Recent posts