I had some fun with a router
+cleartext passwords + external management = death wish
+diff --git a/_posts/2019-06-27-PWNlink.md b/_posts/2019-06-27-PWNlink.md new file mode 100644 index 0000000..27689fd --- /dev/null +++ b/_posts/2019-06-27-PWNlink.md @@ -0,0 +1,45 @@ +--- +layout: post +title: "I had some fun with a router" +description: "cleartext passwords + external management = death wish" +date: 2019-06-27 17:16:00 +categories: random +--- + +I was playing around with some D-link routers today and remembered an [ExploitDB Entry](https://www.exploit-db.com/exploits/33520) I read a while ago. Many D-link routers have a great feature that allows remote management and configuration queries. Interestingly, this cannot be disabled, and one of the pages contains a cleartext version of the admin password (yay!). + +## How to get yourself an admin password +On any supported router, make an HTTP request to `http://your.router.ip.addr/tools_admin.asp/`. This will return a pretty large XML file containing information about your router's hardware and configuration. + +Notice the fact that you did not have to log in. This is due to the fact that this file seems to be used by a remote management service of some sort. + +The important thing to note here is that, when parsed with the regex pattern: `name="user_password_tmp" value="(.*)">`, you get a single string. This string is the admin password of the device. + +## Supported routers +This is supported by many D-link routers. The ones I know about are: + - DIR-835 + - DIR-855L + - DGL-5500 + +Some routers have this XML file, but it is restricted... By a user without a password. These are: + - DHP-1565 + - DIR-652 + +## PWNlink +Like everything I play with, I made a script to do this all for me (and spent a large amount of time adding colours to the text). + +My script is called PWNlink (PWN + D-link), It automatically finds a router on your network by looking for a specific DNS entry created by many D-link routers, then checking your gateway. Next, PWNlink reads you router's `hnap1` config to find it's model number. If supported, the script will read and parse the appropriate configs to give you the admin credentials for your router. + +PWNlink can be installed on any *nix computer that has both `python3.7` and `python3-pip` installed. To install PWNlink, run: +``` +pip3 install pwnlink +``` + +Run the script without any arguments for automatic detection, or pass any IP address to use manual detection. + +## Disclamier thingy +I don't see much point to these, but I should probably put one anyways. + +**Don't be dumb with this script.** + +I have only used it on my own (or 5024's) routers, and did not create PWNlink with any malicious intent. \ No newline at end of file diff --git a/_site/all_posts.html b/_site/all_posts.html index 835df6c..ef09a58 100644 --- a/_site/all_posts.html +++ b/_site/all_posts.html @@ -81,6 +81,177 @@
cleartext passwords + external management = death wish
+Python is a little too forgiving
+I was playing around with some D-link routers today and remembered an ExploitDB Entry I read a while ago. Many D-link routers have a great feature that allows remote management and configuration queries. Interestingly, this cannot be disabled, and one of the pages contains a cleartext version of the admin password (yay!).
+ +On any supported router, make an HTTP request to http://your.router.ip.addr/tools_admin.asp/
. This will return a pretty large XML file containing information about your router’s hardware and configuration.
Notice the fact that you did not have to log in. This is due to the fact that this file seems to be used by a remote management service of some sort.
+ +The important thing to note here is that, when parsed with the regex pattern: name="user_password_tmp" value="(.*)">
, you get a single string. This string is the admin password of the device.
This is supported by many D-link routers. The ones I know about are:
+Some routers have this XML file, but it is restricted… By a user without a password. These are:
+Like everything I play with, I made a script to do this all for me (and spent a large amount of time adding colours to the text).
+ +My script is called PWNlink (PWN + D-link), It automatically finds a router on your network by looking for a specific DNS entry created by many D-link routers, then checking your gateway. Next, PWNlink reads you router’s hnap1
config to find it’s model number. If supported, the script will read and parse the appropriate configs to give you the admin credentials for your router.
PWNlink can be installed on any *nix computer that has both python3.7
and python3-pip
installed. To install PWNlink, run:
pip3 install pwnlink
+
Run the script without any arguments for automatic detection, or pass any IP address to use manual detection.
+ +I don’t see much point to these, but I should probably put one anyways.
+ +Don’t be dumb with this script.
+ +I have only used it on my own (or 5024’s) routers, and did not create PWNlink with any malicious intent.
+ +A rather large number of people know me as “the guy who does weird things with python”. I would object to this title, but it is quite accurate. So, here are some of the things I like playing with in python. None of these are actually breaking the language, just little known facts and syntax. At some point I will share about actually breaking the language. For now, enjoy the weird things I have found over the past 6 years.
+ +A little known feature of python is called “type hinting” (PEP 484). This is actually quite common to see in standard libraries, and has it’s own special syntax:
+# Here is a regular function
+def meep(a, b):
+ return a*b^2
+
+# This function has no real reason to exsist, and is lacking any sort of documentation.
+# Let's add a docstring to explain what it does
+
+def meep(a, b):
+ """ This function returns the result of a times b squared """
+ return a*b^2
+
+# Ok. The docstring explains the function, but is not too helpful
+# what are a and b? what does this return?
+# For all we know, a could actually be a string (in which case, this function would return a string)
+# Let's fix that up with a type hint
+
+def meep(a: int, b: int):
+ """ This function returns the result of a times b squared """
+ return a*b^2
+
+# Thanks to the :int (called a type hint in case you didn't notice that yet), we now know that this function expects two ints.
+# Now, to finish this up with a secondary type hint to specify the return type
+def meep(a: int, b: int) -> int:
+ """ This function returns the result of a times b squared """
+ return a*b^2
+
+# There. Now we can clearly see that this function takes too ints, and returns one int.
+# If only this was a requirement in the language. So many headaches could be solved.
+
Now, keep in mind that this is called a type hint. The python compiler (yes.. Give me a second for that one) does not actually care if you obey the hint or not. Feel free to send incorrect data into a hinted function and see what you can break. Critical functions should both hint and check the data types being provided.
+ +Just like type hints for functions, python has hints for variables too.
+# A regular variable. Must be declared with an initial value
+my_state = None
+
+# my_state is None, as it has not been set, but needs to exist.
+# Let's assume that my_state is to be a state:
+class State:
+ status = False
+ def toggle(self):
+ self.status != self.status
+
+# Finally, its time to set the state to something useful
+my_state = State()
+my_state.toggle()
+
+# Ok.. I hate this. Let's start by using type declarations first
+# Any variable can be un-initialized and just have a type. Like so:
+my_state: State
+
+# This works for anything
+is_alive: bool
+age: int
+name: str
+
+# Now, with this new knowledge, let's rewrite State
+class State:
+ status: bool
+ def toggle(self: State) -> None:
+ self.status != self.status
+
+# And initialize my_state with slightly different syntax
+my_state = State(status=True)
+
I have not found much use for this yet. Hopefully there is something cool to use it for.
+ +This is more common knowlage. A function can be declared in one line
+# Here is an adder function
+def adder1(a:int, b:int) -> int:
+ return a+b
+
+# Here is a one-line adder function
+adder2 = lambda a,b : a+b
+
+# State from above can be compacted further:
+class State:
+ status: bool
+ toggle = lambda self: self.status != self.status
+
On the trend of one-line code, We have the one-line if/else, also known as a Ternary in more sensible languages.
+# Here is an if/else
+if 100 is 5:
+ print("The world has ended")
+else:
+ print("All is good")
+
+# Here is a smaller if/else
+print("The world has ended" if 100 is 5 else "All is good")
+
This one is interesting. Python, like Java, is compiled into bytecode. So yes, it technically is a compiled language. To see said bytecode, take a look at any .pyc
file sitting in your __pycache__
I am still playing with post formats, and various types of content. This is more random than I usually prefer. Let me know your thoughts on the social media platform of your choosing.
+ +