Solved

Passing User ID and Password to a Javascript login screen

Posted on 2003-12-02
9
1,653 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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Convert Jpg /PNG To GIF 5 102
fix34  challenge 9 96
copyEndy  challenge 15 55
Problem to page 4 17
Navigation is an important part of web design from a usability perspective. But it is often a pain when it comes to a developer’s perspective. By navigation, it often means menuing. This is less theory and more practical of how to get a specific gro…
This article will show, step by step, how to integrate R code into a R Sweave document
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

708 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now