Arcturus Labs

Concrete5 Reflected XSS

Posted by Rory M on Thursday, July 25 2019

It’s fun working in this industry. I get paid to break things, like every day. What more could you want?

On a related note, I found myself on a test last week. The client was launching a website, wanted to make sure they weren’t missing anything hilariously obvious. Pretty standard stuff. We did happen to find them leaving a phpinfo file laying around, but that’s besides the point.

I discovered they’re using a CMS called ‘Concrete5’. This was new to me; so, naturally, my ears pricked up. I discovered that it’s open source and actually in fairly wide use (if their website is to be believed..): suspicious numbers I decided to dig in with some source code analysis.

Reading through source code can sometimes be quite a pleasant experience. This application is written in PHP. This was not one of those times. Wrapping my head around how requests are routed took me longer than I care to admit, but my trusty sidekicks ripgrep and echo "<!-- HERE -->"; saved my bacon. suspicious numbers

So. I hacked together, printf-debugging style, some routing information. Got my head around how URLs pair up with Controllers and Views. I’ve not dug into Symfony much before and I hope never to again.

After figuring out how to match a URL request to a specific View, I started grepping for some basic $_GET stuff. It took me a good fifteen minutes to realise Symfony has it’s own wrappers for $_GET, $_POST and $_REQUEST, because REASONS. After adjusting my regex, in one of the views I found this gem:

src="<?= URL::to('/ccm/system/panels/page/preview_as_user/render') . '?&cID=' . Request::request('cID') ?>

Which is a very basic reflected XSS. I spent a bit more time rooting around for an SQL injection or an auth bypass… but other jobs began to clamour for my attention. For fun, here is my printf-debugging patchset.

If anyone finds another XSS with rg 'Request::(post|get|request)\(' then I claim all credit and I want a share of the bounty.

Vegans offended: 26
Found: 12 July 2019
Reported on hackerone: 15 July 2019
Fixed: 17 July 2019
Bounty received: 0.00 GBP
Time wasted: a lot