Archive
MSysObjects SQL injection attack
A colleague of mine recently had his website hacked with a sql injection attack, with a url something like http://www.someurl.com/somepage.asp?
id=153%20union%20%20select%201,2,3,4,fldusername,
6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,fldpassword,
fldpassword,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,
39,40,41,42,43,44,45,46,47,48%20from%20tbluser%27
hense exposing all the usernames and passwords on the page. it lead me to think, how did the hacker guess the column names? – I knew about the sysobjects table in sql server, but being a classic ASP page, it would undoubtedly have an Access back end. Then I spotted the following hidden tables in access:
MSysObjects
MSysACEs
MSysQueries
MSysRelationships
MSysAccessObjects
MSysAccessXML
MSysDb
Which you can query to obtain the database schema. All I can say is . NEVER EVER BUILD SQL STATEMENTS DIRECTLY WITH USER PROVIDED TEXT (without calling Replace("’","”") at least!
Error in OleAut32.Dll Offset 4c47
AppName: vb6.exe AppVer: 6.0.97.82 ModName: oleaut32.dll
ModVer: 5.1.2600.2180 Offset: 00004c47
Unhandled exception at 0x77124c47 in VB6.EXE: 0xC0000005: Access violation reading location 0x80020000.
77124C47 mov eax,dword ptr [eax-4]
This is a lovely error that crashes VB6 if you make a little typo, and here’s how to fix it:
If you make write code like this
Dim rsProduct As New ADODB.Recordset
sql = " select * from orderlines "
rsOrderLines.Open sql, DSN
Do While Not rsProduct
‘ process rsProduct
rsOrderLines.MoveNext
Loop
The application will compile, But, note that I have accidentaly ommitted the ".EOF" in the while loop. This causes VB6 to crash with the above error. To Fix it, use the EOF.
Microsoft.VisualStudio.Shell.Interop.IVsRuningDocumentTable2
After installing Visual Studio 2005 beta 2 on a machine that previously had a copy of VS 2005 Beta 1, I got an error when trying to open the windows forms designer –
visual studio settings and project designers package has failed to load properly
Could not load type Microsoft.VisualStudio.Shell.Interop.IVsRuningDocumentTable2
from Assembly Microsoft.VisualStudio.Shell.Interop.8.0
To fix this, I spotted that in the GAC (C:windowsAssembly) there were two versions of Microsoft.VisualStudio.Shell.Interop.8.0, I uninstalled the older version, restart visual studio and it worked. Apparently the same problem occurs with the ASP.NET web page designer with Microsoft.VisualStudio.Shell.Interop.SVsSmartOpenScope.
There are a number of similar DLL’s in the GAC with identical names and version numbers – such as Microsoft.VisualStudio.TextManager.Interop.8.0 (which causes a bug with Microsoft.VisualStudio.TextManager.Interop.IVsQueryUndoUnit) and Debugger.interop.8.0
On a personal note, I just noticed that one of my websites, www.buymusic.cd just reached a Google PR 5.
Url rewriting
If you have a large website that you need to be google indexable (Googlable if I may coin a new phrase). Then it is worthwhile converting standard links such as myPage.asp?x=1&y=2 to someting like /web/x/1/y/2/myPage.asp where the "folder structure" translated back to a standard querystring before it is processed.
You can do this though .NET by writing a class that implements IHttpModule, however for added performance you should use an ISAPI filter. My personal favourite is UrlReWrite by Smalig software.
The only catch with using url-rewrites the new ‘virtual’ folder structure can lead to a heap of bad links. In this case you have to use <base href> to correct this.
I used it on three new sites www.listofdevelopers.info www.listofEstateAgents.info and www.listofschools.info
Generating thumbnails in ASP.NET
Hi,
I found just developed a nice new function for uploading images from a website, and generating thumbnails on the fly
public string storeFile(HttpPostedFile postedFile)
{
string strFilename="";
string strPath = "c:\wherever\";
if( postedFile.FileName != "" )
{
HttpPostedFile hpfFile = postedFile;
int nFileLen = hpfFile.ContentLength;
byte[] bData = new byte[nFileLen];
hpfFile.InputStream.Read(bData, 0, nFileLen);
strFilename = Path.GetFileName(hpfFile.FileName);
FileStream fsFullImage = new FileStream(strPath + strFilename , FileMode.Create);
fsFullImage.Write(bData, 0, bData.Length);
fsFullImage.Close();
System.Drawing.Image iPhoto;
System.Drawing.Image iThumbnail;
iPhoto = System.Drawing.Image.FromFile(strPath + strFilename);
iThumbnail = iPhoto.GetThumbnailImage(100, 100, null, IntPtr.Zero);
FileStream fsThumbnailImage = new FileStream(strPath + "tn" + strFilename , FileMode.Create);
iThumbnail.Save(fsThumbnailImage, ImageFormat.Gif);
fsThumbnailImage.Close();
}
return strFilename;
}
This is then called in a asp.net page with
string strFilename = storeFile(Photo.PostedFile);
Where Photo is a name of a file input box such as:
<input type=file name="Photo" id="Photo" runat="server">
You also have to add the following – enctype="multipart/form-data" to your form, and ensure you have write permissions on the destination folder.
Browser Helper Objects C#
Can anybody help tell my why this code isn’t working. Its a Browser Helper Object for Internet Explorer, Simply designed to Write the Current Time at the bottom of each page. It compiles ok, and it registers as a COM object with regasm ok, and I put its GUID in the correct place in the registry (under Explorer/Browser Helper Objects). I can’t even get VS.NET to attach to the IEXPLORE process.
using System;
using
SHDocVw;
using
mshtml;
namespace BrowserHelperObject
{
using System;
using System.Runtime.InteropServices;
[ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
void SetSite ([MarshalAs(UnmanagedType.IUnknown)]object site);
void GetSite (ref Guid guid, out object ppvSite);
}
/// <summary>
/// Summary description for CustomBrowserHelperObject
/// </summary>
[ComVisible(
true),
ClassInterface(ClassInterfaceType.None),
Guid("9E6F3590-52D0-406d-A7ED-DAE87BED989F")]
public class CustomBrowserHelperObject : IObjectWithSite
{
const int E_FAIL = unchecked((int)0x80004005);
const int E_NOINTERFACE = unchecked((int)0x80004002);
private IWebBrowser2 iwb2InternetExplorer;
public void SetSite ([MarshalAs(UnmanagedType.IUnknown)]object site)
{
iwb2InternetExplorer = (IWebBrowser2)site;
if (iwb2InternetExplorer != null)
{
WebBrowser wbInternetExplorer = (WebBrowser)iwb2InternetExplorer;
wbInternetExplorer.DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(
this.OnDocumentComplete);
}
}
public void GetSite (ref Guid guid, out object ppvSite)
{
ppvSite=
null;
if (iwb2InternetExplorer != null)
{
IntPtr ipSite = IntPtr.Zero;
IntPtr ipUnknown = Marshal.GetIUnknownForObject(iwb2InternetExplorer);
Marshal.QueryInterface(ipUnknown, ref guid, out ipSite);
Marshal.Release(ipUnknown);
Marshal.Release(ipUnknown);
if (!ipSite.Equals(IntPtr.Zero))
{
ppvSite = ipSite;
}
else
{
Release();
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
}
}
else
{
Release();
Marshal.ThrowExceptionForHR(E_FAIL);
}
}
private void OnDocumentComplete (object frame, ref object urlObj)
{
HTMLDocument hDoc = (HTMLDocument)iwb2InternetExplorer.Document;
hDoc.body.innerHTML = hDoc.body.innerHTML + "<hr><br>Page viewed at " + DateTime.Now;
}
protected void Release()
{
if (iwb2InternetExplorer != null)
{
Marshal.ReleaseComObject(iwb2InternetExplorer);
iwb2InternetExplorer = null;
}
}
}
}
“Send to a Friend” Menu extension for Internet Explorer
I recently was using the Full Source utility by ThunderMain, and I was curious to see if I could make my own context menu for Internet Explorer. A useful utility I thought of using was a "send to a friend" utility.
I created the following registry key
HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMenuExtSend to a friend
and set the default value to
c:windowswebsendToAFriend.html
Which contains the following
<script language="JavaScript">
window.open("http://www.pop3webmail.info/reply.aspx?url=" + external.menuArguments.document.URL);
</script>
From the page on www.pop3webmail.info, it automatically fills in a message saying "Please Visit: (whatever url)"
Javascript for copying a drop down list
I found this nifty piece of javascript handy for copying the contents of one drop down list into another
function copyDropDownList(source,destination)
{
for(i=0;i<source.options.length;i++)
{
optionText = source.options[i].text;
optionValue = source.options[i].value;
destination.add(new Option(optionText,optionValue));
}
}
Grumbles about web service endpoints in SQL 2005
I was interested in trying out the new feature in SQL 2005, whereby it can host web services directly within the database engine, rather than via IIS.
So following a few online guides I created a simple stored procedure
create procedure FindPub
@city varchar(100)
as
select * from pubs where city=@city
Then mapped this to an endpoint with the following code:
CREATE ENDPOINT SQLEP_FindPub
STATE = STARTED
AS HTTP
(
PATH = ‘/FinfPub’,
AUTHENTICATION = (BASIC),
PORTS = (CLEAR),
SITE = ‘listofpubs’
)
FOR SOAP
(
WEBMETHOD ‘FindPub’
(NAME=’dinfo.dbo.FindPub’),
BATCHES = DISABLED,
WSDL = DEFAULT,
DATABASE = ‘dinfo’,
NAMESPACE = ‘http://www.listofPubs.info/FindPub’
)
On running this code – I got an error saying the "CREATE ENDPOINT’ statment is not supported in this edition of SQL server. (note the typo in the error message! :)). Fair enough, it’s a free product. But what really struck me was that it forced me to enter an Authentication option. To me this is counter intuitive for a web service. – I have to add the caveat here that I’m no expert in SQL server webserices, so there may be a way around this.
Forcing the user to provide authentication seems logical, as in, the web service needs to run under some credentials so that it can authenticate itself against the database, but this should be coded into the webservice, not provided by the caller. After all, in order to supply Windows authentication (NTLM) over the internet, We’d need a VPN or similar. Then if we were to use Basic authentication, this is too insecure, it would need to be provided over SSL.
Therefore in order to supply a web service directly from SQL server to the general public over the Internet, you’d need (a) to get a SSL certificate and install it (b) create a new windows login, since, you don’t want mr Joe public logging in under Administrator rights (c) map the new windows login to a sql login, (d) Include the login details in a public place so people can find it easily. – This seems much more difficult then hammering out an equivalent stored procedure in Visual Studio, with hard-coded credentials.
To me, the ethos behind web services, was that they were designed to be publicly viewable and useable resources, not coveted entry points to fulll control of a company’s data.
Anyway, enough grumbling. I just realized this morning that my website www.openmerchantaccount.info just got a PR5 in google. Unfortunately it hasn’t yet re-positioned itself in google yet, I guess I have to wait for the next index shuffle. It’s got over 1,000 backlinks from my own personal ring of data-heavy websites, of which I just launched two more, www.listofhauliers.info and www.listofcardealers.info – I’m quite an expert at SEO !.
Reading an unknown database format (.BDB)
I was given the task of extracting data from an unknown database format – given the extension .BDB. From research on the Internet, I narrowed this down to two database formats, either Microsoft Works or Berkely database.
I tried importing into Works, but only got a cryptic "BTLDB2.0" as an output. I then downloaded Berkly Db from SleepyCat.com, to find, to my dissapointment no binary distribution, just a bulk of C++ code, which when I tried to compile in VS 2005 gave errors like failure during conversion to COFF: file invalid or corrupt , duplicate resource — type: type , name: name , language: language , flags: flags , size: size etc. Which I didn’t have the time or patience to fix. I tried also their Java version but that gave an error too.
I then read that MySQL supported Berkely databases, so I downloaded MySQL, and used the mySQLImport utility to insert it into a table, Unfortunately, you need to have the table created already, in order for mySQLImport to work, apparently it doesn’t import table schema. I created a generic table with just one column of type blob. The import succeded, but the data was as vague as if I opened it up in notepad.
I then decieded to write a C# app to read through the text, splitting on any english phrases (i.e. strings over 3 characters long with ASCII values in the range 32 to 127 and 13) thus:
int iRead = 0;
byte bRead = 0;
ArrayList alStringCollection = new ArrayList();
ArrayList alByteCollection = new ArrayList();
bool isReadingWord = true;
string strWord = "";
byte[] bWord;
int iWordCounter = 0;
frmUI.tbStatus.Text += "rnThread started";
FileStream fsIn = new FileStream(inFile,FileMode.Open);
FileStream fsOut = new FileStream(outFile,FileMode.Create);
StreamWriter swOut = new StreamWriter(fsOut);
while(true)
{
iRead = fsIn.ReadByte();
if (iRead==-1) break;
bRead = Convert.ToByte(iRead);
if (isAlphaNumeric(bRead))
{
isReadingWord = true;
alByteCollection.Add(bRead);
}
if (!isAlphaNumeric(bRead) && isReadingWord)
{
if (alByteCollection.Count>3)
{
bWord = (byte[])alByteCollection.ToArray(bRead.GetType());
strWord = Encoding.UTF8.GetString(bWord);
alStringCollection.Add(strWord);
iWordCounter ++;
swOut.WriteLine("[" + iWordCounter.ToString() + "] " + strWord);
}
alByteCollection = new ArrayList();
isReadingWord=false;
}
}
frmUI.tbStatus.Text += "rnRead " + alStringCollection.Count.ToString() + " words";
fsOut.Close();
I then opened the resultant file in notepad, and tried to figure out the schema from the debug into. And luckily with a little study I got it, for the specific database I was working on. Unfortunately, I can’t give an exact schema of BDB files here, since I don’t 100% understand them. But It serves as an interesting example of reading a non-standard database.
The result of my work should be soon visible on www.listofpubs.info