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

Python telnetlib实例二次调用无法读取内容的问题求助

解决Telnet会话连续读取加法题失败的问题

我编写了一个Python脚本用于连接Telnet会话,自动解答加法题目。第一次调用时能正常读取题目并计算答案,但第二次读取时raw_line仅返回b'\r\n',无法获取下一道题。

原脚本

from telnetlib import Telnet
from pathlib import Path

host = 'fcd070be5ee67a1a.247ctf.com'
port = 50028
tn = Telnet(host, port)     #Sets the telnet connection
path = Path('log.txt')


def get_line():
    #Grabs and returns everything from the initial print of the telnet terminal and returns it.
    raw_line = tn.read_until(b'?', timeout = 5)
    path.write_text(str(raw_line))
    line = str(raw_line.split()).replace('b', '').replace('?', '') 
    print(line)
    return line

def get_nums():
    #Cleans up, strips, and sums the numbers pulled from the line in get_line()
    line = get_line()
    ans = int(line.split(' ')[-1].replace('\'', '').replace(']', '')) + int(line.split(' ')[-3].replace('\'', '').replace(',', ''))
    print(ans)
    return ans

def answer():
    #prints the sum from get_nums() into the telnet terminal and enters
    tn.write(bytes(get_nums()) + b'\n')

answer()
get_line()

#Test to see if calling the instance outside of get_lines() would work
raw_line = tn.read_until(b'?', timeout = 5) 
print(raw_line)

脚本运行输出

PS C:\Users\jeffy\Documents\Python\247CTF> py .\telscript.py
['Welcome', 'to', 'the', '247CTF', 'addition', 'verifier!', 'If', 'you', 'can', 'solve', '500', 'addition', 'prolems,', 'we', 'will', 'give', 'you', 'a', 'flag!', 'What', 'is', 'the', 'answer', 'to', '146', '+', '9']
155
[]
b''
PS C:\Users\jeffy\Documents\Python\247CTF>

手动Telnet操作示例

Welcome to the 247CTF addition verifier!
If you can solve 500 addition problems, we will give you a flag!
What is the answer to 426 + 141?
567
Yes, Correct!
What is the answer to 357 + 263?

测试代码及输出

测试代码

from telnetlib import Telnet
from pathlib import Path

#Sets the telnet connection:
host = 'fcd070be5ee67a1a.247ctf.com'
port = 50028
tn = Telnet(host, port)
path = Path('log.txt')

#Gets and cleans the initial line
raw_line = tn.read_until(b'?', timeout = 1)
path.write_text(str(raw_line))
line = str(raw_line.split()).replace('b', '').replace('?', '') 
ans = int(line.split(' ')[-1].replace('\'', '').replace(']', '')) + int(line.split(' ')[-3].replace('\'', '').replace(',', ''))
print(line)
print(ans)

#Plugs the answer in to the telnet session
str_ans = str(ans)
tn.write(bytes(str_ans + '\n', 'utf-8'))

#Attempts to get next line
new_line = tn.read_until(b'?', timeout = 5)

print(new_line)

测试输出

PS C:\Users\jeffy\Documents\Python\247CTF> py .\test.py
['Welcome', 'to', 'the', '247CTF', 'addition', 'verifier!', 'If', 'you', 'can', 'solve', '500', 'addition', 'prolems,', 'we', 'will', 'give', 'you', 'a', 'flag!', 'What', 'is', 'the', 'answer', 'to', '170', '+', '486']
656
b'\r\n'
PS C:\Users\jeffy\Documents\Python\247CTF>

问题分析与解决方案

问题根源

  1. 换行符不符合Telnet协议:Telnet标准使用\r\n作为换行符,原脚本用\n发送答案,可能导致服务器未正确识别输入,无法返回下一题。
  2. 未处理服务器确认信息:提交答案后服务器会返回Yes, Correct!,原脚本直接读取下一题的?,缓冲区中残留的确认信息会干扰读取逻辑。
  3. 字符串处理逻辑脆弱:直接对字节流的字符串表示进行替换、拆分,容易出错且难以维护。

修正后的代码

from telnetlib import Telnet

host = 'fcd070be5ee67a1a.247ctf.com'
port = 50028

def solve_addition_problems():
    with Telnet(host, port) as tn:
        while True:
            # 读取题目直到问号出现
            raw_question = tn.read_until(b'?', timeout=5)
            if not raw_question:
                break
            
            # 解码为UTF-8字符串并清理格式
            question = raw_question.decode('utf-8').strip()
            print(f"收到题目: {question}")
            
            # 提取题目中的两个数字
            parts = question.split()
            try:
                num1 = int(parts[-3])
                num2 = int(parts[-1])
            except (IndexError, ValueError):
                # 若无法提取数字,可能已拿到flag
                print(f"结束,收到内容: {question}")
                break
            
            # 计算答案并发送
            answer = num1 + num2
            print(f"计算结果: {answer}")
            tn.write(f"{answer}\r\n".encode('utf-8'))
            
            # 读取服务器的确认信息
            raw_confirm = tn.read_until(b'\n', timeout=5)
            confirm = raw_confirm.decode('utf-8').strip()
            print(f"服务器响应: {confirm}")
            
            # 检测是否拿到flag
            if 'flag' in confirm.lower():
                print(f"获取到flag: {confirm}")
                break

if __name__ == "__main__":
    solve_addition_problems()

修正说明

  • 使用with语句管理Telnet连接,自动释放资源。
  • 将字节流解码为UTF-8字符串,简化文本处理逻辑。
  • 发送答案时使用\r\n,符合Telnet协议要求。
  • 每次提交答案后先读取并处理服务器的确认信息,确保缓冲区清空后再读取下一题。
  • 增加错误处理和flag检测,提升脚本稳定性和实用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:10:24