博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ctf-pwn的一些小技巧
阅读量:3891 次
发布时间:2019-05-23

本文共 3952 字,大约阅读时间需要 13 分钟。

目录

奇淫技巧

  1. scanf里面会认为+123还是123, 即+可以用来绕过某些栈中的canary;
  2. scanf可以触发malloc_consolidate释放堆到unsortedbin;

pwntools

当我们在写exp的时候有些需要去复制粘贴某些函数在plt表,got表的地址,或者找ROP的地址,有些时候复制粘贴不方便且不方便阅读,这样时候我们就可以用pwntools中提供的一些函数;

以32位程序的exp为例:

ROPgadget:0x0804872f : pop ebp ; ret0x0804872c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret0x0804843d : pop ebx ; ret0x0804872e : pop edi ; pop ebp ; ret0x0804872d : pop esi ; pop edi ; pop ebp ; ret0x08048426 : ret0x0804857e : ret 0xeac1

在exp中的0x0804843d,可以这样代替:

p32(rop.search(8).address)

其中rop:

proc = '文件路径'elf = ELF(proc)rop = ROP(elf)

找到gets函数在plt表中的位置,并将一段字符串写入bss段中:

p32(elf.plt['gets']) + 'aaaa' + p32(elf.bss()+0x100)p.sendline("要写入的字符串")

获得puts函数在got表中的地址:

p32(elf.got['puts'])

在exp中附加gdb调试exp:

context.log_level = 'debug'#context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']#deepin系统要加这句if args.G:    gdb.attach(p)

当带G参数运行exp时(python exp.py G),就会把gdb附加进去了;

格式化字符串常用函数 fmtstr_payload:

fmtstr_payload(num,{x_addr:str_addr})
num相当于%n$x中的n,表示第几个数,x_addr表示要修改的值的地址,str_addr表示需要修改成的值;

gcc

gcc编译:

NX:-z execstack / -z noexecstack (关闭 / 开启)   Canary:-fno-stack-protector /-fstack-protector / -fstack-protector-all (关闭 / 开启 / 全开启) PIE:-no-pie / -pie (关闭 / 开启)   RELRO:-z norelro / -z lazy / -z now (关闭 / 部分开启 / 完全开启)

alarm

遇到程序当中有alarm时可以:

1. 直接vim程序,修改alarm为isnan可以patch掉alarm函数;2. 或者sed -i s/alarm/isnan/g ./pwn1

系统调用

执行int 0x80可执行对应的系统调用:

查找int 0x80:

ROPgadget --binary ./file_name --only "int 0x80"ROPgadget --binary ./file_name --opcode cd80c3

比如对于系统调用: execve("/bin/sh",NULL,NULL)

系统调用号即eax应该为0xb(32位程序)或0x3b(64位程序)
第一个参数即ebx应该指向/bin/sh的地址,其实执行sh的地址也可以
第二个参数即ecx应该为0
第三个参数edx应该为0

64位系统调用 :

mov rdi,xxxx;		// '/bin/sh'字符串的地址  mov rax,59;			//execve的系统调用号  mov rsi,0;  mov rdx,0 syscall

Linux x64的传参方式:

它不同于x86的栈传参,它是优先6个寄存器传参,依次是RDI,RSI,RDX,RCX,R8,R9,然后多余的参数才传进栈内,所以在进行ROP,找gadget的时候注意先从rdi开始传参数,然后再是RSI,RDX,RCX,R8,R9,最后才是栈上面的;

int 80和syscenter采用的同样的传参顺序:eax,ebx,ecx,edx;

但是syscall的传参顺序变成了rdi,rsi,rdx,r10,r9,r8;
p.shutdown('send'):用于关闭读写通道,相当于Ctrl+c结束while循环;

libc

知道libc.so找函数的偏移的方法:

libc = ELF('./libc.so')system_offset = libc.symbols['system']binsh_offset = next(libc.search('/bin/sh'))

替换libc.so:

export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libproxychains.so.4"
p =  process(["file_name"],env={
"LD_PRELOAD":"./libc_name"})

在线查libc版本:

https://libc.blukat.me/

调试

gdb查看堆的快表:

p/x main_arena.fastbinsY

堆的其他查看:

p *(mchunkprt) 0x602010find_fake_fast // 用于查找fake fastbin

exit退出的函数通过修改<_rtld_global+3848>位置可以修改rip;

(先找_dl_fini的地址可以找到_rtld_global,它一个结构体;)

one_gadget可以通过realloc_hook(one)__malloc_hook(__GI___libc_realloc+n)来调整:

realloc_hook设置为选择好的one_gadget,将malloc_hook设置为realloc函数开头某一push寄存器处; push和pop的次数是一致的,若push次数减少则会压低堆栈,改变栈环境;

IDA下载:

http://fuckilfakp5d6a5t.onion.pet/

pwn异构环境搭建:

  1. 安装qemu
sudo apt-get install qemu-user

通过qemu模拟arm/mips环境,进而用gdb-multiarch进行调试;

  1. 安装gdb-multiarch
sudo apt-get install gdb-multiarch
  1. 安装共享库:
    根据需要安装,查看有那些库;

以mips为例:

apt-cache search "libc6" | grep mips
然后运行apt install +库名就可以安装;

  1. 运行方法:
    静态链接的binary直接运行即可,会自动调用对应架构的qemu;
    动态链接的bianry需要用对应的qemu同时指定共享库路径,使用-L指定共享库;
    例如运行add文件:
    qemu-mipsel -L /usr/mipsel-linux-gnu/ ./add
    用file命令查看文件信息,然后根据文件的类型选择qemu-的类型;

qemu-的类型:

sir@sir-PC:~/desktop$ qemu-qemu-aarch64       qemu-i386          qemu-mipsel        qemu-ppc64abi32    qemu-sparcqemu-aarch64_be    qemu-m68k          qemu-mipsn32       qemu-ppc64le       qemu-sparc32plusqemu-alpha         qemu-microblaze    qemu-mipsn32el     qemu-riscv32       qemu-sparc64qemu-arm           qemu-microblazeel  qemu-nios2         qemu-riscv64       qemu-tilegxqemu-armeb         qemu-mips          qemu-or1k          qemu-s390x         qemu-x86_64qemu-cris          qemu-mips64        qemu-ppc           qemu-sh4           qemu-xtensaqemu-hppa          qemu-mips64el      qemu-ppc64         qemu-sh4eb         qemu-xtensaeb
  1. 调试方法:
    可以使用qemu的-g参数指定端口:
qemu-mipsel -g 1234 -L /usr/mipsel-linux-gnu/ ./add

然后启动gdb-multiarch进行调试,先指定架构,再使用remote功能指定端口:

pwndbg> set architecture mipspwndbg> target remote localhost:1234

转载地址:http://vmlhn.baihongyu.com/

你可能感兴趣的文章
Java 和 Object-c的区别
查看>>
Windows环境下Android NDK环境搭建
查看>>
NDK Build 用法(NDK Build)
查看>>
Android NDK开发起步Hello Jni
查看>>
[已解决]AutoCompleteTextView 不显示匹配的内容,因为将空的内容添加进去了
查看>>
object c的浅拷贝(地址拷贝)和深拷贝(对象拷贝)
查看>>
object c son字符串的解析
查看>>
object c 非常强大的类的属性复制kcv键值码赋值
查看>>
Java中普通代码块,构造代码块,静态代码块区别及代码示例
查看>>
iOS 第4课 UILabel
查看>>
[已解决]junit.framework.AssertionFailedError: No tests found in
查看>>
“服务器端跳转”和“客户端跳转”的区别
查看>>
Datatables基本初始化——jQuery表格插件
查看>>
Servlet监听器——实现在线登录人数统计小例子
查看>>
Oracle笔记——简单查询语句 Oracle入门
查看>>
基于Hibernate和Struts2的用户管理系统小案例
查看>>
打开.class文件的方法
查看>>
基于windows平台Git+GitHub+Hexo搭建个人博客(一)
查看>>
基于windows平台Git+GitHub+Hexo搭建个人博客(二)
查看>>
Windows平台下SVN安装配置及使用
查看>>