首页 > 其他分享 >pwn题工具整理

pwn题工具整理

时间:2022-10-05 08:23:38浏览次数:49  
标签:bin attach libc 整理 地址 pwn -- 工具 buf

目录

语言

汇编

  • mov和lea
mov:取内存单元的值
lea:取内存单元的偏移地址
偏移地址由基址加变址组成

C语言

指针

  • 指针就是地址,地址就是指针

  • 指针地址,指针的值,指针指向的值

数据类型

  • 二进制数据在内存中没有类型,在变量层面分为整形和字符等类型,二者转换时需要处理,考虑可能的隐式转换
  • python字节流两种表示形式:数值和字符,可以使用“\数值”来表示单个字符

文件缓冲区和流

  • FILE是文件缓冲区的结构,fp也是指向文件缓冲区的指针
  • 流向文件缓冲区,buf自定义缓冲区
  • read本身不识别回车,有多少读多少,tty驱动器以一次一行的形式向read提供输入,read不用缓冲区
  • stdin和stdout是指向FILE结构体的指针

操作系统

编译链接

  • plt和got表:动态链接延迟绑定
  • 符号表:保存自定义函数和全局变量的名字和地址
  • 字符串表:保存用到的字符串
  • 调用者保存寄存器和被调用者保存寄存器

加载运行

  • 查看加载后的内存映射
cat /proc/id/maps

保护机制

  • PIE和ASLR都是地址随机化
  • PIE是编译时生效的,给程序一个固定的加载基址,如果不开PIE程序运行后的txt段等地址同静态文件的一样
  • ASLR是操作系统赋予的,0不开启任何随机化;1开启stack、libraries以及加载基址(如果开了PIE)的随机化;2开启heap随机化

格式化字符串漏洞

printf函数族

  • %p、%s、%d
  • %n:将已经打印的字符数量写入指定地址
  • N$:偏移N处(从函数的第二个参数算起)
  • .N(最大宽度)、N(最小宽度)

x86和x64

  • x86从栈上第二个参数开始打印
  • x64从第二个寄存器开始打印(一共六个)

使程序崩溃

  • %s将栈上内容做为地址读取

读取栈上数据

  • %p读取栈上内容

任意地址读取

char buf[100];
read(0, buf, 100);
printf(buf);
  • 找到buf变量地址同printf的buf参数的偏移N
  • 输入"arbitrary_addr+%N$s"

任意地址写

char buf[100];
read(0, buf, 100);
printf(buf);
  • 找到buf变量地址同printf的buf参数的偏移N
  • 输入"arbitrary_addr+%.Mp+%N$n"

工具

#自动计算偏移法一
def exec_fmt(pad):
	p = process("./fmt")
	p.send(pad) 	#send还是sendline以程序为准
	return p.recv()
fmt = FmtStr(exec_fmt)
print("offset ===> ", fmt.offset)

#自动计算偏移法二
fmtarg:在call printf处断下,fmtarg addr

#自动生成payload
fmtstr_payload(offset, address:value)

PwnTools

shellcraft

shellcode = asm(shellcraft.sh())
#另:调用system的shellcode
code0 = asm('xor rax,rax') 
code1 = asm('mov eax,0x3B')
code2 = asm('xor rsi,rsi')
code3 = asm('xor rdx,rdx')
code4 = asm('syscall')

LibcSearcher

  • 该工具很久没更新,可能搜不到,建议在线查用泄露地址的最后三位在线查libc-database
from LibcSearcher import *
libc=LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
sh_addr = libc.dump("str_bin_sh") + libc_base

调用c函数

from ctypes import *
lib = cdll.LoadLibrary("libc.so.6")
lib.srand(1)

设置环境

context(os = 'linux', arch='amd64', log_level='debug')

搜索ELF文件

#搜索程序
elf = ELF("./bin")
system_addr = elf.symbols["name"]
elf.search("/bin/sh")

#搜索库
lib = ELF("./libc.so.6")
lib.symbols["write"]
next(lib.search("/bin/sh"))或lib.search("/bin/sh").next()

本地加载指定libc

  • 本地加载的libc和远程libc大多数时候是不同的,libc不同,函数不同,行为不同
#查看libc版本
strings libc_32.so.6 | grep "LIBC"
#利用patchelf,libc和ld都可在glibc-all-in-one文件夹中找到
patchelf --replace-needed libc.so.6 你要换的libc的硬路径 ./pwn
patchelf --set-interpreter ld的硬路径 ./pwn
#或者
p = process(['./ld-2.23.so','./pwn'], env = {'LD_PRELOAD' : './libc-2.23.so'})
#或者
找一个使用低版本libc的系统

其他命令

payload = payload.ljust(260, b'a') #填充
strings bin | grep "/bin/sh" #搜索目标程序可打印字符串
recv()[:4] #切片
recvuntil不但可以用来定位输入,返回值还可以用来捕获输出
u64(p.recv(6).ljust(8, '\x00')) #解包输出地址
interactive() #取得shell后直接进行交互
注意区分send和sendline!二者都可以按行发送给远端(类似tty),sendline多发送一个换行符,对于read用send就行

远程拿不到shell的原因

  • libc给的不对
  • shell命令不支持
  • send发送字符的问题

gdb

gdb attach技巧

  • 脚本外attach
目标:查看程序运行到p函数前后的环境
原则:让程序等待数据发送,不能破坏输入和程序运行的前后时间关系
步骤:
1)proc.pidof(p)把进程号打印出来,gdb attach
2)脚本里在p之后最近的一次sendline处pause
3)b p下断点,查看调用前,finish查看调用后
4)c继续往下执行,程序等待输入,脚本回车pause
  • 脚本内attach
gdb.attach(p)
pause()
# attach和断点调试时,需要注意下断点或者attach的时候还未执行到目的地
  • 子进程attach
用ps -aux | grep查询子进程号
gdb attach子进程

gdb调试子进程

  • follow-fork-mode
set follow-fork-mode parent	#fork后跟进父进程
set follow-fork-mode child	#fork后跟进子进程,默认是这个
  • detach-on-fork
set detach-on-fork on	#只调试父/子进程中的一个,默认是这个
set detach-on-fork off	#父/子进程都在gdb控制下,其中一个正常调试,另一个被设置为暂停,结合inforior来回切换
  • inforior
info inferiors	#查看当前所有进程信息
inferior [ID]	#切换到指定进程

查看内存映射

  • vmmap查看内存段映射地址和权限

加载libc源码调试

  • 下载源码(已下载到本地glibc-all-in-one中),通过directory命令将libc源码加载进来,如果patch过libc,则仍然看不到源码

编译可调试版本的libc

/home/dfl/tools/glibc/glibc-2.23/configure --prefix=/home/dfl/tools/glibc/lib/ --enable-debug=yes --disable-werror --disable-profile CFLAGS="-O1 -g" CPPFLAGS="-O1 -g"
make -j8
make install

小工具

ROPgadget

ROPgadget --binary 文件名 --only 'pop|ret' | grep 'eax'
ROPgadget --binary 文件名 --string '/bin/sh'

objdump

  • 查看导出符号偏移地址
objdump -T libc | grep puts
  • 查看所有符号地址
objdump -t bin
  • 反汇编指定段
objdump -j .bss -d bin
  • 查看各段偏移
objdump -h bin

readelf

  • 查看文件头信息
readelf -h bin
  • 查看符号表
readelf -s bin

one_gadget

  • 查看libc中one_gadget地址
one_gadget libc

标签:bin,attach,libc,整理,地址,pwn,--,工具,buf
From: https://www.cnblogs.com/z5onk0/p/16755013.html

相关文章