这题有C的源码,直接gcc运行后,拖进IDA分析一下到底出了什么问题
但是并看不出什么,打算用gdb动态看一下
因为看C的源码感觉没什么问题,可能是ebp覆盖报错什么的,我就在两个函数前都设置的断点
因为login中scanf没有用取地址,所以会直接读取当前栈,从而有危险性
welcome中的参数name所处位置是ebp-70,在IDA里面也可以看到,name参数所占的空间一共是96个字节(0x70-0x10)
但是我们要输入100个字节,那么多出来的四个字节就会被login函数使用,但是因为只能输入100个字节第二个password就无法输入,咋办,根据大佬的说法,是根据plt和got表完成的
大家可以看到printf函数执行时有个plt
百度搜了一下这是啥:
程序编译时会采用两种表进行辅助,一个为PLT表,一个为GOT表,PLT表可以称为内部函数表,GOT表为全局函数表,这两个表是相对应的,什么叫做相对应呢,PLT表中的数据就是GOT表中的一个地址
所以就是说是函数的地址
那么我们栈不够的问题就解决了,我们把剩下的字节改为printf的地址,之后在直接加上关键的系统命令就好了,这样当login的scanf函数调用时,调用的是printf的函数,之后就会把系统命令输出了,bingo
找一下printf的got表地址,直接objdump -R passcode 看函数表就好了
感觉方法是对的,但是就是不奏效,我后来参考了一下别人的做法,发现唯一的区别就是编译后的地址偏移不同,我又重新远程下载了文件,特地学了一下
#coding=utf-8
from pwn import *
import struct
addr = 0x0804a00 #printf_address
shellcode = 'a'*96 +p32(addr)+'134514147'
conn=remote('143.248.249.64',22)
conn.sendline(shellcode)
conn.interactiv