BOF 원정대의 마지막 몬스터 death_knight를 잡아보자.!

* death_knight 소스


(death_knight.c)


소스코드를 보니 마지막 문제는 Remote BOF 문제였다.
원격에서 공격하는 방법인데
방법은 크게 두가지가 있다. 바인드쉘을 이용하거나, 리버스쉘을 이용하거나.

나의 계획은 바인드쉘을 이용할 것이었다.
일단 netstat 명령어로 소스코드대로 6666 포트가 열려있는지 확인해본다.


(열린 포트 확인)


파일 권한을 확인해보니 역시 setuid가 설정되어있고 eath_knight가 주인이다.



(setuid)



바인드 쉘을 구해서 테스트해보았다.
1337 포트를 오픈하는 코드이다.



(바인드쉘 테스트)



실행!


(1337 오픈!)



하지만 이 방법에 문제가 있었다.
(아직 이 문제에 대한 의문은 해결되지 않았다...)
(바로 bof 공격 코드까지 파이썬으로 만든후 공격을 성공시켜서 1337 포트가 열리는 것까지 확인했다.



(포트 오픈)



그런데 이상한점이 있었다.
여기서 '아! 이제 열렸으니 접속을 해볼까?' 하고 접속을 시도하면 짤린다...

와이어샤크로 분석해보니 ack 요청을 보내자마자 서버에서 fin 을 날려 종료시킨다...
이유는 모르겠다. 방화벽때문인가??...
계속 이것저것 시도했지만 여전히 접속이 안되었다...

그리하여 방법을 바꾸어 리버스 쉘을 이용하기로 했다.
내가 포트를 오픈하고 서버에서 나에게 접속을 시도하게 하는 것이다.
만약 이때 짤리면 내 방화벽을 내리면 되기때문에 이 방법으로 전환했다.

shell 코드는 인터넷에서 구했다. 내 호스트 IP 주소와 5555 포트번호로 접속을 시도하는 리버스 쉘코드이다.
이 코드를 이용하여 익스플로잇을 만든 후 실행했다.



(exploit 코드)




(공격 모습)



이 때 나는 nc를 이용하여 5555 포트를 열고 기다리고 있었는데 연결이 성립되면서 쉘을 획득 할 수 있었다.



(공격 성공)



쉘 획득!

이로서.....!

BOF 원정대의 모든 문제를 클리어할 수 있었다.



(all clear!)


'WarGame > 500 Project' 카테고리의 다른 글

(38/500) Suninatas - Binary(10)  (0) 2017.06.27
(37/500) Suninatas - Binary(9)  (0) 2017.06.27
(35/500) Lord of the BOF - xavius  (0) 2017.06.25
(34/500) Lord of the BOF - nightmare  (0) 2017.06.23
(33/500) Lord of the BOF - succubus  (0) 2017.06.23


BOF 원정대의 Xavius를 잡아보자!

* Xavius 코드


(xavius.c)



xavius의 특징
1. ret 주소에 라이브러리 함수를 사용하지 못한다.
2. 0x08, 0xbf 로 시작하는 주소 또한 ret 주소에 넣을 수 없다.
3. 단.! fgets를 사용한다.

fgets 함수의 특징을 알고 있어 이 문제를 쉽게 풀 수 있었다.
바로 fgets 함수는 입력 버퍼가 있어 그 곳에 입력을 저장한 후 실제 스택 버퍼에 옮긴다.
우리의 입력이 어딘가에 또 저장이 되어있다는 말이다.

사실을 확인해보기위해 strace를 통해 실제 시스템콜과 사용되는 메모리 주소를 확인해보자.



(read 시스템콜)



아래 write() 시스템 콜이 보인다. 그리고 그 바로 위에 어딘가에서 read 해오고 있는 모습을 볼 수 있다.
바로 이곳이 우리가 생각했던 임시 버퍼라는 것을 예상해 볼 수 있다.

그렇다면 진위를 파악하기 위해 gdb를 통해 실제 메모리를 확인해보자!


(임시 버퍼)


우리의 예상대로 0x40015000 주소가 바로 fgets의 임시버퍼였다.

우리는 바로 이곳에 쉘코드를 올리고 이곳으로 eip를 떨굴것이다.
그렇다면 ret 주소에 이 주소를 넣어야한다. ret 주소에 이 주소가 들어갈 수 있는지 확인!


(ret 주소)


ret 주소에 해당 주소를 입력해도 괜찮았다.

이제 이 주소에 Nop코드와 쉘코드를 올려주고 ret 주소에 해당 영역의 주소를 넣어준다.

공격!


(공격!)



(공격 성공)


쉘을 획득 할 수 있었다. :)


bof 원정대 orge를 잡아보자!

소스코드를 분석한다.


(orge.c)



orge의 소스코드를 보면 특이한 점이 있다. 바로 argv[0]의 길이가 77이여야한다는 점이다.
argv[0]는 프로그램경로 명(프로그램이름포함) 이다.
그러므로 이 문제는 링크를 이용해서 프로그램이름 길이를 조절해야한다.

77바이트니 그 안에 쉘코드를 올리고 argv[0]주소를 넘겨주어도 이 문제를 해결할 수 있을 것이다!

먼저 프로그램 경로명의 길이 77바이트를 맞추기 위한 작업이다.
gdb를 통한 메모리 확인을 위한 것이므로 간단히 cp를 이용해 77바이트만 맞추겠다.



(경로명 77바이트)



이 경로까지 경로 길이는 총 14바이트이므로 나머지 63바이트를 채워주면 된다.

이렇게 만들어진 문제프로그램을 gdb로 열어보자.



(gdb로 실행)



(메모리 확인(인자영역))



인자 영역이 초기화 되지 않는 것을 확인 할 수 있다. 44로 채워진 공간이 프로그램 이름이다.
이 주소를 ret주소로 넘겨주고 이 영역을 NOP + 쉘코드로 만들것이다.

먼저 링크를 생성하기 위해 해야할 일이 있다.
일단한번 만들어보겠다.



(에러발생)


에러가 발생하였다.
이유는 쉘코드 안에 \x2f 가 들어있는데 이것이 아스키문자로 /  를 의미한다. 그렇기에 경로로 인식이 되어서 해당 디렉토리가 없다는 뜻이다. 그러므로 \x2f 가 들어있는 곳을 감안해서 디렉토리를 만들어준다.



(디렉토리 생성)



디렉토리를 생성할 때 -p 옵션을 주어 하위 디렉토리도 한번에 생성한다.


(링크 연결)


그 후 링크를 연결한다.
대상은 Nop(31바이트) + 쉘코드(32바이트) 이다.

자 이제 준비는 끝났다. ret 주소로 아까 확인한 0xbffffbac 로 주고 프로그램을 실행한다!



(Segmentation Fault)



??..?!

뭐지

원인을 파악하기 위해 orge를 ormy로 복사한 후 ormy를 아까 했던 대로 링크를 걸어서 gdb로 열어본다.


(링크 재생성(복사본으로))



그 후 gdb로 메모리를 확인해본다.



(메모리 확인(인자영역))



어라? 이 주소가 맞는데

프로그램을 실행시킨 후 core 파일을 확인해본다.


(core 파일)



core 파일을 확인해보니 원인을 알았다.
이유는 잘 모르겠지만 gdb를 통한 메모리 주소와 조금 다르다...
nop 위치의 아무 주소를 하나 택한 후 그 주소를 넣어준다.

다시 원본 파일에 링크 생성하여 공격 준비



(원본 파일에 링크)


그 후 아까 확인했던 nop영역의 주소 하나를 골라 입력해준다.



(공격 성공)



쉘을 획득하였다 :)


'WarGame > 500 Project' 카테고리의 다른 글

(25/500) Lord of the BOF - vampire  (0) 2017.06.20
(24/500) Lord of the BOF - troll  (0) 2017.06.20
(22/500) Lord of the BOF - darkelf  (0) 2017.06.20
(21/500) Lord of the BOF - wolfman  (0) 2017.06.20
(20/500) Lord of the BOF - orc  (0) 2017.06.20

bof 원정대의 darkelf를 잡아보자!

차근차근 darkelf 소스코드부터 분석해보자.



(소스코드)


추가 된 것은 인자 길이를 체크하고 있다. 게다가 인자를 1개만 넘겨줘야한다.

하나만 넘겨주는데 그 길이도 48바이트를 넘어서는 안된다.

전전 문제에서 풀었던 방법으로 하면 위 조건들을 모두 충족시킨 체로 공격에 성공시킬 수 있었다.

전략은 바로
인자 주소로 ret주소를 넘기는 것이다.
44개 바이트 뒤에 ret 주소가 오는데 여기 ret 주소에 첫번째 인자의 주소를 넘기는 것이다.
그리고 첫번째 인자에 쉘코드를 올리면된다. (아직 인자를 초기화시키지 않기 때문에 공격 가능하다.)

그렇다면 메모리 주소부터 확인해보자!



(gdb 실행)



(메모리 확인 (사용가능한 영역))



예상대로 첫번째 인자의 주소 영역은 날라가지 않았다.
여기에 쉘코드를 올리고 이 주소를 ret주소로 넘겨줄 것이다.

그냥하면 주소를 딱 맞춰야 하기 때문에 Nop 슬레이딩을 쓸것이다. 비록 44바이트 중 내가 쓸 쉘코드는 32바이트 이기 때문에 12바이트 Nop 밖에 쓰지 못하지만 그래도 유용할 것이다.



(gdb 실행)


gdb를 통해 메모리 주소를 확인해본다. 먼저 0xbffffc28 주소로 ret 주소를 넘겨준다.


(메모리 확인(ret주소))


ret 주소에 0xbffffc28 이 잘 넘어간 것을 체크!



(메모리 확인(0xbffffc28))



0xbffffc28 주소 메모리를 확인해보면 Nop코드 위치이고 여기서 Nop이 실행되면서 쉘코드까지 실행될 수 있을거라는 것을 확인 할 수 있다.

그렇다면 darkelf를 공격해보자!



(공격 성공)



바로 쉘을 획득할 수 있었다.



'WarGame > 500 Project' 카테고리의 다른 글

(24/500) Lord of the BOF - troll  (0) 2017.06.20
(23/500) Lord of the BOF - orge  (0) 2017.06.20
(21/500) Lord of the BOF - wolfman  (0) 2017.06.20
(20/500) Lord of the BOF - orc  (0) 2017.06.20
(19/500) Lord of the BOF - goblin  (0) 2017.05.07


BOF 원정대 ORC 를 잡아보자!

먼저 orc.c 소스코드 파일을 주었으니 열어서 확인해본다.


(orc.c 소스코드)



orc 의 특징
1. 버퍼 40바이트이다. 
2. 인자로 프로그램명을 제외하고 하나 이상을 넣어줘야한다.
3. 모든 환경변수를 0으로 초기화한다. ( 환경변수 사용X )
4. 스택영역(\xbf) 영역을 사용해야한다.

그렇다면 gdb를 이용하여 실제 메모리에 어떻게 들어가나 확인해보자.!



(gdb로 프로그램 실행)



인자를 하나 이상 넣어줘야하고 ret 영역의 주소를 bf로 시작하는 주소로 입력해야한다는 조건을 맞추어 시작했다.



메모리 상태(환경변수 초기화)


메모리 상태를 확인해보니 환경변수 있을 자리에 전부 0으로 초기화 되어있는 모습을 볼 수 있다.

그런데?..!



메모리 상태(이용할만한 공간)



바로 ebp 아래 부분에 우리가 인자로 넘겨주는 값을 저장하는 영역을 발견하였다.
이 곳에 쉘코드를 넣고 이 주소를 ret주소로 넘겨주면 쉘을 획득할 수 있을 것 같다 :)

그렇다면 앞에 44바이트 중 우리의 쉘코드(32바이트)를 넣을 것이므로 
쉘코드 + 12바이트(더미) + ret 주소 형식에 맞추어 입력할 것이다. 우리 쉘코드가 위치할 주소 두번째 인자가 저장되는 곳이 0xbffffc2f 이므로 ret 주소에 이 주소를 넣어서 실행해본다.



메모리 확인(ret주소)



ret 주소에 우리가 의도한 0xbffffc2f가 잘 들어가 있는 것 체크!




(메모리 확인(쉘코드))



0xbffffc2f에 쉘코드가 올라가 있는지 체크!

전부 딱 맞게 올라가 있다. 그러므로 이제 gdb를 나와서 직접 실행해보자!

실제로는 메모리 주소가 조금씩 차이가 날 수 있다. 그러므로 일단 core dump를 위해 우리가 복사한 프로그램으로 실행시켜본다.




(bof 시도)



역시 한방에 안됬다. core 덤프 파일을 확인해본다!

우리가 입력한 ret 주소 0xbffffc2f 주소 근처를 확인해본다.




(core dump 파일)



확인해보니 0xbffffc2f에는 다른 것이 들어가있고 우리가 원하는 쉘코드 주소는
0xbffffc32 라는 것을 알 수 있다.

이제 ret 주소에 0xbffffc32를 넣어주고 실행!



(bof 성공)



쉘을 획득 할 수 있었다.

이렇게 orc를 처치하였다. :)


'WarGame > 500 Project' 카테고리의 다른 글

(22/500) Lord of the BOF - darkelf  (0) 2017.06.20
(21/500) Lord of the BOF - wolfman  (0) 2017.06.20
(19/500) Lord of the BOF - goblin  (0) 2017.05.07
(18/500) Lord of the BOF - cobolt  (0) 2017.05.05
(17/500) Lord of the BOF - gremlin  (0) 2017.05.05

+ Recent posts