prob1 파일을 다운받고 실행을 시켜보자
허가 거부라 뜬다.
ls -al로 확인을 해보니 실행권한이 없는 것을 알 수 있다.
따라서 파일에 접근 권한을 주기 위해 chmod를 사용하였다.
chmod는 기존 파일 또는 디렉토리에 대한 접근 권한(파일 모드)을 변경할 때 사용되고 root에서 사용할 수 있다.
chmod +x prob1을 통해 prob1 파일에 실행권한을 부여하자
다시 ls -al을 통해 확인하자
(위에 보다 시간이 더 빠른 이유는 처음에 ls -al로 확인하지 않고 실행권한을 부여해서 다시 다운받아서 해서 그렇습니다.)
user(파일의 소유자)는 rwx접근권한을 가지게 되고, 이는 group도 마찬가지이다. others는 r과 x만 가능하다.
즉, 실행권한이 모두 다 부여된 것을 확인할 수 있다.
이제 파일을 실행해보자
문제는 단순히 이름과 input값만 입력을 받는다.
checsec으로 보호기법을 확인해보자
NX disabled 되었음을 알 수 있다. 셸코드를 통해 공격을 할 수 있다.
IDA로 코드를 확인해보자
name에 50바이트를 입력을 받고 gets()함수를 통해 문자열을 입력받는다.
gets()함수에서 버퍼오버플로우가 이루어진다.
name변수를 더블클릭하면 name 변수가 bss 영역에 있다.
bss는 초기화되지 않은 전역 데이터를 위한 영역으로 일반적으로 static 키워드로 선언된 초기화되지 않은 지역 변수처럼 파일 범위로 선언된 모든 초기화되지 않은 변수를 포함한다.
또한, NO PIE이기 때문에 name의 주소 0804A60은 변하지 않는다.
gdb를 이용하여 main함수를 disassemble 해주자.
main 함수를 disas 해보면 위와 같다.
main+3을 보면 스택에 0x14 = 20바이트를 할당하는 것을 볼 수 있다.
또한 다음의 사진을 보면 s가 ebp-0x14임을 알 수 있고 main+69를 보아도 알 수 있다
따라서 메모리구조가 다음과 같다는 것을 알 수 있다.
s[20] |
sfp[4] |
ret[4] |
prob1.py에 exploit 코드를 짜준다.
read를 통해 name에 쉘코드를 입력하고 gets를 통해 main함수의 ret를 name의 주소로 덮어씌우면 이 문제는 해결될 것이다.
ctf.j0nqhyun.xyz 주소에 3003 포트로 원격접속한다.
shellcode 변수에 shellcode를 작성해준다.
recvuntil (“문자열”) 은 그 문자열이 나올 때 그다음부터 받겠다는 의미이다. 따라서 이걸로 써주고 그다음에 shellcode를 name에 받는다.
그다음에 다시 recvuntil을 써주고 payload에 a*24+”\x60\xa0\x04\x08"을 써준다. 이렇게 써준 이유는 메모리 구조에서 s와 sfp영역을 dummy값으로 채워야 되기 때문에 이렇게 써주고 그리고 ret영역에 name의 주소를 적어준다. interactive를 통해 쉘에 명령을 직접 송신하도록 써주면 코드는 완성이다.
실행시켜 보자
prob1.py은 실행권한이 없기 때문에 root계정에 접속해서 chmod +x로 실행권한을 부여한다.
flag를 구했다!