feat: 实现多个挑战并改进测试
- 重写p1实现纯Rust的hex到base64转换 - 完成p13 ECB剪切粘贴攻击和破解脚本 - 实现p33 Diffie-Hellman密钥交换算法 - 修复p9的PKCS#7测试用例 - 在common库添加gen_random_key和pkcs7_unpadding函数 - 更新workspace依赖管理
This commit is contained in:
@@ -4,3 +4,5 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../../common" }
|
||||
hex = { workspace = true }
|
||||
|
||||
42
problems/p13/crack.py
Normal file
42
problems/p13/crack.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from pwn import *
|
||||
|
||||
# context.log_level = "debug"
|
||||
|
||||
p = process("../../target/x86_64-unknown-linux-musl/debug/p13")
|
||||
p.recvuntil(b"> ") # 等待提示符
|
||||
|
||||
|
||||
p.sendline(b"1")
|
||||
p.recvuntil(b"email: ")
|
||||
p.sendline(b"foo@bar.com12")
|
||||
cipher = p.recvline().strip()
|
||||
print(f"Cipher: {cipher}")
|
||||
|
||||
role_cipher = cipher[32:64]
|
||||
|
||||
p.sendline(b"1")
|
||||
p.recvuntil(b"email: ")
|
||||
p.sendline(b"foo@bar.co" + b"admin" + b"\x0b" * 11)
|
||||
cipher = p.recvline().strip()
|
||||
# admin_cipher = cipher[32:64]
|
||||
print(f"Cipher: {cipher}")
|
||||
|
||||
cracked_cipher = cipher[0:32] + role_cipher + cipher[32:]
|
||||
|
||||
p.recvuntil(b"> ")
|
||||
p.sendline(b"2")
|
||||
p.recvuntil(b"cipher: ")
|
||||
p.sendline(cracked_cipher)
|
||||
|
||||
profile = p.recvline().strip()
|
||||
print(f"Profile: {profile}")
|
||||
|
||||
json = p.recvline().strip()
|
||||
print(f"Json: {json}")
|
||||
|
||||
if b"Cracked!" in json:
|
||||
print("Success!")
|
||||
|
||||
|
||||
p.recvuntil(b"> ")
|
||||
# p.interactive()
|
||||
@@ -1,3 +1,130 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use common::{aes_ecb_dec, aes_ecb_enc, gen_random_key, pkcs7_padding, pkcs7_unpadding};
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::io::Write as IoWrite;
|
||||
|
||||
use std::io::{stdin, stdout};
|
||||
|
||||
fn kv_to_json(input: &str) -> String {
|
||||
let mut json = String::new();
|
||||
if input.is_empty() {
|
||||
return json;
|
||||
}
|
||||
|
||||
json.push('{');
|
||||
|
||||
for kv in input.split('&') {
|
||||
if let Some((key, value)) = kv.split_once('=') {
|
||||
if value.contains('=') {
|
||||
todo!("Ignore here");
|
||||
}
|
||||
if json.contains(key) {
|
||||
todo!("Ignore here")
|
||||
}
|
||||
match value.parse::<i32>() {
|
||||
Ok(num) => write!(json, "{key}: {num}, ").unwrap(),
|
||||
Err(_) => write!(json, "{key}: \'{value}\', ").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
json.pop();
|
||||
json.pop();
|
||||
json.push('}');
|
||||
json
|
||||
}
|
||||
|
||||
/// Generates a user profile string from an email address.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// let profile = profile_for("foo@bar.com");
|
||||
/// assert_eq!(profile, "email=foo@bar.com&uid=10&role=user");
|
||||
/// ```
|
||||
fn profile_for(email: &str) -> String {
|
||||
let email = email.replace(['=', '&'], "");
|
||||
format!("email={email}&uid=10&role=user")
|
||||
}
|
||||
|
||||
fn enc_profile(profile: &str, key: &[u8; 16]) -> Vec<u8> {
|
||||
let mut profile = profile.as_bytes().to_vec();
|
||||
pkcs7_padding(&mut profile, 16);
|
||||
|
||||
aes_ecb_enc(&profile, key).unwrap()
|
||||
}
|
||||
|
||||
fn dec_profile(cipher: &[u8], key: &[u8; 16]) -> Vec<u8> {
|
||||
let profile = aes_ecb_dec(cipher, key).unwrap();
|
||||
pkcs7_unpadding(&profile).unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let key = gen_random_key();
|
||||
println!("input 1 for enc, input 2 for dec");
|
||||
loop {
|
||||
print!("> ");
|
||||
stdout().flush().unwrap(); // 强制刷新输出缓冲区
|
||||
|
||||
let mut option = String::new();
|
||||
stdin().read_line(&mut option).unwrap();
|
||||
let option = option.trim().parse::<i32>();
|
||||
match option {
|
||||
Ok(1) => {
|
||||
print!("email: ");
|
||||
stdout().flush().unwrap();
|
||||
let mut email = String::new();
|
||||
stdin().read_line(&mut email).unwrap();
|
||||
let email = email.trim();
|
||||
let profile = profile_for(email);
|
||||
let cipher = enc_profile(&profile, &key);
|
||||
for i in cipher {
|
||||
print!("{i:02x}");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
Ok(2) => {
|
||||
print!("cipher: ");
|
||||
stdout().flush().unwrap();
|
||||
let mut cipher = String::new();
|
||||
stdin().read_line(&mut cipher).unwrap();
|
||||
let cipher = match hex::decode(cipher.trim()) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(_) => {
|
||||
println!("invalid cipher");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let profile = String::from_utf8(dec_profile(&cipher, &key)).unwrap();
|
||||
println!("{profile}");
|
||||
let json = kv_to_json(&profile);
|
||||
if json.contains("role: 'admin'") {
|
||||
println!("Cracked!");
|
||||
} else {
|
||||
println!("{json}");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!("input 1 for enc, input 2 for dec");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_kv_to_json() {
|
||||
let test = kv_to_json("foo=bar&baz=qux&zap=zazzle");
|
||||
println!("{test}");
|
||||
let test = kv_to_json("foo=bar&baz=qux&zap=123");
|
||||
println!("{test}");
|
||||
let test = kv_to_json("foo=bar&baz=qux&zap=123a");
|
||||
println!("{test}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_profile_for() {
|
||||
let test = profile_for("1@2");
|
||||
println!("u{test}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user