一个小小的pwntools交互

又名试图学习出题·杂记

Pwntools远程交互相关库函数:
[Tools]Pwn中用于远程交互的库函数总结_python pwn remote函数、-CSDN博客

sever

主体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

from hashlib import sha256
import socketserver
from secret import FLAG
import signal
import string
import random
import os

flag = FLAG

class Task(socketserver.BaseRequestHandler):

ctry = 0

def _recvall(self):
BUFF_SIZE = 2048
data = b''
while True:
part = self.request.recv(BUFF_SIZE)
data += part
if len(part) < BUFF_SIZE:
break
return data.strip()

def send(self, msg, newline=True):
try:
if newline:
msg += b'\n'
self.request.sendall(msg)
except:
pass

def recv(self, prompt=b'[-] '):
self.send(prompt, newline=False)
return self._recvall()

def proof_of_work(self):
random.seed(os.urandom(8))
proof = ''.join(
[random.choice(string.ascii_letters+string.digits) for _ in range(20)])
_hexdigest = sha256(proof.encode()).hexdigest()
self.send(f"[+] sha256(XXXX+{proof[4:]}) == {_hexdigest}".encode())
x = self.recv(prompt=b'[+] Plz tell me XXXX: ')
if len(x) != 4 or sha256(x+proof[4:].encode()).hexdigest() != _hexdigest:
return False
return True

def handle(self):
signal.alarm(60)
try:
if not self.proof_of_work():
self.send(b'[!] Wrong!')
return

signal.alarm(300)
self.send(b'[+] ')
while self.ctry < 35:
data = self.recv().decode()
f = self.oraicle(data)
self.send(f)
self.ctry += 1

except TimeoutError:
self.send(b'[!] Timeout occurred!')

def oraicle(self,a):

if a.isdigit() and int(a)<33 and int(a)>0:
a = int(a)-1
return b'[+] ' + flag[a].encode()

return b'[!] Invalid Member!'


class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
pass


if __name__ == "__main__":
HOST,PORT = '0.0.0.0',12321
server = ForkedServer((HOST,PORT),Task)
server.allow_reuse_address = True
print(HOST, PORT)
server.serve_forever()

许多的ai原话

在使用 socketserver.BaseRequestHandler 创建服务器时,通常不需要显式地关闭套接字,因为 socketserver 模块会自动管理套接字的关闭。当客户端断开连接或者出现异常时,socketserver 会在适当的时候自动关闭与客户端相关的套接字。
因此,在这种情况下,通常不需要显式地在 finally: client_socket.close() 中关闭套接字。

在 Python 中,socketserver.BaseRequestHandler 类是处理客户端请求的基类。在服务器端处理客户端请求时,每次客户端连接到服务器时,socketserver 库都会创建一个新的 BaseRequestHandler 类的实例来处理与该客户端的通信。
BaseRequestHandler 类的实例中,self.request 属性代表与客户端连接的套接字对象。通过这个套接字对象,服务器可以与客户端进行通信,包括接收客户端发送的数据.
因此,self.request.recv() 表示从客户端套接字对象中接收数据。在上面的代码中,self.request.recv() 用于接收客户端发送的数据,然后进行处理以完成任务验证(Proof of Work)。

中断服务器用CTRL+CCTRL+Z是暂停进程,会占用端口。

在网络通信中,数据的传输可以是字节流(byte stream)或者字符流(character stream)。
字节流(Byte Stream):字节流是指一系列连续的字节,以二进制形式传输。在网络通信中,数据通常以字节流的形式传输。字节流可以包含任意类型的数据,包括文本、图像、音频等。在 Python 中,字节流通常使用 bytes 类型来表示。
字符流(Character Stream): 字符流是指一系列连续的字符,通常使用字符编码(如 ASCII、UTF-8 等)来表示文本数据。字符流通常用于文本文件的读写,以及与用户交互的过程中。在 Python 中,字符流通常使用 str 类型来表示。
在网络通信中,如果需要传输文本数据,可以将文本转换为字节流进行传输,接收方再将接收到的字节流转换回文本。这样可以确保数据在传输过程中的完整性和准确性。可以使用编码(encode)和解码(decode)来在字符流和字节流之间进行转换。
在Python中,b’’表示的是字节字符串(byte string),也称为字节流(byte stream)。
a.isdigit(),判断是否可以转换为有效整数。只有有效整数才能使用int强制类型转换。

Signal 信号量:发送定时信号single.alarm(),如signal.alarm(60)计时60秒(被用来设置一个60秒的闹钟,在60秒后会向当前进程发送一个闹钟信号),signal.alarm(0)清除定时。
具体来说,当 signal.alarm(60) 被设置后,程序运行到 handle 方法中的任何代码时都会开始计时,60秒后如果没有取消或重置计时器,就会触发 SIGALRM 信号。而 signal.alarm(0) 的作用是取消当前正在运行的 alarm 计时器,如果之前设置了 alarm,那么它就会被取消,不会再触发超时。

exp?

从网络接收到数据时,通常是以字节数据的形式表示的。如果你需要将这些字节数据转换为字符串以便于处理或展示,就可以使用 .decode() 方法。

[+]sha256(XXXX+JaakUDSfxkW0xjzV) == 4dbfdc61cb88f5bd08d87493ac62e5ab174780f5f019051f91df8b3c36564ed0
[+]Plz tell me XXXX:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
table = ascii_letters + digits
#包含所有字母和数字
class Solve():

    def __init__(self):
        self.sh = remote('127.0.0.1',8899)
   
    def proof_of_work(self):
        proof = self.sh.recvuntil(b'[+] Plz tell me XXXX:')
#接收致至'[+] Plz tell me XXXX:',也就是接收第一排
        tail = proof[16:32].decode()
        _hash = proof[37:101].decode()
        for i in product(table, repeat=4):
#itertools.product,接受多个可迭代对象作为参数,并返回一个迭代器,该迭代器产生所有输入可迭代对象的笛卡尔积
#笛卡尔积就是四个位置所有table包含的字符排列组合,离散数学里的
            head = ''.join(i)
            t = hashlib.sha256((head + tail).encode()).hexdigest() #注意是16进制
            if t == _hash:
                self.sh.sendline(head.encode())
                break
不要老是忘了def个函数括号里丢一个self(小声嘀咕)

proof结束

主体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import hashlib
from pwn import *
from string import ascii_letters, digits
from itertools import product
table = ascii_letters + digits

class Solve():
def __init__(self):
self.sh = remote('127.0.0.1', 12321)

def proof_of_work(self):
# [+] sha256(XXXX+JaakUDSfxkW0xjzV) == 4dbfdc61cb88f5bd08d87493ac62e5ab174780f5f019051f91df8b3c36564ed0
# [+] Plz tell me XXXX:
proof = self.sh.recvuntil(b'[+] Plz tell me XXXX:')
tail = proof[16:32].decode()
_hash = proof[37:101].decode()
for i in product(table, repeat=4):
head = ''.join(i)
t = hashlib.sha256((head + tail).encode()).hexdigest()
if t == _hash:
self.sh.sendline(head.encode())
break
def interaction(self):
flag = ''
for i in range(1,34):
self.sh.sendline(str(i).encode()) #注意int不能直接encode()
flag += self.sh.recvline().decode()[-2]
print(flag)

def solve(self):
self.proof_of_work()
self.interaction()
self.sh.close()


if __name__ == '__main__':
solution = Solve()
solution.solve()

然后就可以进行一个小交互了

输出:
1
2
3
[+] Opening connection to 127.0.0.1 on port 12321: Done 
nulctf{DO_YOU_KNOW_ALAN-BECKER?}
[*] Closed connection to 127.0.0.1 port 12321

nc连接效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ nc 127.0.0.1 12
321
[+] sha256(XXXX+UJvk8n7uX5zAj073) == 0c8e4e2a5771107eedba5725c742f0ca5f1d3f05a67949d68c76ed05dfce14cc
[+] Plz tell me XXXX: yyj1
[+]
[-] 1
[+] n
[-] 6
[+] f
[-] 8
[+] D
[-] 9
[+] O
[-] 4
[+] c
[-] 5
[+] t
[-] 7
[+] {
[-] 9
[+] O
[-] 4
[+] c
[-] y
[!] Invalid Member!
[-] 22
[+] A
[-] 99
[!] Invalid Member!
[-] -3
[!] Invalid Member!
[-] 32
[+] }
[-] ^C

代码参考来自密码出题指北 | Harry’s Blog (harry0597.com)


一个小小的pwntools交互
http://example.com/2024/03/31/一个小小的pwntools交互/
作者
AlLvia
发布于
2024年3月31日
许可协议