zoukankan      html  css  js  c++  java
  • 滑动验证码破解(一)

    第一步:把滑动验证码的Canvas输出图片并保存到本地

    利用canvas2image.js脚本

    前端用js封装,调用canvas2image.js脚本(github可以下到的)中的方法,缺点是只能保存到电脑c盘中的downloads文件夹中,如果要布置到服务器上,依然是下在自己的电脑上。如果不布置到服务器上,这个方法就很简单了。

    <script type="text/javascript">
        // 点击转成图片
        function savePic() {
            var oCanvas = document.getElementById("canvas");
            Canvas2Image.saveAsImage(oCanvas,420,420,"png","image1");        
        }
    </script>

    例:获取极验验证码的canvas标签生成的图片,爬虫实现滑动验证码

    在浏览器控制台操作

    首先加载canvas2image.js到控制台

    /**
     * covert canvas to image
     * and save the image file
     */
    
    var Canvas2Image = function () {
    
        // check if support sth.
        var $support = function () {
            var canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');
    
            return {
                canvas: !!ctx,
                imageData: !!ctx.getImageData,
                dataURL: !!canvas.toDataURL,
                btoa: !!window.btoa
            };
        }();
    
        var downloadMime = 'image/octet-stream';
    
        function scaleCanvas (canvas, width, height) {
            var w = canvas.width,
                h = canvas.height;
            if (width == undefined) {
                width = w;
            }
            if (height == undefined) {
                height = h;
            }
    
            var retCanvas = document.createElement('canvas');
            var retCtx = retCanvas.getContext('2d');
            retCanvas.width = width;
            retCanvas.height = height;
            retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
            return retCanvas;
        }
    
        function getDataURL (canvas, type, width, height) {
            canvas = scaleCanvas(canvas, width, height);
            return canvas.toDataURL(type);
        }
    
        function saveFile (strData) {
            document.location.href = strData;
        }
    
        function genImage(strData) {
            var img = document.createElement('img');
            img.src = strData;
            return img;
        }
        function fixType (type) {
            type = type.toLowerCase().replace(/jpg/i, 'jpeg');
            var r = type.match(/png|jpeg|bmp|gif/)[0];
            return 'image/' + r;
        }
        function encodeData (data) {
            if (!window.btoa) { throw 'btoa undefined' }
            var str = '';
            if (typeof data == 'string') {
                str = data;
            } else {
                for (var i = 0; i < data.length; i ++) {
                    str += String.fromCharCode(data[i]);
                }
            }
    
            return btoa(str);
        }
        function getImageData (canvas) {
            var w = canvas.width,
                h = canvas.height;
            return canvas.getContext('2d').getImageData(0, 0, w, h);
        }
        function makeURI (strData, type) {
            return 'data:' + type + ';base64,' + strData;
        }
    
    
        /**
         * create bitmap image
         * 按照规则生成图片响应头和响应体
         */
        var genBitmapImage = function (oData) {
    
            //
            // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
            // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
            //
    
            var biWidth  = oData.width;
            var biHeight    = oData.height;
            var biSizeImage = biWidth * biHeight * 3;
            var bfSize  = biSizeImage + 54; // total header size = 54 bytes
    
            //
            //  typedef struct tagBITMAPFILEHEADER {
            //      WORD bfType;
            //      DWORD bfSize;
            //      WORD bfReserved1;
            //      WORD bfReserved2;
            //      DWORD bfOffBits;
            //  } BITMAPFILEHEADER;
            //
            var BITMAPFILEHEADER = [
                // WORD bfType -- The file type signature; must be "BM"
                0x42, 0x4D,
                // DWORD bfSize -- The size, in bytes, of the bitmap file
                bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
                // WORD bfReserved1 -- Reserved; must be zero
                0, 0,
                // WORD bfReserved2 -- Reserved; must be zero
                0, 0,
                // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
                54, 0, 0, 0
            ];
    
            //
            //  typedef struct tagBITMAPINFOHEADER {
            //      DWORD biSize;
            //      LONG  biWidth;
            //      LONG  biHeight;
            //      WORD  biPlanes;
            //      WORD  biBitCount;
            //      DWORD biCompression;
            //      DWORD biSizeImage;
            //      LONG  biXPelsPerMeter;
            //      LONG  biYPelsPerMeter;
            //      DWORD biClrUsed;
            //      DWORD biClrImportant;
            //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
            //
            var BITMAPINFOHEADER = [
                // DWORD biSize -- The number of bytes required by the structure
                40, 0, 0, 0,
                // LONG biWidth -- The width of the bitmap, in pixels
                biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
                // LONG biHeight -- The height of the bitmap, in pixels
                biHeight & 0xff, biHeight >> 8  & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
                // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
                1, 0,
                // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
                // has a maximum of 2^24 colors (16777216, Truecolor)
                24, 0,
                // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
                0, 0, 0, 0,
                // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
                biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
                // LONG biXPelsPerMeter, unused
                0,0,0,0,
                // LONG biYPelsPerMeter, unused
                0,0,0,0,
                // DWORD biClrUsed, the number of color indexes of palette, unused
                0,0,0,0,
                // DWORD biClrImportant, unused
                0,0,0,0
            ];
    
            var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
    
            var aImgData = oData.data;
    
            var strPixelData = '';
            var biWidth4 = biWidth<<2;
            var y = biHeight;
            var fromCharCode = String.fromCharCode;
    
            do {
                var iOffsetY = biWidth4*(y-1);
                var strPixelRow = '';
                for (var x = 0; x < biWidth; x++) {
                    var iOffsetX = x<<2;
                    strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
                                   fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
                                   fromCharCode(aImgData[iOffsetY+iOffsetX]);
                }
    
                for (var c = 0; c < iPadding; c++) {
                    strPixelRow += String.fromCharCode(0);
                }
    
                strPixelData += strPixelRow;
            } while (--y);
    
            var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
    
            return strEncoded;
        };
    
        /**
         * saveAsImage
         * @param canvasElement
         * @param {String} image type
         * @param {Number} [optional] png width
         * @param {Number} [optional] png height
         */
        var saveAsImage = function (canvas, width, height, type) {
            if ($support.canvas && $support.dataURL) {
                if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
                if (type == undefined) { type = 'png'; }
                type = fixType(type);
                if (/bmp/.test(type)) {
                    var data = getImageData(scaleCanvas(canvas, width, height));
                    var strData = genBitmapImage(data);
                    saveFile(makeURI(strData, downloadMime));
                } else {
                    var strData = getDataURL(canvas, type, width, height);
                    saveFile(strData.replace(type, downloadMime));
                }
            }
        };
    
        var convertToImage = function (canvas, width, height, type) {
            if ($support.canvas && $support.dataURL) {
                if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
                if (type == undefined) { type = 'png'; }
                type = fixType(type);
    
                if (/bmp/.test(type)) {
                    var data = getImageData(scaleCanvas(canvas, width, height));
                    var strData = genBitmapImage(data);
                    return genImage(makeURI(strData, 'image/bmp'));
                } else {
                    var strData = getDataURL(canvas, type, width, height);
                    return genImage(strData);
                }
            }
        };
    
    
    
        return {
            saveAsImage: saveAsImage,
            saveAsPNG: function (canvas, width, height) {
                return saveAsImage(canvas, width, height, 'png');
            },
            saveAsJPEG: function (canvas, width, height) {
                return saveAsImage(canvas, width, height, 'jpeg');
            },
            saveAsGIF: function (canvas, width, height) {
                return saveAsImage(canvas, width, height, 'gif');
            },
            saveAsBMP: function (canvas, width, height) {
                return saveAsImage(canvas, width, height, 'bmp');
            },
    
            convertToImage: convertToImage,
            convertToPNG: function (canvas, width, height) {
                return convertToImage(canvas, width, height, 'png');
            },
            convertToJPEG: function (canvas, width, height) {
                return convertToImage(canvas, width, height, 'jpeg');
            },
            convertToGIF: function (canvas, width, height) {
                return convertToImage(canvas, width, height, 'gif');
            },
            convertToBMP: function (canvas, width, height) {
                return convertToImage(canvas, width, height, 'bmp');
            }
        };
    
    }();
    canvas2image.js

    然后获取极验的canvas标签对象(因为极验的canvas中没有id属性只有类属性,所以只能通过类属性获取对象,通过类获取的是集合所以需要取[0])

    var oCanvas1 = document.getElementsByClassName("geetest_canvas_bg geetest_absolute")[0];
    var oCanvas2 = document.getElementsByClassName("geetest_canvas_slice geetest_absolute")[0];
    var oCanvas3 = document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0];

     通过canvas2image.js中的saveAsImage方法下载

    Canvas2Image.saveAsImage(oCanvas1,260,160,"png");
    Canvas2Image.saveAsImage(oCanvas2,260,160,"png");
    Canvas2Image.saveAsImage(oCanvas3,260,160,"png");

     下载好的图片(如果下载好的图片没有后缀名,手动更改为.png)

     

     

     通过此原理,就可以使用爬虫对获取图片进行像素点比对,确定坐标,模拟用户操作,从而破解滑动验证

  • 相关阅读:
    AC日记——红色的幻想乡 洛谷 P3801
    AC日记——Power收集 洛谷 P3800
    AC日记——妖梦拼木棒 洛谷 P3799
    AC日记——妖梦斩木棒 洛谷 P3797
    AC日记——小魔女帕琪 洛谷 P3802
    AC日记——双栈排序 洛谷 P1155
    AC日记——明明的烦恼 bzoj 1005
    AC日记——[HNOI2014]世界树 bzoj 3572
    AC日记——魔法森林 洛谷 P2387
    AC日记——【模板】点分治(聪聪可可) 洛谷 P2634
  • 原文地址:https://www.cnblogs.com/JinMuBaoBao/p/10632110.html
Copyright © 2011-2022 走看看