Loading... ## 前言 武汉大学 CTF俱乐部招新,这次的招新是一个比较特殊和好玩的游戏,下面小小的记录一下怎么制作一个脚本来刷分。 首先游戏是通过`ssh noname.plus -p 2023`来连接到远程地址,并且进行游戏。  游戏的大致流程就是屏幕输出一个数字,你需要记住这个数字,在一定时间后数字会笑死并且你需要给出这个数字是什么。数字从1位开始增加,每次增加1位数,游戏在30min后会关闭链接。 <div class="tip inlineBlock warning"> 实测应该是在580轮左右(考虑显示数字和消失数字的时间) </div> ## 大致思路 ### 遇到的坑 #### 使用子进程来完成 首先我使用的是C#语言,想着我直接读取一个控制台程序就好了。结果发现并不是这个样子:(。因为我发现读取控制台程序的时候,SSH直接提示`No PTY Request`,而当我想要提供一个伪终端环境的时候,我才发现C# 并没有 PTY 的库。 #### 使用SSH库来完成 同时,我又尝试了能不能直接通过 SSH 库来完成,结果发现是一样的 #### 在Python中使用 SSH 库来完成 我转战了语言,换到了 Python,结果发现 Python 对于连接这个地址是有问题的,因为他不需要任何凭据。这个不属于正常的 SSH 登录,可能算一个 Feature,但是这个地方就让我一直卡在如何连上对应的服务器... ### 解决方案 最后,我想到的解决方案是读取创建一个PTY环境,并且以监控子进程的方式来读取子进程的输出信息,然后捕获输出的信息,并且输入。 ## 实现 ### 前置库 - pexpect - re ### Coding 首先肯定是先创建一个子进程,使用: ```python child = pexpect.spawn(f"ssh noname.plus -p 2023") ``` 来创建一个子进程,并且监控屏幕的输出信息"Input Your player ID:" ```python i = child.expect(["Input Your player ID:", pexpect.EOF, pexpect.TIMEOUT], timeout=10) ``` <div class="tip inlineBlock warning"> 你可能先需要确认是否添加到你的 Known_Hosts 里面,由于我关闭了这个功能,所以不会提示 </div> 然后我们判断是否工作正常,也就是通过 index: ```python if i == 0: user = input("请输入用户名:") child.sendline(user) ``` 如果是正常的,那么我们开始进入游戏: ```python child.sendline("1") ``` 然后便是不断的判断输出的信息然后输入了 ```python child.expect(["Enter numbers now:"]) content = filter(child.before.decode()) if is_digit_ascii(content): number = extract_number(content, length) child.sendline(number) ``` 然后我们让他在一个死循环里面工作就ok。 <div class="tip inlineBlock success"> 为了让大家积极参与,笔者隐藏了几个函数。 - filter: 是过滤光标位置的控制字符和颜色字符,提示:可以使用正则完成 - is_digit_ascii:判断是否是纯数字,以便于确认我们是否在正常的参赛流程中,提示:可以通过库或者正则完成 - extract_number:提取输出,提示:从后往前看哟~ </div> 实现代码: <div class="hideContent">此处内容需要评论回复后(审核通过)方可阅读。</div> 最后修改:2023 年 08 月 04 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 6 如果你觉得文章帮到你了,请以沫喝杯奶茶吧~