我通过检查并提取所有相关代码发现该应用程序是用 Django 构建的
在 CGI 协议中,有一些变量,包括要执行的脚本路径。我认为 uWSGI 协议也应该有相同的机制。
以下是从nginx代理到uwsgi套接字的示例数据包:
请注意,查询 uwsgi 套接字需要一些变量。经过一些尝试,我找到了几个重要的变量
所以,如果我能使用以下变量查询 uwsgi 套接字,就足以执行任意脚本:
我需要发送任意 TCP 数据包来查询 uwsgi,因为他们使用的是特殊的二进制协议。您可以在uwsgi 文档中找到 uwsgi 协议的详细信息。它非常简单,就像这样
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
/proc/self/cmdline。首先,我尝试使用SECRET_KEY`from`获取 shell settings.py,但没有找到序列化相关的代码。接下来,我发现 uWSGI 配置使用 TCP 套接字作为 Nginx 代理的后端服务,所以我尝试利用这一点。在 CGI 协议中,有一些变量,包括要执行的脚本路径。我认为 uWSGI 协议也应该有相同的机制。
以下是从nginx代理到uwsgi套接字的示例数据包:
请注意,查询 uwsgi 套接字需要一些变量。经过一些尝试,我找到了几个重要的变量
UWSGI_FILE,并SCRIPT_NAME用它们来指定要执行的脚本路径。 UWSGI_FILE其中一个是脚本路径,SCRIPT_NAME另一个与要触发的函数名称有关(我不知道具体是什么,但并不重要)。所以,如果我能使用以下变量查询 uwsgi 套接字,就足以执行任意脚本:
我需要发送任意 TCP 数据包来查询 uwsgi,因为他们使用的是特殊的二进制协议。您可以在uwsgi 文档中找到 uwsgi 协议的详细信息。它非常简单,就像这样
2 byte (length) + n byte (data)。渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
S2-029漏洞的问题是OGNL表达式二次执行,对应struts2版本为Struts 2.0.0 - Struts 2.3.24.1(2.3.20.3除外)官方对这个漏洞的简介是会对分配给某些标记的属性值进行二次执行,因此可以传入一个值,该值在rendered tags attribute会再次执行。
我们可以观察一下struts2是如何处理html的id标签,在看UIBean类之前,先讲一下OGNL二次执行的点,首先是这样的。
我在example.jsp的代码是这样的,接收参数的值用${value}包含了起来,就像这样。
那么我存进去的表达式,就会产生OGNL表达式执行,再看看后端的处理方式。
findString方法执行了一次表达式,随后findStringIfAltSyntax又解析了一次表达式
只要html标签的id值可控,就可以任意代码执行,name属性的值同样。
在struts2 2.3.24版本后官方增加了一些黑名单类列表以及一些包名,在struts-default.xml。
安全管理器也增加了包检查器,类检查器和成员类检查器,关于这些检查器的实现,都是从定义好的排除类名迭代循环匹配
结合POC之所以能够执行命令,是因为OGNL上下文一个安全检查方法的逻辑判断出错了,导致现有安全机制失效。关注一下ObjectPropertyAccessor类的setPossibleProperty方法,这个方法是对表达式完成赋值操作的。
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
我们可以观察一下struts2是如何处理html的id标签,在看UIBean类之前,先讲一下OGNL二次执行的点,首先是这样的。
我在example.jsp的代码是这样的,接收参数的值用${value}包含了起来,就像这样。
那么我存进去的表达式,就会产生OGNL表达式执行,再看看后端的处理方式。
findString方法执行了一次表达式,随后findStringIfAltSyntax又解析了一次表达式
只要html标签的id值可控,就可以任意代码执行,name属性的值同样。
在struts2 2.3.24版本后官方增加了一些黑名单类列表以及一些包名,在struts-default.xml。
安全管理器也增加了包检查器,类检查器和成员类检查器,关于这些检查器的实现,都是从定义好的排除类名迭代循环匹配
结合POC之所以能够执行命令,是因为OGNL上下文一个安全检查方法的逻辑判断出错了,导致现有安全机制失效。关注一下ObjectPropertyAccessor类的setPossibleProperty方法,这个方法是对表达式完成赋值操作的。
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
先调用一下这个模块看一下有哪些options是属于用户输入范畴的。
可以看到msf的模块也支持自定义checkurl,并且提供自定义测试标记,即响应码和匹配模式,并且还支持是否验证CONNECT通道代理方法。所以可以发现从用户自定义角度来说,msf相对nmap会更加人性化。不过基本上也是和nmap有异曲同工之妙,为什么这么说,因为,emmm……
然后对模块的方法实现进行一个分析,首先是一个初始化方法,其实就是默认值的赋值,和刚刚在options选项中看到的基本一样。
第二个方法是run_host(),这个方法就是自定义用户输入的内容。直接看一下执行主体的verify_target()方法,脚本里写的代码很简单。就是调用了send_request_cgi()方法获取到response,然后对response处理分析来判断是否存在proxy打开的情况。判断一共分3中,没有response判断没有proxy情况,判断普通http代理就通过判断响应码或者响应数据中的匹配模式,而判断CONNECT通道代理就是只判断响应码是否符合。
其实重点在于这个send_request_cgi()方法,定位一下这个方法地址,先看一下全局include,可以确定为includeMsf::Exploit::Remote::HttpClient,找到这个方法的实现脚本地址为/opt/metasploit-framework/embedded/framework/lib/msf/core/exploit/http/client.rb,其实如果看不懂的话可以用grep一键找。
理一下send_request_cgi()方法主体,执行方法主要是下面这一段,所以接下来要定位一下connect()方法,来弄清楚request_cgi的具体执行参数的表达含义。
connect()方法首先会判断一下ssl协议,然后开始连接http server,可以看到这边的参数opt其实就是制定远程主机rhost的值,实际上就是check_url传入的值。
追踪到/opt/metasploit-framework/embedded/framework/lib/rex/proto/http/client.rb的request_cgi()方法,其实也就是基本的定义参数,然后进行client客户端去连接。
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
可以看到msf的模块也支持自定义checkurl,并且提供自定义测试标记,即响应码和匹配模式,并且还支持是否验证CONNECT通道代理方法。所以可以发现从用户自定义角度来说,msf相对nmap会更加人性化。不过基本上也是和nmap有异曲同工之妙,为什么这么说,因为,emmm……
然后对模块的方法实现进行一个分析,首先是一个初始化方法,其实就是默认值的赋值,和刚刚在options选项中看到的基本一样。
第二个方法是run_host(),这个方法就是自定义用户输入的内容。直接看一下执行主体的verify_target()方法,脚本里写的代码很简单。就是调用了send_request_cgi()方法获取到response,然后对response处理分析来判断是否存在proxy打开的情况。判断一共分3中,没有response判断没有proxy情况,判断普通http代理就通过判断响应码或者响应数据中的匹配模式,而判断CONNECT通道代理就是只判断响应码是否符合。
其实重点在于这个send_request_cgi()方法,定位一下这个方法地址,先看一下全局include,可以确定为includeMsf::Exploit::Remote::HttpClient,找到这个方法的实现脚本地址为/opt/metasploit-framework/embedded/framework/lib/msf/core/exploit/http/client.rb,其实如果看不懂的话可以用grep一键找。
理一下send_request_cgi()方法主体,执行方法主要是下面这一段,所以接下来要定位一下connect()方法,来弄清楚request_cgi的具体执行参数的表达含义。
connect()方法首先会判断一下ssl协议,然后开始连接http server,可以看到这边的参数opt其实就是制定远程主机rhost的值,实际上就是check_url传入的值。
追踪到/opt/metasploit-framework/embedded/framework/lib/rex/proto/http/client.rb的request_cgi()方法,其实也就是基本的定义参数,然后进行client客户端去连接。
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
通过使用 dnSpy,我们可以从内存中导出电路板数据,并编写一些 Python 脚本来提取这些单元格。以下是它们的位置(行,列):
一开始我尝试点击那些单元格,结果发现棋盘的高度超过了屏幕高度,导致我无法点击单元格[24, 28]……🤨
总之,我们仍然可以使用 dnSpy 中的“设置下一条语句”功能来劫持程序流程。这里我让程序跳转到那一行。
直接修改
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
1. [20, 7]
2. [24, 28]
3. [7, 28]
一开始我尝试点击那些单元格,结果发现棋盘的高度超过了屏幕高度,导致我无法点击单元格[24, 28]……🤨
总之,我们仍然可以使用 dnSpy 中的“设置下一条语句”功能来劫持程序流程。这里我让程序跳转到那一行。
1
this.RevealedCells.Add(row * MainForm.VALLOC_NODE_LIMIT + column);
直接修改
row&col变量(在 dnSpy 中按 F2 键)到那些非地雷单元格的位置。然后跳转到GetKey获取标志的函数:渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
这次我们拿到的是一个 .NET 二进制文件(binstall.exe)。通过使用 dnSpy,我们可以看到它被大量不可打印的 Unicode 字符进行了混淆处理:
但是,通过使用进程监视器和dnSpy的调试器,我们仍然可以弄清楚程序逻辑:
它将一个文件写入
它设置了注册表,以便每次启动基于 Microsoft Windows 的应用程序时都会加载它
然后我开始使用 IDA Pro 分析 dll 文件。这里我还使用了hasherezade的dll_to_exe 工具来帮助我直接运行和调试 dll 文件。借助 IDA Pro 及其调试器,我们可以理清程序逻辑
它首先检查主进程的文件名是否为
然后它会下载文件内容
最后,它将使用 DLL 注入来挂钩
从json文件中我们得知,只有当我们使用主机名访问网站时,dll才会注入恶意js代码。通过查看flare-on.com
通过使用 Firefox 54 和其他浏览器检查该网站,我们会发现一些差异。例如,恶意代码
如果您使用的是其他浏览器,则会显示该
现在我们需要找出root用户的密码。这里密码验证逻辑也进行了混淆处理:
之后我们可以确定 root 密码是:
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
但是,通过使用进程监视器和dnSpy的调试器,我们仍然可以弄清楚程序逻辑:
它将一个文件写入
browserassist.dll到C:\Users\<User>\AppData\Roaming\Microsoft\Internet Explorer\browserassist.dll它设置了注册表,以便每次启动基于 Microsoft Windows 的应用程序时都会加载它
browserassist.dll。然后我开始使用 IDA Pro 分析 dll 文件。这里我还使用了hasherezade的dll_to_exe 工具来帮助我直接运行和调试 dll 文件。借助 IDA Pro 及其调试器,我们可以理清程序逻辑
browserassist.dll:它首先检查主进程的文件名是否为
firefox.exe(版本必须小于 55)。然后它会下载文件内容
https://pastebin.com/raw/hvaru8NU,并使用 RC4 进行解密。解密后的内容可以在这里查看。它本质上是一个 JSON 文件,指示了注入的恶意 JavaScript 代码的位置和内容。最后,它将使用 DLL 注入来挂钩
PR_Read&PR_Write函数nspr4.dll(nss3.dll这两个函数都是由 Firefox 加载的)。从json文件中我们得知,只有当我们使用主机名访问网站时,dll才会注入恶意js代码。通过查看flare-on.com
*.flare-on.com的源代码,我们可以确认这就是我们的目标,因为它包含类似这样的文件。/js/view.js通过使用 Firefox 54 和其他浏览器检查该网站,我们会发现一些差异。例如,恶意代码
su在网页中添加了一条命令:如果您使用的是其他浏览器,则会显示该
su命令无效:现在我们需要找出root用户的密码。这里密码验证逻辑也进行了混淆处理:
之后我们可以确定 root 密码是:
k9btBW7k2y,并以 root 用户身份登录。渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。
在使用
如果用 Vue/React 技术栈,并且不使用
DOM 中的内联事件监听器,如
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
在使用
.innerHTML、.outerHTML、document.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent、.setAttribute() 等。如果用 Vue/React 技术栈,并且不使用
v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患。DOM 中的内联事件监听器,如
location、onclick、onerror、onload、onmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
合适的 HTML 转义可以有效避免 XSS 漏洞。
完善的转义库需要针对上下文制定多种规则,例如 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等等。
业务 RD 需要根据每个插入点所处的上下文,选取不同的转义规则。
通常,转义库是不能判断插入点上下文的(Not Context-Aware),实施转义规则的责任就落到了业务 RD 身上,需要每个业务 RD 都充分理解 XSS 的各种情况,并且需要保证每一个插入点使用了正确的转义规则。
这种机制工作量大,全靠人工保证,很容易造成 XSS 漏洞,安全人员也很难发现隐患。
2009年,Google 提出了一个概念叫做:Automatic Context-Aware Escaping。
所谓 Context-Aware,就是说模板引擎在解析模板字符串的时候,就解析模板语法,分析出每个插入点所处的上下文,据此自动选用不同的转义规则。这样就减轻了业务 RD 的工作负担,也减少了人为带来的疏漏。
在一个支持 Automatic Context-Aware Escaping 的模板引擎里,业务 RD 可以这样定义模板,而无需手动实施转义规则:
模板引擎经过解析后,得知三个插入点所处的上下文,自动选用相应的转义规则:
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
完善的转义库需要针对上下文制定多种规则,例如 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等等。
业务 RD 需要根据每个插入点所处的上下文,选取不同的转义规则。
通常,转义库是不能判断插入点上下文的(Not Context-Aware),实施转义规则的责任就落到了业务 RD 身上,需要每个业务 RD 都充分理解 XSS 的各种情况,并且需要保证每一个插入点使用了正确的转义规则。
这种机制工作量大,全靠人工保证,很容易造成 XSS 漏洞,安全人员也很难发现隐患。
2009年,Google 提出了一个概念叫做:Automatic Context-Aware Escaping。
所谓 Context-Aware,就是说模板引擎在解析模板字符串的时候,就解析模板语法,分析出每个插入点所处的上下文,据此自动选用不同的转义规则。这样就减轻了业务 RD 的工作负担,也减少了人为带来的疏漏。
在一个支持 Automatic Context-Aware Escaping 的模板引擎里,业务 RD 可以这样定义模板,而无需手动实施转义规则:
模板引擎经过解析后,得知三个插入点所处的上下文,自动选用相应的转义规则:
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
在
跟随到
跟进
然后跟进到第一行的
对传入的
(本意应该是生成一个
这类似的语句
但是这里没有对拼接的参数进行验证,导致恶意sql语句被拼接,从而引发sql注入
除了
渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM
$res = db('user')->where(['id'=> 1])->insert(['username'=>$username]);下好断点后进入跟随到
insert函数中thinkphp/library/think/db/Query.php:2079public function insert(array $data = [], $replace = false, $getLastInsID = false, $sequence = null)
{
// 分析查询表达式
$options = $this->parseExpress();
$data = array_merge($options['data'], $data);
// 生成SQL语句
$sql = $this->builder->insert($data, $options, $replace);
....
跟进
$sql = $this->builder->insert($data, $options, $replace);然后跟进到第一行的
$data = $this->parseData($data, $options);中看看是如何解析数据的对传入的
$data变量进行遍历,当$val[0]=='inc'时,就会将$val[1]与$val[2]拼接(本意应该是生成一个
INSERT INTO `user` (`username`) VALUES ( username+1 )
这类似的语句
但是这里没有对拼接的参数进行验证,导致恶意sql语句被拼接,从而引发sql注入
除了
insert方法还有update也能触发该漏洞渗透爬虫软件 资源采集 劫持域名 提取抓料子 六合·色站·彩票·博彩·金融 接渗透拿站,各大网站数据-拖库-提权联系 域名劫持 DNS 入侵网站 联系:@hacker_HouZiM