sqlmap二次开发指南

sqlmap基于python编写,开源,源码 https://github.com/sqlmapproj...
一、sqlmap api 1、应用场景
由于SQLMAP每检测一个站点都需要开启一个新的命令行窗口或者结束掉上一个检测任务。虽然 -m 参数可以批量扫描URL,但是模式也是一个结束扫描后才开始另一个扫描任务。通过api接口,下发扫描任务就简单了,无需开启一个新的命令行窗口。
2、使用

Options: -h, --helpshow this help message and exit -s, --serverRun as a REST-JSON API server -c, --clientRun as a REST-JSON API client -H HOST, --host=HOSTHost of the REST-JSON API server (default "127.0.0.1") -p PORT, --port=PORTPort of the the REST-JSON API server (default 8775) --adapter=ADAPTERServer (bottle) adapter to use (default "wsgiref") --username=USERNAMEBasic authentication username (optional) --password=PASSWORDBasic authentication password (optional)

  • 1、开启sqlmapapi server
    python3 sqlmapapi.py -s
  • 2、开启sqlmapapi client
    python3 sqlmapapi.py -c#执行后进入api交互界面,在交互界面执行相关任务

    api> help helpShow this help message new ARGSStart a new scan task with provided arguments (e.g. 'new -u "http://testphp.vulnweb.com/artists.php?artist=1"') use TASKIDSwitch current context to different task (e.g. 'use c04d8c5c7582efb4') dataRetrieve and show data for current task logRetrieve and show log for current task statusRetrieve and show status for current task option OPTIONRetrieve and show option for current task optionsRetrieve and show all options for current task stopStop current task killKill current task listDisplay all tasks versionFetch server version flushFlush tasks (delete all tasks) exitExit this client

  • 3、开启sqlmapapi server后同样可以通过接口方式进行任务的相关操作
任务管理功能
创建一个新任务 GET http://127.0.0.1:8775/task/new删除任务 GET http://127.0.0.1:8775/task//delete

管理功能
获取任务列表 GET http://127.0.0.1:8775/admin/list or GET http://127.0.0.1:8775/admin//list刷新任务后台(删除所有任务) GET http://127.0.0.1:8775/admin/flush or GET http://127.0.0.1:8775/admin//flush

核心交互功能
列出特定任务ID的选项 GET http://127.0.0.1:8775/option//list获取特定任务ID的选项值 POST http://127.0.0.1:8775/option//get value: [option1, option2, ...]设置特定任务ID的选项值 POST http://127.0.0.1:8775/option//set value: {option1: value1, option2: value2, ...}启动某个任务 POST http://127.0.0.1:8775/scan//start value: {option1: value1, option2: value2, ...}停止扫描 GET http://127.0.0.1:8775/scan//stop杀死扫描 GET http://127.0.0.1:8775/scan//kill获取扫描状态 GET http://127.0.0.1:8775/scan//status获取扫描数据 GET http://127.0.0.1:8775/scan//data获取特定的日志信息 GET http://127.0.0.1:8775/scan//log//获取日志信息 GET http://127.0.0.1:8775/scan//log从文件系统下载某个文件 GET http://127.0.0.1:8775/download///获取服务器版本 GET http://127.0.0.1:8775/version

二、sqlmap tamper
1、0eunion 作用:将UNION替换为e0UNION 效果:1 UNION ALL SELECT 1e0UNION ALL SELECT 数据库:MySQL MsSQL 2、charunicodeescape 作用:字符串 unicode 编码 效果:将未编码的字符进行unicode编码 SELECT FIELD FROM TABLE \\\\u0053\\\\u0045\\\\u004C\\\\u0045\\\\u0043\\\\u0054\\\\u0020\\\\u0046\\\\u0049\\\\u0045\\\\u004C\\\\u0044\\\\u0020\\\\u0046\\\\u0052\\\\u004F\\\\u004D\\\\u0020\\\\u0054\\\\u0041\\\\u0042\\\\u004C\\\\u0045 数据库:ASP ASP.NET 3、hex2char 作用:替换0x打头的字符串为CONCAT(CHAR(),...) 形式 效果:SELECT 0xdeadbeef SELECT CONCAT(CHAR(222),CHAR(173),CHAR(190),CHAR(239)) 数据库:MySQL 4, 5.0 and 5.5 4、modsecurityzeroversioned 作用:使用内联注释方式(/*!00000*/)进行注入 效果:1 AND 2>1-- 1 /*!00000AND 2>1*/-- 数据库:MySQL 5.0 5、space2dash 作用:将空格字符(“”)替换为短划线注释(“--”),后跟随机字符串和新行(“\\n”) 效果: '1 AND 9227=9227' '1--nVNaVoPYeva%0AAND--ngNvzqu%0A9227=9227' 数据库:MSSQL SQLite 6、substring2leftright 作用:将SUBSTRING 替换为 LEFT 或 RIGHT 效果:SUBSTRING((SELECT usename FROM pg_user)::text FROM 1 FOR 1) LEFT((SELECT usename FROM pg_user)::text,1) 数据库:PostgreSQL 9.6.12 7、apostrophemask 作用:用utf8代替引号 效果:1 AND '1'='1 1 AND %EF%BC%871%EF%BC%87=%EF%BC%871 数据库:无 8、commalesslimit 作用:替换 limt m,n 为limit n offset m LIMIT 3 OFFSET 2 数据库:MySQL 5.0 and 5.5 9、htmlencode 作用:对所有非数字字母的字符进行HTML编码 效果:1' AND SLEEP(5)# 1' AND SLEEP( 5) # 数据库:ALL 10、multiplespaces 作用:围绕sql关键字添加多个空格 效果:1 UNION SELECT foobar 1UNIONSELECTfoobar 数据库: ALL 11、space2hash 作用:将‘ ’替换为随机字符串和‘\n' 效果:1 AND 9227=9227 1%23upgPydUzKpMX%0AAND%23RcDKhIr%0A9227=9227 数据库:MySQL 4.0, 5.0 12、symboliclogical 作用:将 AND 或 OR 替换为 && 或 || 效果:1 AND '1'='1 1 %26%26 '1'='1 数据库:ALL 13、apostrophenullencode 作用:用非法双字节Unicode字符替换单引号 效果:1 AND '1'='1 1 AND %00%271%00%27=%00%271 数据库:ALL 14、commalessmid 作用:替换 MID(A,B,C)为MID(A FROM B FOR C) 效果:MID(VERSION(), 1, 1) MID(VERSION() FROM 1 FOR 1) 数据库:MySQL 5.0 and 5.5 15、ifnull2casewhenisnull 作用:将'IFNULL(A, B)' 替换为 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END' 效果:IFNULL(1, 2) CASE WHEN ISNULL(1) THEN (2) ELSE (1) END 数据库:* MySQL * SQLite (possibly) * SAP MaxDB (possibly)16、overlongutf8more 作用:将所有未编码字符编码为超长UTF8 效果: SELECT FIELD FROM TABLE WHERE 2>1 %C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94%C0%A0%C1%86%C1%89%C1%85%C1%8C%C1%84%C0%A0%C1%86%C1%92%C1%8F%C1%8D%C0%A0%C1%94%C1%81%C1%82%C1%8C%C1%85%C0%A0%C1%97%C1%88%C1%85%C1%92%C1%85%C0%A0%C0%B2%C0%BE%C0%B1 数据库:ALL 17、space2morecomment 作用:将 (' ')替换为 '/**_**/' 效果:SELECT id FROM users SELECT/**_**/id/**_**/FROM/**_**/users 数据库:MySQL 5.0 and 5.5 18、unionalltounion 作用:将union all select 替换为union select 效果:-1 UNION ALL SELECT -1 UNION SELECT 数据库:ALL 19、appendnullbyte 作用:在有效载荷的结束位置加载null字节字符编码 效果:1 AND 1=1 1 AND 1=1%00 数据库: ALL 20、 commentbeforeparentheses 作用:在括号前加上(内联)注释 效果:SELECT ABS(1) SELECT ABS/**/(1) 数据库:* Microsoft SQL Server * MySQL * Oracle * PostgreSQL 21、ifnull2ifisnull 作用:将类似于IFNULL(A, B)替换为IF(ISNULL(A), B, A),绕过对IFNULL的过滤 效果:IFNULL(1, 2) IF(ISNULL(1),2,1)数据库: MySQL 5.0 and 5.5、SQLite (possibly)、SAP MaxDB (possibly) 22、overlongutf8 作用:将所有非字母未编码的字符转化为超长UTF8 效果: SELECT FIELD FROM TABLE WHERE 2>1 SELECT%C0%A0FIELD%C0%A0FROM%C0%A0TABLE%C0%A0WHERE%C0%A02%C0%BE1 数据库:ALL 23、space2morehash 作用:将空格替换为#,并添加一个随机字符串和换行符 效果:1 AND 9227=9227 1%23ngNvzqu%0AAND%23nVNaVoPYeva%0A%23lujYFWfv%0A9227=9227 数据库:MySQL >= 5.1.13 24、unmagicquotes 作用:用一个多字节组合%bf%27和末尾通用注释一起替换空格 效果:1' AND 1=1 1%bf%27 AND 1=1-- 数据库:ALL 25、base64encode 作用:整体替换为base64编码 效果:1' AND SLEEP(5)# MScgQU5EIFNMRUVQKDUpIw== 数据库:ALL 26、concat2concatws 作用:替换CONCAT(A, B)' 为 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B) 效果:CONCAT(1,2) CONCAT_WS(MID(CHAR(0),0,0),1,2) 数据库:MySQL 5.0 27、informationschemacomment 作用:在information_schema后加上内联注释/**/ 效果:SELECT table_name FROM INFORMATION_SCHEMA.TABLES SELECT table_name FROM INFORMATION_SCHEMA/**/.TABLES 数据库:ALL 28、percentage 作用:在每个字符前添加一个% 效果:SELECT FIELD FROM TABLE %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E 数据库:Microsoft SQL Server 2000, 2005、MySQL 5.1.56, 5.5.11、PostgreSQL 9.0 适用:ASP web服务 29、space2mssqlblank 作用:将空格随机替换为其他空格符号('%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0B', '%0C', '%0D', '%0E', '%0F', '%0A') 效果:SELECT id FROM users SELECT%0Eid%0DFROM%07users 数据库:Microsoft SQL Server 2000、Microsoft SQL Server 2005 30、uppercase 作用:将小写替换为大写 效果:insert INSERT 数据库: * Microsoft SQL Server 2005 * MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0 31、between 作用:用NOT BETWEEN 0 AND #替换> 效果:1 AND A > B-- 1 AND A NOT BETWEEN 0 AND B-- 数据库: Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 32、dunion 作用:将UNION替换为DUNION 效果:1 UNION ALL SELECT 1DUNION ALL SELECT 数据库: Oracle 33、plus2concat 作用:将 ('+') 替换为 CONCAT() 效果:SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL SELECT CONCAT(CHAR(113),CHAR(114),CHAR(115)) FROM DUAL 数据库:Microsoft SQL Server 2012+ 34、space2mssqlhash 作用:将 (' ')替换为 #后跟”\n" 效果:1 AND 9227=9227 1%23%0AAND%23%0A9227=9227 数据库: * MSSQL * MySQL 35、varnish 作用:附加HTTP报头' x - origin- ip '以绕过Varnish Firewall 效果:X-originating-IP: TARGET_LOCAL_IP (127.0.0.1) 数据库:ALL 36、binary 作用:将关键字binary注入可以注入的地方 效果:1 AND 2>1 1 AND binary 2>binary 1 数据库:MySQL 37、equaltolike 作用:like代替等号 效果: SELECT * FROM users WHERE id=1 SELECT * FROM users WHERE id LIKE 1 数据库:Microsoft SQL Server 2005 MySQL 4, 5.0 and 5.5 38、least 作用:将 ('>') 替换为 'LEAST' 效果:1 AND A > B 1 AND LEAST(A,B+1)=B+1 数据库: * MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0 39、plus2fnconcat 作用:将('+') 替换为 {fn CONCAT()} 效果:SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL SELECT {fn CONCAT({fn CONCAT(CHAR(113),CHAR(114))},CHAR(115))} FROM DUAL 数据库:Microsoft SQL Server 2008+ 40、space2mysqlblank 作用:将空格替换为其他空格符号('%09', '%0A', '%0C', '%0D', '%0B') 效果:SELECT id FROM users SELECT%0Bid%0DFROM%0Cusers 数据库:MySQL 5.1 41、versionedkeywords 作用:注释绕过 效果:1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))# 1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/*!AS*//*!CHAR*/),CHAR(32)),CHAR(58,100,114,117,58))# 数据库:MySQL 4.0.18, 5.1.56, 5.5.11 42、bluecoat 作用:在sql语句之后用有效的随机空白字符替换空格符,随后用LIKE替换= 效果:SELECT id FROM users where id = 1 SELECT%09id FROM users where id LIKE 1 数据库:Blue Coat SGOS,MySQL 5.1 43、equaltorlike 作用:将 “=” 号替换为 “RLIKE” 效果:SELECT * FROM users WHERE id=1 SELECT * FROM users WHERE id RLIKE 1 数据库:MySQL 4, 5.0 and 5.5 44、lowercase 作用:将英文全部替换为小写 效果:INSERT insert 数据库: * Microsoft SQL Server 2005 * MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0 45、randomcase 作用:随机大小写 效果:INSERT INseRt 数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 46、space2mysqldash 作用:将空格替换为 -- ,并追随一个换行符 效果:1 AND 9227=9227 1--%0AAND--%0A9227=9227 数据库:MySQL、MSSQL 47、versionedmorekeywords 作用:将每个关键字用(MySQL)版本注释括起来 效果: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,122,114,115,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,115,114,121,58))# 1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/,/*!CONCAT*/(/*!CHAR*/(58,122,114,115,58),/*!IFNULL*/(CAST(/*!CURRENT_USER*/()/*!AS*//*!CHAR*/),/*!CHAR*/(32)),/*!CHAR*/(58,115,114,121,58))# 数据库: MySQL >= 5.1.13 48、chardoubleencode 作用:对给定的payload全部字符使用双重url编码(不处理已经编码的字符) 效果: SELECT FIELD FROM%20TABLE %2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545 数据库:ALL 49、escapequotes 作用:用 '\'转义单引号或双引号 效果:1" AND SLEEP(5)# 1\\\\" AND SLEEP(5)# 数据库:ALL 50、luanginx 作用:给payload加上大于100个参数 效果: 1 AND 2>1 34=&Xe=&90=&Ni=&rW=&lc=&te=&T4=&zO=&NY=&B4=&hM=&X2=&pU=&D8=&hm=&p0=&7y=&18=&RK=&Xi=&5M=&vM=&hO=&bg=&5c=&b8=&dE=&7I=&5I=&90=&R2=&BK=&bY=&p4=&lu=&po=&Vq=&bY=&3c=&ps=&Xu=&lK=&3Q=&7s=&pq=&1E=&rM=&FG=&vG=&Xy=&tQ=&lm=&rO=&pO=&rO=&1M=&vy=&La=&xW=&f8=&du=&94=&vE=&9q=&bE=&lQ=&JS=&NQ=&fE=&RO=&FI=&zm=&5A=&lE=&DK=&x8=&RQ=&Xw=&LY=&5S=&zi=&Js=&la=&3I=&r8=&re=&Xe=&5A=&3w=&vs=&zQ=&1Q=&HW=&Bw=&Xk=&LU=&Lk=&1E=&Nw=&pm=&ns=&zO=&xq=&7k=&v4=&F6=&Pi=&vo=&zY=&vk=&3w=&tU=&nW=&TG=&NM=&9U=&p4=&9A=&T8=&Xu=&xa=&Jk=&nq=&La=&lo=&zW=&xS=&v0=&Z4=&vi=&Pu=&jK=&DE=&72=&fU=&DW=&1g=&RU=&Hi=&li=&R8=&dC=&nI=&9A=&tq=&1w=&7u=&rg=&pa=&7c=&zk=&rO=&xy=&ZA=&1K=&ha=&tE=&RC=&3m=&r2=&Vc=&B6=&9A=&Pk=&Pi=&zy=&lI=&pu=&re=&vS=&zk=&RE=&xS=&Fs=&x8=&Fe=&rk=&Fi=&Tm=&fA=&Zu=&DS=&No=&lm=&lu=&li=&jC=&Do=&Tw=&xo=&zQ=&nO=&ng=&nC=&PS=&fU=&Lc=&Za=&Ta=&1y=&lw=&pA=&ZW=&nw=&pM=&pa=&Rk=&lE=&5c=&T4=&Vs=&7W=&Jm=&xG=&nC=&Js=&xM=&Rg=&zC=&Dq=&VA=&Vy=&9o=&7o=&Fk=&Ta=&Fq=&9y=&vq=&rW=&X4=&1W=&hI=&nA=&hs=&He=&No=&vy=&9C=&ZU=&t6=&1U=&1Q=&Do=&bk=&7G=&nA=&VE=&F0=&BO=&l2=&BO=&7o=&zq=&B4=&fA=&lI=&Xy=&Ji=&lk=&7M=&JG=&Be=&ts=&36=&tW=&fG=&T4=&vM=&hG=&tO=&VO=&9m=&Rm=&LA=&5K=&FY=&HW=&7Q=&t0=&3I=&Du=&Xc=&BS=&N0=&x4=&fq=&jI=&Ze=&TQ=&5i=&T2=&FQ=&VI=&Te=&Hq=&fw=&LI=&Xq=&LC=&B0=&h6=&TY=&HG=&Hw=&dK=&ru=&3k=&JQ=&5g=&9s=&HQ=&vY=&1S=&ta=&bq=&1u=&9i=&DM=&DA=&TG=&vQ=&Nu=&RK=&da=&56=&nm=&vE=&Fg=&jY=&t0=&DG=&9o=&PE=&da=&D4=&VE=&po=&nm=&lW=&X0=&BY=&NK=&pY=&5Q=&jw=&r0=&FM=&lU=&da=&ls=&Lg=&D8=&B8=&FW=&3M=&zy=&ho=&Dc=&HW=&7E=&bM=&Re=&jk=&Xe=&JC=&vs=&Ny=&D4=&fA=&DM=&1o=&9w=&3C=&Rw=&Vc=&Ro=&PK=&rw=&Re=&54=&xK=&VK=&1O=&1U=&vg=&Ls=&xq=&NA=&zU=&di=&BS=&pK=&bW=&Vq=&BC=&l6=&34=&PE=&JG=&TA=&NU=&hi=&T0=&Rs=&fw=&FQ=&NQ=&Dq=&Dm=&1w=&PC=&j2=&r6=&re=&t2=&Ry=&h2=&9m=&nw=&X4=&vI=&rY=&1K=&7m=&7g=&J8=&Pm=&RO=&7A=&fO=&1w=&1g=&7U=&7Y=&hQ=&FC=&vu=&Lw=&5I=&t0=&Na=&vk=&Te=&5S=&ZM=&Xs=&Vg=&tE=&J2=&Ts=&Dm=&Ry=&FC=&7i=&h8=&3y=&zk=&5G=&NC=&Pq=&ds=&zK=&d8=&zU=&1a=&d8=&Js=&nk=&TQ=&tC=&n8=&Hc=&Ru=&H0=&Bo=&XE=&Jm=&xK=&r2=&Fu=&FO=&NO=&7g=&PC=&Bq=&3O=&FQ=&1o=&5G=&zS=&Ps=&j0=&b0=&RM=&DQ=&RQ=&zY=&nk=&1 AND 2>1 数据库:ALL 适用:绕过lua-nginx waf,如cloudflare 51、randomcomments 作用:用注释符分割sql关键字 效果:INSERT I/**/N/**/SERT 数据库:ALL 52、space2plus 作用:用加号替换空格 效果:SELECT id FROM users SELECT+id+FROM+users 数据库:ALL 53、xforwardedfor 作用:添加一个假的HTTP报头'X-Forwarded-For'及其他类似的 效果:headers["X-Forwarded-For"] = randomIP() 数据库:ALL 54、charencode 作用:对给定的payload全部字符使用url编码(不处理已经编码的字符) 效果:SELECT FIELD FROM%20TABLE %53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45 数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 55、greatest 作用:绕过过滤’>’ ,用GREATEST替换大于号。 效果:1 AND A > B' 1 AND GREATEST(A,B+1)=A 数据库:MySQL 4, 5.0 and 5.5 Oracle 10g PostgreSQL 8.3, 8.4, 9.0 56、misunion 作用:将UNION 替换为 -.1UNION 效果:1 UNION ALL SELECT 1-.1UNION ALL SELECT 数据库:MySQL 57、schemasplit 作用:用空格拆分标识模式符,如替换testdb.users为testdb 9.e.users 效果:SELECT id FROM testdb.users SELECT id FROM testdb 9.e.users 数据库:MySQL 58、space2randomblank 作用:将空格替换为其他有效字符 效果:SELECT id FROM users SELECT%0Did%0DFROM%0Ausers 数据库:ALL 59、charunicodeencode 作用:对字符串的unicode编码 效果:SELECT FIELD%20FROM TABLE %u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045 数据库:Microsoft SQL Server 2000/2005、MySQL 5.1.56、PostgreSQL 9.0.3 适用:ASP、ASP.NET web服务 60、halfversionedmorekeywords 作用:在每个关键字前添加mysql版本注释 效果: value' UNION ALL SELECTCONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa 数据库:MySQL < 5.1 61、modsecurityversioned 作用:过滤空格,使用mysql内联注释的方式进行注入 效果:1 AND 2>1-- 1 /*!30874AND 2>1*/-- 数据库:MySQL 5.0 62、space2comment 作用:将空格替换为/**/ 效果:SELECT id FROM users SELECT/**/id/**/FROM/**/users 数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 63、sp_password 作用:将(MsSQL)函数'sp_password'附加到有效负载的末尾,以便从DBMS日志中自动混淆 效果:1 AND 9227=9227-- 1 AND 9227=9227-- sp_password 数据库:MSSQL

三、核心算法 1、相似度对比算法
比较出名的页面相似度算法,有tf-idf算法,余弦相似度计算,simhash等等,各有优劣,可以根据不同的应用场景进行选取。
1.1、tf-idf算法 TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术,常用于挖掘文章中的关键词,而且算法简单高效,常被工业用于最开始的文本数据清洗。
TF-IDF有两层意思,一层是"词频"(Term Frequency,缩写为TF),另一层是"逆文档频率"(Inverse Document Frequency,缩写为IDF)。
假设我们现在有一片长文叫做《量化系统架构设计》词频高在文章中往往是停用词,“的”,“是”,“了”等,这些在文档中最常见但对结果毫无帮助、需要过滤掉的词,用TF可以统计到这些停用词并把它们过滤。当高频词过滤后就只需考虑剩下的有实际意义的词。
但这样又会遇到了另一个问题,我们可能发现"量化"、"系统"、"架构"这三个词的出现次数一样多。这是不是意味着,作为关键词,它们的重要性是一样的?事实上系统应该在其他文章比较常见,所以在关键词排序上,“量化”和“架构”应该排在“系统”前面,这个时候就需要IDF,IDF会给常见的词较小的权重,它的大小与一个词的常见程度成反比。
当有TF(词频)和IDF(逆文档频率)后,将这两个词相乘,就能得到一个词的TF-IDF的值。某个词在文章中的TF-IDF越大,那么一般而言这个词在这篇文章的重要性会越高,所以通过计算文章中各个词的TF-IDF,由大到小排序,排在最前面的几个词,就是该文章的关键词。
sqlmap二次开发指南
文章图片

TF-IDF的优点是简单快速,而且容易理解。缺点是有时候用词频来衡量文章中的一个词的重要性不够全面,有时候重要的词出现的可能不够多,而且这种计算无法体现位置信息,无法体现词在上下文的重要性。如果要体现词的上下文结构,那么你可能需要使用word2vec算法来支持。
1.2、余弦相似度算法 在数学几何运算中,余弦定理用于计算两条边的夹角,余弦值越大,夹角越小。当夹角为 0° 时,两条边 (x,y) 完全重合。计算公式如下:
sqlmap二次开发指南
文章图片

而对于多维图像 (x,y,z...) 三(甚至 n)条边,计算公式如下:
sqlmap二次开发指南
文章图片

同样对于计算两段文本,计算两段文本的相似度。将文本切割成若干个词向量,切词则交由 NLP 进行。而将每一个词向量看成数学几何运行中的边,最后则演变成计算多维余弦夹角。
  • 文本切词
    • 文本 1:明天 \ 不 \ 下雨
    • 文本 2:明天 \ 不 \ 可能 \ 下雨
  • 文本词频统计
    • 文本 1 词频:(明天 =>1, 不 =>1, 下雨 =>1, 可能 =>0)
    • 文本 2 词频:(明天 =>1, 不 =>1, 下雨 =>1, 可能 =>1)
  • 文本词向量
    • 文本 1 词向量:(1,1,1,0)
    • 文本 2 词向量:(1,1,1,1)
1.3、simhash算法
  • 其主要思想是降维,将高维的特征向量映射成低维的特征向量,通过两个向量的Hamming Distance来确定文章是否重复或者高度近似。
  • 其中,Hamming Distance,又称汉明距离,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。也就是说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:1011101 与 1001001 之间的汉明距离是 2。至于我们常说的字符串编辑距离则是一般形式的汉明距离。
  • simhash算法分为5个步骤:分词、hash、加权、合并、降维,具体过程如下所述:
    • 分词
      • 给定一段语句,进行分词,得到有效的特征向量,然后为每一个特征向量设置1-5等5个级别的权重(如果是给定一个文本,那么特征向量可以是文本中的词,其权重可以是这个词出现的次数)。例如给定一段语句:“CSDN博客结构之法算法之道的作者July”,分词后为:“CSDN 博客 结构 之 法 算法 之 道 的 作者 July”,然后为每个特征向量赋予权值:CSDN(4) 博客(5) 结构(3) 之(1) 法(2) 算法(3) 之(1) 道(2) 的(1) 作者(5) July(5),其中括号里的数字代表这个单词在整条语句中的重要程度,数字越大代表越重要。
    • hash
      • 通过hash函数计算各个特征向量的hash值,hash值为二进制数01组成的n-bit签名。比如“CSDN”的hash值Hash(CSDN)为100101,“博客”的hash值Hash(博客)为“101011”。就这样,字符串就变成了一系列数字。
    • 加权
      • 在hash值的基础上,给所有特征向量进行加权,即W = Hash * weight,且遇到1则hash值和权值正相乘,遇到0则hash值和权值负相乘。例如给“CSDN”的hash值“100101”加权得到:W(CSDN) = 100101 4 = 4 -4 -4 4 -4 4,给“博客”的hash值“101011”加权得到:W(博客)=101011 5 = 5 -5 5 -5 5 5,其余特征向量类似此般操作。
    • 合并
      • 将上述各个特征向量的加权结果累加,变成只有一个序列串。拿前两个特征向量举例,例如“CSDN”的“4 -4 -4 4 -4 4”和“博客”的“5 -5 5 -5 5 5”进行累加,得到“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”,得到“9 -9 1 -1 1”。
    • 降维
      • 对于n-bit签名的累加结果,如果大于0则置1,否则置0,从而得到该语句的simhash值,最后我们便可以根据不同语句simhash的海明距离来判断它们的相似度。例如把上面计算出来的“9 -9 1 -1 1 9”降维(某位大于0记为1,小于0记为0),得到的01串为:“1 0 1 0 1 1”,从而形成它们的simhash签名。
        sqlmap二次开发指南
        文章图片
  • 优缺点:完全无关的文本正好对应成了相同的simhash,精确度并不是很高,而且simhash更适用于较长的文本,但是在大规模语料进行去重时,simhash的计算速度优势还是很不错的。
1.4、sqlmap相似度算法 在sqlmap中使用difflib这个模块来进行页面相似度的对比,实际处理的时候,sqlmap 并不仅仅是直接计算页面的相似度,而是通过首先对页面进行一些预处理,预处理之后,根据预设的阈值来计算请求页面和模版页面的相似度。比如说,我们设定一个阈值0.8,如果输入payload之后网页与正常网页的相似度计算后大于0.8,即强相关,我们则认定没有遇到waf。
在difflib模块中存在ratio()方法,该方法返回两段文本的相似度,相似度的算法如下:我们假设两段文本分别为 text1 与 text2,他们相同的部分长度总共为 M,这两段文本长度之和为 T,那么这两段文本的相似度定义为 2.0 * M / T,这个相似度的值在 0 到 1.0 之间。
一般来说针对某一类型漏洞,其页面相似度的阈值是需要对不同页面大量测试之后取相对稳定的值,sqlmap的编写人员根据他们的算法和测试取值为0.02-0.98
四、开发指南 1、sqlmap流程
  • 相似度对比流程
    sqlmap二次开发指南
    文章图片

2、核心代码
2.1、全局常量/变量 数据定义部分在lib/core/data.py下,重点看conf和kb对象。
# conf对象共享类和函数中的结构,用于存储一些通用配置项 conf = AttribDict()# kb对象共享类和函数中的结构,用于存储过程中的全局变量 kb = AttribDict()#AttribDict类定义 class AttribDict(dict): """ This class defines the dictionary with added capability to access members as attributes>>> foo = AttribDict() >>> foo.bar = 1 >>> foo.bar 1 """def __init__(self, indict=None, attribute=None): if indict is None: indict = {}# Set any attributes here - before initialisation # these remain as normal attributes self.attribute = attribute dict.__init__(self, indict) self.__initialised = True# After initialisation, setting attributes # is the same as setting an itemdef __getattr__(self, item): """ Maps values to attributes Only called if there *is NOT* an attribute with this name """try: return self.__getitem__(item) except KeyError: raise AttributeError("unable to access item '%s'" % item)def __setattr__(self, item, value): """ Maps attributes to values Only if we are initialised """# This test allows attributes to be set in the __init__ method if "_AttribDict__initialised" not in self.__dict__: return dict.__setattr__(self, item, value)# Any normal attributes are handled normally elif item in self.__dict__: dict.__setattr__(self, item, value)else: self.__setitem__(item, value)def __getstate__(self): return self.__dict__def __setstate__(self, dict): self.__dict__ = dictdef __deepcopy__(self, memo): retVal = self.__class__() memo[id(self)] = retValfor attr in dir(self): if not attr.startswith('_'): value = https://www.it610.com/article/getattr(self, attr) if not isinstance(value, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)): setattr(retVal, attr, copy.deepcopy(value, memo))for key, value in self.items(): retVal.__setitem__(key, copy.deepcopy(value, memo))return retVal

  • conf和kb大部分的定义可以在lib/core/option.py查看,其他的也可以在lib/parse/cmdline.py中查找到定义
    def initOptions(inputOptions=AttribDict(), overrideOptions=False): _setConfAttributes() _setKnowledgeBaseAttributes() _mergeOptions(inputOptions, overrideOptions)def _setConfAttributes(): """ This function set some needed attributes into the configuration singleton. """debugMsg = "initializing the configuration" logger.debug(debugMsg)conf.authUsername = None conf.authPassword = None conf.boundaries = [] conf.cj = None conf.dbmsConnector = None conf.dbmsHandler = None conf.dnsServer = None conf.dumpPath = None conf.hashDB = None conf.hashDBFile = None conf.httpCollector = None conf.httpHeaders = [] conf.hostname = None conf.ipv6 = False conf.multipleTargets = False conf.outputPath = None conf.paramDict = {} conf.parameters = {} conf.path = None conf.port = None conf.proxyList = None conf.resultsFP = None conf.scheme = None conf.tests = [] conf.trafficFP = None conf.HARCollectorFactory = None conf.fileWriteType = None def _setKnowledgeBaseAttributes(flushAll=True): """ This function set some needed attributes into the knowledge base singleton. """debugMsg = "initializing the knowledge base" logger.debug(debugMsg) kb.alerted = False kb.aliasName = randomStr() kb.alwaysRefresh = None kb.arch = None kb.authHeader = None kb.bannerFp = AttribDict() kb.base64Originals = {} kb.binaryField = False kb.browserVerification = Nonekb.brute = AttribDict({"tables": [], "columns": []}) kb.bruteMode = Falsekb.cache = AttribDict() kb.cache.addrinfo = {} kb.cache.content = {} kb.cache.encoding = {} kb.cache.alphaBoundaries = None kb.cache.hashRegex = None kb.cache.intBoundaries = None kb.cache.parsedDbms = {} kb.cache.regex = {} kb.cache.stdev = {}kb.captchaDetected = Nonekb.chars = AttribDict() kb.chars.delimiter = randomStr(length=6, lowercase=True) kb.chars.start = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR) kb.chars.stop = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR) kb.chars.at, kb.chars.space, kb.chars.dollar, kb.chars.hash_ = ("%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, _, KB_CHARS_BOUNDARY_CHAR) for _ in randomStr(length=4, lowercase=True))kb.codePage = None kb.columnExistsChoice = None kb.commonOutputs = None kb.connErrorChoice = None kb.connErrorCounter = 0 kb.cookieEncodeChoice = None kb.copyExecTest = None kb.counters = {} kb.customInjectionMark = CUSTOM_INJECTION_MARK_CHAR kb.data = https://www.it610.com/article/AttribDict() kb.dataOutputFlag = False# Active back-end DBMS fingerprint kb.dbms = None kb.dbmsFilter = [] kb.dbmsVersion = [UNKNOWN_DBMS_VERSION]kb.delayCandidates = TIME_DELAY_CANDIDATES * [0] kb.dep = None kb.disableHtmlDecoding = False kb.dnsMode = False kb.dnsTest = None kb.docRoot = None kb.droppingRequests = False kb.dumpColumns = None kb.dumpTable = None kb.dumpKeyboardInterrupt = False kb.dynamicMarkings = [] kb.dynamicParameter = False kb.endDetection = False kb.explicitSettings = set() kb.extendTests = None kb.errorChunkLength = None kb.errorIsNone = True kb.falsePositives = [] kb.fileReadMode = False kb.fingerprinted = False kb.followSitemapRecursion = None kb.forcedDbms = None kb.forcePartialUnion = False kb.forceThreads = None kb.forceWhere = None kb.forkNote = None kb.futileUnion = None kb.fuzzUnionTest = None kb.heavilyDynamic = False kb.headersFile = None kb.headersFp = {} kb.heuristicDbms = None kb.heuristicExtendedDbms = None kb.heuristicMode = False kb.heuristicPage = False kb.heuristicTest = None kb.hintValue ="" kb.htmlFp = [] kb.httpErrorCodes = {} kb.inferenceMode = False kb.ignoreCasted = None kb.ignoreNotFound = False kb.ignoreTimeout = False kb.identifiedWafs = set() kb.injection = InjectionDict() kb.injections = [] kb.laggingChecked = False kb.lastParserStatus = None kb.lastCtrlCTime = Nonekb.locks = AttribDict() for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "log", "socket", "redirect", "request", "value"): kb.locks[_] = threading.Lock()kb.matchRatio = None kb.maxConnectionsFlag = False kb.mergeCookies = None kb.multipleCtrlC = False kb.negativeLogic = False kb.nullConnection = None kb.oldMsf = None kb.orderByColumns = None kb.originalCode = None kb.originalPage = None kb.originalPageTime = None kb.originalTimeDelay = None kb.originalUrls = dict()# Back-end DBMS underlying operating system fingerprint via banner (-b) # parsing kb.os = None kb.osVersion = None kb.osSP = Nonekb.pageCompress = True kb.pageTemplate = None kb.pageTemplates = dict() kb.pageEncoding = DEFAULT_PAGE_ENCODING kb.pageStable = None kb.partRun = None kb.permissionFlag = False kb.postHint = None kb.postSpaceToPlus = False kb.postUrlEncode = True kb.prependFlag = False kb.processResponseCounter = 0 kb.previousMethod = None kb.processUserMarks = None kb.proxyAuthHeader = None kb.queryCounter = 0 kb.randomPool = {} kb.redirectChoice = None kb.reflectiveMechanism = True kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0} kb.requestCounter = 0 kb.resendPostOnRedirect = None kb.resolutionDbms = None kb.responseTimes = {} kb.responseTimeMode = None kb.responseTimePayload = None kb.resumeValues = True kb.rowXmlMode = False kb.safeCharEncode = False kb.safeReq = AttribDict() kb.secondReq = None kb.serverHeader = None kb.singleLogFlags = set() kb.skipSeqMatcher = False kb.smokeMode = False kb.reduceTests = None kb.tlsSNI = {} kb.stickyDBMS = False kb.storeHashesChoice = None kb.suppressResumeInfo = False kb.tableFrom = None kb.technique = None kb.tempDir = None kb.testMode = False kb.testOnlyCustom = False kb.testQueryCount = 0 kb.testType = None kb.threadContinue = True kb.threadException = False kb.tableExistsChoice = None kb.uChar = NULL kb.udfFail = False kb.unionDuplicates = False kb.unionTemplate = None kb.webSocketRecvCount = None kb.wizardMode = False kb.xpCmdshellAvailable = Falseif flushAll: kb.checkSitemap = None kb.headerPaths = {} kb.keywords = set(getFileItems(paths.SQL_KEYWORDS)) kb.normalizeCrawlingChoice = None kb.passwordMgr = None kb.preprocessFunctions = [] kb.skipVulnHost = None kb.storeCrawlingChoice = None kb.tamperFunctions = []#控制tamper脚本的变量 kb.targets = OrderedSet() kb.testedParams = set() kb.userAgents = None kb.vainRun = True kb.vulnHosts = set() kb.wafFunctions = [] kb.wordlists = None

  • 一些定义的常量在lib/core/settings.py里
    # Minimum distance of ratio from kb.matchRatio to result in True DIFF_TOLERANCE = 0.05 CONSTANT_RATIO = 0.9# Ratio used in heuristic check for WAF/IPS protected targets IPS_WAF_CHECK_RATIO = 0.5# Timeout used in heuristic check for WAF/IPS protected targets IPS_WAF_CHECK_TIMEOUT = 10# Lower and upper values for match ratio in case of stable page LOWER_RATIO_BOUND = 0.02 UPPER_RATIO_BOUND = 0.98

2.2 PageRatio算法
sqlmap的页面相似度算法主要用了difflib模块的SequenceMatcher 这个类。简单来说这个类使用了 Ratcliff 和 Obershelp 提供的算法,匹配最长相同的字符串,设定无关字符(junk)。在实际使用中,他们应用最多的方法应该就是 ratio()。sqlmap 并不仅仅是直接计算页面的相似度,而是通过首先对页面进行一些预处理,预处理之后,根据预设的阈值来计算请求页面和模版页面的相似度。
3、代码结构 sqlmap |___sqlmap.py主入口 |___data存储数据 |___extra |___lib主要逻辑控制处 |___controller主要是逻辑流程 ||___handler.py检测数据库类型 ||___controller.py模块的主入口,见start()函数,初始的各种检测 ||___checks.py各种检测的实现 ||___action.py检测到注入点后, |___core主要是各种数据处理 |___settings.py 各种配置 |___enums.py配置 |___option.py根据配置做的一些初始化操作 |___common.py初始化的数据处理

其他细节点
  • 删除历史数据:/root/.local/share/sqlmap/output/192.168.50.137/session.sqlite
  • Sqlmap client加headers、tamper、显示详细数据 :new -u "http://192.168.50.137/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit" --tamper=space2fuzzdefined --headers="Cookie: security=low; PHPSESSID=jjjnpgulfevirq0grtten9qtbg" -v 4
  • sqlmap需要改User-agent头,否则会被拦截。多个请求头用‘\n'分割
参考文档 【sqlmap二次开发指南】fuzz:https://blog.csdn.net/weixin_...
tamper:https://www.cnblogs.com/r00tu...
算法:https://paper.seebug.org/729/
算法:https://cl0udg0d.github.io/20...
tf-idf算法:https://zhuanlan.zhihu.com/p/...
余弦:https://www.cnblogs.com/airne...
余弦:http://www.ruanyifeng.com/blo...
simhash:https://blog.csdn.net/lengye7...
sqlmap核心三篇:https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/... https://zhuanlan.zhihu.com/p/...、
sqlmap参数:https://blog.csdn.net/haha13l...

    推荐阅读