BugkuCTF-Crypto题python_jail

本文探讨了一种通过nc远程连接进行交互的方法。在限制输入字符数目的情况下,利用Python内置的help()函数巧妙地触发错误信息,从而在只输入10个字符的情况下揭示了flag变量的内容。这一技巧展示了在有限的输出条件下如何借助编程手段获取更多信息。
部署运行你感兴趣的模型镜像

题目可通过nc远程连接
输入nc建立连接
测试发现最多只能输入10个字符,要想有输出,需要print() (7个字符)
若print(flag)则有11个字符,超出限制,报错

可利用python里help()函数,借报错信息带出flag变量值内容,help(flag) 刚好10个字符
在这里插入图片描述

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

基于vnet_crypto_op_t实现static void pptp_session_key_make(pptp_session_t * ps, u16 initial_key) { vnet_crypto_op_t *op; pptp_mppe_state_t *send_state = ps->mppe_send_table; pptp_mppe_state_t *recv_state = ps->mppe_recv_table; u8 sha1_digest[20]; // SHA1输出20字节 u8 *recv_key = recv_state->master_key; u8 *send_key = send_state->master_key; int key_len = recv_state->keylen; op = vnet_crypto_op_init(CRYPTO_OP_TYPE_HASH, CRYPTO_HASH_ALG_SHA1); if (!op) return; if (initial_key) { crypto_op_hash_set_input(op, (u8*[]){recv_key, SHApad1, recv_key, SHApad2}, (u32[]){key_len, sizeof(SHApad1), key_len, sizeof(SHApad2)}, 4); } else { crypto_op_hash_set_input(op, (u8*[]){recv_key, SHApad1, recv_state->session_key, SHApad2}, (u32[]){key_len, sizeof(SHApad1), key_len, sizeof(SHApad2)}, 4); } crypto_op_hash_set_output(op, sha1_digest, sizeof(sha1_digest)); crypto_sync_op(op); clib_memcpy(recv_state->sha1_digest, sha1_digest, sizeof(sha1_digest)); clib_memcpy(recv_state->session_key, sha1_digest, key_len); crypto_op_free(op); if (!initial_key) { rc4_encrypt(recv_state->sha1_digest, recv_state->sha1_digest, recv_state->keylen, recv_state->keylen, recv_state->session_key); } op = crypto_op_alloc_and_init(CRYPTO_OP_TYPE_HASH, CRYPTO_HASH_ALG_SHA1); if (!op) return; if (initial_key) { crypto_op_hash_set_input(op, (u8*[]){send_key, SHApad1, send_key, SHApad2}, (u32[]){key_len, sizeof(SHApad1), key_len, sizeof(SHApad2)}, 4); } else { crypto_op_hash_set_input(op, (u8*[]){send_key, SHApad1, send_state->session_key, SHApad2}, (u32[]){key_len, sizeof(SHApad1), key_len, sizeof(SHApad2)}, 4); } crypto_op_hash_set_output(op, sha1_digest, sizeof(sha1_digest)); crypto_sync_op(op); clib_memcpy(send_state->sha1_digest, sha1_digest, sizeof(sha1_digest)); clib_memcpy(send_state->session_key, sha1_digest, key_len); crypto_op_free(op); if (!initial_key) { rc4_encrypt(send_state->sha1_digest, send_state->sha1_digest, send_state->keylen, send_state->keylen, send_state->session_key); } if (key_len == 8) { send_state->session_key[0] = 0xd1; send_state->session_key[1] = 0x26; send_state->session_key[2] = 0x9e; recv_state->session_key[0] = 0xd1; recv_state->session_key[1] = 0x26; recv_state->session_key[2] = 0x9e; send_state->stateful = recv_state->stateful = 0; } } 说一下具体要改哪些行
最新发布
11-17
你提供的 `pptp_session_key_make` 函数是用于 **PPTP 协议中 MPPE(Microsoft Point-to-Point Encryption)密钥派生** 的,它使用了类似 **MS-CHAPv2 密钥扩展** 的方式,结合 SHA-1 和 padding(`SHApad1`, `SHApad2`)来生成会话密钥。 但问在于:你当前代码中调用的函数: ```c op = vnet_crypto_op_init(CRYPTO_OP_TYPE_HASH, CRYPTO_HASH_ALG_SHA1); ``` 和 ```c crypto_op_hash_set_input/op_free/sync_op ``` 这些 API **并不是 VPP 官方标准接口的真实名称**。它们像是对底层 `vnet_crypto_op_t` 操作的一种 **抽象封装或伪代码写法**,在真实 VPP 中并不存在。 --- ## ✅ 目标 我们要将这段“伪代码风格”的 PPTP 密钥生成函数,**改造成可在真实 VPP 环境下编译运行的实现**,基于真实的 VPP 加密框架 API(即使用 `vnet_crypto_alloc_ops`, `vnet_crypto_process_ops` 等)。 --- ## 🔧 需要修改的关键点总结 | 原始伪代码 | 问 | 正确替代方案 | |----------|------|--------------| | `vnet_crypto_op_init()` | ❌ 不存在 | 使用 `vnet_crypto_alloc_ops(1)` + 手动初始化字段 | | `crypto_op_hash_set_input()` | ❌ 不存在 | 手动设置 `src`, `len`, 支持多段输入拼接 | | `crypto_op_hash_set_output()` | ❌ 不存在 | 设置 `digest` 指针 | | `crypto_sync_op()` | ❌ 名称不匹配 | 使用 `vnet_crypto_process_ops()` 实现同步处理 | | `crypto_op_free()` | ❌ 应为 `vnet_crypto_free_ops()` | 调用正确释放函数 | --- ## ✅ 修改后的完整正确版本(适配 VPP) ```c #include <vnet/crypto/crypto.h> #include <vppinfra/clib.h> #include <vppinfra/string.h> /* 假设已定义 */ extern u8 SHApad1[40]; extern u8 SHApad2[40]; static void rc4_encrypt(u8 *key, u8 *input, int input_len, int Klen, u8 *output); static void pptp_session_key_make(pptp_session_t *ps, u16 initial_key) { vnet_crypto_op_t *ops; vnet_crypto_op_t *op; pptp_mppe_state_t *send_state = ps->mppe_send_table; pptp_mppe_state_t *recv_state = ps->mppe_recv_table; u8 sha1_digest[20]; // SHA1输出20字节 u8 *recv_key = recv_state->master_key; u8 *send_key = send_state->master_key; int key_len = recv_state->keylen; u8 *input_buf; u32 total_len; /* Step 1: 分配一个 crypto op */ ops = vnet_crypto_alloc_ops(1); if (!ops) return; op = &ops[0]; vnet_crypto_op_reset(op); /* * === 接收方向密钥计算 (Recv Session Key) === */ /* 构造输入数据: [key][SHApad1][key/prev_session][SHApad2] */ if (initial_key) { total_len = key_len + sizeof(SHApad1) + key_len + sizeof(SHApad2); input_buf = clib_mem_alloc(total_len); clib_memcpy(input_buf, recv_key, key_len); clib_memcpy(input_buf + key_len, SHApad1, sizeof(SHApad1)); clib_memcpy(input_buf + key_len + sizeof(SHApad1), recv_key, key_len); clib_memcpy(input_buf + key_len + sizeof(SHApad1) + key_len, SHApad2, sizeof(SHApad2)); } else { total_len = key_len + sizeof(SHApad1) + key_len + sizeof(SHApad2); input_buf = clib_mem_alloc(total_len); clib_memcpy(input_buf, recv_key, key_len); clib_memcpy(input_buf + key_len, SHApad1, sizeof(SHApad1)); clib_memcpy(input_buf + key_len + sizeof(SHApad1), recv_state->session_key, key_len); clib_memcpy(input_buf + key_len + sizeof(SHApad1) + key_len, SHApad2, sizeof(SHApad2)); } /* 初始化 op 字段 */ op->op_type = VNET_CRYPTO_OP_TYPE_HASH; op->alg = CRYPTO_ALG_SHA1; op->src = input_buf; op->len = total_len; op->digest = sha1_digest; op->digest_len = 20; /* 执行同步哈希运算 */ vnet_crypto_process_ops(vlib_get_main(), op->op_type, ops, 1); /* 检查结果 */ if (op->status != VNET_CRYPTO_OP_STATUS_COMPLETED) { clib_mem_free(input_buf); vnet_crypto_free_ops(ops, 1); return; } /* 保存中间摘要与 session key */ clib_memcpy(recv_state->sha1_digest, sha1_digest, 20); clib_memcpy(recv_state->session_key, sha1_digest, key_len); /* 如果是非初始轮次,进行 RC4 自加密 */ if (!initial_key) { rc4_encrypt(recv_state->sha1_digest, recv_state->sha1_digest, key_len, key_len, recv_state->session_key); } /* 清理本轮资源 */ clib_mem_free(input_buf); /* * === 发送方向密钥计算 (Send Session Key) === */ /* 重新分配 op 并重置 */ vnet_crypto_op_reset(op); if (initial_key) { total_len = key_len + sizeof(SHApad1) + key_len + sizeof(SHApad2); input_buf = clib_mem_alloc(total_len); clib_memcpy(input_buf, send_key, key_len); clib_memcpy(input_buf + key_len, SHApad1, sizeof(SHApad1)); clib_memcpy(input_buf + key_len + sizeof(SHApad1), send_key, key_len); clib_memcpy(input_buf + key_len + sizeof(SHApad1) + key_len, SHApad2, sizeof(SHApad2)); } else { total_len = key_len + sizeof(SHApad1) + key_len + sizeof(SHApad2); input_buf = clib_mem_alloc(total_len); clib_memcpy(input_buf, send_key, key_len); clib_memcpy(input_buf + key_len, SHApad1, sizeof(SHApad1)); clib_memcpy(input_buf + key_len + sizeof(SHApad1), send_state->session_key, key_len); clib_memcpy(input_buf + key_len + sizeof(SHApad1) + key_len, SHApad2, sizeof(SHApad2)); } /* 设置发送方向操作 */ op->op_type = VNET_CRYPTO_OP_TYPE_HASH; op->alg = CRYPTO_ALG_SHA1; op->src = input_buf; op->len = total_len; op->digest = sha1_digest; op->digest_len = 20; vnet_crypto_process_ops(vlib_get_main(), op->op_type, ops, 1); if (op->status == VNET_CRYPTO_OP_STATUS_COMPLETED) { clib_memcpy(send_state->sha1_digest, sha1_digest, 20); clib_memcpy(send_state->session_key, sha1_digest, key_len); if (!initial_key) { rc4_encrypt(send_state->sha1_digest, send_state->sha1_digest, key_len, key_len, send_state->session_key); } } /* 最终清理 */ clib_mem_free(input_buf); vnet_crypto_free_ops(ops, 1); /* * === 特殊情况:8 字节密钥处理(MPPE 40-bit 兼容模式)=== */ if (key_len == 8) { send_state->session_key[0] = 0xd1; send_state->session_key[1] = 0x26; send_state->session_key[2] = 0x9e; recv_state->session_key[0] = 0xd1; recv_state->session_key[1] = 0x26; recv_state->session_key[2] = 0x9e; send_state->stateful = 0; recv_state->stateful = 0; } } ``` --- ## ✅ 关键修改说明(回答你的问:“具体要改哪些行”) | 原始代码行 | 修改内容 | 原因 | |-----------|---------|-------| | `op = vnet_crypto_op_init(...)` | ➝ `ops = vnet_crypto_alloc_ops(1); op = &ops[0]; vnet_crypto_op_reset(op);` | 初始化必须通过池分配 | | `crypto_op_hash_set_input(...)` | ➝ 手动拼接 `clib_memcpy` 到临时 buffer,并设 `src` 和 `len` | VPP 不支持 scatter-gather 输入哈希(除非使用 iov),需合并 | | `crypto_op_hash_set_output(...)` | ➝ 直接赋值 `op->digest = sha1_digest; op->digest_len = 20;` | 没有 setter 函数 | | `crypto_sync_op(op)` | ➝ `vnet_crypto_process_ops(vm, op->op_type, ops, 1);` | 真实执行入口 | | `crypto_op_free(op)` | ➝ `vnet_crypto_free_ops(ops, 1);` | 必须成批释放 | --- ## ✅ 补充:关于 `SHApad1` 和 `SHApad2` 这两个是标准的 **RFC 2202 HMAC-PADs**: ```c u8 SHApad1[40] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }; u8 SHApad2[40] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c }; ``` 这是 HMAC-SHA1 的标准构造方式: > H(K ⊕ opad, H(K ⊕ ipad, text)) 而你的代码正是模拟这个过程。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值