网鼎杯2020线下半决赛两道WEB题WriteUp
网鼎杯2020线下半决赛两道WEB题WriteUp
第一次参与网鼎杯线下赛,五道题3道PWN、两道WEB(PHP),下午又加了一道web(nodejs)。
先说下赛制,网鼎杯赛制叫做AWD PLUS,应该是全国唯一采用这个赛制的比赛。名字叫做AWD,实际这个赛制队伍之间不需要也不允许相互打。每个队伍每个题目有一个GameBox,提供下载源代码包,攻击和修复代码漏洞就可以得分。与一般AWD不同的是,网鼎杯赛制不需要准备不死马/通防脚本等,更加偏重于代码审计、漏洞挖掘、漏洞利用和修复。(也许叫CTF PLUS 或者 AWD STATIC 更合适?)
两道web题write_up
WEB1 web_AliceWebsite
打开主页,容易看到上面有个文件包含。
查看源码,看到
<?php $action = (isset($_GET['action']) ? $_GET['action'] : 'home.php'); if (file_exists($action)) { include $action; } else { echo "File not found!"; } ?>
没有任何过滤, include /flag 拿到flag;
payload
?action=/flag
修复加固:
1、正则过滤掉../ ./
2、配置php.ini文件
关闭远程文件包含功能(allow_url_include = Off allow_url_fopen = Off)
2、 设置文件白名单。
4、 建议假定所有输入都是可疑的,尝试对所有输入提交可能可能包含的文件地址,包括服务器本地文件及远程文件,进行严格的检查,参数中不允许出现../之类的目录跳转符。
// 验证邮箱格式 function checkEmail($email) { if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/", $email)) { return false; } else { return true; } }
WEB2 FAKA
先部署代码到本地,并导入sql文件。代码目录
根目录robots.txt 里提示1.txt,1.txt里面是注册邀请码,根据提示注册,是一般用户,略微审计了下 /application/merchat/ 目录,没啥用。
后台页面在/application/admin目录下,使用的表叫做 system_user
打开system_user表,第一行为账户名为admin,密码为md5的用户。赛前准备了TOP10W密码的哈希值,搜索了下这个哈希值没有搜到。看来需要修改密码或者新增一个用户。
继续审代码,application/admin/index.php 文件下有两个方法:
public function pass() { if (intval($this->request->request('id')) !== intval(session('user.id'))) { $this->error('只能修改当前用户的密码!'); } if ($this->request->isGet()) { $this->assign('verify', true); return $this->_form('SystemUser', 'user/pass'); } $data = $this->request->post(); if ($data['password'] !== $data['repassword']) { $this->error('两次输入的密码不一致,请重新输入!'); } $user = Db::name('SystemUser')->where('id', session('user.id'))->find(); if (md5($data['oldpassword']) !== $user['password']) { $this->error('旧密码验证失败,请重新输入!'); } if (DataService::save('SystemUser', ['id' => session('user.id'), 'password' => md5($data['password'])])) { $this->success('密码修改成功,下次请使用新密码登录!', ''); } $this->error('密码修改失败,请稍候再试!'); } /** * 修改资料 */ public function info() { if (intval($this->request->request('id')) === intval(session('user.id'))) { return $this->_form