网络安全

RoarCTF 部分WP

2019-10-20  本文已影响0人  Err0rzz

WEB

easy_calc

访问calc.php不带num参数的时候就可以得到calc.php源码

<?php 
error_reporting(0); 
if(!isset($_GET['num'])){ 
    show_source(__FILE__); 
}else{ 
        $str = $_GET['num']; 
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^']; 
        foreach ($blacklist as $blackitem) { 
                if (preg_match('/' . $blackitem . '/m', $str)) { 
                        die("what are you want to do?"); 
                } 
        } 
        eval('echo '.$str.';'); 
} 
?> 

输入?num=phpinfo(),发现有403错误。
接下来就是绕WAF的问题。
参考利用PHP函数parse_str绕过IDS、IPS和WAF,只需要在参数num前加一个%20即可,如下

然后就是绕单引号和个别函数之类的过滤。
尝试如下:
  1. 因为不能使用引号和system,所以无法直接执行系统命令,如lspwd等,所以使用?%20num=dirname(__FILE__)?%20num=print_r(scandir(dirname(__FILE__)))读取当前路径和当前目录下的文件 ,一开始我以为flagindex.html里,所以想用highlight_file()去读取文件,但是不能使用引号的情况下,无法读取指定文件。
  2. 既然num参数被加了黑名单过滤,那可不可以在别的地方执行命令?这里参考一叶飘零师傅无参Getshell,里面随便用一个方法都能绕过过滤。我这里使用的是
  3. 还能通过编码的方式来实现绕过,如使用eval(base64_decode(cHJpbnRfcihzY2FuZGlyKCcvJykpOzs7)) 其中base64编码过的部分为print_r(scandir('/'));;;,为什么是三个分号我也没搞懂。。
  4. 还能使用a{b}的方式来替代a['b'],从而绕过引号过滤,如eval(get_defined_vars(){_GET}{a})&a=print_r(scandir('/'));,其中{_GET}{a}[_GET][a]一样。

simple_upload

题目如下:

<?php 
namespace Home\Controller; 

use Think\Controller; 

class IndexController extends Controller 
{ 
    public function index() 
    { 
        show_source(__FILE__); 
    } 
    public function upload() 
    { 
        $uploadFile = $_FILES['file'] ; 
         
        if (strstr(strtolower($uploadFile['name']), ".php") ) { 
            return false; 
        } 
         
        $upload = new \Think\Upload();// 实例化上传类 
        $upload->maxSize  = 4096 ;// 设置附件上传大小 
        $upload->allowExts  = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型 
        $upload->rootPath = './Public/Uploads/';// 设置附件上传目录 
        $upload->savePath = '';// 设置附件上传子目录 
        $info = $upload->upload() ; 
        if(!$info) {// 上传错误提示错误信息 
          $this->error($upload->getError()); 
          return; 
        }else{// 上传成功 获取上传文件信息 
          $url = .substr($upload->rootPath,1).$info['file']['savepath'].$info['file']['savename'] ; 
          echo json_encode(array("url"=>$url,"success"=>1)); 
        } 
    } 
}

已知的是使用了ThinkPHP的框架,发现以下代码为开发者自己写的过滤,怀疑存在问题

if (strstr(strtolower($uploadFile['name']), ".php") ) { 
         return false; 
} 

该代码将判断文件名是否存在.php
打开thinkphp3.2.3源码中/Library/Think/Upload.class.php,找到对应的上传文件处理过程代码,如下:

 // 对上传文件数组信息处理
$files   =  $this->dealFiles($files);    
foreach ($files as $key => $file) {
   $file['name']  = strip_tags($file['name']);
   if(!isset($file['key']))   $file['key']    =   $key;
/* 通过扩展获取文件类型,可解决FLASH上传$FILES数组返回文件类型错误的问题 */
   if(isset($finfo)){
       $file['type']   =   finfo_file ( $finfo ,  $file['tmp_name'] );
}

可以发现,thinkphp框架会对filename进行strip_tags操作


剥去标签,这样的话我们文件后缀只需要在php中插入任何HTML标签即可绕过过滤,且可以正常解析。
构造一个上传页面
<html>
<body>
    <form action="http://cndljjs6roarctf.4hou.com.cn:37326/index.php/home/index/upload" method="post" enctype="multipart/form-data">
        <label for="file">Filename:</label>
        <input type="file" name="file" id="file" />
        <br />
        <input type="submit" name="submit" value="Submit" />
    </form>
</body>
</html>

上传任意一个php文件,然后抓包修改后缀为p<img>hp,上传成功

访问目标文件,得到flag

Easy java

点开help,发现url里有个Download?filename=,怀疑存在任意文件下载
GET改成POST,发现下载成功。

下载WEB-INF/web.xml查看目录结构 查阅javaweb的目录结构,以及得到的servlet-class值,可以下载到所需要的class文件 可以发现文件中有着一串base64编码过的字符串,解码得到flag

Crypto

RSA

题目如下:

A=(((y%x)**5)%(x%y))**2019+y**316+(y+1)/x
p=next_prime(z*x*y)
q=next_prime(z)
A =  2683349182678714524247469512793476009861014781004924905484127480308161377768192868061561886577048646432382128960881487463427414176114486885830693959404989743229103516924432512724195654425703453612710310587164417035878308390676612592848750287387318129424195208623440294647817367740878211949147526287091298307480502897462279102572556822231669438279317474828479089719046386411971105448723910594710418093977044179949800373224354729179833393219827789389078869290217569511230868967647963089430594258815146362187250855166897553056073744582946148472068334167445499314471518357535261186318756327890016183228412253724
n =  117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127
c =  41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128

未知数有三个,包括xyz,我们能做的就是通过AN恢复出未知数的值。
先观察A,可以发现有个迷惑性的运算,**2019,我们要知道, 即使是2^{2019},结果也是至少2019/3位的十进制数,而A仅仅为607位,因此我们可以知道(((y\%x)^5)\%(x\%y))的值,其实为1。
接下来就是解方程了,我们可以通过化解等式得到x=(y+1)/(A-1-y^{316}),而且很明显,A的主要是有y**316组成。这样的话,我们可以通过遍历y来确定y的值,然后求得x。代码如下:

for y in range(1000):
    if y**316>A:
        y-=1
        break
x = (y+1)/(A-1-y**316)

然后是如何根据N恢复出pq
我们首先需要知道的是,z*x*yz其实并没有相差太多,所以next_prime(z*x*y)next_prime(z)也不会相差太多。
所以我们可以用求根的方法,然后在根值附件寻找,代码如下:

z = gmpy2.iroot(n/(x*y),2)[0]
q = gmpy2.next_prime(z)
while True:
    if n % q == 0:
        break
    q = gmpy2.next_prime(q)
p = n/q

接下来就是正常的RSA的过程了,另外,加密密钥e可以试试几个常用的就能试出来了,总的代码如下

import gmpy2
from libnum import n2s
# A=(((y%x)**5)%(x%y))**2019+y**316+(y+1)/x
# p=next_prime(z*x*y)
# q=next_prime(z)
A =  2683349182678714524247469512793476009861014781004924905484127480308161377768192868061561886577048646432382128960881487463427414176114486885830693959404989743229103516924432512724195654425703453612710310587164417035878308390676612592848750287387318129424195208623440294647817367740878211949147526287091298307480502897462279102572556822231669438279317474828479089719046386411971105448723910594710418093977044179949800373224354729179833393219827789389078869290217569511230868967647963089430594258815146362187250855166897553056073744582946148472068334167445499314471518357535261186318756327890016183228412253724
n =  117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127
c =  41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128
for y in range(1000):
    if y**316>A:
        y-=1
        break
x = (y+1)/(A-1-y**316)
z = gmpy2.iroot(n/(x*y),2)[0]
q = gmpy2.next_prime(z)
while True:
    if n % q == 0:
        break
    q = gmpy2.next_prime(q)
p = n/q
d = gmpy2.invert(0x10001,(p-1)*(q-1))
m = pow(c,d,n)
print n2s(m)

babyrsa

import sympy
import random

def myGetPrime():
    A= getPrime(513)
    print(A)
    B=A-random.randint(1e3,1e5)
    print(B)
    return sympy.nextPrime((B!)%A)
p=myGetPrime()
#A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
#B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596

q=myGetPrime()
#A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
#B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026

r=myGetPrime()

n=p*q*r
#n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
c=pow(flag,e,n)
#e=0x1001
#c=38620963949231568493951852806812359956058522979245676395704780066879051018892175913415575431734194586035432099562300809271498658506900105389975586615280808081596988894713047252672924018208747721253303054480800386069769084714127190055658807083226038640292692679215406182331245636616583141043207599068234065117886147748321058731290102675088056205224134057176167818706519201527516421824645801542347535393294450756726281744763656819345306146716190523210020241675468
#so,what is the flag?

主要的问题就是大数阶乘模运算怎么求
这里用到的是威尔逊定理,当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )来减少阶乘模的运算量。
已知( A -1 )! ≡ -1 ( mod A ),B=A-r,求(B)!≡? (mod A),即(A-r)!≡? (mod A)
解过程如下\begin{align} ( A -1 )! &≡ -1 ( mod A ) \\ ( A -2 )!& ≡ -1 *(A-1)^{-1}( mod A ) \\ \cdots \\ ( A -r )!& ≡ -1 *(A-1)^{-1}(A-2)^{-1}\cdots(A-r+1)^{-1}( mod A ) \end{align}
代码如下:

import gmpy2
import libnum
def getpq(A,B):
    rand = A - B
    b = -1
    for i in range(1,rand):
        tmp = (b%A)*gmpy2.invert(A-i,A)
        b = tmp%A
    return gmpy2.next_prime(b)

A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596
p = getpq(A1,B1)

A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026
q= getpq(A2,B2)

n = 85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733

r=n/(p*q)
e=0x1001
d = gmpy2.invert(e,(p-1)*(q-1)*(r-1))
c=38620963949231568493951852806812359956058522979245676395704780066879051018892175913415575431734194586035432099562300809271498658506900105389975586615280808081596988894713047252672924018208747721253303054480800386069769084714127190055658807083226038640292692679215406182331245636616583141043207599068234065117886147748321058731290102675088056205224134057176167818706519201527516421824645801542347535393294450756726281744763656819345306146716190523210020241675468
m = pow(c,d,n)
print libnum.n2s(m)
上一篇下一篇

猜你喜欢

热点阅读