
shell脚本及监控文件+rsa题目
一个简单的 hello.sh
脚本像下面这样,第一行 #!/bin/bash
标识该 Shell 脚本由哪个 Shell 解释:
#!/bin/bash
echo "Hello World!"
赋予权限才可以执行:,
# 赋予可执行权限
chmod a+x hello.sh
# 执行
./hello.sh
# 结果
Hello World!
![[shell1.png]]
Shell 的编写流程:
- 编写 Shell 脚本
- 赋予可执行权限
- 执行,调试
Shell 关键字
常用的关键字如下:
- echo:打印文字到屏幕
- exec:执行另一个 Shell 脚本
- read:读标准输入
- expr:对整数型变量进行算术运算
- test:用于测试变量是否相等、 是否为空、文件类型等
- exit:退出
例子:
#!/bin/bash
echo "Hello Shell"
# 读入变量
read VAR
echo "VAR is $VAR"
# 计算变量
expr $VAR - 5
# 测试字符串
test "Hello"="HelloWorld"
# 测试整数
test $VAR -eq 10
# 测试目录
test -d ./Android
# 执行其他 Shell 脚本
exec ./othershell.sh
# 退出
exit
运行前,你需要新建一个 othershell.sh 的文件,让它输出 I'm othershell,并且中途需要一次输入,我这里输入的是 10:
Hello Shell
10
VAR is 10
5
I'm othershell
变量定义方法
![[shell2.png]]
Shell 变量
Shell 变量分为 3 种:
- 用户自定义变量
- 预定义变量
- 环境变量
定义变量需要注意下面 2 点:
- 等号前后不要有空格:NUM=10
- 一般变量名用大写:M=1
使用 $VAR 调用变量:
echo $VAR
1 . 用户自定义变量
这种变量只支持字符串类型,不支持其他字符,浮点等类型,常见有这 3 个前缀:
- unset:删除变量
- readonly:标记只读变量
- export:指定全局变量
一个例子:
#!/bin/bash
# 定义普通变量
CITY=SHENZHEN
# 定义全局变量
export NAME=cdeveloper
# 定义只读变量
readonly AGE=21
# 打印变量的值
echo $CITY
echo $NAME
echo $AGE
# 删除 CITY 变量
unset CITY
# 不会输出 SHENZHEN
echo $CITY
运行结果:
SHENZHEN
cdeveloper
21
![[shell3.png]]
2 . 预定义变量
预定义变量常用来获取命令行的输入,有下面这些:
$0 :脚本文件名
$1-9 :第 1-9 个命令行参数名
$# :命令行参数个数
$@ :所有命令行参数
$* :所有命令行参数
$? :前一个命令的退出状态,可用于获取函数返回值
$ $ :执行的进程 ID
一个例子:
#!/bin/bash
echo "print $"
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$# = $#"
echo "\$@ = $@"
echo "\$* = $*"
echo "\$$ = $$"
echo "\$? = $?"
执行./hello.sh 1 2 3 4 5
的结果:
print $
# 程序名
$0 = ./hello.sh
# 第一个参数
$1 = 1
# 第二个参数
$2 = 2
# 一共有 5 个参数
$# = 5
# 打印出所有参数
$@ = 1 2 3 4 5
# 打印出所有参数
$* = 1 2 3 4 5
# 进程 ID
$$ = 9450
# 之前没有执行其他命令或者函数
$? = 0
![[shell4.png]]
3 . 环境变量
环境变量默认就存在,常用的有下面这几个:
- HOME:用户主目录
- PATH:系统环境变量 PATH
- TERM:当前终端
- UID:当前用户 ID
- PWD:当前工作目录,绝对路径
还是看例子:
#!/bin/bash
echo "print env"
echo $HOME
echo $PATH
echo $TERM
echo $PWD
echo $UID
运行结果:
print env
# 当前主目录
/root
# PATH 环境变量
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
# 当前终端
xterm-256color
# 当前目录
/home
# 用户 ID
0
![[shell5.png]]
Shell 运算
我们经常需要在 Shell 脚本中计算,掌握基本的运算方法很有必要,下面就是 4 种比较常见的运算方法,功能都是将 m + 1:
- m=$[ m + 1 ]
- m=expr $m + 1 # 用 “ 字符包起来
- let m=m+1
- m=$(( m + 1 ))
来看一个实际的例子:
#!/bin/bash
m=1
m=$[ m + 1 ]
echo $m
m=`expr $m + 1`
echo $m
#注意:+ 号左右不要加空格
let m=m+1
echo $m
m=$(( m + 1 ))
echo $m
运行结果:
2
3
4
5
![[shell6.png]]
了解了基本的运算方法,下面进一步来学习 Shell 的语句。
Shell 语句
Shell 语句跟高级语言有些类似,也包括分支,跳转,循环,下面就带着大家一个一个突破。
1 . if 语句
这个跟高级语言的 if - else - if 类似,只是格式有些不同而已,也来看个例子吧:
#!/bin/bash
read VAR
# 下面这两种判断方法都可以,使用 [] 注意左右加空格
#if test $VAR -eq 10
if [ $VART -eq 10 ]
then
echo "true"
else
echo "false"
fi
2 . case 语句
case 语句有些复杂,要注意格式:
#!/bin/bash
read NAME
# 格式有点复杂,一定要注意
case $NAME in
"Linux")
echo "Linux"
;;
"cdeveloper")
echo "cdeveloper"
;;
*)
echo "other"
;;
esac
运行结果:
# 输入 Linux
Linux
Linux
# 输入 cdeveloper
cdeveloper
cdeveloper
# 输入其他的字符串
hello
other
![[shell7.png]]
3 . for 循环
这是一个 for 循环基本使用例子,挺简单的,有点类似 Python:
#!/bin/bash
# 普通 for 循环
for ((i = 1; i <= 3; i++))
do
echo $i
done
# VAR 依次代表每个元素
for VAR in 1 2 3
do
echo $VAR
done
运行结果:
1
2
3
1
2
3
![[shell8.png]]
4 . while 循环
注意与 for 循环的区别:
#!/bin/bash
VAR=1
# 如果 VAR 小于 10,就打印出来
while [ $VAR -lt 10 ]
do
echo $VAR
# VAR 自增 1
VAR=$[ $VAR + 1 ]
done
运行结果:
1
2
3
4
5
6
7
8
9
![[shell9.png]]
5 . until 循环
until 语句与上面的循环的不同点是它的结束条件为 1:
#!/bin/bash
i=0
# i 大于 5 时,循环结束
until [[ "$i" -gt 5 ]]
do
echo $i
i=$[ $i + 1 ]
done
6 . break
Shell 中的 break 用法与高级语言相同,都是跳出循环,来看个例子:
#!/bin/bash
for VAR in 1 2 3
do
# 如果 VAR 等于 2 就跳出循环
if [ $VAR -eq 2 ]
then
break
fi
echo $VAR
done
运行结果:
1
![[shell10.png]]
7 . continue
continue 用来跳过本次循环,进入下一次循环,再来看看上面的例子:
#!/bin/bash
for VAR in 1 2 3
do
# 如果 VAR 等于 2,就跳过,直接进入下一次 VAR = 3 的循环
if [ $VAR -eq 2 ]
then
continue
fi
echo $VAR
done
运行结果:
1
3
![[shell11.png]]
Shell 函数
函数可以用一句话解释:带有输入输出的具有一定功能的黑盒子,相信有过编程经验的同学不会陌生。那么,我们先来看看 Shell 中函数定义的格式。
1 . 定义函数
有 2 种常见格式:
function fun_name()
{
}
fun_name()
{
}
例如:
#!/bin/bash
function hello_world()
{
echo "hello world fun"
echo $1 $2
return 1
}
hello()
{
echo "hello fun"
}
2 . 调用函数
如何调用上面的 2 个函数呢?
# 1. 直接用函数名调用 hello 函数
hello
# 2. 使用「函数名 函数参数」来传递参数
hello_world 1 2
# 3. 使用「FUN=`函数名 函数参数`」 来间接调用
FUN=`hello_world 1 2`
echo $FUN
3 . 获取返回值
获取 hello_world 函数的返回值
hello_world 1 2
# $? 可用于获取前一个函数的返回值,这里结果是 1
echo $?
4 . 定义本地变量
使用 local 来在函数中定义本地变量:
fun()
{
local x=1
echo $x
}
Shell 调试
使用下面的命令来检查是否有语法错误:
sh -n script_name.sh
使用下面的命令来执行并调试 Shell 脚本:
sh -x script_name.sh
来看个实际的例子,我们来调试下面这个 test.sh 程序:
#!/bin/bash
for VAR in 1 2 3
do
if [ $VAR -eq 2 ]
then
continue
fi
echo $VAR
done
首先检查有无语法错误:
sh -n test.sh
没有输出,说明没有错误,开始实际调试:
sh -x test.sh
调试结果如下:
+ [ 1 -eq 2 ]
+ echo 1
1
+ [ 2 -eq 2 ]
+ continue
+ [ 3 -eq 2 ]
+ echo 3
3
![[shell12.png]]
其中带有 + 表示的是 Shell 调试器的输出,不带 + 表示我们程序的输出。
Shell 易错点
这里我总结了一些初学 Shell 编程容易犯的错误,大多都是语法错误:
- [] 内不能嵌套 (),可以嵌套 []
- $[ val + 1 ] 是变量加 1 的常用方法
- [] 在测试或者计算中里面的内容最好都加空格
- 单引号和双引号差不多,单引号更加严格,双引号可以嵌套单引号
- 一定要注意语句的格式,例如缩进
监控文件
要创建一个监控文件改动的 shell 脚本,可以利用inotifywait
工具,它能实时监控文件系统的变化。下面是一个实现此功能的脚本:
#!/bin/bash
# 检查是否提供了要监控的文件路径
if [ $# -ne 1 ]; then
echo "使用方法: $0 <要监控的文件路径>"
exit 1
fi
FILE_TO_MONITOR="$1"
# 检查文件是否存在
if [ ! -f "$FILE_TO_MONITOR" ]; then
echo "错误: 文件 $FILE_TO_MONITOR 不存在!"
exit 1
fi
# 检查inotifywait是否安装
if ! command -v inotifywait &> /dev/null; then
echo "错误: inotifywait 未安装。请先安装 inotify-tools 包。"
echo "在Debian/Ubuntu上: sudo apt-get install inotify-tools"
echo "在Fedora/RHEL上: sudo dnf install inotify-tools"
exit 1
fi
# 获取初始的文件哈希值,用于检测内容变化
get_file_hash() {
sha256sum "$FILE_TO_MONITOR" | awk '{print $1}'
}
INITIAL_HASH=$(get_file_hash)
LOG_FILE="file_changes.log"
echo "开始监控文件: $FILE_TO_MONITOR"
echo "监控日志将保存到: $LOG_FILE"
echo "按Ctrl+C停止监控"
echo "----------------------------------------"
# 记录监控开始时间
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 开始监控文件: $FILE_TO_MONITOR" >> "$LOG_FILE"
# 使用inotifywait监控文件变化
while true; do
# 等待文件发生变化
inotifywait -q -e modify,delete,move,create "$FILE_TO_MONITOR" 2>/dev/null
# 检查是否是正常的修改事件
if [ $? -eq 0 ]; then
CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S')
# 检查文件是否仍然存在
if [ ! -f "$FILE_TO_MONITOR" ]; then
CHANGE_MSG="文件已被删除或移动"
else
# 检查内容是否变化
CURRENT_HASH=$(get_file_hash)
if [ "$CURRENT_HASH" != "$INITIAL_HASH" ]; then
CHANGE_MSG="文件内容已修改"
INITIAL_HASH="$CURRENT_HASH" # 更新哈希值
else
CHANGE_MSG="文件属性已修改,但内容未变"
fi
fi
# 输出到控制台并记录到日志
echo "[$CURRENT_TIME] $CHANGE_MSG: $FILE_TO_MONITOR"
echo "[$CURRENT_TIME] $CHANGE_MSG: $FILE_TO_MONITOR" >> "$LOG_FILE"
else
# 处理可能的错误
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 监控出错,将重新开始监控" >> "$LOG_FILE"
sleep 1
fi
done
这个脚本的主要功能和特点:
1 . 使用方法:运行时需要指定要监控的文件路径,例如 ./file_monitor.sh /path/to/your/file
2 . 监控内容:
- 文件内容修改
- 文件删除
- 文件移动
- 文件创建(如果被监控的文件曾被删除后又重建)
3 . 记录功能: - 所有改动都会实时显示在控制台
- 同时记录到
file_changes.log
日志文件 - 记录包括时间戳和具体的改动类型
4 . 依赖: - 需要
inotifywait
工具,通常包含在inotify-tools
包中 - 脚本会自动检查该工具是否安装,并提示安装方法
5 . 工作原理: - 使用 sha256 哈希值检测文件内容变化
- 利用 inotify 机制实时监控文件系统事件
- 即使出现临时错误也会自动重新开始监控
但是,经过测试![[文件监控.png]]
当我修改了我监控的文件,在日志里显示的是监控出错,而不是说文件内容被修改
于是调整脚本,并且在终端实时显示文件情况
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
if [ $# -ne 1 ]; then
echo "使用方法: $0 <要监控的文件路径>"
exit 1
fi
FILE_TO_MONITOR="$1"
LOG_FILE="file_changes.log"
ERROR_LOG="file_monitor_errors.log"
# 检查文件是否存在
check_file_exists() {
if [ ! -f "$FILE_TO_MONITOR" ]; then
printf "${YELLOW}[%s] 警告: 文件 %s 不存在,将等待其创建${NC}\n" "$(date +'%Y-%m-%d %H:%M:%S')" "$FILE_TO_MONITOR" | tee -a "$LOG_FILE"
return 1
fi
return 0
}
# 检查inotifywait是否安装
if ! command -v inotifywait &> /dev/null; then
echo "错误: inotifywait 未安装。请先安装 inotify-tools 包。"
echo "在Debian/Ubuntu上: sudo apt-get install inotify-tools"
echo "在Fedora/RHEL上: sudo dnf install inotify-tools"
exit 1
fi
# 获取文件哈希值
get_file_hash() {
sha256sum "$FILE_TO_MONITOR" 2>/dev/null | awk '{print $1}'
}
# 初始化日志
printf "${BLUE}[%s] 开始监控文件: %s${NC}\n" "$(date +'%Y-%m-%d %H:%M:%S')" "$FILE_TO_MONITOR" | tee -a "$LOG_FILE"
echo "开始监控文件: $FILE_TO_MONITOR"
echo "监控日志将保存到: $LOG_FILE"
echo "错误日志将保存到: $ERROR_LOG"
echo "按Ctrl+C停止监控"
echo "----------------------------------------"
# 主监控循环
while true; do
# 等待文件存在
while ! check_file_exists; do
sleep 2
done
INITIAL_HASH=$(get_file_hash)
# 运行inotifywait并捕获错误输出,增加attrib事件监控属性变化
inotifywait -q -e modify,delete,move,create,attrib "$FILE_TO_MONITOR" 2>> "$ERROR_LOG"
EXIT_CODE=$?
CURRENT_TIME=$(date +'%Y-%m-%d %H:%M:%S')
# 处理不同的退出码
if [ $EXIT_CODE -eq 0 ]; then
# 正常捕获事件
if [ ! -f "$FILE_TO_MONITOR" ]; then
CHANGE_MSG="文件已被删除或移动"
COLOR=$RED
else
CURRENT_HASH=$(get_file_hash)
if [ "$CURRENT_HASH" != "$INITIAL_HASH" ]; then
CHANGE_MSG="文件内容已修改"
COLOR=$GREEN
else
CHANGE_MSG="文件属性已修改(权限/时间戳等,内容未变)"
COLOR=$YELLOW
fi
fi
# 处理move后文件恢复原路径的情况
if echo "$CHANGE_MSG" | grep -q "文件已被删除或移动"; then
# 检查文件是否又回到了原路径
if [ -f "$FILE_TO_MONITOR" ]; then
CHANGE_MSG="文件已移动/重命名后恢复,继续监控"
COLOR=$YELLOW
INITIAL_HASH=$(get_file_hash) # 重新初始化哈希值
fi
fi
# 实时显示在终端并记录到日志
printf "${COLOR}[%s] %s: %s${NC}\n" "$CURRENT_TIME" "$CHANGE_MSG" "$FILE_TO_MONITOR" | tee -a "$LOG_FILE"
elif [ $EXIT_CODE -eq 1 ]; then
printf "${RED}[%s] 文件操作异常(可能被删除): %s${NC}\n" "$CURRENT_TIME" "$FILE_TO_MONITOR" | tee -a "$LOG_FILE"
echo "[$CURRENT_TIME] inotifywait退出码: $EXIT_CODE" >> "$ERROR_LOG"
elif [ $EXIT_CODE -eq 2 ]; then
printf "${RED}[%s] 脚本配置错误,请检查参数${NC}\n" "$CURRENT_TIME" | tee -a "$LOG_FILE"
echo "[$CURRENT_TIME] inotifywait退出码: $EXIT_CODE" >> "$ERROR_LOG"
exit 1
elif [ $EXIT_CODE -eq 3 ]; then
printf "${RED}[%s] 系统资源不足,无法监控${NC}\n" "$CURRENT_TIME" | tee -a "$LOG_FILE"
echo "[$CURRENT_TIME] inotifywait退出码: $EXIT_CODE" >> "$ERROR_LOG"
sleep 5
else
printf "${YELLOW}[%s] 监控异常,将重试${NC}\n" "$CURRENT_TIME" | tee -a "$LOG_FILE"
echo "[$CURRENT_TIME] inotifywait退出码: $EXIT_CODE" >> "$ERROR_LOG"
sleep 2
fi
done
![[修改后的文件监控.png]]
这样就实现了一个简单的shell脚本来监控文件是否被改动
rsa题目
rsaroll
![[rsaroll1.png]]
以下是给的数据:
{920139713,19} 704796792 752211152 274704164 18414022 368270835 483295235 263072905 459788476 483295235 459788476 663551792 475206804 459788476 428313374 475206804 459788476 425392137 704796792 458265677 341524652 483295235 534149509 425392137 428313374 425392137 341524652 458265677 263072905 483295235 828509797 341524652 425392137 475206804 428313374 483295235 475206804 459788476 306220148
这样看来应该是循环来rsa解密
我先将n=920139713,e=19,c=704796792
算出来的结果是:
![[rsaroll2.png]]
看到解的明文是f,说明思路应该是正确的,应该每个对应的都是一个字母
写出以下脚本:
```python
import math
def broken(n):
"""分解n为两个因数p和q"""
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return i, n // i
return None, None
def mod_inverse(e, phi):
"""计算e在模phi下的逆元d"""
g, x, y = extended_gcd(e, phi)
if g != 1:
return None # 逆元不存在
else:
return x % phi
def extended_gcd(a, b):
"""扩展欧几里得算法"""
if a == 0:
return (b, 0, 1)
else:
g, y, x = extended_gcd(b % a, a)
return (g, x - (b // a) * y, y)
def rsa_decrypt(c, d, n):
"""RSA解密:m = c^d mod n"""
return pow(c, d, n)
def main():
# 初始值
n1 = 920139713
e = 19
# 保持n2的原始顺序(将集合改为列表)
n2 = [704796792,752211152,274704164,18414022,368270835,483295235,263072905,
459788476,483295235,459788476,663551792,475206804,459788476,428313374,
475206804,459788476,425392137,704796792,458265677,341524652,483295235,
534149509,425392137,428313374,425392137,341524652,458265677,263072905,
483295235,828509797,341524652,425392137,475206804,428313374,483295235,
475206804,459788476,306220148]
# 分解初始n1得到p和q
p, q = broken(n1)
if not p or not q:
print(f"无法分解n1: {n1}")
return
print(f"初始n1分解结果: p={p}, q={q}")
# 计算phi(n1)
phi = (p - 1) * (q - 1)
print(f"phi(n1) = {phi}")
# 计算私钥d
d = mod_inverse(e, phi)
if d is None:
print(f"无法计算e={e}在模{phi}下的逆元")
return
print(f"私钥d = {d}\n")
# 解密每个密文并转换为字母
result = []
for i, c in enumerate(n2):
# 解密得到明文数字
m = rsa_decrypt(c, d, n1)
# 转换为对应的ASCII字符
char = chr(m) if 32 <= m <= 126 else f"[无法识别: {m}]"
result.append(char)
print(f"密文 {i+1}: {c} -> 明文: {m} -> 字符: {char}")
# 输出完整解密结果
print("\n完整解密结果:")
print(''.join(result))
if __name__ == "__main__":
main()
```
算出结果:
![[rsaroll3.png]]
获得flag:flag{13212je2ue28fy71w8u87y31r78eu1e2}
Dangerous RSA
题目描述:
littlE littlE RSA Big Big Dangerous
附件内容:
n: 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793L
e: 0x3
c: 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
so,how to get the message?
n的数值很大,无法分解,而e很小,不再是常见的65537。
这要用到低加密指数攻击,根据RSA加密算法的原理,有 c ≡ m^e ^(mod n)
在e=3时,则 c ≡ m^3 ^(mod n)
因为这里的n很大,不确定m的大小,则有两种情况
即若 m^e^<n ,则 c = m^e^,可以通过对c进行开方得到m
若 m^e^>n ,则 m ^e = kn+c,我们可以通过爆破k,若k满足kn+c能够开e次方,那么就可以得到明文
解题脚本如下:
```python
from Crypto.Util.number import *
import gmpy2
e = 0x3
n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
k = 0
while 1:
res = gmpy2.iroot(c+k*n,e) #c+k*n 开3次方根 能开3次方即可
#print(res)
#res = (mpz(13040004482819713819817340524563023159919305047824600478799740488797710355579494486728991357), True)
if(res[1] == True):
print(long_to_bytes(res[0])) #转为字符串
break
k=k+1
#输出b'flag{25df8caf006ee5db94d48144c33b2c3b}'from Crypto.Util.number import *
import gmpy2
e = 0x3
n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
k = 0
while 1:
res = gmpy2.iroot(c+k*n,e) #c+k*n 开3次方根 能开3次方即可
#print(res)
#res = (mpz(13040004482819713819817340524563023159919305047824600478799740488797710355579494486728991357), True)
if(res[1] == True):
print(long_to_bytes(res[0])) #转为字符串
break
k=k+1
#输出b'flag{25df8caf006ee5db94d48144c33b2c3b}'
```
![[dangerous rsa.png]]
-
[HDCTF2019]basic rsa
附件内容:import gmpy2 from Crypto.Util.number import * from binascii import a2b_hex,b2a_hex flag = "*****************" p = 262248800182277040650192055439906580479 q = 262854994239322828547925595487519915551 e = 65533 n = p*q c = pow(int(b2a_hex(flag),16),e,n) print c # 27565231154623519221597938803435789010285480123476977081867877272451638645710
非常基础的一道题,给了p,q,e,c
直接大脚本带进去就行了
![[[DCTF2019basic rsa.png]]
![DCTF2019basic rsa.png