一些常用小操作

替换 libc

查看 libc

strings libc.so.6 | grep ubuntu
patchelf --set-interpreter /home/ctf/glibc-all-in-one/libs/2.34-0ubuntu3.2_amd64/ld-linux-x86-64.so.2  ./pwn

patchelf --replace-needed libc.so.6 /home/ctf/glibc-all-in-one/libs/2.34-0ubuntu3.2_amd64/libc.so.6 ./pwn

给libc ld可执行权限就可以了

开启 PIE/ASLR 下调试

start
vmmap 看代码段
找到对应的代码后三位换掉下断点
r

gdb 调试

python调试代码

gdb.attach(p)
pause()
gdb.attach(p, gdbscript='b *main')

gdb 调试溢出长度

  1. 先生成字符串,然后复制
pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
  1. 等到需要我们输入的时候把这串字符串输进去

  2. 等到发生溢出时我们会知道溢出的地址,此时我们复制这串地址,然后用 cyclic -l +溢出的地址 就可以得到溢出长度了

    image-20241023234012148

    有事也会发生没用报错的情况,而是停在 ret 上,无论怎么 ni,fin 都没法往下,此时我们直接复制 ret 旁边的地址用也一样可以

    image-20241024000326594

gdb指令

run		# 将程序完全跑一遍
start   # 运行到类似于入口点的地方
i r 	# 查看寄存器
i b 	# 查看断点
disassemble $rip	# 反编译rip所在函数的位置,查看rip在什么地方
b *0x000055555555527a # 设置断点,这里b即位breakpoint
ni		# 单步运行程序
c		# 到下一个断点
d 2 	# 删除断点
disable b 2 # 使断点失效
enable b 3  # 使断点重新生效
si 		# 步入
finish  # 步出
x		# 查看
set		# 改变值
p/print # 打印值
vmmap   # 查看内存基本情况
cyclic 100 #打出100长度的字符串
cyclic -l kaaaaaaa #查找字符
x/20g rbp
x/数字显示格式 地址
x查看内存
20查看行的内存
g以16进制显示
rbp查看内存的开始是rbp的所指的地址
x/20i 以汇编显示
x/20g 以16进制,八个字节显示
x/20b 以16进制,单字节显示
x/20w 以16进制,4字节显示
x/20d 以10进制,4字节显示
x/20s 以字符串形式显示

set *0x7fffffffe550=0x61
set *((unsigned int)$ebp)=0x61
// 利用解引用符号,修改地址里面的值
search -t string xxxx

64 位函数传参

前六个参数依次存放于 rdi rsi rdx rcx r8 r9

ROPgdget

ROPgadget --binary ezpwn --only "pop|ret"

alpha3

1.生成shellcode

from pwn import *
context.arch='amd64'
sc = shellcraft.sh()
print asm(sc)

2.将上述代码保存成sc.py放到alpha3目录下,然后执行如下命令生成待编码的shellcode文件

python sc.py > shellcode

3.使用

python2 ./ALPHA3.py x64 ascii mixedcase rax --input="shellcode"

我这里只能用python2,不然说我缺少一些库????

x86 ascii uppercase (数字+大写字母)

x86 ascii lowercase (数字+小写字母)

x86 ascii mixedcase (数字+大小写字母)
复制代码
Valid base address examples for each encoder, ordered by encoder settings,
are:

[x64 ascii mixedcase]
  AscMix (r64)              RAX RCX RDX RBX RSP RBP RSI RDI

[x86 ascii lowercase]
  AscLow 0x30 (rm32)        ECX EDX EBX

[x86 ascii mixedcase]
  AscMix 0x30 (rm32)        EAX ECX EDX EBX ESP EBP ESI EDI [EAX] [ECX]
                            [EDX] [EBX] [ESP] [EBP] [ESI] [EDI] [ESP-4]
                            ECX+2 ESI+4 ESI+8
  AscMix 0x30 (i32)         (address)
  AscMix Countslide (rm32)  countslide:EAX+offset~uncertainty
                            countslide:EBX+offset~uncertainty
                            countslide:ECX+offset~uncertainty
                            countslide:EDX+offset~uncertainty
                            countslide:ESI+offset~uncertainty
                            countslide:EDI+offset~uncertainty
  AscMix Countslide (i32)   countslide:address~uncertainty
  AscMix SEH GetPC (XPsp3)  seh_getpc_xpsp3

[x86 ascii uppercase]
  AscUpp 0x30 (rm32)        EAX ECX EDX EBX ESP EBP ESI EDI [EAX] [ECX]
                            [EDX] [EBX] [ESP] [EBP] [ESI] [EDI]

[x86 latin-1 mixedcase]
  Latin1Mix CALL GetPC      call

[x86 utf-16 uppercase]
  UniUpper 0x10 (rm32)      EAX ECX EDX EBX ESP EBP ESI EDI [EAX] [ECX]
                            [EDX] [EBX] [ESP] [EBP] [ESI] [EDI]

pwntools

  • p.recv(), p.send(), p.sendline(): 收发数据。
  • p.recvuntil(): 等待特定字符串。
  • p32, p64: 打包数据为小端格式。
  • flat(), cyclic(): 生成 Payload。

调试

使用 Python 脚本动态调试

  • 在脚本中设置断点:

    gdb.attach(p, gdbscript='b *main')
    

常用 Payload 模板

  • Buffer Overflow:

    pythonCopy codepayload = flat(
        b'A' * offset,
        system_addr,
        b'JUNK',  # 伪造的返回地址
        bin_sh_addr
    )
    p.sendline(payload)
    
  • ROP 链:

    pythonCopy coderop = ROP(elf)
    rop.raw(b'A' * offset)
    rop.system(next(elf.search(b'/bin/sh')))
    p.sendline(rop.chain())
    

查找以\x00开头的汇编

from pwn import *
from itertools import *
import re

for i in range(1, 3):
    for j in product([p8(k) for k in range(256)], repeat=i):
        payload = b"\x00" + b"".join(j)
        res = disasm(payload)
        if (
            res != "        ..." #…表示没有对应的汇编
            and not re.search(r"\[\w*?\]", res)#第二个正则是防止出现[ecx]这种,因为可能导致无效地址访问

            and ".byte" not in res#第三种是数据定义类型,这种可能会导致系统异常解释shellcode
        ):
            print(res)
            input()

不用for j in product([chr(k) for k in range(256)], repeat=i):的原因是chr(128)之后的ASCII码encode后变成utf-8编码,其对应的utf-8编码会变成两个字节,这样总共就三个字节了,因此\x7f后面的字符对应的bytes都是2byte.

为了可以编码到\x80以上的字节,必须要用p8来生成

from pwn import *
from itertools import *
import re
for j in product([chr(k) for k in range(256)], repeat=1): #chr()后再encode()可以得到字节,但是不能遍历所有
	print(b"".join(j).encode(),end="")

沙盒过滤

seccomp-tools dump ./pwn
posted @ 2024-10-14 14:19  r_0xy  阅读(45)  评论(0)    收藏  举报