Tutorial : Rapidleech Upload Plugin

NOTE: This article might not be suitable for everyone. You must at least have a little knowledge with PHP and be quite capable with HTML to continue.

NOTE: We are using Filefactory member upload plugin as an example in this tutorial. The code you see is simply to illustrate how things work with filefactory so you can see how to put the whole plugin together. Don’t expect to just copy this code into a new plugin and expect it to work!

How Rapidleech Works
Before teaching you how to really write a plugin, I must explain the way Rapidleech works, you can see this if you read the Rapidleech Download Plugin Tutorial. If however, you already understand, you can skip it.
Categorised Upload Stages
The main stages in getting Rapidleech to upload a file to a site are (btw these are what we need to make the Rapidleech script do itself):
Log in to the target site
Grab any cookies sent back from the server
Navigate to (=load) the upload page of the target site using the login cookies we just got earlier
Get the target upload url and perhaps a random id from the upload form using the cut_str() function, or you can use preg_match()
Use these login cookies and/or upload id together for the file upload if required – they may or may not be needed for uploading depending on how the uploader works
Always remember, Rapidleech acts like a browser does, in that it ‘imitates’ what a normal user does when logging in to a site, clicking the login / upload buttons etc.

Logging In with HTTP Debugger

Login via browser (to see headers)
So we first get Rapidleech to login to the target site and load the cookies that are sent back.
Simply load up HTTP Debugger or your HTTP header catcher of choice, and then login to FileFactory in your browser. Make sure you are on the login page, or can see a login form where you can enter your user and pass, and then clear your cookies. We do this to make sure no session cookies were already set when we initially loaded the login page. Input your login and pass, and click on Login. In your HTTP debugger you should see the postdata:


As you can see the postdata got urlencoded before it was posted (sent) to the server, that’s why you can see the %40 instead of an @ symbol.
Analysing the Header Response Code
The server’s response to this post is a 302 Found, and a cookie is set:

HTTP/1.1 302 Found
Date: Tue, 31 Mar 2009 16:09:17 GMT
Server: Apache
X-Powered-By: PHP/5.2.6
Set-Cookie: ff_membership=xLjW0ueLtA4IdfYHy%2F7imBhYGl0eV%2FwUNE4bw5FPzoGYgPVERneUMr6TSVSvMLWc%2v9ZVXQwBr%2BLI7ZIp1CiUSJB9VJSb3h%2FeE1gSvigoNfs4m92WxfhruNqoQuAKbpc5pb9AxYSRYRE%3D; expires=Thu, 30-Apr-2009 16:09:17 GMT; path=/; domain=.filefactory.com
Location: /?login=1
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Connection: close
Content-Type: text/html

As you can see, it tells us the new location is /?login=1 so that’s where we basically point Rapidleech. You can see it easier if you look at the filefactory.com_member.php file in the uploads/ folder.

Logging In with Rapidleech

Log In to Filefactory

First, login to filefactory with RL:
$post = array();
$post['email'] = trim($_REQUEST['my_login']);
$post['password'] = trim($_REQUEST['my_pass']);
$post['redirect'] = '/';
$page = geturl("www.filefactory.com", 80, "/", 0, 0, $post, 0, $_GET["proxy"], $pauth);
is_notpresent($page, 'HTTP/1.1 302 Found', 'Error logging in - are your logins correct?');

Storing the Login Cookies
Next, grab all the cookies the server sent us. We preg_match the ff_membership cookie to see if it was sent, and if it is missing we know there was an error so we return our own custom html error with the html_error() function.

$cook = GetCookies($page,true);
$cookie = @implode("; ",$cook);
if (!preg_match('%(ff_membership=.+); expires%', $cookie, $lcook)) html_error('Error getting login-cookie');

Log in again (with login cookies)
Now we can login to the site using the cookie we just got, and the upload form is on the page we’re getting:

$page = geturl("www.filefactory.com", 80, "/?login=1", 0, $lcook[1], 0, 0, $_GET["proxy"], $pauth);
is_notpresent($page, 'You have been logged in as', 'Error logging in - are your logins correct?');

Retrieving the Upload Url

Analysing the upload form
As is the case with downloading, for uploading you basically send some content to the server at some pre-defined address. If you look at the upload form on a website, you will see a form:

Upload, download and share any file for free!

Upload up to 25 files of any type, under 300MB each.

Upload a single file in basic mode. Up to 300MB of any file type.

Upload files to

Switch to basic uploader

Ok, so that form is pretty big..but it doesn’t matter, depending on what folders you set up in Filefactory, you’ll only see them in the options dropdown (the “select” tag).
The action url ‘http://ul016….’ is dynamically generated, because filefactory has more than one upload server, that’s why we have to cut it out and use the one they give at upload-time, rather than use the same one all the time! – you can be sure that if we did use the same one all the time, that server would become very loaded and probably fail eventually.
Storing the upload url
The good thing is, all you usually need to realise is the

part, because the action url is where the filedata is posted to. In php, we can use the cut_str() function in Rapidleech to get the action value into a string:

$upload_form = cut_str($page, '

Analysing the upload headers
Before you do anything else, you should grab HTTP Debugger Pro (or whatever you prefer using), then try uploading a file to the site in question so we can see what headers were sent along. You'll be glad to know that in most cases, all you ever need is what's posted via the upload form when you look at it via http debugger, because most of the other 'stuff' you see in the upload forms of a site is not necessary to be sent along with the file data. only some very basic stuff is needed.
So here we go - load up HTTP Debugger or whatever http header catcher you like, and upload a file to the server in your browser. You'll see it send a POST request to the url http://ul016.filefactory.com/upload.php, plus it will send some cookies along too (take a look at the 'Request Content' tab in HTTP debugger).
A sample upload postdata stream would look like this:

POST /upload.php HTTP/1.1
Accept: text/*
Content-Type: multipart/form-data; boundary=----------ae0GI3cH2KM7gL6ae0cH2KM7KM7Ij5
User-Agent: Shockwave Flash
Host: ul020.filefactory.com
Content-Length: 285429
Connection: Keep-Alive
Cache-Control: no-cache

Content-Disposition: form-data; name="Filename"

Content-Disposition: form-data; name="cookie"

Content-Disposition: form-data; name="folderViewhash"

Content-Disposition: form-data; name="Filedata"; filename="36.zip"
Content-Type: application/octet-stream

Content-Disposition: form-data; name="Upload"

Submit Query
The 'funny symbols' you see above are just the raw binary data of the file that is posted above and what I posted is a very small amount of what would be there normally. From this postdata stream, you can build your post array in the Rapidleech plugin script.
$fpost = array();
$fpost['Filename'] = $lname;

//Filefactory needs the ff_membership cookie it sent you when you logged in, so it knows who owns the files you are posting with Rapidleech! :)
$fpost['cookie'] = urldecode(str_replace('ff_membership=', '', $lcook[1]));

//this is the folder we want to put the files in, just leaving it as 0 is ok as the files will be uploaded to the 'Default' filefactory account folder)
$fpost['folderViewhash'] = '0';
$fpost['Upload'] = 'Submit+Query';


Uploading the file
Now, we have all the necessary data so we can upload the file. You will need to find the fieldname in the request content that is sent and set that as the fieldname in the upload function, upfile(). It's usually the one that contains the filename, followed by "Content-Type: application/octet-stream" - in this case, 'Filedata':

Content-Disposition: form-data; name="Filedata"; filename="36.zip"
Content-Type: application/octet-stream
Now upload the file:
$upfiles = upfile($url["host"],$url["port"] ? $url["port"] : 80, $url["path"].($url["query"] ? "?".$url["query"] : ""), $upload_form, 0, $fpost, $lfile, $lname, "Filedata");

NOTE: You do have to be careful with how you pass cookies and post arrays along to servers, as you can see above we had to urldecode() the ff_membership cookie, because if you pass it already urlencoded (where is has all %21%22%23 for special characters and so on) then the upload will fail; you can see it 'not urlencoded' if you look at the post request in your http debugger, so that's how we know to urldecode it.
Analysing The Upload Response
Ok, so now we have uploaded the file successfully, the server will return a response into the $upfiles variable. In most sites cases it could be a page returned that gives a download and/or delete link, or it could be a new location: where we have to pass some parameters. You would know this if you use your HTTP catcher to see what the exact case is, because once you know, making Rapidleech do it is the easy part.
We look for the upload response with this code. In filefactory's case, the usual response is a 7-character string, such as 'af81ce3'. We check for that string with preg_match(), but if we can't find it maybe the file wasn't uploaded.

if (!preg_match('%\r\n\r\n([a-z0-9]{7})$%', $upfiles, $curi)) html_error('Couldn\'t get the download link, but the file might have been uploaded to your account ok');
$completeurl = 'http://www.filefactory.com/file/complete.php/' . $curi[1] . '/';

Retrieving the completion URL
We then tell Rapidleech to request the completed url with the id string attached (the $completeurl). So parse out the completed url, and download it with Rapidleech using the login cookie we got earlier ($lcook[1]) into the $page variable:

$Url = parse_url($completeurl);
$page = geturl($Url["host"], $Url["port"] ? $Url["port"] : 80, $Url["path"].($Url["query"] ? "?".$Url["query"] : ""), 0, $lcook[1], 0, 0, $_GET["proxy"], $pauth);
is_notpresent($page, 'Upload Complete', 'Error getting download link - The upload probably failed');

Storing the download / delete links
From there, we can get the download link that is returned on the $page. We also have to trim() it because there was space around the download link we want to get rid of after we cut it out. We call the download link $download_link as that's what is written in the upload php to be added to some html files to record our links for uploads (done automatically).

$download_link = trim(cut_str($page, ''));

Upload Template

Here's a nice template you can use to start from, when creating upload plugins. It has most of the necessary html and php, you can be inventive and swap/create new functions yourself if needed, and there's some descriptions of how and when you'd normally use each function.

 username and password
$site_login = 'username';
$site_pass = 'password';

if ($site_login & $site_pass)
   $_REQUEST['my_login'] = $site_login;
   $_REQUEST['my_pass'] = $site_pass;
   $_REQUEST['action'] = "FORM";
   echo "
Use Default login/pass...
\n"; } if ($_REQUEST['action'] == "FORM") { $continue_up=true; } else { echo <<Login to Site
EOF; } if ($continue_up) { $not_done = false; if ( empty($_REQUEST['my_login']) || empty($_REQUEST['my_pass']) ) html_error('No user and pass given', 0); echo ""; ////////////////////////// EDIT FROM HERE DOWN /////////////////////////////////////// //Other post values Rapidleech might need to login to the site, such as submit-button values and so on $post['submit.x'] = rand(0, 100); $post['submit.y'] = rand(0, 50); $post['submit'] = 'submit'; //The login page that the postdata above is posted to when we click the login submission button $Url = parse_url('http://www.site.tld/login'); //Login to the site and return the result into $page (the result will be what we'd see if we logged in via our browser!) //It's important to use this particular line in full when requesting a resource, as it will support using a proxy if that data is passed, even a proxy login/password can be sent $page = geturl($Url["host"], $Url["port"] ? $Url["port"] : 80, $Url["path"].($Url["query"] ? "?".$Url["query"] : ""), 0, 0, $post, 0, $_GET["proxy"], $pauth); //checks for global errors is_page($page); //check if any text should/shouldn't exist after login, otherwise quit with an error (might need one or more of these) is_present($page, 'Wrong user/pass', 'Error logging into the website'); is_notpresent($page, 'You are logged in!', 'Error logging into the website'); //since $page returns the header as well as the page content, we search for any 'Set-Cookie' headers and load them into $cookies with the GetCookies function $cookies = GetCookies($page); //we might need to cut out different session cookie strings depending on how the site uses the values in future requests, you'll understand if you look at the uploading stages. the preg_matches below are just examples, they might not apply to all sites, so don't expect them to work with every site! //once we know if a particular cookie should exist, it's a good idea to do some basic error checking; instead of just preg_matching we can do an if (preg_match) and die with a custom error if it wasn't found //do some various manipulation of the cookies depending on what's required echo <<document.getElementById('login').style.display='none';
Retrieve upload ID
EOF; //set the page wherever the actual upload form is, it's usually the index page when logged in or not, or it could be [url="http://

Leave a Reply

Your email address will not be published. Required fields are marked *