zj3t

email: euntaejang@gmail.com

Latest Posts

hackerschool ftz-level19(기초적인 rop을 학습할 수 있도록 풀이함)

By 오후 10:47 ,

이번문제는 약간 난이도가 있는 문제였습니다. 일단 스택의 구조를 정확히 알아야 했더군요 예전에 풀었을 때에는 쉬운 방법으로 풀었었는데 이번에는 ROP도 약간 배웠겠다. 
POP| POP| RET을 조금 써보고 싶어 다른 방법으로 풀었습니다. 



일단 문제의 코드입니다. 권한상승을 위한 함수가 없는게 눈에 띕니다. 따라서 이 문제는 return to lib 기법을 사용하라는 문제임은 확실합니다.

라이브러리에서 필요한 함수(예를 들어 system(), setreuid() 등)의 주소를 알아내어 사용하는 기법입니다.

두가지 방법이 있습니다. 
1.                          ebp
------------------------------------------------------------------------------------------
 | buf[20] | dummy[20] | sfp | setreuid() | ad of shellcode | 매개변수1 | 매개변수2 |
-------------------------------------------------------------------------------------------
낮                                                                                                     높

리턴 어드레스에 권한상승을 해주는 함수를 넣었습니다. 이 때 스택은 함수 바로 뒤가 아닌+4 한 거리에서 매개변수들을 가져와 실행됩니다. (바로 뒤는 그 함수의 ret의 주소) 그리고 ret 으로가서(여기서는 ad of shellcode) /bin/sh 쉘 코드가 담긴 환경변수의 주소를 실행합니다.

그렇게 하면 권한을 얻고 /bin/sh를 실행시킴으로써 level20의 권한으로 my-pass를 실행시킬 수 있습니다.





환경 변수의 주소를 얻는 코드!!!


이렇게 setreuid의 주소와 환경변수의 주소만 가지고 문제를 clear 할 수 있었습니다.
(0x00000C1C 는 3100 즉 level 20의 id)

2. 이번 방법은 rop 공부를 할 때 배운 pop ret을 이용 한것인데, 굳이 이 문제를 이렇게 푸는 사람을 드물겠지만 한번 보여드리겠습니다.

낮                                                                                                           높
| buf[20] | dummy[20] | sfp | setreuid() (ret) | pop pop ret | 3100 | 3100 | system() | \x90*4(ret)| "/bin/sh"문자열의 주소(환경 변수 아님) | 

우선 아까 위에서는 setreuid의 리턴 값에 /bin/sh를 실행시키는 쉘코드를 넣었지만 이번 방법은 pop pop ret 을 넣었습니다.

여기서 중요한데 깊게는 안다루고 간단히 설명하자면

setreuid(3100, 3100) 함수가 실행되고 나면 esp가 한칸 올라가게 된다.

말이 조금 어려운데 만약 pop pop ret이 없다면, (빨간색이 esp의 위치)
                                                                                                  
| buf[20] | dummy[20] | sfp | setreuid() | setreuid의 ret주소 | 3100 | 3100 | system() | 
                                                                      

이랬던 스택이 
                                                                                     
| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() | 
                                                                            
이렇게 된다. 그러므로 우리는  esp 가 system 함수를 실행 시킬 위치가 아니게 된다.

                                                            
| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() | \x90*4 | "/bin/sh"|
                                                                    

이 구조에서 그렇다면 어떻게 esp 를 

| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() | \x90*4 | "/bin/sh"|
                                                                        

이렇게 움직여서 system() 함수를 실행시킬 수 있을까?

그것이 바로 pop pop ret 을 setreuid()의 return address에 넣어 esp 의 위치를 두번 이동시킨뒤 채택하는 것이다.

(채택이라는 말이 조금 이상한데 ret 명령어 자체가 pop eip jmp eip 라 채택이라고 받아들이면 쉬울 것이다.)

따라서 그림을 보면 

-처음 상태
| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() |
                                                        

-pop
| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() |
                                                                        
-pop
| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() | 
                                                                                 

-ret (채택)
| buf[20] | dummy[20] | sfp | setreuid() | ret | 3100 | 3100 | system() |
                                                                                             

이렇게 esp를 바꿔주어 system() 을 실행시킬 수 있는 것이다.

system() 함수에서도 마찬가지이다. \x90*4가 아닌 pop | ret 가젯을 써서 명령어를 이어 붙일 수가 있다.
여기서는 그럴 필요가 없기 때문에 하지 않았다.



먼저 system(), setreuid() 함수를 이용할 것이기 때문에 이 두 주소의 주소를 구한다.



이는 아주 유명한 코드인데 라이브러리 영역에서 "/bin/sh" 문자열이 있는 주소를 찾는 코드이다.


이렇게 "/bin/sh" 의 주소 그리고 system(), setreuid()의 주소를 구했다. 이제 pop | pop | ret이 있는 주소의 위치를 찾으면 된다.


이는 objdump -d(disassemble) ./실행파일 명 | egrep "찾을 어셈블리 명령어"

을 이용하면 된다. 

그러면 여러 pop ret 가젯들이 보이는데 이어져 있는 주소를 골라야 한다 여기서는 804849d 정도면 될 것 같다.


그럼 이제 공격 코드를 작성하면 성공 할 수 있다.

첫번 째 방법으로 푸는 것이 아마 이 문제 출제자의 목적이라고 생각이 되지만, 밑에 방법으로 푸는 것이 나중에 어차피 공부할 것을 미리 공부하는 마음가짐으로 공부하면 재밌을 것이라 생각된다.

You Might Also Like

0 개의 댓글