Skip to content

Commit

Permalink
用户密码加密部分上线,SQL指令更新防止注入攻击
Browse files Browse the repository at this point in the history
  • Loading branch information
DLmaster authored and DLmaster committed Feb 11, 2024
1 parent 863b6dd commit 3b0b506
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 36 deletions.
Binary file modified AUTO_MAA.exe
Binary file not shown.
40 changes: 25 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ This software is open source, free of charge and for learning and exchange purpo

本软件是MAA的外部工具,需要安装配置MAA后才能使用。

**MAA安装**
#### MAA安装

什么是MAA? [官网](https://maa.plus/)/[GitHub](https://github.com/CHNZYX/Auto_Simulated_Universe/archive/refs/heads/main.zip)

MAA下载地址 [GitHub下载](https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases)

**MAA配置**
#### MAA配置

1.完成MAA的adb配置等基本配置

Expand All @@ -46,13 +46,23 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

## 配置用户信息与相关参数

**第一次启动**
注意:当前所有的密码输入部分都存在一点“小问题”,请在输入密码时避免输入Delete、F12、Tab等功能键。

双击启动`manage.exe`,输入MAA所在文件夹路径并回车(注意使用斜杠的种类,不要使用反斜杠)
-------------------------------------------------

#### 第一次启动

双击启动`manage.exe`,输入MAA所在文件夹路径并回车(注意使用斜杠的种类,不要使用反斜杠),然后设置管理密钥。

![信息配置1](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置1.png "MAA配置1")

**添加用户**
管理密钥是解密用户密码的唯一凭证,与数据库绑定。密钥丢失或`data/key/`目录下任一文件损坏都将导致解密无法正常进行。

本项目采用自主组建的混合加密模式,项目组也无法找回您的管理密钥或修复`data/key/`目录下的文件。如果不幸的事发生,建议您删除`data/data.db`重新录入信息。

当前暂不支持修改管理密钥,请等待后续更新。

#### 添加用户

输入“+”以开始添加用户。依次输入:

Expand All @@ -66,7 +76,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![信息配置2](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置2.png "MAA配置2")

**删除用户**
#### 删除用户

输入用户名+“-”以删除用户。格式:

Expand All @@ -76,7 +86,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![信息配置3](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置3.png "MAA配置3")

**配置用户状态**
#### 配置用户状态

启用代理:输入用户名+“y”以启用该用户的代理。格式:

Expand All @@ -94,7 +104,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![信息配置5](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置5.png "MAA配置5")

**续期**
#### 续期

输入用户名+续期天数+“+”以延长该用户的代理天数。格式:

Expand All @@ -104,7 +114,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![信息配置6](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置6.png "MAA配置6")

**修改刷取关卡**
#### 修改刷取关卡

输入用户名+关卡号+“~”以更改该用户的代理关卡。格式:

Expand All @@ -120,7 +130,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![gameid](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/gameid.png "gameid")

**设置MAA路径**
#### 设置MAA路径

输入“/”+新的MAA文件夹路径以修改MAA安装位置的配置。格式:

Expand All @@ -132,7 +142,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![信息配置8](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置8.png "MAA配置8")

**设置启动时间**
#### 设置启动时间

添加启动时间:输入“:+”+时间以添加定时启动时间。格式:

Expand All @@ -154,7 +164,7 @@ GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/rel

![信息配置10](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置10.png "MAA配置10")

**检索信息**
#### 检索信息

检索所有信息:`manage.exe`打开时会打印所有用户与配置信息。除此之外,你可以通过输入“all ?”以打印所有信息,如下:

Expand Down Expand Up @@ -188,7 +198,7 @@ time ?

![信息配置14](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置14.png "MAA配置14")

**退出**
#### 退出

输入“-”以退出`manage.exe`,如下:

Expand All @@ -198,11 +208,11 @@ time ?

## 运行代理

**直接运行**
#### 直接运行

双击`run.exe`直接运行

**定时运行**
#### 定时运行

双击`AUTO_MAA.exe`打开,不要关闭。它会读取设定时间,在该时刻自动运行

Expand Down
Binary file modified manage.exe
Binary file not shown.
145 changes: 128 additions & 17 deletions manage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,107 @@
import sqlite3
import datetime
import msvcrt
import sys
import os
import hashlib
import random
import secrets
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Util.Padding import pad,unpad

#读入密码
def readpass(text):
sys.stdout=sys.__stdout__
sys.stdout.write(text)
sys.stdout.flush()
p=''
while True:
typed=msvcrt.getch()
if len(p)!=0:
if typed==b'\r':
sys.stdout.write('\b*')
sys.stdout.flush()
break
elif typed==b'\b':
p=p[:-1]
sys.stdout.write('\b \b')
sys.stdout.flush()
else:
p+=typed.decode("utf-8")
sys.stdout.write('\b*'+typed.decode("utf-8"))
sys.stdout.flush()
elif typed!=b'\r' and typed!=b'\b':
p+=typed.decode("utf-8")
sys.stdout.write(typed.decode("utf-8"))
sys.stdout.flush()

print('')
return p

#配置密钥
def getPASSWORD(PASSWORD):
#生成RSA密钥对
key=RSA.generate(2048)
public_key_local=key.publickey()
private_key=key
#保存RSA公钥
with open('data/key/public_key.pem','wb') as f:
f.write(public_key_local.exportKey())
#生成密钥转换与校验随机盐
PASSWORDsalt=secrets.token_hex(random.randint(32,1024))
with open("data/key/PASSWORDsalt.txt","w",encoding="utf-8") as f:
print(PASSWORDsalt,file=f)
verifysalt=secrets.token_hex(random.randint(32,1024))
with open("data/key/verifysalt.txt","w",encoding="utf-8") as f:
print(verifysalt,file=f)
#将管理密钥转化为AES-256密钥
AES_password=hashlib.sha256((PASSWORD+PASSWORDsalt).encode("utf-8")).digest()
#生成AES-256密钥校验哈希值并保存
AES_password_verify=hashlib.sha256(AES_password+verifysalt.encode("utf-8")).digest()
with open("data/key/AES_password_verify.bin","wb") as f:
f.write(AES_password_verify)
#AES-256加密RSA私钥并保存密文
AES_key=AES.new(AES_password,AES.MODE_ECB)
private_key_local=AES_key.encrypt(pad(private_key.exportKey(),32))
with open("data/key/private_key.bin","wb") as f:
f.write(private_key_local)

#加密
def encryptx(note):
#读取RSA公钥
with open('data/key/public_key.pem','rb') as f:
public_key_local=RSA.import_key(f.read())
#使用RSA公钥对数据进行加密
cipher=PKCS1_OAEP.new(public_key_local)
encrypted=cipher.encrypt(note.encode("utf-8"))
return encrypted

#解密
def decryptx(note,PASSWORD):
#读入RSA私钥密文、盐与校验哈希值
with open("data/key/private_key.bin","rb") as f:
private_key_local=f.read().strip()
with open("data/key/PASSWORDsalt.txt","r",encoding="utf-8") as f:
PASSWORDsalt=f.read().strip()
with open("data/key/verifysalt.txt","r",encoding="utf-8") as f:
verifysalt=f.read().strip()
with open("data/key/AES_password_verify.bin","rb") as f:
AES_password_verify=f.read().strip()
#将管理密钥转化为AES-256密钥并验证
AES_password=hashlib.sha256((PASSWORD+PASSWORDsalt).encode("utf-8")).digest()
AES_password_SHA=hashlib.sha256(AES_password+verifysalt.encode("utf-8")).digest()
if AES_password_SHA!=AES_password_verify:
return "管理密钥错误"
else:
#AES解密RSA私钥
AES_key=AES.new(AES_password,AES.MODE_ECB)
private_key_pem=unpad(AES_key.decrypt(private_key_local),32)
private_key=RSA.import_key(private_key_pem)
#使用RSA私钥解密数据
decrypter=PKCS1_OAEP.new(private_key)
return decrypter.decrypt(note)

#添加用户
def add():
Expand All @@ -14,9 +115,10 @@ def add():
numberx=input("手机号码:")
dayx=int(input("代理天数:"))
gamex=input("关卡号:")
passwordx=input("密码:")
passwordx=readpass("密码:")
passwordx=encryptx(passwordx)
#应用更新
cur.execute("INSERT INTO adminx(admin,number,day,status,last,game,password) VALUES('%s','%s',%d,'y','2000-01-01','%s','%s')" %(adminx,numberx,dayx,gamex,passwordx))
cur.execute("INSERT INTO adminx VALUES(?,?,?,'y','2000-01-01',?,?)",(adminx,numberx,dayx,gamex,passwordx))
db.commit()
cur.close()
db.close()
Expand All @@ -27,12 +129,12 @@ def delete(id):
db=sqlite3.connect(DATABASE)
cur=db.cursor()
#检查用户是否存在
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
data=cur.fetchall()
if len(data)==0:
return "未找到"+id
#应用更新
cur.execute("DELETE FROM adminx WHERE admin='%s'" %(id))
cur.execute("DELETE FROM adminx WHERE admin=?",(id,))
db.commit()
cur.close()
db.close()
Expand Down Expand Up @@ -71,7 +173,7 @@ def search(id,book):
if id=="all":
cur.execute("SELECT * FROM adminx WHERE True")
else:
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
data=cur.fetchall()
#处理全部信息查询时的MAA路径与启动时间查询
if id=="all":
Expand Down Expand Up @@ -109,6 +211,12 @@ def search(id,book):
data[i][3]="禁用"
if id=="all":
data[i][6]="******"
else:
#解密
global PASSWORD
if PASSWORD==0:
PASSWORD=input("请输入管理密钥:")
data[i][6]=decryptx(data[i][6],PASSWORD).decode("utf-8")
#制表输出
if book==1:
print('')
Expand All @@ -132,14 +240,14 @@ def renewal(readxx):
#检查用户是否存在
db=sqlite3.connect(DATABASE)
cur=db.cursor()
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
data=cur.fetchall()
if len(data)==0:
cur.close()
db.close()
return "未找到"+id
#应用更新
cur.execute("UPDATE adminx SET day=%d WHERE admin='%s'" %(data[0][2]+dayp,id))
cur.execute("UPDATE adminx SET day=? WHERE admin=?",(data[0][2]+dayp,id))
db.commit()
cur.close()
db.close()
Expand All @@ -150,14 +258,14 @@ def turn(id,t):
#检查用户是否存在
db=sqlite3.connect(DATABASE)
cur=db.cursor()
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
data=cur.fetchall()
if len(data)==0:
cur.close()
db.close()
return "未找到"+id
#应用更新
cur.execute("UPDATE adminx SET status='%s' WHERE admin='%s'" %(t,id))
cur.execute("UPDATE adminx SET status=? WHERE admin=?",(t,id))
db.commit()
cur.close()
db.close()
Expand All @@ -177,7 +285,7 @@ def gameid(readxx):
#检查用户是否存在
db=sqlite3.connect(DATABASE)
cur=db.cursor()
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
data=cur.fetchall()
if len(data)==0:
cur.close()
Expand All @@ -197,7 +305,7 @@ def gameid(readxx):
if gamep in games:
gamep=games[gamep]
#应用更新
cur.execute("UPDATE adminx SET game='%s' WHERE admin='%s'" %(gamep,id))
cur.execute("UPDATE adminx SET game=? WHERE admin=?",(gamep,id))
db.commit()
cur.close()
db.close()
Expand All @@ -210,9 +318,9 @@ def setpath(pathx):
cur.execute("SELECT * FROM pathset WHERE True")
pathold=cur.fetchall()
if len(pathold)>0:
cur.execute("UPDATE pathset SET path='%s' WHERE True" %(pathx))
cur.execute("UPDATE pathset SET path=? WHERE True",(pathx,))
else:
cur.execute("INSERT INTO pathset(path) VALUES('%s')" %(pathx))
cur.execute("INSERT INTO pathset VALUES(?)",(pathx,))
db.commit()
cur.close()
db.close()
Expand All @@ -235,15 +343,15 @@ def settime(book,timex):
db.close()
return "已存在"+timex
else:
cur.execute("INSERT INTO timeset(time) VALUES('%s')" %(timex))
cur.execute("INSERT INTO timeset VALUES(?)",(timex,))
db.commit()
cur.close()
db.close()
return "已添加"+timex
#删除时间设置
elif book=='-':
if timenew in timeold:
cur.execute("DELETE FROM timeset WHERE time='%s'" %(timex))
cur.execute("DELETE FROM timeset WHERE time=?",(timex,))
db.commit()
cur.close()
db.close()
Expand All @@ -265,17 +373,20 @@ def unit(x,m):

#初期检查
DATABASE="data/data.db"
PASSWORD=0
if not os.path.exists(DATABASE):
db=sqlite3.connect(DATABASE)
cur=db.cursor()
db.execute("CREATE TABLE adminx(admin text,number text,day int,status text,last date,game text,password text)")
db.execute("CREATE TABLE adminx(admin text,number text,day int,status text,last date,game text,password byte)")
db.execute("CREATE TABLE pathset(path text)")
db.execute("CREATE TABLE timeset(time text)")
readx=input("首次启动,请设置MAA路径:")
cur.execute("INSERT INTO pathset(path) VALUES('%s')" %(readx))
cur.execute("INSERT INTO pathset VALUES(?)",(readx,))
db.commit()
cur.close()
db.close()
PASSWORD=readpass("请设置管理密钥(密钥与数据库绑定且唯一不可变):")
getPASSWORD(PASSWORD)

#初始界面
print("Good evening!")
Expand Down
Binary file modified res/README/信息配置1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified run.exe
Binary file not shown.
Loading

0 comments on commit 3b0b506

Please sign in to comment.