Solved

Passing User ID and Password to a Javascript login screen

Posted on 2003-12-02
9
1,684 Views
Last Modified: 2007-12-19
Help once again!  

I am putting together a perl script to access a web page and extract certain information.  

The problem is that the login screen is written in Java.

It seems that the login form is built dynamically - below is code that defines the username and password fields:

document.write("<td align=left><INPUT TYPE=TEXT NAME=\"username\" VALUE=\"\" MAXLENGTH=128 SIZE=7></td>");
      document.write("</tr>");
      document.write("<tr>");
      document.write("<th align=right><LABEL ID=PWD>Password:</LABEL></th>");
      document.write("<td align=left><INPUT TYPE=password NAME=\"password\" VALUE=\"\" MAXLENGTH=46 SIZE=12>");

I am using WWW::Mechanize.  it seems to get back the page just fine, (and I have the latest version .70) .  

I keep working on it - but any advice is appreciated.

Cheers

Matt
0
Comment
Question by:mattstarbuck
  • 4
  • 3
9 Comments
 
LVL 16

Expert Comment

by:JohnBPrice
ID: 9866404
It looks like their page is going to post the data after the user fills it in, in which case you could perhaps skip the login screen altogether by posting your own page to the same place that the login screen posts to, essentially making it think it is receiving a regular login.  Somewhere in the login screen is the URL where the info is posted.
0
 

Author Comment

by:mattstarbuck
ID: 9870807
Thanks

I can't find any URLs in the Java Script.  

I have attempted to post to the URL itself, and it seems to accept it (at least I don't get an error of any kind and I would expect it to tell me that the username and password are not found, if they weren't there)  Correct me if I am wrong.  :)

If I trace the actions through a browser, Go through the login screen, etc - an I finally get routed back to the desired page, I have a session-id of 310 characters that in the next action is trimmed down.

If I go through Perl, I get routed to the login screen, pick up the trimmed down version of the session-id, I do a post with username and password, but I am still at the screen.  If I try to click() on the OK but it errors with can't peroform the action on an unidentified object.

Now what I have tried is to next simply get the URL I was trying to get in the first place, but it is somehow getting routed to a different URL.  (the session-id is being retained by WWW::Mechanize).

I'll keep trying things, and any more help is appreciated.  

I have bumped the points up a bit - getting a little desperate.

Cheers

Matt  

 
0
 
LVL 16

Expert Comment

by:JohnBPrice
ID: 9874238
Can you capture the entire HTML of the login page and post it here?  (If it is not confidential)

Based on the snippet above it has to post the info somewhere, but it might be embedded in a included .js file, or otherwise obscured.  Is the login page http or https?
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 

Author Comment

by:mattstarbuck
ID: 9874518
John -

Since it is a corporate thing, I don't feel right posting it. It is https - I have gotten everything installed so LWP/Mechanize are able to handle https/SSL calls. (not an easy process - Cygwin/gcc/OpenSSL, and all the perl pieces seems to be working great).

I have stripped down the code a bit and included it here (I removed the company info etc.  I have also removed a couple of functions that related to 'Tokens' since 'we' are trying to login under the username/password path and not the token/password path).  The username path should be intact.

This isn't going to be pretty ........  :)

<!--
%W% %G% %U%
-->
<html>
<head>
<TITLE>CO Global Single Sign-On: Login</TITLE>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="keywords" content="security, single_sign_on">
<meta name="description" content="Global Single Sign-On.">

<script language="javascript">
<!--

var browName = navigator.appName;
var browVer = navigator.appVersion.substring(0, 4);
var strNSMessage = "To log on and access secure sites, your browser must accept \'cookies\'." +"\n\n"
      +"For Netscape Navigator 4.x "+"\n"
      +" 1. Select Edit > Preferences > Advanced" +"\n"
      +" 2. Within the Cookies frame, select \'Accept all cookies\'";
var strIEMessage = "To log on and access secure sites, your browser must accept \'cookies\'."+"\n\n"
      +"For Microsoft Internet Explorer 4.x "+"\n"
      +" 1. Select View > Internet Options > Advanced"+"\n"
      +" 2. Within the Security > Cookies section, select \'Always accept cookies\'";
var bIsIE = 0;
var bIsNS = 0;
if ( browName == 'Microsoft Internet Explorer' )
      bIsIE = 1;
if ( browName == 'Netscape' )
      bIsNS = 1;

function doSubmit()
{
            // Only disable the Submit button for IE and NS. NetFront (PDAs)
            // browsers fail with this call.
      if ( ( bIsIE ) || ( bIsNS ) )
      {
            document.frmLogin.btnSubmit.disabled = true;
      }

      if ( document.frmLogin.authmethod[1].checked )
      {
            idx = document.frmLogin.SelectTokenAuth.selectedIndex;
            TokenAuth = document.frmLogin.SelectTokenAuth.options[idx].value;

            document.frmLogin.tokenuser.value = TokenAuth + "|" +
                  document.frmLogin.username.value;
            document.frmLogin.passcode.value = document.frmLogin.tokenpin.value +
                  document.frmLogin.tokendisplay.value;
      }
      return(true);
}

function checkSubmit()
{
      return(checkFormSubmit(document.frmLogin));
}

function checkFormSubmit(form)
{
      if ( ( form.username.value == "" ) ||
            ( form.password.value == "" ) )
      {
            alert("You must enter a User Name and Password!");
            setInputFocus();
            return(false);
      }
}

function checkCookiesOnLoad()
{
      var strSearch = "PinLogin"
      var nOffset = -1;

            // Don't try to set cookie again if it already exists
      if ( document.cookie.length > 0 )
      {
                  // There are cookies, so look for the one we care about
            nOffset = document.cookie.indexOf(strSearch)
            if ( nOffset != -1 )
            {
                  return true;
            }
      }

      document.cookie = strSearch + "=" + "TestCookies";

      if ( document.cookie.length > 0 )
      {
                  // There are cookies, so look for the one we care about
            nOffset = document.cookie.indexOf(strSearch);
            if ( nOffset != -1 )
            {
                  return true;
            }
            else
            {
                  if ( bIsNS )
                        alert(strNSMessage);
                  else if ( bIsIE )
                        alert(strIEMessage);
                  return false;
             }
      }
      else
      {
                  // Cookie could not be set
            if ( bIsNS )
                  alert(strNSMessage);
            else if ( bIsIE )
                  alert(strIEMessage);
            return false;
      }
}

function checkCookiesAtField(hrid)
{
      var bCookiesOK = 0;

      bCookiesOK = checkCookiesOnLoad();

      if ( ( bIsIE && browVer < 4.0 ) || ( bIsNS && browVer < 4.04 ) )
      {
            alert("Your browser is not approved.  Please use Netscape 4.04 or higher or Internet Explorer 4.0 or higher");
      }

      if ( bCookiesOK == true )
            return true;

      hrid.focus();
      hrid.select();

      return false;
}

function getObject(thisObj)
{
      if (document.getElementById)
            return document.getElementById(thisObj)
      else if (document.all)
            return document.all[thisObj]
}

      // Get the cookie value at the specified offset
function getCookieVal(nOffset)
{
      var nEndStr = document.cookie.indexOf(";", nOffset);

      if (nEndStr == -1)
            nEndStr = document.cookie.length;

      return unescape(document.cookie.substring(nOffset, nEndStr));
}

      // Get a cookie
      // var someVariable = getCookie('your_cookie_name');
function getCookie(strName)
{
      var arg = strName + "=";
      var alen = arg.length;
      var clen = document.cookie.length;
      var i = 0;

      while (i < clen)
      {
            var j = i + alen;

            if ( document.cookie.substring(i, j) == arg )
                  return getCookieVal(j);

            i = document.cookie.indexOf(" ", i) + 1;

            if ( i == 0 )
                  break;
      }

      return null;
}

      // Set a cookie
      // setCookie('your_cookie_name', 'your_cookie_value', exp);
      // examples for setting expiration value:
      // var expDays = 100;
      // var expMinutes = 5;
      // var exp = new Date();
      // to set timeout in days:
      // exp.setTime(exp.getTime() + (expDays*24*60*60*1000));
      // to set timeout in minutes:
      // exp.setTime(exp.getTime() + (expMinutes*60*1000));
function setCookie(strName, strValue)
{
      var argv = setCookie.arguments;
      var argc = setCookie.arguments.length;
      var expires = (argc > 2) ? argv[2] : null;
      var path = (argc > 3) ? argv[3] : null;
      var domain = (argc > 4) ? argv[4] : null;
      var secure = (argc > 5) ? argv[5] : false;

      document.cookie = strName + "=" + escape (strValue) +
            ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
            ((path == null) ? "" : ("; path=" + path)) +
            ((domain == null) ? "" : ("; domain=" + domain)) +
            ((secure == true) ? "; secure" : "");
}

var strCookieName = "CSPLoginType";
var strPwd = "PWD";
var strToken = "Token";

function start()
{
      var bShowDebug = false;
      var bPwd = true;
      var strCookieVal = getCookie(strCookieName);

      if ( strCookieVal != null )
      {
            if ( bShowDebug == true )
            {
                  document.write(strCookieName + " found<br>");
                  document.write("Value is " + strCookieVal + "<br>");
            }
            if ( strCookieVal == strToken )
                  bPwd = false;
      }
      else
      {
            if ( bShowDebug == true )
            {
                  document.write(strCookieName + " not found<br>");
            }
      }

      showLogin(bPwd);
}

function doReload(bPwd)
{
      var bShowDebug = false;
      var bDoReload = false;
      var strCookieVal = getCookie(strCookieName);

            // if we can verify that the requested page is the current
            // page, then don't do the reload
      if ( strCookieVal != null )
      {
            if ( bShowDebug == true )
            {
                  document.write(strCookieName + " found<br>");
                  document.write("Value is " + strCookieVal + "<br>");
            }
            if ( ( ( bPwd == true ) && ( strCookieVal != strPwd ) ) ||
                  ( ( bPwd == false ) && ( strCookieVal != strToken ) ) )
                  bDoReload = true;
      }
      else
      {
            if ( bShowDebug == true )
            {
                  document.write(strCookieName + " not found<br>");
            }
            bDoReload = true;
      }

      if ( bDoReload == true )
      {
            var exp = new Date();
            var expMinutes = 5;
            exp.setTime(exp.getTime() + (expMinutes*60*1000));
            if ( bPwd == true )
            {
                  //setCookie(strCookieName, strPwd);
                  //setCookie(strCookieName, strPwd, exp, "/", ".co.com");
                  setCookie(strCookieName, strPwd, null, "/", ".co.com");
            }
            else
            {
                  //setCookie(strCookieName, strToken);
                  //setCookie(strCookieName, strToken, exp, "/", ".co.com");
                  setCookie(strCookieName, strToken, null, "/", ".co.com");
            }

            window.location.reload();
      }
}

function showLogin(bPwd)
{
      //document.clear();
      document.write("<font face=\"Arial\">");
      document.write("<FORM name=\"frmLogin\" METHOD=POST ACTION=\"/pkmslogin.form\" onsubmit=\"return(doSubmit());\">");

      document.write("<a href=\"http://www.co.com\"><img border=0 src=\"/images/coglobe.gif\"></a>");

      document.write("<center>");
      document.write("<table border=1 width=500>");
      document.write("<TR>");
      document.write("<TD ALIGN=CENTER>");
      document.write("<font size=+1><b>CO Global Log On</b></font>");
      document.write("</TD>");
      document.write("</TR>");

      document.write("<TR>");
      document.write("<TD ALIGN = CENTER>");
      document.write("<BR>");
      if ( bPwd == true )
            document.write("<font size=-1><b>Need help with your password?</b>&nbsp;<a href=\"/empsvcs/hrpinmgt/pagMenu\">Click here.</a></font>");
      else
            document.write("<font size=-1><b>Need help with your token?</b>&nbsp;<a href=\"/empsvcs/hrpinmgt/faq.html#6.1\">Click here.</a></font>");
      document.write("<BR>");

            // SRP Start
            // Added by srp 10/24/2000 to show error text on failed login attempts
            // Set bShowRawErrors to 1 to show PD error information
      document.write("<font size=-1 color=\"#FF0000\">");

      var bShowRawErrors = 0;
      if ( bShowRawErrors )
      {
            var emsg;
            emsg = "";
            if (emsg != "")
            {
                  if ( emsg.indexOf("%ERR") != 0 )
                  {
                        document.write ("<br>");
                        document.write (emsg);
                        document.write ("<br>");
                  }
            }
      }
      document.write("</font>");
      // SRP End

      document.write("<center>");
      document.write("<table border=1 width=400>");
      document.write("<tr>");
      document.write("<td align=left>");

            // SRP Start
            // Added by srp 10/24/2000 to show error text on failed login attempts
      document.write("<font size=-1 color=\"#FF0000\">");
      var emsg;
      var emsg2;
      emsg = "";
      if (emsg != "")
      {
            if ( emsg.indexOf("%ERR") != 0 )
            {
                  emsg2 = emsg.substring(0, emsg.indexOf("."));
                  if ( (emsg2 == "Could not acquire a client credential") ||
                        (emsg2 == "The client's account has expired") ||
                        (emsg2 == "The%20client's%20account%20has%20expired") )
                  {
                        document.write ("<b>Your account has been suspended.  Please contact customer service.</b>");
                  }
                  else if ( emsg == "Unauthorized" )
                  {
                  }
                  else
                  {
                        document.write ("<b>Login incorrect.  Please try again.</b>\n");
                  }
            }
      }
      document.write("</font>");
      // SRP End

      document.write("</td>");
      document.write("</tr>");
      document.write("<tr>");
      document.write("<td align=\"center\">");

      var strPwdChecked = "";
      var strTokenChecked = "";
      if ( bPwd == true )
            strPwdChecked = "CHECKED";
      else
            strTokenChecked = "CHECKED";

      document.write("<table border=0 align=center>");
      document.write("<tr>");
      //document.write("<th align=right>Login Method:</th>");
      document.write("<th></th>");
      document.write("<td align=left>");
      document.write("<INPUT TYPE=\"RADIO\" NAME=\"authmethod\" onclick=\"doReload(true);\" " + strPwdChecked + ">Password");
      //document.write("<br>");
      document.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
      document.write("<INPUT TYPE=\"RADIO\" NAME=\"authmethod\" onclick=\"doReload(false);\" " + strTokenChecked + ">SecurID<sup>&reg;</sup>&nbsp;Token");
      document.write("</td>");
      document.write("</tr>");
      document.write("</table>");

      if ( bPwd == true )
            showPwd();
      else
            showToken();

      .................
      if ( bPwd == true )
      {
            if ( document.frmLogin.username.value.length > 0 )
                  document.frmLogin.password.focus();
            else
                  document.frmLogin.username.focus();
      }
      else
      {
            if ( document.frmLogin.username.value.length > 0 )
                  document.frmLogin.tokenpin.focus();
            else
                  document.frmLogin.username.focus();
      }
      //document.close();
}

function showPwd()
{
      document.write("<table border=0 align=center>");
      document.write("<tr>");
      document.write("<th align=right>HRID:</th>");
      document.write("<td align=left><INPUT TYPE=TEXT NAME=\"username\" VALUE=\"\" MAXLENGTH=128 SIZE=7></td>");
      document.write("</tr>");
      document.write("<tr>");
      document.write("<th align=right><LABEL ID=PWD>Password:</LABEL></th>");
      document.write("<td align=left><INPUT TYPE=password NAME=\"password\" VALUE=\"\" MAXLENGTH=46 SIZE=12>");
      document.write("</td>");
      document.write("</tr>");
      document.write("<tr>");
      document.write("<td align=center colspan=2><INPUT TYPE=submit NAME=\"btnSubmit\" VALUE=\"  OK  \"onClick=\"if (checkCookiesAtField(username)) return true; else return false;\"></td>");
      document.write("</tr>");
      document.write("</table>");
}


var nCheckPage = document.location.href.indexOf("pkmslogin.form");
//document.write("nCheckPage is " + nCheckPage);
if ( nCheckPage == -1 )
{
      setCookie("cspReqLnk", window.location.href, null, "/", null);
}

//-->
</script>
</head>

<body bgcolor="#FFFFFF" onLoad="checkCookiesOnLoad();">
<script language="javascript">
//<!--
start();
//-->
</script>
</body>

</html>

0
 
LVL 16

Expert Comment

by:JohnBPrice
ID: 9875088
OK, it looks like they stuff the user name and password into a cookie, and then when they hit submit, it goes to \pkmslogin.form, which presumably is this same form but could be another form.  However, it looks to me like you took out the wrong part in DoSubmit, it appears you left the token code, not the cookie code.  e.g. the other half of      if ( document.frmLogin.authmethod[1].checked )

Anyway, probably there is server code that reads the user/password from the cookie and validates it.  To fake it out, you would have to sppof a cookie (presuming you can't put a page on the same domain).  I'm sure there are ways to spoof a cookie, but I don't know how.  So unless you know how to spoof a cookie, I think that alternative is out.

I don't know Mechanize, can it fill in the form values document.frmLogin.username.value and password.value, call the doSubmit(), and then frmlogin.submit()?

Another idea is to create a frame set, load their login form in one frame, and drive it from another frame.

0
 

Author Comment

by:mattstarbuck
ID: 9876777
John -

I am pretty close behind you - I am looking at the cookie - and I get the first part captured by Mech, then the system (through three calls where the detail is not shown), this becomes 385 characters of which the first 131 charaters are the same, and the last 101 also match.  The middle 153 characters vary per login. Incidently the last 101 characters have my first and last name imbedded (and is attached after entering my user ID and password).

I am tracing the cookie through the code now - thanks for the hint.

Mechanize - a child of LWP user agent for automating Web page extraction (HTML).  It doesn't understand or attempt to interpret the Javascipts.  If you note from the code above, none of the document.write commands are translated, so the form tags are not assembled. HTML::Form looks for <form> and </form> to identify the form, and since these are still in the Javascript, HTML::Form can't recognise the form, and therefore the fields, username, password, and the submit button are all lost in the Java script.  the example below will return an empty set to $form assumming  $html is the content from my login url.

use HTML::Form;
 $form = HTML::Form->parse($html, $base_uri);
 $form->value(query => "Perl");

 use LWP::UserAgent;
 $ua = LWP::UserAgent->new;
 $response = $ua->request($form->click);

Once I get past the login screen, it should be relatively easy to get the information I want, since its in HTML format (famous last words??)  

Cheers

Matt
0
 
LVL 16

Accepted Solution

by:
JohnBPrice earned 300 total points
ID: 9877297
I see on the web that LWP::UserAgent does have a cookie_jar attribute that might be useful for hacking in the cookie values.  You should see in doSubmit() some calls to setCookie(...), at least two I would think, one for the username, one for the password.  Each call gets a bunch of fields in the actual cookie string from setCookie from the line

document.cookie = strName + "=" + escape (strValue) +
          ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
          ((path == null) ? "" : ("; path=" + path)) +
          ((domain == null) ? "" : ("; domain=" + domain)) +
          ((secure == true) ? "; secure" : "");


also look at the code right before the body and the call to
    setCookie("cspReqLnk", window.location.href, null, "/", null);
My guess it is you will also have to have this in your cookie string too.

I'm not sure why doReload(...) calls setCookie(...) for the password.

I haven't used cookies except for straigtforward stuff (in my own domain), but it looks like the domain parameter is how you can spoof the cookies into the right domain.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Add mobile access to browser application 3 199
Specific format 21 207
wordappend challenge 8 201
Problem to open Excel file 15 178
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
This video teaches viewers about errors in exception handling.
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question