Tuesday, May 14, 2013

DYNDNS Auto Login - A programmatic approach

So DynDns.org have decided to make their precious users work for their free accounts by forcing users to login periodically. What a pain in the ass! How can we automate this process programmatically? Lets explore the inner workings of the DynDns login page:


Apart from the obvious fields we need to send back (username, password...),  you can see by the highlighted sections there are 2 hidden fields. Thankfully the first one (iov1) is not necessary for a login - this field is rather complexly generated by javascript and does not render except in a browser. This means we are only interested in the "multiform" hidden field which we need to send back in our request.

That sorts out the fields we need to populate: username, password, submit and multiform. What about cookies? Yes there are cookies but that is easily captured in the header request message (set-cookie) and we can simply attach the same cookie back into our response header unmodified.

I have since setup a cron job on Google App Engine that runs my code once every month. This should help alleviate the headache of logging in manually every month. Here is the code if anyone wants to use it:


URL url = new URL("https://account.dyn.com/entrance/");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//Spoof as if from a web browser
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31");
con.setDoOutput(true);
con.connect();
// give it 15 seconds to respond
con.setReadTimeout(15 * 1000);

//Get cookie id
String headerName = null;
String cookie = null;
for(int i = 1; (headerName = con.getHeaderFieldKey(i)) != null; i++) 
{
 if (headerName.equalsIgnoreCase("Set-Cookie")) 
 {                  
  cookie = con.getHeaderField(i);
  break;
 }
}

//Read the website into a string so we can parse with Jsoup
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String temp = "";
String line = null;
while((line = reader.readLine()) != null)
{
 temp += line + "\r\n";
}
reader.close();

Document doc = Jsoup.parse(temp);
Elements els = doc.getElementsByTag("input");
String multiform = null;
for(Element e : els)
{
 String name = e.attr("name");
 String value = e.attr("value");
 //Get the hidden field required for login
 if(name.equalsIgnoreCase("multiform"))
 {
  multiform = value;
  break;
 }
}

//Open the connection again with the correct headers
con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Cookie", cookie);
con.setRequestProperty("Host", "account.dyn.com");
con.setRequestProperty("Origin", "https://account.dyn.com");
con.setRequestProperty("Referer", "https://account.dyn.com/entrance/");
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31");
con.setRequestMethod("POST");
con.setDoOutput(true);

String username = "your_username_here";
String password = "your_password_here";

//Set the login fields
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
String data = 
 URLEncoder.encode("username", "UTF-8")
 + "="
 + URLEncoder.encode(username, "UTF-8");
 data += "&"
 + URLEncoder.encode("password", "UTF-8")
 + "="
 + URLEncoder.encode(password, "UTF-8");
 data += "&"
 + URLEncoder.encode("submit", "UTF-8")
 + "="
 + URLEncoder.encode("Log in", "UTF-8");
 data += "&"
 + URLEncoder.encode("multiform", "UTF-8")
 + "="
 + URLEncoder.encode(multiform, "UTF-8");
out.write(data);
out.flush();
out.close();

//Read the response message
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
boolean success = false;
while((line = reader.readLine()) != null)
{
 //If the title says we are logged in everything worked
 if(line.contains("My Dyn Account"))
 {
  success = true;
  break;
 }
}

if(success)
{
 System.out.println("Succesfully logged in!");
}
else
{
 System.out.println("Login failed!");
}

reader.close();

Sunday, November 14, 2010

Windows Media Connect Xbox 360 Error 545

I have decided that since I come across many technically challenging or just plain irritating problems on a day to day bases that I would help my fellow man and spread my knowledge.

The most recent of these has been trying to get my Xbox 360 to connect to Windows Media Connect. Sounds easy right? Not quite. The error I got was that my Xbox would go to the Windows Media Connect screen but would just hang there, saying contacting... My PC would say error in configuring Extender. So looking in the Windows Event Log under Media Connect application I found error 545; Media Center Extender Setup cannot create an account for the Extender with ID... 


What was really annoying is that it was creating new profiles and folders in C:\Users everytime I was trying to connect, and you cannot delete these unless you boot in safe mode. But what I found is that in these folders there was only one app; Rapport. Makes sense now... This application is for banks that helps prevent phising and man-in-the-middle attacks. It was obviously blocking the connection to the machine. So I had to disable this application via it's console (no need to uninstall) and delete all the previous user profiles and it worked. Finally!!

So if you encounter the same problem, I would suggest having a look in the user profile it creates for the connection and see what apps are creating the problem.

Heres hoping this post helps someone..