Cenzic 232 Patent
Paid Advertising
sla.ckers.org is
ha.ckers sla.cking
Sla.ckers.org
Whether this is about ha.ckers.org, sla.ckers.org or some other project you are interested in or want to talk about, throw it in here to get feedback. 
Go to Topic: PreviousNext
Go to: Forum ListMessage ListNew TopicSearchLog In
Pages: Previous123
Current Page: 3 of 3
Re: Greasemonkey XSS assistant
Posted by: Anonymous User
Date: June 19, 2007 03:03PM

the xml below line 359 is new

http://mario.heideri.ch/xss.xml

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: WhiteAcid
Date: June 19, 2007 04:44PM

aah, good stuff. I couldn't see those things due to cache issues. Now I see you also have HTML tags in the name element. I'm not sure if I should render those in the script. I don't see how a user could be exploited without manually adding the evil .xml file to the list, but what if your domain was hacked and someone else edited the xml file. Then suddenly a lot of users of this script will be vulnerable.

Now, how to filter this? If I use JS's escape() the it uglifies the whole thing by changing spaces to %20 etc. If I filter < and > then it could work, but as the charset depends on the parent page (I imagine) it's possible that variablel width encoding would be possible. Or should I just leave the HTML enabled and write a note on the site to tell people to download a copy of the XML file locally and use that to prevent any tampering.

I really should have an announcement mailing list for this script.

Don't forget our IRC: irc://irc.irchighway.net/#slackers
-WhiteAcid - your friendly, very lazy, web developer

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: Anonymous User
Date: June 20, 2007 02:41AM

Jep - if you want em out just drop me a line. What about bringing the project to google code/ creating a google group? I think it would be way easier to maintain those issues that way.

Greetings,
.mario

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: WhiteAcid
Date: June 20, 2007 05:47AM

That's a good idea.
http://groups.google.com/group/xss-assistant/
RSS feed: http://groups.google.com/group/xss-assistant/feed/rss_v2_0_msgs.xml

Don't forget our IRC: irc://irc.irchighway.net/#slackers
-WhiteAcid - your friendly, very lazy, web developer

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: mstampar
Date: February 09, 2008 04:59AM

// ==UserScript==
// @name XSS assistant
// @description This will help people find Cross site scripting flaws in forms as well and ease making a PoC from the XSS which is easy to show people.
// @include *
// ==/UserScript==

/*
How to use:
Install this script into greasemonkey. To start XSSing forms select tools > Greasemonkey > User script commands > Start XSSing forms.
From now on all forms on all pages will have an image by them, clicking that image will bring up a menu with plenty of options to help
you speedily find flaws in the form.
To stop XSSing forms (which means the image won't appear anymore) select tools > Greasemonkey > User script commands > Stop XSSing forms.

Don't forget you can change some variables just below this block of comments
*/

//USER SETINGS START
//list of xml files to read to get the XSS vectors from
//vectorsURL = new Array("http://ha.ckers.org/xssAttacks.xml","http://127.0.0.1/xss.xml")
vectorsURL = new Array("http://ha.ckers.org/xssAttacks.xml")
//The url of the page which can showcase XSSes using POST. default = "http://www.whiteacid.org/misc/xss_post_forwarder.php"
setting_PoC_POST = "http://www.whiteacid.org/misc/xss_post_forwarder.php"
//USER SETTINGS END

glb_xss = new Array()
glb_forms = new Array()

//Load the remote XML files with all the XSSes in them
function getRemoteXMLFiles()
{
for (i=0; i<vectorsURL.length; i++)
{
GM_xmlhttpRequest
(
{
method:"GET",
url:vectorsURL,
headers:
{
"User-Agent":"XSS assistant",
"Accept":"text/xml",
},
onload:function(details)
{
add2glb_xss(this.url,parseXML(details.responseText))

//As a one time thing we need to set the default list of values in the second select box
//We can only do this after the first AJAX request has been returned, so this is where we do it
if (glb_xss.length == 1)
{
changeVectors(this.url)
}
}
}
)
}
}

//Given the remote XML files, store that data
function add2glb_xss(url,xml)
{
glb_xss.push(new Array(url,xml.name,xml.vector))
}

//Find all forms on the page and add the relevant image button by them
function findForms()
{
xss_images = new Array() //array of all images
frms = document.forms //array of all forms
for (i=0; i<frms.length; i++) //for each form
{
xss_images.push(createButton(i)) //create a new image
frms.insertBefore(xss_images[xss_images.length-1],document.forms.firstChild) //insert image as first thing inside form
glb_forms.push(new Array(i,frms.innerHTML))
}
}

//creates the button which when clicked brings up the menu
function createButton(n)
{
x = document.createElement('img')
x.src = "data:image/gif,GIF89aP%00%0F%00%91%00%00%00%00%00%FFf%00%FF%FF%FF%00%00%00!%F9%04%00%00%00%00%00%2C%00%00%00%00P%00%0F%00%40%02%86%84%8F%A9%CB%ED%0F%8F%084%CCY%B3%D5%14%5B%01%86!%20%0A%A4)%92%E7%C8%96%AE%E1q%F2%9C%B9%F6%8D%E78L%F7%B4%0E%0C%06y%BEbM%88L%8EH%B5%8D%26V%81~n%2B%D0%A9zM%A9%AAT%A6%F1%AB%0C%0B%23%E4%B2%F9%BC%10%AB%D7a%E2%B7%C8%8Ek%3DtN%E8%09%8A%EE%60%CB%92%24%D5%92%E3%D61%93%87w%D4%B5%92%B5%C4%A5%82%A2%E3V%87%88%17%23%F8%D2h%05%98%09%E9%F5%E6%23%07%CA%07%3A%1AZ%00%00%3B"
x.alt = n //Just for holding the form number
x.setAttribute("onclick","openMenu(this)")
x.setAttribute("style","display: block; z-index: 9")
return x
}

//Opens the menu and places it at the button which called this function
function openMenu(getter)
{
father = document.getElementById('menu_father')
coords = findPos(getter)

father.style.top = coords.top+"px"
father.style.display = 'block'
//If the box is off the bottom or off too far to the right, bring it home (this can only be done after we've set father.style.display = "block"
while (coords.left+getter.offsetWidth+5+father.offsetWidth > screen.width)
{
coords.left--
}
father.style.left = coords.left+getter.offsetWidth+5+"px"
//And now for height - broken (hence commented out)
/*
while (coords.top+father.offsetHeight > (screen.height)+coords.top)
{
coords.top--
}
father.style.top = coords.top+getter.offsetHeight+"px"
*/

//Enter the form info in the menu's heading
heading = document.getElementById('menu_heading')

heading.innerHTML = "Form "+getter.alt
try
{
heading.innerHTML += " ["+getter.parentNode.name+"]"
} catch (err) {}

//shove the correct options into the menu_target_select select box
targets = document.getElementById('menu_target_select')
//remove existing elements
while (targets.childNodes.length != 0)
targets.removeChild(targets.childNodes[0])

children = getChildren(document.forms[getFormNumber()])

//Add the global option
tmp = document.createElement('option')
tmp.value = ""
tmp.innerHTML = "#GLOBAL#"
targets.appendChild(tmp)

//Loop through named elements and add them
for (i=0; i<children.length; i++)
{
try
{
if (children.hasAttribute('name'))
{
tmp = document.createElement('option')
tmp.value = children.name
tmp.innerHTML = children.name
targets.appendChild(tmp)
}
}
catch(err) {}
}
}

//Function to create the menu
function createMenu()
{
//Create top level of menu
father = document.createElement('div')
father.id = "menu_father"
father.setAttribute("style","display: none; position: absolute; z-index: 10; top: 0px; left: 0px; style;")

//the title bar (empty but allows the box to be dragged)
title = document.createElement('div')
title.setAttribute("onmousedown","dragStart(event,'menu_father')")
title.appendChild(document.createElement('br'))
title.setAttribute("style", "cursor: move; border: none;")
father.appendChild(title)

//The heading with the info of the form that currently being looked at
heading = document.createElement('div')
heading.id = "menu_heading"
father.appendChild(heading)

//Create the options
//Show info will show all the info about the form including the forms target and method as well as the name attribute of every element
showInfo = document.createElement('div')
showInfo.innerHTML = "Show form information"
showInfo.setAttribute("onclick","showInfo()")
father.appendChild(showInfo)

//A couple of select boxes allowing the user to apply certain XSS vectors.
vectors_div = createVectors()
father.appendChild(vectors_div)

//The create PoC function will supply the user with a ready-to-copy-n-paste link to showcase their XSS.
PoC = document.createElement('div')
PoC.innerHTML = "Generate PoC link"
PoC.setAttribute("onclick","createPoC()")
father.appendChild(PoC)

//The reset function sets the form back to how it was when the page loaded.
reset = document.createElement('div')
reset.innerHTML = "Reset form"
reset.setAttribute("onclick","resetForm()")
father.appendChild(reset)

//Create a submit form button
submit = document.createElement('div')
submit.innerHTML = "Submit form"
submit.setAttribute("onclick","submitForm()")
father.appendChild(submit)

//The close button, closes the menu
close_button = document.createElement('input')
close_button.type = "button"
close_button.value = " [ close ] "
close_button.setAttribute("onclick","hideMe(document.getElementById('menu_father'))")
father.appendChild(close_button)

//And shove the whole box onto the document.
document.body.appendChild(father) //hehe, semantics went out the window there
}

//Function which creates the bar which lets you XSS the querystrings
function createGETBar(GET)
{

bar = document.createElement('div')
bar.className = "GETBar"
//An error may have occured when reading the querystring
if (GET == 'ERROR')
{
bar.innerHTML = "Error, cannot read the querystring variables and corresponding values"
document.body.appendChild(bar)
return
}

//An easy way to let people XSS these variables is by creating a hidden form and then just letting the rest of the script treat it as such
form = document.createElement('form')
form.method = "get"
form.action = location.href.substring(0,location.href.indexOf("?"))
form.id = "xss_querystring"

//Start looping through each GETed variable and add that to this form
for (i=0; i<GET.list_name.length; i++)
{
tmp = document.createElement('input')
tmp.type = 'hidden'
tmp.setAttribute('name',GET.list_name)
tmp.setAttribute('value',GET.list_value)
form.appendChild(tmp)
}

bar.appendChild(form)

document.body.appendChild(bar)
}

//Given the returned code from a remote location, turn it into usable XML
function parseXML(html)
{
names = new Array()
vectors = new Array()
parser = new DOMParser()
var dom = parser.parseFromString(html,"application/xml")
var entries = dom.getElementsByTagName('attack')
for (var i = 0; i < entries.length; i++)
{
names.push(entries.getElementsByTagName('name')[0].textContent)
vectors.push(entries.getElementsByTagName('code')[0].textContent)
}
return {name:names,vector:vectors}
}

//Show the info about a form
showInfoDone = new Array()
function showInfo()
{
x = getFormNumber()
//Check if already done
for (i=0; i<showInfoDone.length; i++)
{
if (showInfoDone == x)
{
alert("Already shown information on this form.\nIf you want to run it again reset the status and run this again.")
return false;
}
}
showInfoDone.push(x)

f = document.forms[x]
//Add the forms info
x = document.createElement('span')
x.setAttribute("class","form_info")
x.innerHTML = "name: "+f.name+"<br />target: "+f.target+"<br />"
f.insertBefore(x,f.childNodes[1])

//Go through all nodes with a name attribute and add info about them
children = getChildren(f)
for (i=0; i<children.length; i++)
{
try
{
if (children.hasAttribute('name'))
{
x = document.createElement('span')
x.setAttribute("class","form_info")
x.innerHTML = children.name
children.parentNode.insertBefore(x,children)
}
//Show any hidden elements
if (children.type == "hidden")
children.type = "text"
}
catch(err) {}
}
}

//Create the select boxes and return their objects.
function createVectors()
{
holder = document.createElement('div')

url_list = document.createElement('select')
url_list.setAttribute('onchange','changeVectors(this.value)')

vector_list = document.createElement('select')
vector_list.id = "menu_vector_select"

target_list = document.createElement('select')
target_list.id = "menu_target_select"

apply_button = document.createElement('input')
apply_button.type = "button"
apply_button.value = "apply"
apply_button.setAttribute('onclick','applyVectors(document.getElementById("menu_target_select").value,document.getElementById("menu_vector_select").value)')


for (i=0; i<vectorsURL.length; i++)
{
x = document.createElement('option')
x.value = vectorsURL
x.innerHTML = getDomain(vectorsURL)
url_list.appendChild(x)
}

x = document.createElement('option')
x.innerHTML = "Select a vector"
x.value = ""
vector_list.appendChild(x)
holder.appendChild(url_list)
holder.appendChild(vector_list)
holder.appendChild(document.createElement("br"))
holder.appendChild(target_list)
holder.appendChild(apply_button)
return holder
}

//Function will change which vectors are visible in the second select box, shows the vectors from the source supplied as parameter.
function changeVectors(val)
{
for (i=0; i<glb_xss.length; i++)
{
if (glb_xss[0] == val)
{
o = document.getElementById('menu_vector_select')
o.innerHTML = "" //clear any old data
x = document.createElement('option')
x.innerHTML = "Select a vector"
x.value = ""
o.appendChild(x)
for (j=0; j<glb_xss[1].length; j++)
{
x = document.createElement('option')
x.value = glb_xss[2][j]
x.innerHTML = glb_xss[1][j]
o.appendChild(x)
}
}
}
}

//Apply a certain vector to all elements in form which have a name attribute
function applyVectors(target,vector)
{
f = document.forms[getFormNumber()]

children = getChildren(f)

//If we are to apply globally
if (target == "")
{
for (i=0; i<children.length; i++)
{
try
{
if (children.hasAttribute('name'))
{
if (children.hasAttribute('maxlength'))
children.removeAttribute('maxlength')
children.value = vector
}
//Show any hidden elements
if (children.type == "hidden")
children.type = "text"
}
catch(err) {}
}
}
else //If we are to apply only to one element
{
for (i=0; i<children.length; i++)
{
if (children.name == target)
{
children.removeAttribute('maxlength')
children.value = vector
}
}
}
}

//Create a prompt box which allows users to easily copy paste PoC links
function createPoC()
{
f = document.forms[getFormNumber()]
method = f.method.toLowerCase()
target = f.target
if (target == "")
target = location.href
if (method != "post") //incase they are odd, or didn't supply one then default to get
method = "get"
if (method == "get")
{
//Scrap any existing querystring variables in the target
if (target.indexOf("?") > -1)
{
target = target.substring(0,target.indexOf("?"))
}

target += "?"
children = getChildren(f)
target = addToTarget(target,children)
//Chop off the last &
target = target.substr(0,target.length-1)

prompt("Copy the below url",target)
}
else
{
//Esacpe any existing querystring variables in the target
if (target.indexOf("?") > -1)
{
target = target.substring(0,target.indexOf("?")) + escape(target.substring(target.indexOf("?"),target.length))
}
target = setting_PoC_POST+"?xss_target="+target+"&"
children = getChildren(f)
target = addToTarget(target,children)
//Chop off the last &
target = target.substr(0,target.length-1)

prompt("Copy the below url",target)
}

}

//Reset form to how it was when the page loaded
function resetForm()
{
x = getFormNumber()
f = document.forms[x]
f.innerHTML = glb_forms[x][1]

//Find and remove from the showInfoDone array
for (i=0; i<showInfoDone.length; i++)
if (showInfoDone == x)
{
showInfoDone.splice(i,1)
return true //End function so we don't do unnecessary work
}
}

//Submit the form, useful if the submit button isn't there, for whatever reason
function submitForm()
{
//Why am I using a variable at all? cos rdivilbiss said:
/*
I had a similar problem with form fields once were document.forms[0].field returned the correct reference but document.forms[0].field.focus() returned not a function.
I was able to work around that with;
tmp = document.forms[0].field;
tmp.focus();
I still to this day don't know why I had to do that but it worked.
*/
tmp = document.forms[getFormNumber()]
tmp.submit()
}

//Using the "Form 1 [form_name]" field, we'll get the forms number
function getFormNumber()
{
x = document.getElementById('menu_heading').innerHTML
x = parseInt(x.substring(4,x.length))
return x
}

//Given a url, get that urls domain
function getDomain(url)
{
url = url.substring(7,url.length)
url = url.substr(0,(url.search("/") > -1)? url.search("/"):url.length)
return url
}

//Recusively find all children of one node minus the text nodes
function getChildren(obj)
{
var children = new Array()
for (var i=0; i<obj.childNodes.length; i++)
{
if (obj.childNodes.type != 3) //type 3 is a text node
{
children.push(obj.childNodes)
if (obj.childNodes.hasChildNodes())
{
x = getChildren(obj.childNodes)
for (j=0; j<x.length; j++)
children.push(x[j])
}
}
}
return children
}

//Hide an object
function hideMe(obj)
{
obj.style.display = "none"
}

function addToTarget(target,children)
{
for (i=0; i<children.length; i++)
{
try
{
if (children.hasAttribute('name'))
{
target += children.name+"="+children.value+"&"
}
}
catch(err) {}
}
return target
}

//Function to find the X and Y co-ordinates of where the menu should go. Returns both within a struct, of sorts
function findPos(obj)
{
var curtop = 0;
var curleft = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curtop += obj.offsetTop
curleft += obj.offsetLeft
obj = obj.offsetParent
}
}
return {left:curleft,top:curtop}
}

//A crap load of functions for dragging from http://www.brainjar.com/dhtml/drag/demo.html
//Removed browser checking

//*****************************************************************************
// Do not remove this notice.
//
// Copyright 2001 by Mike Hall.
// See http://www.brainjar.com for terms of use.
//*****************************************************************************

// Determine browser and version.

function Browser() {

var ua, s, i;

this.isNS = false;
this.version = null;

ua = navigator.userAgent;


// Treat any other "Gecko" browser as NS 6.1.
s = "Gecko";
if ((i = ua.indexOf(s)) >= 0) {
this.isNS = true;
this.version = 6.1;
return;
}
}

var browser = new Browser();

// Global object to hold drag information.

var dragObj = new Object();
dragObj.zIndex = 0;

function dragStart(event, id) {

var el;
var x, y;

// If an element id was given, find it. Otherwise use the element being
// clicked on.

if (id)
dragObj.elNode = document.getElementById(id);
else {
dragObj.elNode = event.target;

// If this is a text node, use its parent element.

if (dragObj.elNode.nodeType == 3)
dragObj.elNode = dragObj.elNode.parentNode;
}

// Get cursor position with respect to the page.

x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;

// Save starting positions of cursor and element.

dragObj.cursorStartX = x;
dragObj.cursorStartY = y;
dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);

if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;

// Update element's z-index.

dragObj.elNode.style.zIndex = ++dragObj.zIndex;

// Capture mousemove and mouseup events on the page.

document.addEventListener("mousemove", dragGo, true);
document.addEventListener("mouseup", dragStop, true);
event.preventDefault();
}

function dragGo(event) {

var x, y;

// Get cursor position with respect to the page.

x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;

// Move drag element by the same amount the cursor has moved.

dragObj.elNode.style.left = (dragObj.elStartLeft + x - dragObj.cursorStartX) + "px";
dragObj.elNode.style.top = (dragObj.elStartTop + y - dragObj.cursorStartY) + "px";

event.preventDefault();
}

function dragStop(event) {

// Stop capturing mousemove and mouseup events.

document.removeEventListener("mousemove", dragGo, true);
document.removeEventListener("mouseup", dragStop, true);
}
///////////////////////////////ENDETH THE DRAGGING FNUCTIONS


//Function to read the querystring
function v_GET_init()
{
v_GET = new Object()
v_GET.list_name = new Array()
v_GET.list_value = new Array()

v_GET.raw = location.href.substring(location.href.indexOf('?')+1,location.href.length)
getted_var = v_GET.raw.split("&")
for (i=0; i<getted_var.length; i++)
{
getted_var_name = getted_var.substring(0,getted_var.search('='))
getted_var_value = getted_var.substring(getted_var.search('=')+1,getted_var.length)
v_GET.list_name.push(getted_var_name)
v_GET.list_value.push(getted_var_value)
}
return v_GET
}

//If this is the main page (not an iframe), add the buttons to the toolbar allowing user to start/stop
if (location.href == top.location)
{
GM_registerMenuCommand("Start XSSing forms", start)
GM_registerMenuCommand("Stop XSSing forms", stop)
}

//Create functions those buttons call
function start() { GM_setValue("live", true) }
function stop() { GM_setValue("live", false) }

//Add some CSS
GM_addStyle('#menu_father {background-color:#BCD2EE; padding: 2px;}')
GM_addStyle('#menu_father div {display:block; border: solid #000; border-width: 1px; cursor: pointer;}')
GM_addStyle('.form_info {color:red; background-color:#ffe4c4; font-size:small; font-family:Courier New, arial;}')
GM_addStyle('.GETBar {color:black; background-color:#ffff00; text-align:center; position: absolute; top: 0px; left: 40%; width: 20%; padding: 3px; cursor: pointer; font-size:small; font-family:Courier New, arial;}')
GM_addStyle('.GETBar * {display: inline !important;}')

//Write some function onto the page
unsafeWindow.eval(openMenu.toString())
unsafeWindow.eval(findPos.toString())
unsafeWindow.eval(hideMe.toString())
unsafeWindow.eval(showInfo.toString())
unsafeWindow.eval(resetForm.toString())
unsafeWindow.eval(submitForm.toString())
unsafeWindow.eval(changeVectors.toString())
unsafeWindow.eval(applyVectors.toString())
unsafeWindow.eval(createPoC.toString())
unsafeWindow.eval(addToTarget.toString())
//And the dragging functions
unsafeWindow.eval(Browser.toString())
unsafeWindow.eval(dragStart.toString())
unsafeWindow.eval(dragGo.toString())
unsafeWindow.eval(dragStop.toString())

//Start the whole thing off, if we're live
if (GM_getValue('live', false) == true)
{
getRemoteXMLFiles()

//If there is a querystring, add the bar
if (location.href.indexOf("?") > 0)
{
try
{
x = v_GET_init()
}
catch (err) {x = 'ERROR'}
createGETBar(x)
}
findForms()
createMenu()
}

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: mstampar
Date: February 09, 2008 05:02AM

that last message was with purpose of preserving the script - i just can't find it anywhere on net (http://www.whiteacid.org/greasemonkey/ is inaccessible).

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: Anonymous User
Date: February 09, 2008 05:07AM

You can find it here:
http://groups.google.com/group/xss-assistant/browse_thread/thread/369dd328249d77ba

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: macguffin
Date: July 30, 2008 06:55AM

Does it work in Firefox 3?

I have some problems with it, the image (xss) does not appear.

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: Anonymous User
Date: July 30, 2008 05:00PM

Nup

But love the porn spam.

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: straylight
Date: July 31, 2008 08:43AM

Great tool, keeps me from memorizing all those vectors! :) Any plans to update for FF3? Any idea what happened in FF3 that broke the script?

-straylight

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: Anonymous User
Date: August 03, 2008 10:08AM

There are some issues with the GM eval() method. I recently talked to someone who said he wanted to try to fix it. If done I will post here with credits.

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: asilvermtzion
Date: August 14, 2008 02:15PM

This is made of win and awesome. Do want ff3 version

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: ted
Date: July 17, 2009 10:25PM

I want the firefox 3.5 version

_______________________________________________________________
Nature is wonderful!
One million years ago, she didn't know our going to need glasses.
But look where she put our ears!

Options: ReplyQuote
Re: Greasemonkey XSS assistant
Posted by: xyberpix
Date: July 19, 2009 05:12PM

What's it going to take to make this script FF3 compatable, as I'm willing to try and sort it out, but I'm not too sure where to even start?

Options: ReplyQuote
Pages: Previous123
Current Page: 3 of 3


Sorry, only registered users may post in this forum.