VNCTF-CRYPTO-ezmath是一道完全没难度的密码题,但是又是一道非常有难度的脚本题
这题只要返回4*N
就好,难度就在写脚本了
在PWN等运用到nc的题目中,Sha256是最好的防止扫端口的计算方法。
由于Sha256不可逆,我们只好通过暴力或者撞库的方式找出所有解
但是这题又使用的是Sha256(????+XXXXXXXXXXXX)
这样的方式,所以只好选择暴力了
再配合上pwntools,发就完事了
import os
import pwn
import time
import sqlite3
import string
import hashlib
import itertools
class sqliteDB:
def __init__(self) -> None:
if(os.path.exists('HashData.db')==False):
self.db = sqlite3.connect('HashData.db')
print("Building HashDataBase...")
self.make()
print("Building Database Succeed.")
else:
self.db = sqlite3.connect('HashData.db')
print("Connect Database Succeed.")
self.db.execute('PRAGMA temp_store=MEMORY;')
self.db.execute('PRAGMA journal_mode=MEMORY;')
self.db.execute('PRAGMA auto_vacuum=INCREMENTAL;')
def make(self) -> None:
self.db.execute('''CREATE TABLE IF NOT EXISTS SHA256
(ID CHAR(4) PRIMARY KEY NOT NULL,
HASH CHAR(64) NOT NULL);''')
d = string.ascii_letters + string.digits
for i in itertools.product(d,repeat=4):
target="".join(i)
res = hashlib.sha256(target.encode()).hexdigest()
self.db.execute("INSERT INTO SHA256 (ID,HASH) VALUES (?,?)",(target,res))
self.db.commit()
def getid(self, target):
cursor = self.db.execute("SELECT ID from SHA256 WHERE HASH=? LIMIT 1",(target,))
for i in cursor:
return i[0]
def gethash(self, target):
cursor = self.db.execute("SELECT HASH from SHA256 WHERE ID=? LIMIT 1",(target,))
for i in cursor:
return i[0]
class Violent:
def getid(self, target1, target2):
d = string.ascii_letters + string.digits
for i in itertools.product(d,repeat=4):
target="".join(i)+target1
ret = hashlib.sha256(target.encode()).hexdigest()
if(ret==target2):
return i+j+k+m
vio = Violent()
sqldb = sqliteDB();
以下为Pwntools交互示范
host = 'hz2016.cn'
port = 8080
while(1):
nc = pwn.remote(host, port)
nc.recvuntil('sha256(XXXX+')
target1 = nc.recv(16)
nc.recvuntil('== ')
target2 = nc.recv(64)
nc.sendline(vio.getid(target1.decode(),target2.decode()))
i=0
while(i<777):
print(nc.recvuntil('me the '))
number=nc.recvuntil('th (n')
print(number)
nc.sendline(str(int(number[:len(number)-5].decode())*4))
print(int(number[:len(number)-5].decode())*4)
i=i+1
print(i)
nc.interactive()#进入交互
nc.close()
PS:其实redis效率比sqlite3更好,甚至直接可以把所有数据读进去内存,但是我太懒了
2022/2/18:
在经过小小的测试之后发现,Sqlite3的效率够用了,顺便了解了下Redis等NOsql数据结构,发现可能真没必要,之前慢的原因可能是没放在SSD罢了
如果觉得数据库文件过大的话,可以考虑将SHA256截取一部分,或者再取个32位/16位的md5,能有效节省空间
2022/2/21:
由于for太丑被嫌弃了,于是改成了itertools.product+join的写法