RoarCTF 部分WP

WEB

easy_calc

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

 

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

RoarCTF 部分WP_第1张图片
然后就是绕单引号和个别函数之类的过滤。
尝试如下:

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

simple_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 = __ROOT__.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操作

RoarCTF 部分WP_第6张图片

剥去标签,这样的话我们文件后缀只需要在php中插入任何HTML标签即可绕过过滤,且可以正常解析。
构造一个上传页面



    

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

RoarCTF 部分WP_第7张图片
访问目标文件,得到flag
RoarCTF 部分WP_第8张图片

Easy java

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

RoarCTF 部分WP_第9张图片
下载WEB-INF/web.xml查看目录结构
RoarCTF 部分WP_第10张图片
查阅javaweb的目录结构,以及得到的servlet-class值,可以下载到所需要的class文件
RoarCTF 部分WP_第11张图片
可以发现文件中有着一串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,我们要知道, 即使是,结果也是至少位的十进制数,而A仅仅为607位,因此我们可以知道的值,其实为1。
接下来就是解方程了,我们可以通过化解等式得到,而且很明显,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为素数时:来减少阶乘模的运算量。
已知
解过程如下
代码如下:

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)

你可能感兴趣的:(RoarCTF 部分WP)