35, 1/2 회원가입  로그인  
   I'm Not GoN
   [파도콘2011] karma100 과 goe200 질문입니다.

http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=3 [복사]


karma100 은 FSB 문제였는데, 혹시 푸는 방식이 main() 함수의
Return Address 변조를 통한 방법인가요?

Random Stack 때문에 그렇게 하려면 브루트 포싱이 필요했는데 정확히 맞아떨어져야 해서
잘 되질 않더군요. 다른 방법이 있는지 궁금합니다.
printf 를 호출한 후에 실행하는 명령이라곤

mov eax,0
leave
ret
mov dword ptr [esp], eax
call exit

이 정도밖에 없던걸로 기억하는데, 이 과정에서 발생할 수 있는 것이라곤
저한텐 ret 에서의 Return Address 변조를 통한 방법밖에 보이지 않네요.



그리고 goe200 의 경우는 64비트 시스템의 FSB 문제였는데
이건 main() 에서 exit를 직접 호출해줘서 exit@plt 가 존재했고
exit 호출시에 참조하는 Global Offset Table 을 변조해서 풀 수 있으리라 생각했는데
잘 생각해보니 GOT 의 주소를 변조한다고 해도 인자 전달하는데에 에로사항이 있을것 같더군요.

무엇보다 64비트 시스템인지라 주소에 널문자가 굉장히 많이 들어가는데
fgets 에서 입력을 받을 땐 널 문자에 관계없이 그냥 한줄 다 받지만,
snprintf 호출할 때 포맷 스트링 문자열로 입력받은 문자열을 넘기니 그땐 널 문자를
결국 포맷스트링 문자열의 끝으로 인식할 것이니 방법이 없더군요.

어떻게 푸는지 약간의 풀이법을 설명해주셨으면 감사하겠습니다..^^
(제가 첫글이군요)

  Hit : 5351     Date : 2011/01/17 08:17



    
blueh4g 저도 got 변경해서 exit를 system 같은 함수로 바꾼다고 하더라도 인자가 상수 1이라서 값 변경에 애로사항이 있더군요 (...)

그래서 함수로 안돌리고 rop처럼 buf에 인자값 집어넣고 해당 문자열을 참조해서edi(rdi) 에 주소값 집어넣는걸로 생각하고 삽질하다가 풀렸어요.
는 훼이끄

사실 삽질하다가 되는지 안되는지도 확인 못하고 대회시간 끝나서 집에와서 캔맥주 하나먹고 잤어요 (...)

자세한건 아랫분이 설명을 ↓
2011/01/17  
멍멍 karma100의 실마리는 exit() 함수 안에 있습니다. exit() 함수 안쪽으로 계속 따라가면서
살펴보시면 _dl_fini()라는 함수가 호출되고, 이 안에서 call *[---]와 같이 포인터참조하는 부분이
나옵니다. 이 참조되는 주소가 항상 일정하고 write 가능하기 때문에 이 주소를 덮어쓰시면 됩니다.
goe200은 전 아예 문제도 못 봤고.. 저희 팀원중에도 푼 사람이 없어서 답변을 못 드리겠네욤~
2011/01/18  
멍멍 혹시 goe200의 소스를 가지고 계시거나 기억하고 계시면 한번 올려봐주세요~ 2011/01/18  
Leopardan [goe200@localhost ~]$ uname -a
Linux localhost.localdomain 2.6.35.6-45.fc14.x86_64 #1 SMP Mon Oct 18 23:57:44 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
[goe200@localhost ~]$ ls
attackme attackme.c
[goe200@localhost ~]$ cat attackme.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char tmp[8];
int main()
{
char buf[100];
fgets(buf,100,stdin);
snprintf(tmp,8,buf);
exit(1);
}
2011/01/18  
ggabu420 오 자세한 설명 정말 감사합니다.

그새 윗분이 코드를 올려주셨네요.
2011/01/18  
멍멍 64비트 vmware 이미지 준비해놓은게 없어서 생각만 해보았습니다
일단.. exit의 GOT를 바꿔야하는건 확실하고요
karma100이나 karma300 같은 경우엔 ascii-armor(buf에 NULL 못 넣는 문제)를 우회하기
위해 환경변수나 argv를 이용했었는데.. 지금은 64비트이기 때문에 둘 다 못쓰겠네요
(NULL을 1개가 아닌, 4~5개 넣어야하니..)

결국 buf 변수를 이용해야 할 것 같은데요 (주소는 바뀌어도 offset은 일정하므로)
payload는 대충..

[덮어쓰고자하는 값(execve 주소의 하위 1 or 2바이트)만큼의 %NNNNx] + ["%"]
["아래 ABCD가 위치하고 있는 스택 주소 - fsb가 일어나는 시점의 ESP" 만큼의 $-flag] +
["$(h)n"] + ["ABCD( == exit GOT의 주소)"]

이렇게 될 것 같습니다. 4~5개의 NULL은 어차피 buf 변수의 많은 부분이 NULL이므로
자연스럽게 해결되거나 반복 실행으로 해결될 것 같네요. (반복 실행때마다 값이 바뀌므로)

마지막으로 execve의 인자는.. 출력되는 찌꺼기에 대해 symbolic link를 걸면 될 것 같습니다
이 부분은 타겟을 무한반복 실행하면서 해당하는 찌꺼기 들에 대해 모두 symbollic link를 걸어
두었다가 그것이 실행되기를 기다리는 방법도 있고.. 그 외 다른 꽁수같은 것도 있습니다
(이는 닉네임 singi님한테 물어보세요 ㅎㅎ)

이런식으로 공략하시면 될 것 같고..
실제로 해보면 생각한거랑 다른 경우도 많아서 장담은 못하겠네요 ㅋㅋ
서버 주소랑 계정 아시면 좀 알려주세요~ 다시 열어놨다고 하던데..
2011/01/18