1.开始的步骤都是如出一辙,直接看C代码。(checksec的文件保护机制各项指标之后统一解释)
(之前定义了v4一个整型变量),进入一个死循环,给v4赋值,分别进入不同的子函数(begin函数如下说明)。解释encrypt:加密,点击去看,先初始化缓冲区,利用可以栈溢出的gets函数对输入的s与v0作比较进行加密,得出并返回加密后的文本。
2.加密是有条件的,当v0小于s的长度时才会进行加密,否则直接break退出,这是突破口。而strlen函数的性质时:当遇到\0时以其作为结束符,返回其之前的字符数量,而不是计算后面所跟参数的全部长度。所以可以先添上'\x00'使得跳出加密过程,又因为之前执行了puts函数,利用该性质加上gets的栈溢出,书写第一个payload来泄露gets的libc版本(注意64位的寄存器,可以参考之间的文章)。
3.发送完payload2后,注意是有两个recv的信息:第一个是“Ciphertext”文本,第二个是加密后的s,所以此时要在两个recvline()后得到的数据才是puts_addr,之后得到libc地址,以其套公式写出bin和system的addr。返回main函数后sendline令v4等于1,不要让它break退出,发送第二个payload(注意含有ret地址),交互得到程序控制权。
4.补充小下pwntools和C语言中的标准输出:
1.recvline():用于接收数据,直到遇到换行符为止,然后返回接收到的整行数据(注意不包括换行符!)。recvuntil('\n'):接收数据直到遇到换行符为止,然后返回接收到的数据(包含换行符!)。
2.puts函数会在打印文本的末尾自动添加一个换行符(\n)。这是因为puts函数会将字符串打印到标准输出,并在字符串末尾自动添加换行符,以便在输出文本的同时换行。而printf函数不会自动添加换行符。(对理解程序运行和下面的脚本执行)
3.python中的strip()表示清除数据两端的无关信息如换行回车,空格等,使信息呈现的更简练规范。
完整wp如下: