- #include <stdio.h>
- #include <stdlib.h>
- void login(){
- int passcode1;
- int passcode2;
- printf("enter passcode1 : ");
- scanf("%d", passcode1);
- fflush(stdin);
- printf("enter passcode2 : ");
- scanf("%d", passcode2);
- printf("checking...\n");
- if(passcode1==338150 && passcode2==13371337){
- printf("Login OK!\n");
- system("/bin/cat flag");
- }
- else{
- printf("Login Failed!\n");
- exit(0);
- }
- }
- void welcome(){
- char name[100];
- printf("enter you name : ");
- scanf("%100s", name);
- printf("Welcome %s!\n", name);
- }
- int main(){
- printf("Toddler's Secure Login System 1.0 beta.\n");
- welcome();
- login();
- // something after login...
- printf("Now I can safely trust you that you have credential :)\n");
- return 0;
- }
코드를 보면 main( ) -> welcome( ) -> login( ) 순으로 흘러간다.
welcome( ) 함수를 살펴보면 name 배열에 100byte를 입력받고 그것을 인자로 출력한다. login( )함수에서는 2개의 입력받을 받아 출력하는데
scanf( )함수에 &가 없다.
또한 fflush(stdin)을 통해 버퍼를 비운다.
우리가 여기서 알고 가야할 점은
scanf( ) 는 &가 없으면 받은 인자를 주소로 인식한다.
gdb를 통해 분석해보자.
다음은 welcome을 disassembly 한 모습이다.
scanf( ) 가 실행되고 입력을 받은 이후를 봐야 하므로 실행이 된 이후 임의의 지점에 break point를 걸어준다. 필자는 0x804864d에 걸어주었다.
96byte 뒤의 주소를 덮어 씌울 수 있다.
그렇다면 원하는 곳의 4byte를 입력할 수 있다.
fflush(stdin)을 우회하기 위해 fflush의 got를 overwrite 한다.
이후 system("/bin/cat flag") 로 점프하면 플래그가 나올 것 같다.
exit( )함수를 사용할 것이므로 info function 명령어를 통해 exit( ) 함수의 주소를 알 수 있다. exit( ) 함수의 주소는 0x08048480이다.
exit( ) 함수의 got 는 0x804a018이다.
/bin/cat flag 의 주소는 0x080485e3 이다.
페이로드를 작성하면
buffer(96) + exit@got + 0x080485e3의 10진수 + "\n" + "asdfasdf" + "\n"
이정도가 될것이다
10진수를 취하는 이유는 scanf가 %d , 즉 정수를 인자로 받기 때문이다.
앙 기모띠
'pwnable > pwnable.kr' 카테고리의 다른 글
pwnable.kr -leg (0) | 2016.09.25 |
---|---|
pwnable.kr -random (0) | 2016.09.25 |
pwnable.kr -echo1 (0) | 2016.09.23 |
pwnable.kr -bof (0) | 2016.07.29 |
pwnable.kr -flag (0) | 2016.07.15 |