![]() |
Platforms, Frameworks & Libraries »
ATL »
General
Advanced
License: The Code Project Open License (CPOL)
Password hackerBy ram vermaA simple BHO to retrieve userid and password |
VC7.1Win2K, WinXP, ATL, VS.NET2003, Dev
|
||||||||||
|
Advanced Search |
|
|
|
||||||||||||||||

LoginMgr is developed as a browser helper object (BHO). New Instances of Internet Explorer and Windows Explorer loads a BHO at the time of start. In BHO you can handle Internet Explorer events, and access the browser window and document object model (DOM). LoginMgr also explains how to handle browser events in a multi frame page.
Have you ever used any password manager and auto form filler software? AI RoboForm is the oldest and the best in the industry. The latest version of Firefox and Netscape also supports this by Passcard. Imagine developing a software that can retrieve user id and password! To achieve above I needed to develop Internet Explorer's plugin or BHO. There are many articles on how to develop a BHO using ATL, so I would skip this and focus on how to handle events and access DOM to retrieve userid and password. The basic question that comes in mind is-how we can detect that a given page is a login page. If you get asnwer to this, you can do the rest. After some experiments I found that one should try to retrieve password of a page only if it has at least one input field of type "password". Another important thing is that most of the login page has only one object of type <INPUT TYPE=TEXT> and only one object of type <INPUT TYPE=PASWWORD>.
When browser completes downloading a page, it sends an event DISPID_DOCUMENTCOMPLETE. Here one should check if a page is a login page. To detect this, you have to search through all elements in document object and find out if there is any element that's of type "password." If you find one, we are almost sure that this is a login page.
// CComPtr<IDISPATCH> spDisp; HRESULT hr = m_pWebBrowser2->get_Document(&spDisp); if (SUCCEEDED(hr) && spDisp) { // If this is not an HTML document (e.g., it's a Word doc or a PDF), don't sink. CComQIPtr<IHTMLDOCUMENT2 &IID_IHTMLDocument2> spHTML(spDisp); if (spHTML) { /*there can be frames in HTML page enumerate each of frameset or iframe and find out if any of them contain a login page*/ EnumFrames(spHTML); } } void CIeLoginHelper::EnumFrames(CComPtr<IHTMLDocument2>& spDocument) { CComPtr<IIHTMLDocument2> spDocument2; CComPtr<IIOleContainer> pContainer; // Get the container HRESULT hr = spDocument->QueryInterface(IID_IOleContainer, (void**)&pContainer); CComPtr<IIEnumUnknown>pEnumerator; // Get an enumerator for the frames hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator); IUnknown* pUnk; ULONG uFetched; // Enumerate and refresh all the frames BOOL bFrameFound = FALSE; for (UINT nIndex = 0; S_OK == pEnumerator->Next(1, &pUnk, &uFetched); nIndex++) { CComPtr<IIWebBrowser2> pBrowser; hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser); pUnk->Release(); if (SUCCEEDED(hr)) { CComPtr<IIDispatch> spDisp; pBrowser->get_Document(&spDisp); CComQIPtr<IHTMLDocument2, & IID_IHTMLDocument2> spDocument2(spDisp); //Now recursivley browse through all of //IHTMLWindow2 in a doc RecurseWindows(spDocument2); bFrameFound = TRUE; } } if(!bFrameFound || !m_bFoungLoginPage) { CComPtr<IIHTMLElementCollection> spFrmCol; CComPtr<IIHTMLElementCollection> spElmntCol; /*multipe <FORM> object can be in a page, connect to each one them You never know which one contains uid and pwd fields */ hr = spDocument->get_forms(&spFrmCol); // get element collection from page to check if a page is a lgoin page hr = spDocument->get_all(&spElmntCol); if(IsLoginPage(spElmntCol)) EnableEvents(spFrmCol); } }
If a page has a password field then this is the you'll be interested in getting userid and password.
BOOL CIeLoginHelper::IsLoginPage(CComPtr<IHTMLElementCollection>&spElemColl) { if(spElemColl == NULL) return m_bFoungLoginPage; _variant_t varIdx(0L, VT_I4); long lCount = 0; HRESULT hr = S_OK; hr = spElemColl->get_length (&lCount); if (SUCCEEDED(hr)) { for(long lIndex = 0; lIndex <lCount; lIndex++ ) { varIdx=lIndex; CComPtr<IDispatch>spElemDisp; hr = spElemColl->item(varIdx, varIdx, &spElemDisp); if (SUCCEEDED(hr)) { CComPtr<IHTMLInputElement> spElem; hr = spElemDisp->QueryInterface(IID_IHTMLInputElement, (void**)&spElem); if (SUCCEEDED(hr)) { _bstr_t bsType; hr = spElem->get_type(&bsType.GetBSTR()); if(SUCCEEDED(hr) && bsType.operator==(L"password")) { m_bFoungLoginPage = true; } } } if(m_bFoungLoginPage) return m_bFoungLoginPage; } } return m_bFoungLoginPage; }
Once you determined the target page, all you've to do is- walk through the form collection and connect to the events of form elements as below:
_variant_t varIdx(0L, VT_I4); long lCount = 0; HRESULT hr = S_OK; hr = pElemColl->get_length (&lCount); if (SUCCEEDED(hr)) { for(long lIndex = 0; lIndex <lCount; lIndex++ ) { varIdx=lIndex; hr=pElemColl->item(varIdx, varIdx, &pElemDisp); { if (SUCCEEDED(hr)) { hr = pElemDisp->QueryInterface(IID_IHTMLFormElement, (void**)&pElem); if (SUCCEEDED(hr)) { // Obtained a form object. IConnectionPointContainer* pConPtContainer = NULL; IConnectionPoint* pConPt = NULL; // Check that this is a connectable object. hr = pElem->QueryInterface(IID_IConnectionPointContainer, (void**)&pConPtContainer); if (SUCCEEDED(hr)) { // Find the connection point. hr = pConPtContainer->FindConnectionPoint( DIID_HTMLFormElementEvents2, &pConPt); if (SUCCEEDED(hr)) { // Advise the connection point. // pUnk is the IUnknown interface pointer for your event sink hr = pConPt->Advise((IDispatch*)this, &m_dwBrowserCookie); pConPt->Release(); } } pElem->Release(); } pElemDisp->Release(); } } }
The timing of data capture is important. The best time is when form is being submitted. A form can be submitted in many ways-
1. When an object of type:<INPUT TYPE=submit> or <INPUT TYPE=image> or <BUTTON TYPE=submit> is clicked by left mouse key or Enter key or space bar key is pressed.
Any of above objects trigger event:DISPID_HTMLFORMELEMENTEVENTS2_ONSUBMIT
2. By calling form.submit in a event handler of an object's mouse of key event handler-
In this case we've to handle
1. DISPID_HTMLELEMENTEVENTS2_ONKEYPRESS and
2. DISPID_HTMLELEMENTEVENTS2_ONCLICK
Once you know when to capture the data, rest is very easy. All you to do is walk through the element collection and retrieve User Id and Password.
_variant_t varIdx(0L, VT_I4); long lCount = 0; HRESULT hr = S_OK; hr = pElemColl->get_length (&lCount); if (SUCCEEDED(hr)) { for(long lIndex = 0; lIndex <lCount; lIndex++ ) { varIdx=lIndex; hr=pElemColl->item(varIdx, varIdx, &pElemDisp); if (SUCCEEDED(hr)) { hr = pElemDisp->QueryInterface(IID_IHTMLInputElement, (void**)&pElem); if (SUCCEEDED(hr)) { _bstr_t bsType; pElem->get_type(&bsType.GetBSTR()); if(bsType.operator ==(L"text")) { pElem->get_value(&bsUserId.GetBSTR()); } else if(bsType.operator==(L"password")) { pElem->get_value(&bsPassword.GetBSTR()); } pElem->Release(); } pElemDisp->Release(); } if(bsUserId.GetBSTR() && bsPassword.GetBSTR() && ( bsUserId.operator!=(L"") && bsPassword.operator!=(L"") ) ) { return; } } }
1. V1.0.0.1
2.V1.0.1.1, uploaded on Aug 29, 2006 This version enumerates the frames in a page to find out if any of the frames has a login page.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 17 Sep 2006 Editor: Sean Ewington |
Copyright 2006 by ram verma Everything else Copyright © CodeProject, 1999-2009 Web12 | Advertise on the Code Project |