SQL injection
Hokay. So I made a mistake and a SQL website was attacked by a SQL Injection doofer. The problem was in a logging function that took the URL and put it into the database (along with some time and other data). Anyway, Bloombit has a great article on how it happens. I found it in the IIS logs and verified what they said was true. So, I took their uglyness and used it to fix the SQL database:
DECLARE @T VARCHAR(255)
DECLARE @C VARCHAR(255)
DECLARE Table_Cursor CURSOR FOR
SELECT [A].[Name], [B].[Name]
FROM sysobjects AS [A], syscolumns AS [B]
WHERE [A].[ID] = [B].[ID] and
[A].[XType] = 'U' /* Table (User-Defined) */ AND
([B].[XType] = 99 /* NTEXT */ OR
[B].[XType] = 35 /* TEXT */ OR
[B].[XType] = 231 /* SYSNAME */ OR
[B].[XType] = 167 /* VARCHAR */)
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T,@C
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC ( 'UPDATE [' + @T + '] SET [' + @C + '] = replace(convert(VARCHAR(max), [' + @C + ']) ,
''<script src=http://www.bnrupdate.mobi/b.js></script>'','''') ' )
FETCH NEXT FROM Table_Cursor INTO @T, @C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
Some notes:
- varchar(max) is a SQL 2005 construct
- Change the srcipt src to match your infection
Updated!
I have seen this infect Cold Fusion now. I wrote this Cold Fusion code to protect the site (hopefully).
<cfset strUrl = (
IIF(
(CGI.https EQ "On"),
DE( "https://" ),
DE( "http://" )
) &
CGI.http_host &
CGI.script_name & "?" &
CGI.query_string
) />
<cfif len(strUrl) gt 500 >
<cfoutput>#cdcdcc#</cfoutput>
</cfif>
<cfif strUrl contains "EXEC" >
<cfoutput>cdcdcc#</cfoutput>
</cfif>
Cross-Browser View/Hide
I just gotta say that this pissed me off to no end. I had code that worked well with IE, Opera and Firefox but Safari just wouldn't work. Most of my work is for Intranets so I could code to IE but once I had to do some public stuff the "squeeze hit the fan" - so to speak.
It turns out that the only way I could get it to work is with a style called hidden. It has one entry: display:none.
I had to change the className of the object to hidden and then change it back later on. I also created an entry called shown that also had one entry: display:block that I could use to show an element.
Now, in order to change it back I needed to know what it's className was. So here is how I solved for "X"....
I created 2 javascript arrays and a counter to keep track of how many I added:
var aclasslist = new Array();
var aidlist = new Array();
var acount=0;
I also created a function called cbtoggle() that accepts on parameter - the objectid. It looks for the element in the arrays
and if it does not find it it adds it and it's className to the arrays. If the className is either hidden or blank it adds the value shown.
This also uses a function called findObj a buddy sent me. It seems to return stuff better that getElementById
Now if you are like me you quit reading and just want the damned code. Here it is:
<style>
.hidden { display:none }
.shown { display:block }
</style>
<a href="javascript:cbtoggle('someelementid')">view/hide element</a>
<div id='someelementid'>some html text and stuff </div>
<script language=javascript>
function findObj(theObj, theDoc) {
var p, i, foundObj;
if(!theDoc) theDoc = document;
if( (p = theObj.indexOf("?")) > 0 && parent.frames.length) {
theDoc = parent.frames[theObj.substring(p+1)].document;
theObj = theObj.substring(0,p);
}
if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all [theObj];
for (i=0; !foundObj && i < theDoc.forms.length; i++)
foundObj = theDoc.forms[i][theObj];
for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
foundObj = findObj(theObj,theDoc.layers[i].document);
if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);
if( ! foundObj ) return false;
return foundObj;
}
var aclasslist = new Array();
var aidlist = new Array();
var acount=0;
function cbtoggle( oid )
{
if( ! findObj(oid ) ) return;
var o = findObj(oid);
if( acount==0 )
{
cbaddid( oid );
}
else
{
if( cbindex(oid)==-1 )
{
cbaddid(oid);
}
}
if( o.className=='hidden' )
{
o.className=cbgetclass( oid );
}
else
o.className='hidden';
}
function cbaddid( oid )
{
aidlist[acount]=oid;
if( findObj(oid).className != '' && findObj(oid).className !='hidden' )
aclasslist[acount]=findObj(oid).className;
else
aclasslist[acount]='shown';
acount++;
}
function cbindex( oid )
{
for( i=0; i < acount; i++ )
{
if( aidlist[i]==oid )
return i;
}
return -1;
}
function cbgetclass( oid )
{
var i=cbindex(oid )
if( i > -1 )
{
return aclasslist[i];
}
return '';
}
</script>
Print Stuff
Recently I had a web page that had a menu with all the trimmings plus a report in a table. The client wanted to print the table.
The last thing I wanted to do was re-generate the table or duplicate my code in another page. So this is what I did:
- Created a popup with a function called getdata() that gets the report from the page that opened it.
- Created a function called doprint() that opens a new window.
- Created a function called senddata() that provides the object to be printed (it is called by getdata()
The code in page 1:
<div id=holder >
This is a report. It could be a table. It could be an image. It could be whatever
</div >
< input type=button value="Print" onclick="doprint()" >
<script>
var oid;
function senddata()
{
return findObj(oid).innerHTML;
}
function doprint()
{
oid="printstuff";
window.open("/popups/print.php");
}
function findObj(theObj, theDoc) {
var p, i, foundObj;
if(!theDoc) theDoc = document;
if( (p = theObj.indexOf("?")) > 0 && parent.frames.length) {
theDoc = parent.frames[theObj.substring(p+1)].document;
theObj = theObj.substring(0,p);
}
if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all [theObj];
for (i=0; !foundObj && i < theDoc.forms.length; i++)
foundObj = theDoc.forms[i][theObj];
for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
foundObj = findObj(theObj,theDoc.layers[i].document);
if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);
if( ! foundObj ) return false;
return foundObj;
}
<script>
Then we have the popup which is very simple:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Print Report</title>
<link rel="stylesheet" type="text/css" href="/include/style.css" media="screen"/>
</head>
<body onload=getdata() id=bdy>
</body>
</html>
<Script>
function getdata()
{
findObj("bdy").innerHTML=window.opener.senddata()
print();
}
function findObj(theObj, theDoc) {
var p, i, foundObj;
if(!theDoc) theDoc = document;
if( (p = theObj.indexOf("?")) > 0 && parent.frames.length) {
theDoc = parent.frames[theObj.substring(p+1)].document;
theObj = theObj.substring(0,p);
}
if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all
[theObj];
for (i=0; !foundObj && i < theDoc.forms.length; i++)
foundObj = theDoc.forms[i][theObj];
for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
foundObj = findObj(theObj,theDoc.layers[i].document);
if(!foundObj && document.getElementById) foundObj =
document.getElementById(theObj);
return foundObj;
}
</Script>
See it in action here:
|