From 196cf331a8e1cc94ceba064f5ff0b13785153669 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 2 Jan 2025 07:54:37 +0100 Subject: [PATCH] reworking in progress --- README.md | 2 +- scripts/darknet_exploration.py | 146 ++++++++++++++++++ .../banner.png | Bin 0 -> 14119 bytes .../blacklist.csv | 2 + .../sensitive.csv | 5 + .../unverified.csv | 4 + .../verified.csv | 5 + .../webring-participants.csv | 2 + 8 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 scripts/darknet_exploration.py create mode 100644 www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/banner.png create mode 100644 www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/blacklist.csv create mode 100644 www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/sensitive.csv create mode 100644 www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/unverified.csv create mode 100644 www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/verified.csv create mode 100644 www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/webring-participants.csv diff --git a/README.md b/README.md index f6d3bf3..0ce13ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [Darknet Onion Webring](http://uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/) +# [Darknet Onion Webring (WIP)](http://uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/) ![logo](./www/img/onion.png) diff --git a/scripts/darknet_exploration.py b/scripts/darknet_exploration.py new file mode 100644 index 0000000..a2232c3 --- /dev/null +++ b/scripts/darknet_exploration.py @@ -0,0 +1,146 @@ +import os, pwd +def main(): + + rootpath='/srv/darknet-onion-webring/' + homepath=pwd.getpwuid(os.getuid()).pw_dir + urlpath=homepath+'/.darknet_participant_url' + print(urlpath) + isitvalid="n" + + #check if ~/.darknet_participant_url exists, + # if exists, instance= the content of ~/.darknet_participant_url (which is the url: such as uptime.nowherejez...onion) + + while isitvalid != "y": + if os.path.isfile(urlpath): + with open(urlpath) as f: + instance = f.read() + # TODO check if the instance URL domain is valid + + print("[+] file exists, your Webring URL is ", instance) + isitvalid = "y" + else: + print("[+] Instance Path doesn't exist yet") + # and ask for the instance URL domain + instance = input("What is your Instance domain ? (ex: uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion):") + instancepath=rootpath+'www/participants/'+instance + # TODO check if the instance URL domain is valid + + # ask the user if the instance URL is valid ? + print() + print(instance) + isitvalid=input("Is your this your instance domain ?") + # if yes, then write it into ~/.darknet_participant_url + if isitvalid != "y" : + print("OK writing the instance url to ~/.darknet_participants_url") + with open(urlpath, 'w') as file: + file.write(instance) + + print("[+] Welcome to the Darknet Onion Webring, where you are exploring the Darknet and helping others do the same.") + print(""" + 1) add a new entry (into unverified.csv) + 2) verify an entry (move an entry from unverified to verified.csv) + 3) add a new webring participant (and download their files into their directory (without trusting them yet!)) + 4) trust a webring participant (Potentially dangerous) + """) + option = input("Select Option? (1-4)") + print(option) + match option: + case "0": + print("[+] Initial Setup") + # what is your instance url ? ex: uptime.nowherejez...onion + instance = input("What is your Instance domain ? (ex: uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion):") + # check that it is only url.onion or subdomain.url.onion, and if the characters are only [a-zA-Z0-9.], use the function IsOnionDomainValid() + instancepath='/srv/darknet-onion-webring/www/participants/'+instance + print(instancepath) + # check if the directory already exists or not in www/participants/nowherejez...onion + if os.path.isdir(instancepath): + print("[+] Instance Path already exists, skipping.") + else: + print("[-] path doesnt exist") + # if doesnt exist, create it, copy the default anonymous instance banner in there. + # copy the blank verified.csv unverified.csv sensitive.csv blacklist.csv and webring-participants.csv files in the new directory + # print message to explain what's next: you have a new instance, it's now time to list your own links, and to browse other participant's links + + case "1": + print("[+] Add a new Entry (into unverified.csv)") + # ask for the following: + # the name of the website (required) + # the url of the website (required) + # a quick description (optional) + # sensitive ? (y/n) + # (rest is automatic: status, score, instance is = '' because it is your own instance) + # check if the entry doesn't already exist in verified.csv and in unverified.csv + # if it doesnt exist, add it into unverified.csv + + case "2": + print("[+] Verify an entry (move an entry from unverified.csv to verified.csv)") + # search for a word + # and display only the matching entries in an array format (display it in CLI). + # Each of the rows must have an index, + # prompt the user to ask for with row they want to move to verified.csv + # once selected, it must be able to print that row, and: + # append it into verified.csv + # remove it from unverified.csv + # print completed! You are now listing [name] (url) (sensitive). + + case "3": + print("[+] add a new webring participant (and download their files into their directory (without trusting them yet!))") + # ask for the url to the other webring participant + # check if the url is valid or not: at http://URL.onion/participants/URL.onion/{verified.csv,unverified.csv,sensitive.csv,blacklist.csv,webring-participants.csv} + + case "4": + print("[+] trust a webring participant (Potentially dangerous)") + # list the existing webring participants from webring-participants.csv and + # ask the user to pick the index (0-9?) of the instance to trust + # if index is valid, then mark the instance as trusted in webring-participants.csv + + case _: + print("[-] ERROR, incorrect input") + + +def IsOnionValid(domain): + # check if the characters are only [a-zA-Z0-9.] with maximum 128 chars max? + # check that it is only url.onion or subdomain.url.onion, + # if OK return True + #if not : return False + return True + +def IsUrlValid(url): + # check if the characters are only [a-zA-Z0-9.:/] with maximum 128 chars max? + # check that it is only http(s)://wordA.wordB or http(s)://WordC.WordB.WordC, (onion or not), clearnet is fine too (double check if those are fine!) + # if OK return True + #if not : return False + return True + +def IsStatusValid(status): + # check if the characters are only [vx] with maximum 1 chars max + # if OK return True + #if not : return False + return True + +def IsDescriptionValid(desc): + # check if the characters are only [a-zA-Z0-9.,' ] with maximum 256 chars max + #(careful with the ' and , make sure you test if it fucks the csv up or else) + # if OK return True + #if not : return False + return True + +def IsCategoryValid(category): + # check if the characters are only [a-zA-Z0-9 ] with maximum 64 chars max + #(careful with the ' and , make sure you test if it fucks the csv up or else) + # if OK return True + #if not : return False + return True + +def IsNameValid(name): + # check if the characters are only [a-zA-Z0-9 ] with maximum 64 chars max + #(careful with the ' and , make sure you test if it fucks the csv up or else) + # if OK return True + #if not : return False + return True + + + + +if __name__ == '__main__': + main() diff --git a/www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/banner.png b/www/participants/uptime.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..8e7af7380ab4bf22a26251b78949ea8efe89c0a6 GIT binary patch literal 14119 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 ZTzN}Ry>fC