You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

客户端服务器通信访问桌面时出现UnicodeDecodeError

问题解决:反向Shell执行dir命令触发UnicodeDecodeError

问题场景

开发类netcat反向Shell工具,切换到Windows桌面目录(如C:/Users/Desktop)执行dir命令时,客户端抛出UnicodeDecodeError,错误显示'charmap' codec can't decode byte 0x81。

错误原因

Windows系统中,CMD命令输出默认采用GBK编码,但Python的subprocess模块默认会使用系统ANSI编码(此处为cp1252)解码命令输出。当桌面目录包含中文或cp1252编码不支持的特殊字符时,解码过程就会失败,触发上述错误。

解决方案

方案1:显式指定subprocess的编码为GBK

修改run_command函数,调用subprocess.run时指定编码为GBK,匹配Windows CMD的输出编码:

def run_command(command):
    try:
        result = subprocess.run(
            command,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            encoding='gbk',
            check=True
        )
        return result.stdout
    except subprocess.CalledProcessError as e:
        return e.output

方案2:以字节形式获取输出,手动处理解码

如果不确定目标系统编码,也可以先获取字节输出,再指定编码解码并设置错误处理策略(如忽略或替换无法解码的字符):

def run_command(command):
    try:
        result = subprocess.run(
            command,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=False,  # 以字节形式返回输出
            check=True
        )
        # 用GBK解码,无法解码的字符替换为?
        return result.stdout.decode('gbk', errors='replace')
    except subprocess.CalledProcessError as e:
        return e.output.decode('gbk', errors='replace')

额外优化:确保Socket传输编码一致

客户端和服务器的Socket传输建议统一使用UTF-8编码,避免跨编码问题:

  • 客户端发送输出时:client_socket.send(message.encode('utf-8'))
  • 服务器接收输出时:output = server.recv(buffer_size).decode('utf-8')

补充修正:修复客户端代码缩进错误

原客户端代码存在缩进错误(command = client_socket.recv(...)后的if语句未缩进),修正后片段如下:

# 修正后的客户端代码片段
command = client_socket.recv(buffer_size).decode()
if command.lower() == "exit":
    print("[*] Connection closed by server ...")
    break
if command.lower() == "open shell":
    client_socket.send("[*] reverse shell established\n[*] To exit reverse shell type in 'exit'".encode())
    while True:
        execute = client_socket.recv(buffer_size).decode()
        if execute.lower() == "exit":
            break
        message = run_command(execute)
        client_socket.send(message.encode('utf-8'))  # 统一UTF-8编码

内容的提问来源于stack exchange,提问作者user13021032

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:10:30