PPV, my experiences

May 12th, 2010 by admin No comments »

I’m one of those people that can’t stand PPV. I stopped doing it long before the hype came about. I think the traffic quality is a complete joke, long term sustainability is impossible because you’re advertising the same product to almost the same set of users every day, and lastly the competition is now fierce because every blogger is talking about it. If you’re a newb, don’t touch PPV, you’ll go through a decent size ad budget in literally 30 seconds, drop your ad server even faster than that, and lose a ton of money! With that said, here’s what I learned about PPV when I did it, and maybe this can help some of you that are still interested in doing it.

1) For the best results, create a landing page that looks similar to your target site to convert the user. You’ll essentially trick them into thinking your site is the site they were looking for and they’ll dish out a lot of information. It’s sort of like legal phishing. This will skyrocket conversions but also lower quality quite a bit so it’s not perfect for every product. Either way, I did have a lot of success doing this.

2) I can’t recommend rackspace.com’s cloudsites enough. I thought my servers were good until I realized I could send thousands of impressions a second to them with PPV traffic instantly dropping them and spending $100s sending traffic to a down site. With that said, I moved all my PPV landing pages to cloudsites on the cheap and haven’t been happier. In fact, I use cloudsites for most of my static landing pages now.

3) Remember the pros have automated much of PPV, which means people are using programs to auto adjust their bids to out bid you by a penny on every target. If you raise your bid, I can guarantee you any legitimate competition will be automatically raising that bid higher than yours within the next hour. If you’re running manually this is going to cause you a complete headache. With that said it usually doesn’t matter too much to be in the second or third spot providing your competition isn’t advertising the same product. I did research on this awhile back looking at the conversion statistics of a 2nd view of my product compared to a first but I can’t remember the results at the moment. I’m fairly certain first views converted much higher. If you decide to do your own research let me know what you find.

4) Cloaking is used quite a bit by the bigger PPV guys to add sound to their landing pages and beat the landing page approval process. This does increase conversions although it’s generally against any PPV network’s TOS so be careful.

5) Finding a white label offer and creating it to look like the target site is a winner.

Toorcon 11 in San Diego (A review)

October 30th, 2009 by admin No comments »

Last weekend I was at Toorcon 11 in San Diego mostly because of my interest in botnets and malware. Just some brief cliff notes from the conference I thought were semi-interesting:

Koobface is absolutely the coolest virus/trojan ever. Whatever dev team is maintaining that project is genius. For instance, to create accounts they’ll download a captcha from one infected user, show it to another infected user telling them they need to type it in to continue using their computer, and then they’ll take that response and send it back over to the first infected user to create an account.

Another hilarious thing is a guy by the name of Dancho Danchev has been doing research on koobface, and they mess with him all the time. For instance, they redirected facebook’s IP space to his blog.

Lastly, koobface spoofs as a Flash updater to get people to install it. Pretty interesting way to get someone to download something. It’s something I’d even fall for probably.

A little bit on Malware installs was discussed along with some interesting tools.

SDDownloader is software you manage to get installed on a users machine and it allows you to install more software (aka payperinstall toolbars) with it.

Although not new:
VirusTotal – does full virus scans on anything you upload to it via a bunch of commercial and free virus scanners.

iMacros Firefox wrapped with PHP, Linux, VirtualBox

October 30th, 2009 by admin 1 comment »

NOTE: Please please please feel free to leave comments criticizing anything I write here or if you have any questions! If it can help me learn to do something better I’m all for it.

So, as much as I love using PHP and CURL, I’ve finally graduated to none other than iMacros because a majority of my bigger projects have started to require me to read pages which contain necessary javascript to view. Reverse engineering javascript is fun, when it works, but wasting valuable time reversing it doesn’t make sense.

If you haven’t heard of iMacros it’s a super powerful macro scripting program made specifically to automate web browser sessions. Now before you start thinking to yourself macros are for newbs who don’t know how to code, trust me this is far from newb. iMacros on its own is very newb, mixing iMacros + PHP/MySQL + other scripting = insanely complex.

My setup is this:

Fedora Core 11 w/ VirtualBox installed (a free VMware type application), and a WinXP Pro Virtual Machine w/ iMacros scripting edition installed along with the iMacros Firefox Plug-in.

The reasoning behind running Linux and a virtual machine is this, if a WinXP virtual machine starts leaking memory/freezes/dies, I can simply close the virtual machine and reopen it via Linux command line. I’m an avid fan of making sure stuff can run unattended for months. Although it makes things a bit more complex, it’s well worth the time investment in doing it right.

With that said, I plan to slowly add my entire setup to this post, along with some more complex coding that will allow you to multi-thread iMacros sessions.

iMacros + Firefox Plugin
The reasoning behind using the iMacros Firefox Plug-in versus the iMacros Browser is that the current iMacros browser doesn’t support threaded sessions. What this means is that the same cookies, cache, proxy settings will be used across every iMacros browser session. This is no good if you want to log in to 2 different accounts at once using 2 different proxy IPs. Firefox however allows you to create different browser profiles (just run ‘firefox -ProfileManager’ with firefox already closed to view the profile manager), and iMacros allows you to choose different profiles during Firefox’s execution. As a result you get browser sessions that are entirely different from one another.

Setting up WAMPServer.

1) Download and install WAMP Server at http://www.wampserver.com/

2) Setup the command PHP to execute the WAMP server version of PHP. You won’t need Apache, I just like WampServers version of the php config which already has most of the plugins I need installed which saves a lot of headache. To make the PHP command work on Windows Vista click the start button, right click Computer and go to Properties. Click advanced system settings, go to the Advanced tab, click environment variables at the bottom, under System Variables go to the variable PATH and add the PATH to the folder that contains the php.exe (my path is: ‘C:\wamp\bin\php\php5.3.0′;)

Setting up Firefox –

First off you’re going to need to download the Firefox version of iMacros here.

To make Firefox and iMacros run most efficiently I highly recommend you do several things.

1) Disable Flash – iMacros seems to have page loading issues when Flash is involved. Since you can’t play with flash in the iMacros Firefox Plug-in anyway, lets disable flash by going to Tools/Add-ons clicking the “Plugins” tab and going down to ‘Shockwave Flash’ and disabling it.

2) Install AdBlock Plus - why spend bandwidth and CPU processes running ads you’ll never see as well as get advertisers charged for those ads. Secondly, AdBlock Plus will allow you to block certain sites or scripts from loading that you specify. This again saves valuable resources and sometimes is necessary since iMacros still appears a bit buggy when trying to figure out whether a page is done loading or not.

3) Disable loading images automatically. 99% of the time there is no point to loading images either unless your system is some sort of image scraper. Although iMacros has an image removal function (‘FILTER TYPE=IMAGES STATUS=(ON|OFF)’) I prefer disabling images via Firefox instead. I highly recommend disabling images in Firefox by going to Tools/Options clicking the ‘Content’ tab and removing the checkmark on ‘Load images automatically’. If you have images that might be an exception, say a captcha image, you can simply click the ‘Exceptions’ button and add the url of the exception. I’ve also included an iMacro in the package above that will allow you to disable and re-enable images in Firefox.

4) Make every browser session you start a private browsing session. You can do this by going to: Tools/Options/Privacy in Firefox and then choose in the drop down “Firefox will never remember history”. The reasoning for this is that I’ve found the iMacros “CLEAR” command is unreliable.

The scripts/PHP code I’ve written:

iMacros Firefox Proxy  Setting Script (taken from: http://thepemberton.com/posts/archives/23 and modified a little bit)

To use it, simply replace {{IP}} and {{PORT}} with the IP and port of your proxy.

iMacros AdBlock Plus enable/disable script

To use it, simply install ABP and then modify {{status}} to ‘true’ or ‘false’ to enable or disable it.

iMacros Firefox images enable/disable script

To use it simply replace {{images}} to 1 or 2 to enable or disable images in Firefox.

iimfx.class.php

This file allows you to run iMacros from PHP with ease providing your running the iimRunner.exe. I haven’t documented it very well, but if you take a look through it you should be able to easily figure it out. Any updates, changes you see fit, please let me know, I’d love to improve on it. You’ll also need the 3 previous scripts above to use it appropriately as it’s customized for my setup.

The code of iimfx.class.php

<?php
 
class imacros {
	function __construct($proxyip = '', $proxyport = '', $silent = false, $noexit = false) {
 
		echo "--------------------------------------\nNew imacros session started!\nUsing Proxy: $proxyip:$proxyport\n";
		$this->proxyip = $proxyip;
		$this->proxyport = $proxyport;
 
		if (empty ( $this->proxyip ))
			echo "NO PROXY!!\n";
 
		$this->noexit = $noexit;
		$this->fso = new COM ( 'Scripting.FileSystemObject' );
		$this->fso = NULL;
 
		$this->iim = new COM ( "imacros" );
 
		$toexec = "-runner -fx -fxProfile default";
 
		if ($silent === true)
			$toexec .= " -silent";
 
		if ($noexit === true)
			$toexec .= " -noexit";
 
		echo $toexec . "\n";
 
		$this->iim->iimInit ( $toexec );
 
		if (! empty ( $this->proxyip )) {
			$dvars ['IP'] = $this->proxyip;
			$dvars ['port'] = $this->proxyport;
			$this->play ( $dvars, 'proxy' );
		}
	}
 
	function __destruct() {
		if ($this->noexit === false)
			$this->iim->iimExit ();
	}
 
	function play($immvars = '', $macro) {
 
		echo "--------------------------------------------------------\n";
 
		if (is_array ( $immvars )) {
			foreach ( $immvars as $key => $value ) {
				echo "Setting Value $key => $value\n";
				$this->iim->iimSet ( "-var_" . $key, $value );
			}
		}
 
		echo "Playing Macro $macro\n";
		$s = $this->iim->iimPlay ( $macro );
 
		if($s>0){
			echo "Macro successfully played!\n";
		}else{
			echo "--------MACRO ERROR!-------------------\n ERROR: " . $this->getLastError() . "\n";
		}
		return $s;
	}
 
	// This function retrieves extracts in your iMacros script if you have any. 
	function getLastExtract($num) {
		return $this->iim->iimGetLastExtract ( $num );
	}
 
	// Returns the last error :)
	function getLastError(){
		return $this->iim->iimGetLastError();
	}
 
	// Enables/disables images
	function setImages($images = 1) { // 1 = on 2 = off
 
		$dvars ['images'] = $images;
		$this->play ( $dvars, 'images' );
 
	}
 
	// Enables or disables adblockplus
	function enableABP($status = true){
 
		$dvars['status'] = $status;
		$this->play ( $dvars, 'abp.iim' );
 
	}
 
}
 
?>

Scraping Forms with DOM and PHP for Posting with CURL

September 1st, 2009 by admin 3 comments »

I posted in the past about scraping forms for use when you need to make a post using CURL along with a little bit of code. I’ve recently moved on to using DOM and this little function I wrote below. I finally got fed up with sites adding new hidden fields and having to write preg_matches for unique variables that a lot of sites are stuffing into their forms these days to prevent spammers and/or track sessions. 

If you don’t have the plugin already in you need the php-xml plugin. Depending on your setup ‘yum install php-xml’ should do the trick.

$html is the html code of the site you’d get using file_get_contents, CURL or whatever.

$form_number is the number of the form you want – 1. It’s usually ok just to leave this at 0 but sometimes sites have more than 1 form on the page so you have to specify. 

The postData array is returned and ready for posting in CURL, all you need to do is find the few fields you actually need to specify and update those fields within the postData array. It’s usually as easy as $postData['email'] = myemail@emailme.com;

Updated Sept. 1st, 2009. This is my inputs.php. Some input fields I’ve found had some unique text names to make posting data more annoying. To quickly build around this I built a few functions to pull those as well by providing known parameters such as the inputs width, textsize, etc. It’s similar to what iMacros does.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<?php
function getInputs($html, $form_number = 0) {
 
	$dom = new DOMDocument ( );
	@$dom->loadHTML ( $html ); //@ is there cuz this will throw up a bunch of errors if the html code isn't perfect
 
 
	$forms = $dom->getElementsByTagName ( "form" );
 
	$form = $forms->item ( $form_number );
 
	// Gets input areas and also checks to make sure the form exists
 
 
	if ($form) {
		$inputs = $form->getElementsByTagName ( "input" );
	} else {
		echo "Form does not exist! Line: " . __LINE__ . "\n";
		return '';
	}
 
	foreach ( $inputs as $input ) {
 
		$attval = $input->getAttribute ( 'name' );
 
		if (! empty ( $attval ))
			$postData [$attval] = $input->getAttribute ( 'value' );
 
	}
 
	// Gets textareas
 
 
	$inputs = $form->getElementsByTagName ( "textarea" );
 
	foreach ( $inputs as $input ) {
 
		$attval = $input->getAttribute ( 'name' );
 
		if (! empty ( $attval ))
			$postData [$attval] = $input->nodeValue;
 
	}
 
	// Gets buttons
 
 
	$inputs = $form->getElementsByTagName ( "button" );
 
	foreach ( $inputs as $input ) {
 
		$attval = $input->getAttribute ( 'value' );
 
		if (! empty ( $attval ))
			$postData [$attval] = $input->getAttribute ( 'value' );
 
	}
 
	// Gets selects
 
 
	$inputs = $form->getElementsByTagName ( "select" );
 
	foreach ( $inputs as $input ) {
		$attval = $input->getAttribute ( 'name' );
 
		if (! empty ( $attval ))
			$postData [$attval] = '';
 
	}
 
	return $postData;
 
}
 
function getForms($html) {
 
	$dom = new DOMDocument ( );
	@$dom->loadHTML ( $html );
	$xpath = new DOMXPath ( $dom );
 
	$forms = $xpath->evaluate ( "/html/body//form" );
 
	$returnform = array ();
 
	for($i = 0; $i < $forms->length; $i ++) {
		$form = $forms->item ( $i );
		$returnform [] = $form->getAttribute ( 'action' );
	}
 
	return $returnform;
 
}
 
// Finds unique variables by finding other variables within the form
 
 
function findUniqueInput($html, $variables, $form_number = 0) {
 
	$dom = new DOMDocument ( );
	@$dom->loadHTML ( $html ); //@ is there cuz this will throw up a bunch of errors if the html code isn't perfect
 
 
	$forms = $dom->getElementsByTagName ( "form" );
 
	$form = $forms->item ( $form_number );
 
	// Gets input areas and also checks to make sure the form exists
 
 
	if ($form) {
		$inputs = $form->getElementsByTagName ( "input" );
	} else {
		echo "Form does not exist! Line: " . __LINE__ . "\n";
		return '';
	}
 
	$keys = array_keys ( $variables );
 
	foreach ( $inputs as $input ) {
 
		$good = true;
 
		for($i = 0; $i < count ( $keys ); $i ++) {
 
			if ($input->getAttribute ( $keys [$i] ) == $variables [$keys [$i]]) {
 
			} else {
				$good = false;
			}
		}
 
		if ($good === true) {
			echo $input->getAttribute ( 'name' ) . "\n";
			echo "Found Input!" . "\n";
			return $input->getAttribute ( 'name' );
		}
 
	}
 
}
 
function findUniqueTextArea($html, $variables, $form_number = 0) {
 
	$dom = new DOMDocument ( );
	@$dom->loadHTML ( $html ); //@ is there cuz this will throw up a bunch of errors if the html code isn't perfect
 
 
	$forms = $dom->getElementsByTagName ( "form" );
 
	$form = $forms->item ( $form_number );
 
	// Gets input areas and also checks to make sure the form exists
 
 
	if ($form) {
		$inputs = $form->getElementsByTagName ( "textarea" );
	} else {
		echo "Form does not exist! Line: " . __LINE__ . "\n";
		return '';
	}
 
	$keys = array_keys ( $variables );
 
	foreach ( $inputs as $input ) {
 
		$good = true;
 
		for($i = 0; $i < count ( $keys ); $i ++) {
 
			if ($input->getAttribute ( $keys [$i] ) == $variables [$keys [$i]]) {
 
			} else {
				$good = false;
			}
		}
 
		if ($good === true) {
			echo $input->getAttribute ( 'name' ) . "\n";
			echo "Found TextArea!" . "\n";
			return $input->getAttribute ( 'name' );
		}
 
	}
 
}
 
?>

Example getting a unique input name.

1
2
	$variables = array ("maxlength" => '10', "size" => '10', "tabindex" => '1' ); // the other variables of the text input that you want to retrieve
	$uniqueName = $this->findUniqueInput ( $text, $variables );

function getInputs example

1
2
3
4
5
6
7
$text = $c->getFile("http://www.wordpress.com"); // integrates with my curl class (you can replace this with file_get or something similar depending on what you use.)
                $postData = getInputs ( $text ); // gets the inputs from the html returned
		$postData [login] = $login; // sets the unique variables needed for the post
		$postData [password] = $password;
 
 
$this->curl->getFile("http://www.wordpress.com", $postData); // posts our data to wordpress, p.s. this is just an example and won't actually work with wordpress.

Handling Redirects with PHP/CURL

June 29th, 2009 by admin No comments »

Ever wanted to see all the different redirect urls a particular link redirects through with PHP/CURL? Now you can with this nifty little piece of code (the only thing I haven’t written yet is a way to handle redirects that don’t contain the hostname). Anyway, with that said, check this out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$url = "http://www.somesiteyouknowuseslocationredirect.com";
 
$ch = curl_init();
 
curl_setopt($ch, CURLOPT_URL, $url);
 
$data = curl_exec($ch);
 
$curl_info = curl_getinfo($ch);
 
$redirect_count = $curl_info['redirect_count'];
 
$header_size = $curl_info['header_size'];
 
$header = substr($data, 0, $header_size);
 
$redirecturls = array();
 
if($redirect_count>0){
 
preg_match_all("/location:(.*?)\n/is", $header, $locations);
 
foreach($locations[1] as $location){;
$redirecturls[] = trim($location);
}
 
}

Why marketing works

June 18th, 2009 by admin No comments »

This was a conversation about a sketchy ad I put together with a hot chick on it.

(11:41:16 AM) Brett: yowzas
(11:41:19 AM) Brett: i’d hit it
(11:41:50 AM) Me: would u click it
(11:42:05 AM) Brett: well i’m not a retard, so no
(11:42:15 AM) Brett: but luckily movies like dance flick and scary movie make it to #1 box office

I think that was pretty well said.

Some of my friends think I’m stupid

February 9th, 2009 by admin 1 comment »

I’m gunna go cry now. Thx. Seriously though, I normally don’t like posting content that is completely useless on my blog but I laughed pretty hard when I saw this for an IQ offer.

lol

A lot of Gmail email addresses, yet only 1 Gmail account.

February 5th, 2009 by admin 5 comments »

 Basically Gmail strips all .’s out of an email address when it receives the email. So you can essentially make 100s of different email addresses out of only 1 gmail address by simply taking your current email and adding .’s to it. For example: exosusrocks@gmail.com and making it e.xosusrocks@gmail.com, e.x.osusrocks@gmail.com, so on and so forth will all still go to exosusrocks@gmail.com.  It comes in handy when say you want to create a new user on a forum but don’t want to have to create a new email address.

Facebook Update! Grants + Obama = WIN!

February 4th, 2009 by admin 3 comments »

Dating is still holding up, but grants with Obama and soldiers on ‘em are where it’s at!

grants

Oh and here are the nice images you can copy and paste that facebook is allowing.  They nicely misrepresent Obama and our soldiers. But don’t try to post any deceiving text adcopy that would be bad!

49811e49d9ebd188875688 498884facfc94385124570 498789066c3f9491631498 498277c534c33223080313

Grendel-Scan

February 1st, 2009 by admin No comments »

Grendel-Scan is a security scanner which you can run against your website to check for vulnerablities. It was demonstrated/announced at DefCon last year and I never really got around to reviewing it/recommending it. Anyway, it’s a pretty cool little program that you can use to pentest your website/scripts for vulnerabilities. Just a simple test on prosper202 without logging into it prior revealed the following:

Directories were found supporting content listing.The vulnerable directories(s) are listed below:

http://www.mydom.com:80/202-img/

http://www.mydom.com:80/202-img/flags/

http://www.mydom.com:80/icons/

http://www.mydom.com:80/icons/small/

Although not that intriguing since these are hardly major vulnerabilities, you can play around w/ this program against various other types of free web applications out there along with testing your own.