level13 --- have no clue
우선 level13의 디렉터리를 확인한다.
attackeme라는 의심스러운 파일이 존재한다. attackme는 level14의 권한을 가지고 있고, setuid가 걸려있는 파일이다.
우리가 공결할 대상이 attackme일 가능성이 크다고 생각하고 hint를 보자.
level12의 버퍼 오버플로우의 소스와 매우 비슷하다.
하지만 배열을 선언하기 전에 long i=0x1234567 이라는 지역변수가 추가로 선언 되어있다.
long i=0x1234567은 무엇을 뜻하길래 추가로 선언되어 있을까?
버퍼 오버플로우 취약점이 발생한 이후 많을 프로그래머들이 이를 해결하기 위해 많은 방법을 고안하였다.
여기서 착안한 방법이 스택 가드 기법이다.
스택 가드 기법은 덮어씌여질 임의의 공간을 특정 숫자로 값을 할당해, 만일 이 값이 변경되었다면 버퍼 오버플로우가 발생했다고 가정하고 프로그램을 종료시키는 기법이다.
if(i != 0x1234567), kill(0,11)을 통해 확인 할 수 있다.
스택 가드가 있는 메모리 구조를 보면 아래와 같이 나타낼 수 있다.
즉, 우리가 버퍼오버플로우를 통해 RET을 변경시켜야하는데, Stack Guard의 값을 반드시 덮어쓰는 과정이 필요한 것이다.
Stack Guard를 확인하는 과정 혹은 덮어쓰는 과정을 우회하면 성공적으로 버퍼 오버플로우 취약점을 통해 셸을 띄울 수 있다.
Stack Guard를 우회하는 가장 쉬운 방법은 Stack Guard에 확인하는 값으로 덮어 씌우는 것이다.
level13의 소스는 0x1234567과 비교한다는 것이 하드코딩 되어있어 Stack Guard를 0x1234567로 덮어 쓰면 프로그램은 버퍼 오버플로우가 발생했다고 인지할 수 없다.
지금까지 공부한것을 바탕으로 attackme를 분석하자.
우리가 예상하기로 long i, char buf[1024]로 인해 0x404(1028) byte가 할달될 거라고 예측했는데,
실제로 0x418(1048) byte가 할당되었다. 무려 20바이트가 추가로 할당되었다.
이것을 컴파일러가 최적화를 위해 자동적으로 생성한 dummy값이라고 생각하면 된다.
더미를 포함한 메모리 구조를 다시 그려보면 아래와 같이 나타낼 수 있다.
gdb를 통해 attackme의 스택 구조와 공격 방법을 찾아보자.
파라미터로 "AAAAAAAA"를 전달하면 stack guard로 0x01234567 이 있고, SFP와 RET값을 확인 할 수 있다.
파라미터로 더미 값을 포함하여 "A"*1048을 전달하면 stack guard 값이 덮어지고 SFP, RET을 확인 가능하다.
지금과 같은 메로리 구조에서 continue 명령어를 입력하면 당연히 stack guard에 의해 오류 메세지가 나오고 종료될 것이다.
버퍼 오버플로우는 발생시키되 stack guard에는 원본 내용인 0x01234567을 write해야한다.
따라서 성공적으로 버퍼 오버플로우를 발생시키기 위해서 NOP*1036 + 0x1234567 + NOP*12 + shellcode의 형식으로 공격하면 된다.
'Wargame > FTZ' 카테고리의 다른 글
해커스쿨 FTZ level15 (0) | 2018.08.04 |
---|---|
해커스쿨 FTZ level14 (0) | 2018.08.02 |
해커스쿨 FTZ level12 (버퍼 오버 플로우) (0) | 2018.08.01 |
해커스쿨 FTZ level11 (포맷 스트링 버그) (0) | 2018.08.01 |
해커스쿨 FTZ level10 (0) | 2017.09.02 |