5

渗透基础——Exchange版本探测的优化

 1 year ago
source link: https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%9F%BA%E7%A1%80-Exchange%E7%89%88%E6%9C%AC%E6%8E%A2%E6%B5%8B%E7%9A%84%E4%BC%98%E5%8C%96
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

渗透基础——Exchange版本探测的优化

30 Jun 2022

0x00 前言


在上篇文章《渗透基础——Exchange版本探测和漏洞检测》介绍了通过Python进行版本探测的两种方法,在版本识别上,首先从官网获得已知的版本信息,将版本信息存储在列表中,然后通过字符串匹配的方式获得Exchange版本的详细信息。开源的代码Exchange_GetVersion_MatchVul.py反馈很好。但是这个方法存在一个缺点:需要定期访问官网,手动更新扫描脚本中的版本信息列表。 为了进一步提高效率,本文介绍另外一种实现方法,通过访问官网,从返回数据中直接提取出详细的版本信息,优点是不再需要定期更新脚本。

0x01 简介


本文将要介绍以下内容:

  • 通过BeautifulSoup解析网页数据

0x02 通过BeautifulSoup解析网页数据


BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库,可以提高开发效率

pip install bs4

1.基本使用

在Python实现上,需要先通过requests库获取网页内容,再调用BeautifulSoup进行解析

测试代码:

from bs4 import BeautifulSoup
import requests
import urllib3
urllib3.disable_warnings()
url = "https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
} 
response = requests.get(url, verify=False, headers=headers)
soup = BeautifulSoup(response.text, features="html.parser")
print(soup.prettify())

以上代码将会访问https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019,将网页数据交由BeautifulSoup进行优化并显示

执行代码的部分输出结果示例:

   <tr>
    <td>
     Â Â Â
     <a data-linktype="external" href="https://support.microsoft.com/help/5014261">
      Exchange Server 2019 CU12 May22SU
     </a>
    </td>
    <td>
     May 10, 2022
    </td>
    <td style="text-align: center;">
     15.2.1118.9
    </td>
    <td style="text-align: center;">
     15.02.1118.009
    </td>
   </tr>
   <tr>
    <td>
     <a data-linktype="external" href="https://www.microsoft.com/download/details.aspx?familyID=a149e06c-62f4-4b62-adf8-7d382223a239">
      Exchange Server 2019 CU12 (2022H1)
     </a>
    </td>
    <td>
     April 20, 2022
    </td>
    <td style="text-align: center;">
     15.2.1118.7
    </td>
    <td style="text-align: center;">
     15.02.1118.007
    </td>
   </tr>

对于以上结果,每个"tr"节点对应一个版本信息,子节点"td"为具体的版本细节

2.只筛选出"tr"节点的内容

测试代码:

from bs4 import BeautifulSoup
import requests
import urllib3
urllib3.disable_warnings()
url = "https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
} 
response = requests.get(url, verify=False, headers=headers)
soup = BeautifulSoup(response.text, features="html.parser")
for tag in soup.find_all('tr'):
	print(tag)
	print("---")

执行代码的部分输出结果示例:

<tr>
<td>   <a data-linktype="external" href="https://support.microsoft.com/help/5014261">Exchange Server 2019 CU12 May22SU</a></td>
<td>May 10, 2022</td>
<td style="text-align: center;">15.2.1118.9</td>
<td style="text-align: center;">15.02.1118.009</td>
</tr>
---
<tr>
<td><a data-linktype="external" href="https://www.microsoft.com/download/details.aspx?familyID=a149e06c-62f4-4b62-adf8-7d382223a239">Exchange Server 2019 CU12 (2022H1)</a></td>
<td>April 20, 2022</td>
<td style="text-align: center;">15.2.1118.7</td>
<td style="text-align: center;">15.02.1118.007</td>
</tr>
---
<tr>
<td>   <a data-linktype="external" href="https://support.microsoft.com/help/5014261">Exchange Server 2019 CU11 May22SU</a></td>
<td>May 10, 2022</td>
<td style="text-align: center;">15.2.986.26</td>
<td style="text-align: center;">15.02.0986.026</td>
</tr>

接下来,尝试去除无效数据

3.提取出版本信息

测试代码:

from bs4 import BeautifulSoup
import requests
import urllib3
urllib3.disable_warnings()
url = "https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
} 
response = requests.get(url, verify=False, headers=headers)
soup = BeautifulSoup(response.text, features="html.parser")
for tag in soup.find_all('tr'):
	for string in tag.stripped_strings:
		print((string))
	print("---")

执行代码的部分输出结果示例:

---
  Â
Exchange Server 2019 CU12 May22SU
May 10, 2022
15.2.1118.9
15.02.1118.009
---
Exchange Server 2019 CU12 (2022H1)
April 20, 2022
15.2.1118.7
15.02.1118.007
---
  Â
Exchange Server 2019 CU11 May22SU
May 10, 2022
15.2.986.26
15.02.0986.026
---
  Â
Exchange Server 2019 CU11 Mar22SU
March 8, 2022
15.2.986.22
15.02.0986.022
---

接下来,可以尝试对精确版本进行匹配

4.精确匹配版本

测试代码:

from bs4 import BeautifulSoup
import requests
import urllib3
urllib3.disable_warnings()
url = "https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
} 
response = requests.get(url, verify=False, headers=headers)
soup = BeautifulSoup(response.text, features="html.parser")

version = "15.2.986.26"
for tag in soup.find_all('tr'):
	if version in tag.stripped_strings:
		print("[+] Exchange Information")
		for versiondata in tag.stripped_strings:
			if (len(versiondata)==5):
				continue
			print("    " + versiondata)

执行代码的输出结果示例:

[+] Exchange Information
    Exchange Server 2019 CU11 May22SU
    May 10, 2022
    15.2.986.26
    15.02.0986.026

对于Exchange较老的版本,无法获得准确的版本号,所以还需要实现粗略匹配版本的功能

5.粗略匹配版本

测试代码:

from bs4 import BeautifulSoup
import requests
import urllib3
urllib3.disable_warnings()
url = "https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
} 
response = requests.get(url, verify=False, headers=headers)
soup = BeautifulSoup(response.text, features="html.parser")

version = "15.2.986"
for tag in soup.find_all('tr'):
	if version in tag.text:
		print("[+] Exchange Information")
		for versiondata in tag.stripped_strings:
			if (len(versiondata)==5):
				continue
			print("    " + versiondata)

执行代码的输出结果示例:

[+] Exchange Information
    Exchange Server 2019 CU11 May22SU
    May 10, 2022
    15.2.986.26
    15.02.0986.026
[+] Exchange Information
    Exchange Server 2019 CU11 Mar22SU
    March 8, 2022
    15.2.986.22
    15.02.0986.022
[+] Exchange Information
    Exchange Server 2019 CU11 Jan22SU
    January 11, 2022
    15.2.986.15
    15.02.0986.015
[+] Exchange Information
    Exchange Server 2019 CU11 Nov21SU
    November 9, 2021
    15.2.986.14
    15.02.0986.014
[+] Exchange Information
    Exchange Server 2019 CU11 Oct21SU
    October 12, 2021
    15.2.986.9
    15.02.0986.009
[+] Exchange Information
    Exchange Server 2019 CU11
    September 28, 2021
    15.2.986.5
    15.02.0986.005

6.提取出网页数据时间

为了能够准确获得版本信息,这里还需要提取出网页数据的更新时间

标记网页数据时间的位置:

   <li>
    <time aria-label="Article review date" class="is-invisible" data-article-date="" data-article-date-source="git" datetime="2022-06-29T22:54:00Z">
     06/29/2022
    </time>
   </li>

定位该时间的代码:

print(soup.find_all('time'))

执行代码的输出结果示例:

[<time aria-label="Article review date" class="is-invisible" data-article-date="" data-article-date-source="git" datetime="2022-06-29T22:54:00Z">06/29/2022</time>]

提取出时间的代码:

print(soup.find('time').text)

执行代码的输出结果示例:

06/29/2022

结合以上信息,我们可以写出新的识别Exchange版本的代码,通过从官网读取数据信息来获得准确的版本,考虑自动化判断多个目标的情况下,为了避免多次访问网站读取数据信息,在代码结构上做了适当优化,只需访问一次https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019,将网页结果保存在变量中。代码已上传至github,地址如下:

https://github.com/3gstudent/Homework-of-Python/blob/master/Exchange_GetVersion_ParseFromWebsite.py

考虑到内网无法访问官网的情况,实现了一个从本地解析网页文件来获得准确的版本,代码已上传至github,地址如下:

https://github.com/3gstudent/Homework-of-Python/blob/master/Exchange_GetVersion_ParseFromFile.py

可以先访问官网并将网页内容保存为exchange.data,再执行脚本Exchange_GetVersion_ParseFromFile.py即可

0x03 小结


本文介绍了在Exchange版本识别上的优化方法,可以不必手动更新扫描脚本中的版本信息列表,开源代码Exchange_GetVersion_ParseFromWebsite.pyExchange_GetVersion_ParseFromFile.py


LEAVE A REPLY


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK