ÿØÿà JFIF    ÿÛ „ !.%+&8&+/1555$;@;4?.451 4,$,44444444444414444444444444444444444444444444444444ÿÀ  á á" ÿÄ     ÿÄ ?    !1AQaq"2‘¡±ÁðBRbrÑá#‚’¢²3S CñÿÄ   ÿÄ !    !1QAa‘2ÿÚ   ? 5˜Z¯V¦cø)›t/? z¨±>Õ5€¶‹Á¤·¼z¼Ü¬+ñ®v¤¨_ˆR­BFn©—˜ý®ç̝P8gýt·ÉSTŦˆìät?þé¼íìN/Þa)ì–í6ô… Ï¿øÃj´¿KÇü]ÿ ªô¹-eKànëÕHTx}ýSÜ›ÿ ”7Ø×&µ<¦  ¥ÑO¶[Ù¯ä¨ÞÃÿ PZ-¬;#õ|•oaÿ ©CìÞz3˜öː/¤­ñTûIØ}š^ mÓ%ªxˆ¥ÉŸu=Z+ISe¿45™¼u;ú&WØ÷€æßQ™®{|íx*TC“#ZŠìZ§²‹ 6pv…³¿¡äª*áZÐ%ÒOáˆo"x«OHk w±æ+¬V(kMúŸ5Vö«$ ÁrÏbàb57/luR ¸ÑÛj Òµì`Мq­û žICÀÊ•©4€Âcà¨Ï€O´<èÐ:›ù(Ë^L8þ‘ÍÌ#¸Ð_Ì©ÙK(Öz 4¬û+¸;ü’V’84‘¬ÃŽ:[â‡ÔÌáõp¢~§ªlæ£ö{®G>J¼"°‡7¯ÆÉèßû ‹É‹§ÁòÃýâßî ^ƾÙõ‹×óH#«LP½ïX=xÑÍ$|W?•~• îëÔ©ª‹ {ÝT…Kÿ ”hûâá)J*ö˜–ÔU;iÇ€/ ÆþjóZ\ýwØ=Ìm ºèËL9 ýèÆð/¨’¥öo=nË.%Îì ŽÕ¯È|{Oj²ƒE6e/ßdÄõ²Ìâ1O®ò×TsəԸhOMýíMˆ¿¼H˜l²,7Â¥#MF/Úf°Ö½± ¸–dr‹NýÊ íjqx{œÉ ä-È ¦ øÄër¨q°ð †nцýÑÄÆ’mä…n<0È™;ÁÝá¯ÁZƒ7FÀmì­ É&9ˆîéi¶ùN§Y• ÃZãAâ?•‡©‰ , ó¾IŸŠc1 4â&y­&pŠ­6;M À 0¹qç»p.á …ŸÅáK@%6·y6ƒ‰3?”úºŽ‰éX5ªPT §µ!=Mž«Ú½‹ÅgÂSâÉaþÓoö–¯ÁÔìR>5éÿ üs¶ÆUcÌ kÇR ]ÿ ù¬¼«VŽ;Â|‡~¢¦”ÏŰæ {L™Õ°Óv¹ò¸írޡעCÃ!íVÕ {¶»sŒNPg/ "uÕbkm²“$ďå¿é¹§°½æz¯6 †s¿!s–wÚÝ“™Œ °.ûj>·+™Òa…©Œ&rÝÎtÛë긪Ît’LAVp%c Úý[ÄzJ¾ÇàXXç@˜ó<êL]·T˜¾¥1Ó©V‡g´æ½¦Ý@¹óø!_@´ÞâSÁ —S3™•& ]@JHÚý©ZŽ €×æÔr»Áf!‡yÞ4Mv*èÓã_{‘åóUuљØ«Oïé*®EvÑ Œ÷‡U \"㪒ÍK+À 4“M¡ï:0¥5í!'<@î´”>Ç»&Z–ïCCV˜Ì5Šo&îhè.žû |ÓK©h$s6KìŒëã)¹hI¦GïOåóI;ììü#É$Š0…Ææ¥TØ.5­¾gn´ “ÂÖ\:hœ89G)J@„}œ:’Ò{/Š"¦_Æ×7Æ3VÇŠÊa]ÚŒÙ€Ä–=®uÁßâACZƒ§§£ Qnâ:«,×{tyø¬iÛcœÜÄ€H½ÄÍCk´÷šß .W'b¤Íåh]÷€=,Žv×cÚEÚHXJX¶îo¨FÒtèöŸ>ªª6[J®Fµ£sGÁeqõfe\íjÒÐïÄÐGˆe1Ø‹.Ø”‘Ëuø Y­ˆÜ ŽG|zùªüMpDnQWÄ”%JŠ™)â*p@Örš«ÕT2Ð%ˆG#ª„ ·¤!°ŸOTÂT¸aÚ%4&h™LµšØüÐ.F¿²ÐÞ_Ç‚¾ÅÃaÜ÷09Æ q€öy˜v‡85õN÷]¬äѼóS{°_MެúÔ#°Ç¸0åÞè2ëôPcvÆw9®ií1Ä8F™˜à‰´+‰Ik1òÝ7“Ñ×ÒsÝ\x‚h`ÞÑ`ó"|µEcý£n˜h`}GÞ !±ù²Ápü²ß6 0ïi󜵩SÈÇ7˜-ÕURO˜¦´f$ªž-Í6(œ}<„ éc øs]ŽŽ„*—¾ ìdŽ„)méª\¿êÎIg¾ØÞ~I#C/¼¼´EÁÈŽi8“©õådô·>euä ƒ'Ê×लR1ÉJE1ÐAát`t;ÇР%Ý<‡¥„ÍÆ`×Oyó)õiI€ñQaŸ4Ûù\áàaÃÔ¹HÃu¹*k€¦<„e S‡&õÏ B!ŽhüÞ`yj}mªf×\¿ Ç~æ­9‡û\՞Ǖg²1Žû5V7 !àöšm° c`ܬøÇìµÒ'P"?…´Ö,"§^•õލsÔ)6˜sæéÍR¼ ò|Sl”‹7 nPW Gòú÷½§O¯‡„l¡kSÞŒr½PÊ@æ¢pŽ-mÿ #Ÿ˜Àº¶Áä¦;ïÔæ$1££`“Õ>„—·ž)ßð³ñ#Ï Ô$¶œ‰ÊE‹À;÷º ¯«P:Ñ”8–IÊtpÞ3ª“>ê“þës4ò2OÏÕ­±zô†Õ§‰.÷ä¸;¿˜“'œ›žª}«Œ{ª±Ì 9ÔóÞÕ‡0 $íWV3Üì¬ —@kÝ4@¿r¼±½¬™›?øØæ´'Áé®CË3-g$˜ö‡×auÚi´Žp/êÛ æF›Ú2v‹ã¿¿,nB1̨ƃqÞa5͝@&Æû“él÷ \C²½UÍc ¯k×¢U ÖéQå™—-r wô ÞÏ<Ò=&=ÿ Ôê Òêˈt,i—;LîÜ á¸*ÚÃ1$êL•LÍ <É)ýÐà’ ;F™{ƒ™˜€&'}‚ãÄK`¡ÞT@I;®žZóè‚s’7®°›+§O­Åq©é»²9<Ô J ¼9O’HL»Ùïì¸rk¼Ž_ý‘TŸu[²ßÚŒ·ü÷B%¯E ŸÔX5êO´ Ç•€’I0 ÉJX` ñ¹õ%;µŸD‘«´€àwÒ™U ûئžÖö\×®×´8 ½‡ºÐÆÓ§?Àkmœ=;d5*@-ì0F Rªýš[Ü6âö̃ڸr*KA9· u*µæ£?U¸Âêí†8@¦X4 e-ò„0s{ HâUpU?¼mñRa°®a%Ð'tÉ×’\¾ÊÉ]t›h>·(Ë@R¼¡Ãt h}’O÷au<+nT…Ö…MӐ??Óe95 q>í/;&JSû °¯ÊéÞ øƒ*Ã2½Ài&:nôUl=¾¿5eˆ3”ñc|Ú2V”>„»&eE;«ÚäC p¢Û úy 9š[ŒÌx¼擼A&DåÒ¯ˆ¤ÀÌ;"˜ ÏQä¸åhÊ}Ûq«Û0WžÒ|»€ø®öCm5•\ÇÀ§Pe3£]0ÃàLDÉ‰1øªxjgwT‚÷¿LΨK‹›ùs—xˆÜ±µ kæ¸f‰‰ÜGk/LÛØ6d9ò¶ùA{ƒA3š/¬D¬khÓk‰`˜"㯒r¿±Óã jx‡°e}<Ñø\3y:'À•/h½Í€Ç4~g ?Û(¼]v‘ªlKÎâ~?O‚W%{Ì:“'©úNq¾›úo(X’¥¯ˆ nFê{Ç€ü?º'ë ø‹ì Þ09ŒÌç9Æ —ËC`j@ÓÄ(+a‹un¸#ÂꟋ{K`‘ÑÍÍ'à´»/Û,KW;Þ4²þð ï Nm|~fGÏ(…³Ã)«1ö­Õ ¥‡¨©ƒÃ™ü-s=à=U66Ï«Ýc蓦W¹íž®›nÔ%êÇìŒ<#Ü×84ån®Ð ÒåOC` ñânÑs‡¢ç 1õ%Îhì½Ã½® e:ݼUZo™`  ÅZŸŒÊ«ê1ÏÄo$q¹Þ€©ˆhÐÉä¯ñ[!…Ú˜àJ:x2$Íß&PåT£6ç— ‡Í*4Ýšçjÿ ‰É nófÐ ó(L5C•åÆ\rMÒ@ò }y-W}™üýVù—ú¢=Ù”c®‘< M ž ´Phr ¦©TD ‘ù.$´÷O‡‘V2Æò.=IUŒ=ž‡â¬i™aþÓåÙ?òUø'ØÖ•.~* šTŒ!•-×áºTâ®ä#õü'´ eýlYÅÓeÕKÂrT"CÚ@u!Óxƒ{š3€}1¿(r}%«nËamjÑ%ÑNEò v ˜à  σöK³,*º.àzù¨™Ó ÚçâU¦*¿ 9{%Ö¹ njûdaXöb) kÛÆ±ûÓ\°M7ˆÂ=û›ç¿Ã‚­V»Cg–8ÙêE- j)k$º`Ã-ùEýeBÆÇ]c¡°ñty&Òd0nõ'¡W+ƒ*|–øµFa\GQªEAÔp5\Ǽ·¼Ç8·õ -â§Ú[ ‡ uZeÖ 3}×d'+¹:ð+K†Û®s!Ï$úe€<Û”x)1»a­¡LC]¸µík…ÚàA»AYº{†ªS[¦5HÒ7ù --,ísòDØ€èk ÞÀîÜ ò@â( ËNˆë›4ô½•/¦o‡€Û7 ê•ÆêòðÜy'Án½µ á˜ݦ ndeo…[ì¶Ê,¥R³Ä=À±—–ß;£™´ñSâ*g§”ïaið‘Jå~™ÓÞ ß³Õ¢»8x埒²52>AÊb&-÷\7´éÄù€T˜,w;3{ï˜k…à¹ÄqÀ«œ{€\ ˆ¾[´¨јr &Úé„Ívˆ±8†¿]|¬ņ4I×pÞS1ÈÖz‰#Ìv‡G!YNògñ:màTz¢Ý1ô©^O=~ë|5Bã™ç•¼µõ•bÆ@úÕS¬ÈŒ#¬zünrŸ û” Z²•èðV"ÁHÚý©wÝ €7¼Ìu1hÑa3Éä û f$o¿É ™Ú›ÝçnpÒ3äÌ3†Í§,Äï]$‰/pê †«À¼¸e9­Æê_C]žƒ·ý·frÁN«, E=›Çq -‰öŒ:aÏ¿±í&£Í:-} 84‘ÿ eƒQÑeëSsuiA ³g㟥ú£?ÿ ʼn*”“÷aühe:ÊWa@ÒÞk±eØ] F Ô—r.åä˜ @ö¥ªZoÐýYL·¥S²G/‡ñ <~*ZÆ´è>JlòàÛÆ½ÿ 窘ìGN¢:I®KšJp/`íIÁÀõ#Ä-€ö­šµŒoF4|ÆQØÆ@Ì|£Ô…¢À{9˜è½Üó›€ôYÒÎYsið;ís¤€à²ˆ‚4qÉVŒI$ ‰"° æµ8cXGjœˏ¡Aâý•ËÜ¢ûï e·çLx']á"oÅÎê3¯Ç—¹”ó0nå‚âg{Œñ> S´˜îè°g238‚ãköÝfÚd´6Ò€;ò÷±¢™¼›º ¢Æ'¥Ðx'e¬ç ]bÈÆV¢ó‹kýBO ðÊâ$Ÿ!×T 3Mýמ žìٍàÌü‘8÷€àæØ8æ©6‰©L´«…oãpð„~Çk‰!ñ;‹”ÛžÍ àž±z Ÿôû øŸÝužÏ;ÿ #|u6™Þ¬ÚˆÐõA4¶â|ôl|Ê2ŽÇ¤ÝÅÇY.<#Aí.k§hóF‚”Y; M½Ö4hŸ4&›­¿tès´%FìL¥£Ãk‰ÇT¤haÁ¤ÚxfÉ`ÑìË›>i 3t‚:,–+^÷´–{Û–Nxi"x‘Ûg î¨>¥Õ܁ùZH,2Û“:8xÊ¢Çí9.É-Ìâã-=çjwµS˜dütžçwýGòú®®ûº_ˆýx$–¡ãøO EÚÛÏ÷R„×w+3£Á£öUMyR²¹âŒ°š›¸Ñãò9§Ó_Dl+Ùßc›úšGÅÌc†Ž!Ko=¶.‘Îÿ c²(2®V mª.ÿ ¹B›¹å ù„öŸSV>™ü¯$y:G¢Z×àøúdî¹û­·ýÇ´:•c LÍõi_‹ö+ÎæGÊè>OŠ•äž´§Þ{X}¨1ÚTc›»Qþ•êô°t¿OP?eæ~É{5]•ÙR£r5†nZ\ã@ &îJõ ¾àC°þV>fé¥/ü5ñÊIº_é5 ;e­h<@ Ä&æÃëE%;X,ÒãÆÞ`Oò¦kŸm#˜!ÀyÄ¢| óLšò¥Ä` ¶R=|ÈCâh5ò3DˆïF†ðÒ#ÅìÛœ?¸yhBãœí ZxßÎÄhºRK„`Þödvײ™ÀÈÑÒgŒuY w³%†ƒÓzõ ÖÏp‚dH®¦A´ù§»ÓÇMæ~)ˆð‡û:ù&Ä •vGD´À n ݇¼Ö8Fö óáà£~Ë¥x`oK|Ä?fxiØü%pìR>éò+Û±éÎ>núlFŤ'tq8LZÏvÃ?„¡ß±È⽆¯³íü@x|PöUäèØã¡ð‚ŒAìÏ"vÍwóŸÍ{ ý0.z È•Ö{,N¡£¡ŸKÕÙž>Ýœþ ÍÀ°<×EA!Å‚D™IúOÍ¡>ôG}Â` ÍßkÜL™Ž Þð™ {IøF²¹òQ3&!ÃÂÞz.d&Ï-sH¸,Ôõ˜ŽP€ 77ˆÝ¼ÊëÜw =cÕ Ú,ØÐ5ÎYÐ)ì´öœgŒ[¤ßv㙑8心>h]§µháYš£²ºÑ.{Ï7Sð•?´~×SÃKýJÛ˜ ™Íäiúu<µX¶1õ^kâçIÑ£sZ4h>j*ÔšD:4­¿_ ÷¸ Õxæÿ ¸?Mù _•­ÊÐ ä ÷ý ÑwL œ­ïnTkÛUÍN©ë:¦fV ¶ÜÔÜMªÅâA½–¿R×TXš-%iTÊT•‡Ù‚JôϐZxWÑè‰f‰òG º ×Õû2aZ7OU3[“×AT–ÞŒ…-‘¤”Ì ì&(ˆ¿­•ƒkï’:ðY¦W‘ Å)“†‘˜³Åtcø˜ñTÂwÚÇ4|üLÇªí–v- qˆèU qPE.†â‘˜µ Æ,ÐÅs]8¾„oúÑ i>ÜxxÈó)ƒ ´æÁâØ$À‰vžŸf$Ž |ãw;ÀÁIJ»b` {¦Ó¤Ú$©YÀ‘n@Óïž«9J¼êG m¤ ܯ¹ÌW4€ÐÒÅÛ‡#褕Ÿn-?í|с¥÷Ú¹¬'´ÞÜ9ÓK `hê£SÄSà?7—Wí_´…óB›»:=Ãïq`<8ñÓŒÑlú2d¬ê³£hÖ[l|$vÝro~'R®‰§°ñmY ͧäP |PUª¹·:3Œ[Û{Xÿ ºâ@‚W–Äé u‚ ¯´*=íή.pûÒdt @G‰¬ s¸ ëÉücr ÞæÑ¨Ê@>¤¢Ö±. Þ'¯°ÌME[YéïĵÂCå½ Ué©Áû'Ê9%eÔðNU”ë‘ÌsD3/®+UI˜9h.WC”빓$#:pz:YÓ ¿xž* ³$Í +$kñAŠ‹†¢ Uê>¸)_š¬÷©ßAÂÔb9ÇU ¯¾á•9¯ÏÏ÷O÷¼¼Fähal1‰3Ì[Ïr•´UCksNÐ] R‘¸¥H+§Šé†c©vÖÞ0iÓ76s†î!§=ß ¼~Ô'°Ãmäoäš³ªøi1úÉ)³yV8 CLÄØÁ‘WYïi€H6ÖÑiámø^ÈY´°Ñ7¥Û*—Ñ©L«Qƒï—Ùrÿ ›£Ð*š¸ˆL©ˆ$ˆ ÷¾D§9È®«qbqC)–ˆïv´çñsÑVT­Ø, <àïºÀO«Jý·õ àfPìð .wFšir´þ’2_Y *Æ€x\« ì€9š@ Ž|F⇥ˆkZ@hÖÄ0t¿-<“‹qµ¾*ZL¤Ú)&BJpÓF5=$„at*Zš$’ÑtdûÝRI1 2މ$€$I$#‰SÞ’Hë¬ï;Á$¡t$’`<(ñÇt)$‡Ð.Êf¢X’Kt=Éé$‚ˆªè¢oÝëòI%Rgcª÷ŠyI%¡‰ÿ !ñ)´õ $¤ Ô’IIGÿÙ--- --A very basic IKE library. -- --The current functionality includes: -- -- 1. Generating a Main or Aggressive Mode IKE request packet with a variable amount of transforms and a vpn group. -- 2. Sending a packet -- 3. Receiving the response -- 4. Parsing the response for VIDs -- 5. Searching for the VIDs in 'ike-fingerprints.lua' -- 6. returning a parsed info table -- --This library is meant for extension, which could include: -- -- 1. complete parsing of the response packet (might allow for better fingerprinting) -- 2. adding more options to the request packet -- vendor field (might give better fingerprinting of services, e.g. Checkpoint) -- 3. backoff pattern analyses -- --An a implementation resembling 'ike-scan' could be built. -- --@author Jesper Kueckelhahn --@license Same as Nmap--See https://nmap.org/book/man-legal.html local _G = require "_G" local nmap = require "nmap" local stdnse = require "stdnse" local string = require "string" local table = require "table" local rand = require "rand" _ENV = stdnse.module("ike", stdnse.seeall) local ENC_METHODS = { ["des"] = 0x80010001, ["3des"] = 0x80010005, ["cast"] = 0x80010006, ["aes/128"] = { 0x80010007, 0x800E0080 }, ["aes/192"] = { 0x80010007, 0x800E00C0 }, ["aes/256"] = { 0x80010007, 0x800E0100 }, } local AUTH_TYPES = { ["psk"] = 0x80030001, ["rsa"] = 0x80030003, ["ECDSA"] = 0x80030008, ["Hybrid"] = 0x8003FADD, ["XAUTH"] = 0x8003FDE9, } local HASH_ALGORITHM = { ["md5"] = 0x80020001, ["sha1"] = 0x80020002, ["sha2-256"] = 0x80020004, ["sha2-384"] = 0x80020005, ["sha2-512"] = 0x80020006, } local GROUP_DESCRIPTION = { ["768"] = 0x80040001, ["1024"] = 0x80040002, ["1536"] = 0x80040005, ["2048"] = 0x8004000E, } local EXCHANGE_MODE = { ["Main"] = 0x02, ["Aggressive"] = 0x04, } local PROTOCOL_IDS = { ["tcp"] = 0x06, ["udp"] = 0x11, } -- Response packet types local EXCHANGE_TYPE = { [0x02] = "Main", [0x04] = "Aggressive", [0x05] = "Informational", } -- Payload names local PAYLOADS = { [0x00] = "None", [0x01] = "SA", [0x03] = "Transform", [0x04] = "Key Exchange", [0x05] = "ID", [0x08] = "Hash", [0x0A] = "Nonce", [0x0D] = "VID", } -- Load the fingerprint file -- (located in: nselib/data/ike-fingerprints.lua) -- local function load_fingerprints() local file, filename_full, fingerprints -- Check if fingerprints are cached if(nmap.registry.ike_fingerprints ~= nil) then stdnse.debug1("ike: Loading cached fingerprints") return nmap.registry.ike_fingerprints end -- Try and find the file -- If it isn't in Nmap's directories, take it as a direct path filename_full = nmap.fetchfile('nselib/data/ike-fingerprints.lua') -- Load the file stdnse.debug1("ike: Loading fingerprints: %s", filename_full) local env = setmetatable({fingerprints = {}}, {__index = _G}); file = loadfile(filename_full, "t", env) if( not(file) ) then stdnse.debug1("ike: Couldn't load the file: %s", filename_full) return false, "Couldn't load fingerprint file: " .. filename_full end file() fingerprints = env.fingerprints -- Check there are fingerprints to use if(#fingerprints == 0 ) then return false, "No fingerprints were loaded after processing ".. filename_full end return true, fingerprints end -- Extract Payloads local function extract_payloads(packet) -- packet only contains HDR if #packet < 29 then return {} end local np = packet:byte(17) -- next payload local np_txt = PAYLOADS[np] local index = 29 -- starting point for search local ike_headers = {} -- ike headers -- loop over packet while np_txt and np_txt ~= "None" and index <= #packet do local payload_length, payload np, payload_length, index = string.unpack(">B x I2", packet, index) payload, index = string.unpack("c" .. (payload_length - 4), packet, index) payload = stdnse.tohex(payload) -- debug if np_txt == 'VID' then stdnse.debug2('IKE: Found IKE Header: %s - %s', np_txt, payload) else stdnse.debug2('IKE: Found IKE Header: %s', np_txt) end -- Store payload if ike_headers[np_txt] == nil then ike_headers[np_txt] = {payload} else table.insert(ike_headers[np_txt], payload) end np_txt = PAYLOADS[np] end return ike_headers end -- Search the fingerprint database for matches -- This is a (currently) divided into two parts -- 1) version detection based on single fingerprints -- 2) version detection based on the order of all vendor ids -- -- NOTE: the second step currently only has support for CISCO devices -- -- Input is a table of collected vendor-ids, output is a table -- with fields: -- vendor, version, name, attributes (table), guess (table), os local function lookup(vendor_ids) if vendor_ids == {} or vendor_ids == nil then return {} end -- concat all vids to one string local all_vids = '' for _,vid in pairs(vendor_ids) do all_vids = all_vids .. vid end -- the results local info = { vendor = nil, attribs = {}, } local unmatched = {} local status, fingerprints status, fingerprints = load_fingerprints() if status then -- loop over the vendor_ids returned in ike request for _,vendor_id in pairs(vendor_ids) do -- loop over the fingerprints found in database for _,row in pairs(fingerprints) do if vendor_id:find(row.fingerprint) then -- if a match is found, check if it's a version detection or attribute if row.category == 'vendor' then local debug_string = '' if row.vendor ~= nil then debug_string = debug_string .. row.vendor .. ' ' end if row.version ~= nil then debug_string = debug_string .. row.version end stdnse.debug2("IKE: Fingerprint: %s matches %s", vendor_id, debug_string) -- Only store the first match if info.vendor == nil then -- the fingerprint contains information about the VID info.vendor = row end elseif row.category == 'attribute' then info.attribs[ #info.attribs + 1] = row stdnse.debug2("IKE: Attribute: %s matches %s", vendor_id, row.text) break end else unmatched[#unmatched+1] = vendor_id end end end end if next(unmatched) then info.unknown_ids = unmatched end --------------------------------------------------- -- Search for the order of the vids -- Uses category 'vid_ordering' --- -- search in the 'vid_ordering' category local debug_string = '' for _,row in pairs(fingerprints) do if row.category == 'vid_ordering' and all_vids:find(row.fingerprint) then -- Use ordering information if there where no vendor matches from previous step if info.vendor == nil then info.vendor = row -- Debugging info debug_string = '' if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' ' end if info.vendor.version ~= nil then debug_string = debug_string .. info.vendor.version .. ' ' end if info.vendor.ostype ~= nil then debug_string = debug_string .. info.vendor.ostype end stdnse.debug2('IKE: No vendor match, but ordering match found: %s', debug_string) return info -- Update OS based on ordering elseif info.vendor.vendor == row.vendor then info.vendor.ostype = row.ostype -- Debugging info debug_string = '' if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' to ' end if row.ostype ~= nil then debug_string = debug_string .. row.ostype end stdnse.debug2('IKE: Vendor and ordering match. OS updated: %s', debug_string) return info -- Only print debugging information if conflicting information is detected else -- Debugging info debug_string = '' if info.vendor.vendor ~= nil then debug_string = debug_string .. info.vendor.vendor .. ' vs ' end if row.vendor ~= nil then debug_string = debug_string .. row.vendor end stdnse.debug2('IKE: Found an ordering match, but vendors do not match. %s', debug_string) end end end return info end --- -- Handle a response packet -- -- A very limited response parser. -- Currently only the VIDs are extracted. -- This could be made more advanced to -- allow for fingerprinting via the order -- of the returned headers -- @param packet A received IKE packet -- @return A table of parsed response values function response(packet) local resp = { ["mode"] = "", ["info"] = nil, ['vids']={}, ['success'] = false } if #packet > 19 then -- extract the return type local resp_type = EXCHANGE_TYPE[packet:byte(19)] local ike_headers = {} -- simple check that the type is something other than 'Informational' -- as this type does not include VIDs if resp_type ~= "Informational" then resp["mode"] = resp_type ike_headers = extract_payloads(packet) -- Extract the VIDs resp['vids'] = ike_headers['VID'] -- search for fingerprints resp["info"] = lookup(resp['vids']) -- indicate that a packet 'useful' packet was returned resp['success'] = true end end return resp end --- Send a request and parse the response -- -- Sends an IKE request such as generated by ike.request(), -- binding to the same source port as the destination port. -- @param host Destination host -- @param port Destination port (table) -- @return Parsed IKE response (output of ike.response()) function send_request( host, port, packet ) local socket = nmap.new_socket() -- lock resource (port 500/udp) local mutex = nmap.mutex("ike_port_500"); mutex "lock"; -- send the request packet socket:set_timeout(1000) socket:bind(nil, port.number) socket:connect(host, port, "udp") local s_status = socket:send(packet) -- receive answer if s_status then local r_status, data = socket:receive_bytes(1) if r_status then socket:close() -- release mutex mutex "done"; return response(data) else socket:close() end else socket:close() end -- release mutex mutex "done"; return {} end -- Create the aggressive part of a packet -- Aggressive mode includes the user-id, so the -- length of this has to be taken into account -- local function generate_aggressive(port, protocol, id, diffie) -- get length of key data based on diffie local key_length if diffie == 1 then key_length = 96 elseif diffie == 2 then key_length = 128 elseif diffie == 5 then key_length = 192 end return ( -- Key Exchange string.pack(">Bx I2", 0x0a, -- Next payload (Nonce) key_length + 4) -- Length .. rand.random_string(key_length) -- Random key data -- Nonce .. string.pack(">Bx I2", 0x05, -- Next payload (Identification) 20 + 4) -- Length ..rand.random_string(20) -- Nonce data -- Identification .. string.pack(">Bx I2 BBI2", 0x00, -- Next Payload (None) #id + 4 + 4, -- Payload length 0x03, -- ID Type (USER_FQDN) PROTOCOL_IDS[protocol], -- Protocol ID (UDP) port) -- Port (500) .. id ) end -- Create the transform -- AES encryption needs an extra value to define the key length -- Currently only DES, 3DES and AES encryption is supported -- local function generate_transform(auth, encryption, hash, group, number, total) local key_length, trans_length, aes_enc, sep, enc local next_payload, payload_number -- handle special case of aes if encryption:sub(1,3) == "aes" then trans_length = 0x0028 enc = ENC_METHODS[encryption][1] key_length = ENC_METHODS[encryption][2] else trans_length = 0x0024 enc = ENC_METHODS[encryption] key_length = nil end -- check if there are more transforms if number == total then next_payload = 0x00 -- none else next_payload = 0x03 -- transform end -- set the payload number local trans = string.pack(">Bx I2 BB xx I4I4I4I4", next_payload, -- Next payload trans_length, -- Transform length number, -- Transform number 0x01, -- Transform ID (IKE) enc, -- Encryption algorithm HASH_ALGORITHM[hash], -- Hash algorithm AUTH_TYPES[auth], -- Authentication method GROUP_DESCRIPTION[group] -- Group Description ) if key_length ~= nil then trans = trans .. string.pack(">I4", key_length) -- only set for aes end trans = trans .. string.pack(">I4I8", 0x800b0001, -- Life type (seconds) 0x000c000400007080 -- Life duration (28800) ) return trans end -- Generate multiple transforms -- Input must be a table of complete transforms -- local function generate_transforms(transform_table) local transforms = '' for i,t in pairs(transform_table) do transforms = transforms .. generate_transform(t.auth, t.encryption, t.hash, t.group, i, #transform_table) end return transforms end --- Create a request packet -- -- Support for multiple transforms, which minimizes the -- the amount of traffic/packets needed to be sent -- @param port Associated port number -- @param proto Associated protocol -- @param mode "Aggressive" or "Main" -- @param transforms Table of IKE transforms -- @param diffie DH group number -- @param id Identification data -- @return IKE request datagram function request(port, proto, mode, transforms, diffie, id) local payload_after_sa, str_aggressive, l, l_sa, l_pro local transform_string = generate_transforms(transforms) -- check for aggressive vs Main mode if mode == "Aggressive" then str_aggressive = generate_aggressive(port, proto, id, diffie) payload_after_sa = 0x04 else str_aggressive = "" payload_after_sa = 0x00 end -- calculate lengths l = 48 + transform_string:len() + str_aggressive:len() l_sa = 20 + transform_string:len() l_pro = 8 + transform_string:len() -- Build the packet local packet = rand.random_string(8) -- Initiator cookie .. ("\0"):rep(8) -- Responder cookie .. string.pack(">BBBBI4I4 BxI2I4I4 BxI2BBBB", 0x01, -- Next payload (SA) 0x10, -- Version EXCHANGE_MODE[mode], -- Exchange type 0x00, -- Flags 0x00000000, -- Message id l, -- packet length -- Security Association payload_after_sa, -- Next payload (Key exchange, if aggressive mode) l_sa, -- Length 0x00000001, -- IPSEC 0x00000001, -- Situation --## Proposal 0x00, -- Next payload (None) l_pro, -- Payload length 0x01, -- Proposal number 0x01, -- Protocol ID (ISAKMP) 0x00, -- SPI Size #transforms -- Proposal transforms ) packet = packet .. transform_string -- transform if mode == 'Aggressive' then packet = packet .. str_aggressive end return packet end return _ENV