队里没人打pwn,由于某些原因还是练练吧。
我是pwn完全新手(就会点c语言),开个博客系列记录一下自己的pwn之路。
网上pwn题目不是很多,主要从攻防世界的几个pwn开始练吧
由于博客是个分享的地方,我就详细写写我遇到的大部分问题,网上pwn入门还是太深了
hello_pwn
这里先看文件多少位和栈保护啥的,这里不重要就不截图了
先看main函数,当dword_60106c==1853186401即可执行sub_400686函数
该函数就是输出flag,那怎么让它等于,先看read函数
函数名:read 头文件:<io.h> 函数原型: int read(int handle,void *buf,int len); 功能:用于读取打开文件的内容 参数:int handle 为要读取的文件 void *buf 为要将读取的内容保存的缓冲区 int len 读取文件的长度 返回值:返回实际读取的字节数
看这句话就是读取你输入的参数,读取到unk_601068处,长度就是0x10uLL
但什么是0x10uLL?0x开头是10进制,那么uLL结尾是十六进制的数字吗,查了一下不是
那么长度就是接收16位OK,我们看一下unk_601068和dword_60106c
发现目标dword_60106c就在写入位置下面4个位置,那么写内容填入到目标位置就可以了,但是填多少呢
我观察可以发现地址右边有db和dd的表示,查一下
db定义字节类型变量,一个字节数据占1个字节单元,读完一个,偏移量加1 dw定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2 dd定义双字类型变量,一个双字数据占4个字节单元,读完一个,偏移量加4
那么db是一个字节我们要写填好4给db,那就输入四个字节内容:aaaa(什么都可以)
然后到了目标位置他是dd,是双字类型,占据4个字节。我们要让这4个字节等于1853186401
我们要是直接输入1853186401,会发现这其实占了10个字节,因此我们要想一个字节和数字转换的方式。
字节是计算机存储数据的存储单元,是一个8位的二进制数,所以最多只能表示256个数字(0-255)。 编码是大家对计算机如何使用字节来表示一个字符的约定,可分为ASCII编码,ANSI编码(本地化编码),UNICODE编码(国际化编码)三种。
我们先把10进制转16进制
1853186401->6e756161
16进制转字符串
6e756161->nuaa
发现转换后正好是目标位置的双字类型,4个字节。
但是组合输入aaaanuaa发现没有flag,这个原因是因为大小端序
大端就是:存储最高有效字节在最小的地址(网络传输文件存储常用)。 小端就是:存储最低有效字节在最小的地址(计算机内部存储)。
大小端序就是字节顺序相反,因为我们覆盖存储,所有这里采用小端序
那么输入aaaa+aaun即可