Jump to content

AlfAlfa

Active Members
  • Posts

    70
  • Joined

  • Last visited

Everything posted by AlfAlfa

  1. Send it over SSL wrapped email, and / or send a password reset link rather than just the password. (although someone who receives either could still use both reset types to gain access, so make the password reset step mandatory and they should also be required to enter some information that only they would know!) This way even if someone that shouldn't gets a hold of the password reset link or temporary password, they still would have to know a secret piece of information that doesn't get sent and that they won't be able to figure out or guess.
  2. You can just secure it with a WPA passphrase, rather than just having the network open. I do this with my PC, perhaps check my signature for the link to "Hosting you're own access point to share from one interface to another". Just adapt it for the pineapple, pretty similar it is. Aside from that, you just made me think of a really cool idea and I'm going to see how quickly I can create it! Another way I just thought of
  3. Just as an update, I had to get caught up in my other work, but I finally got uploadwpa2 into a state that it has been much improved and is a worthy update! Also something looks different about this module, dependency? The main difference is adding SSL support, but also switching from hard coded specialized functions which would have to be coded for each site and re-done if the site changed, to a json config file with the default config stored at ~/.uploadwpa2/sites.cfg It's a pretty simple format, and should be able to be configured for most sites except that require a logged in session or captcha. (maybe future features) So with the standard openwrt sdk now I'm fairly sure I got the packaging right this time, so check the package out or it can be just built from source again. additional dependencies: +libopenssl +libcrypto makefile has been updated. "I cant put enough emphasis on this, this is not an official package provided from the hak5 team, and there for is NOT supported by them. Until if and or when they add it into their official repos, and you download it from their official repos, this is all installed at YOUR OWN RISK. so using this provided ipk, do not go to the hak5 team for support for which are not officially provided by them. i also hold no responsibility for any damage or for your usage that may occur, i can provide the sources and installable ipk, and can give you my word that their is no malicious code added to this ipk, it is clean and has no infection. it is your choice and responsibility if you want to use them or not." You've been warned, now here is the goods :) --------------------------------------------------------------------------------------------------------------- IPK: http://www.filedropper.com/uploadwpa21ar71xx http://www.speedyshare.com/jwNNd/uploadwpa2-1-ar71xx.ipk Source: https://github.com/Alf-Alfa/uploadwpa EDIT: I've just realized I completely overlooked the javascript and php side of things, I'll have to flesh it out with support for the newer features. Like being able to give it more than 10 hashes at a time (you just configure how many hashes it accepts per post) and it sends out as many post requests as necessary to complete the job. (example of one new feature)
  4. Well actually, 'wlan0mon IEEE 802.11bgn Mode:Managed' doesn't look right. It should be Mode: Monitor no? When in that state try: 'iwconfig wlan0mon mode monitor' Then iwconfig again, and see if it's in monitor, or if it is and it changes back after a short while, then something is manipulating it still. As for getting stuck at the M2 message, I forgot whether it was -N (no nacks) or -n (always target ap nacks) that helped for getting passed that so try either one of those separately and see if it helps. Your device has to stay in monitor mode though or it's going to screw up. Also you should make sure you're using the latest reaver, and latest pixiewps for best results: https://github.com/t6x/reaver-wps-fork-t6x&& https://github.com/wiire/pixiewps Note: you'll have to build them manually if your package manager isn't holding an updated package, which is likely the case.
  5. I know sftp is kind of similar to scp but not exactly so what about scp?, did you try scp when you said 'webinterface or sftp etc'? I wonder if that will work: scp root@172.42.16.1:/root/caps/largecap.pcap ~/caps/largecap.pcap Excuse my post if you've already tried it, but you weren't clear on that. Maybe when downloading it uses up all or too much memory and that causes something vital to crash creating the issue you find... That's just a guess though because it's hard to see what's going on from your log files (as it looks almost like it was unplugged and re-plugged). Which is the first line that the transfer stops '[ 459.450000] usb 1-1.2: USB disconnect, device number 6' that one?
  6. It doesn't for you? In my example above it did, I only did that to show that only that one byte out of the 4 bytes actually are changed. Typing two bytes would change the first 2 bytes of the four byte (32 bit) instruction, typing 3 changes the first 3 bytes, and typing 4 changes all four bytes of the one instruction. I think it'll do that no matter how many bytes you type it'll overwrite starting from the address you're at with however many bytes you typed after wx. If you look closely it goes from 10 40 00 26 to 14 40 00 26 -> 10 40 00 26 -> 14 40 00 26 All instructions for this architecture are 32-bit (4 bytes) in length, so it only really make sense to edit multiples of 4 bytes at a time unless the last instruction in the sequence of instructions you're modifying is just the first byte or just the first two or just the first three. Like in this case, the first instruction to be modified is also the last and only the first byte needs to be changed. EDIT: As for the hex editor method of patching, yes it isn't disassembling it's just showing the raw bytes of the file. The addresses also aren't different they are just based from 0 rather than 0x400000. In this image here you can see the ELF magic number header at offset 0 in the file, but at virtual address 0x400000 in radare2: And at offset 0x1fcc in the hex editor is virtual address 0x401fcc in radare2: (it's hard to see where the cursor is, but on the line with offset 0x1fb8 the cursor is grey before an 0x14 byte and the next line offset 0x1fd4 can be seen as 0x401fd4 immediately following the two lines highlighted in radare2) When looking at a file everything starts from 0 since that makes sense for files, the hex editor doesn't know it's a binary file or what kind of file it is at all it's just showing what the file is made of. In radare2 it knows it's a binary file so it also knows what the image base is (usually 0x400000) and uses that as the where to base everything from, since if you were looking at the memory of the application while it was running that is what addresses you would use and be looking at! The image base can be configured to be something else besides 0x400000, or it can even be randomized. (something like ASLR [address space layout randomization]) Most of the time though it is the default of 0x400000. That should clear it up... The hashes may not have to do with the admin console, but you said some places or files on the filesystem weren't accessible from root, maybe the tw user does have access to them, and that might be what they're using to store the admin control panel password which makes it inaccessible to the 'root' user. It could be possible that root isn't actually root, and tw is actually root or at least higher privileged than the 'root' user. If you 'ls -lah' what kind of files are owned by 'tw' and which are owned by 'root'
  7. WOOT WO0T! Awesome! So you've got it going! I'll just get the standard OpenWrt SDK then, the issue lies somewhere in the sdk i've downloaded which is more specific to the mk5. At least now I can see that it works! (I've removed that wrong ipk so there'll be no confusion as you've asked) Version 2.0 is almost complete, it also links to libopenssl and libcrypto and I've gotten it to compile even with my broken sdk, (except openssl didn't have the version it was requesting anymore and had to source it from somewhere else (1.0.1e)) Perhaps the standard OpenWrt sdk will have a newer version anyway (like 1.0.2)!
  8. Thank you again, I really do appreciate you trying to help me! I think the problem is I shouldn't of used that outside of the httpclient that's the only place I used it outside of it. replace line 43 in uploadwpa.cpp: if(!file) { http->Log("ERROR Cannot open file"); return false; }With:if(!file) { std::cout << "ERROR Cannot open file"; return false; }And if you have a version of HTTPClient.hpp that doesn't have these headers add them to the top as well: #include <stdio.h> #include <cstdlib> When I was compiling I had to add those, as the reduced version of the standard library doesn't automatically include them with iostream like the normal desktop verison does...You still didn't say what you're using though for your compiling, is it that much of a secret? lol
  9. Thanks for checking it out, as for the Tetra not being a mips I guess I read that wrong he said a newer RISC architecture but that didn't mean it's not mips just a newer better mips arch... As for it failing to extract the control file, I think there's something wrong with the way it's packaging it since the file is actually in there if I do this I can extract it manually: Alf@UNKNOWN:~/Downloads/uploadwpa-ipk$ tar xzvf uploadwpa_1_ar71xx.ipk ./debian-binary ./data.tar.gz ./control.tar.gz Alf@UNKNOWN:~/Downloads/uploadwpa-ipk$ tar xzvf control.tar.gz ./ ./control Alf@UNKNOWN:~/Downloads/uploadwpa-ipk$ tar xzvf data.tar.gz ./ ./bin/ ./bin/uploadwpa Alf@UNKNOWN:~/Downloads/uploadwpa-ipk$ ls bin/ uploadwpa Alf@UNKNOWN:~/Downloads/uploadwpa-ipk$ The control file itself contains: Package: uploadwpa Version: 1 Depends: libc, libstdcpp Provides: Source: package/uploadwpa Section: utils Status: unknown ok not-installed Essential: no Priority: optional Maintainer: OpenWrt Developers Team <openwrt-devel@openwrt.org> Architecture: ar71xx Installed-Size: 8198 Description: Uploads a WPA handshake to various online crackers! And the binary itself is mips so it wont execute on my x86_64 (didn't even try, just looked at it with readelf) I think I see the problem, when I open the individual control.tar.gz and data.tar.gz with a visual extractor I see: and inside the . folder is the control file! Unless that's how it's supposed to be, then that appears to be the problem. What could be wrong with my configuration that it creates that extra "." (dot) folder and that's why it isn't finding it. Downloaded another ipk for something else extracted it and it has the same thing, so that .(dot) folder actually does appear to be normal so that's not the problem! Looking more closely at the information you gave me though I think I see the actual problem. I'm using the older MK5 toolchain aren't I, and that isn't going to work for the nano and Tetra is it!? AR71XX is not AR93XX!! Or is it? Because it says when I enter the menuconfig with "make menuconfig" and select the first option 'Target System' I get: ───────────────────────── Target System ───────────────────────────┐ │ Use the arrow keys to navigate this window or press the hotkey of │ │ the item you wish to select followed by the <SPACE BAR>. Press │ │ <?> for additional information about this option. │ │ ┌───────────────────^(-)─────────────────────────────────────────┐ │ │ │ ( ) ARM Ltd. Realview board (qemu) │ │ │ │ ( ) Atheros AR231x/AR5312 │ │ │ │ (X) Atheros AR7xxx/AR9xxx │ │ │ │ ( ) Atmel AT91 │ │ │ │ ( ) Atmel AVR32 │ │ │ │ ( ) Broadcom BCM2708/BCM2835 I do have that option selected as well. Should a ar93xx*.ipk be generated or do the packages called ar71xx*.ipk fit under the same umbrella and are combined supported for both? So I'm confused, will the MK5 toolchain work, or do I need the newer one! You said you've got the environment set up, I bet you're not using the MK5 toolchain! I'll keep it in case I want to make my work backwards compatible for it, but I really should have the newer toolchain! I don't really need the firmware unless that's required since I'm not intending on extending the firmware or making anything 'baked into' the firmware, but just a way to produce a binary with a proper magic number. When looking at a valid binary what does the magic number look like? Is it different than: Magic: 7f 45 4c 46 01 02 01 00 01 00 00 00 00 00 00 00 ? CONFIG_TARGET_ar71xx: │ │ │ │ Build firmware images for Atheros AR7xxx/AR9xxx based boards. │ │ │ │ │ │ Symbol: TARGET_ar71xx [=y] │ │ Prompt: Atheros AR7xxx/AR9xxx │ │ Defined at tmp/.config-target.in:59 │ │ Depends on: <choice> │ │ Location: │ │ -> Target System (<choice> [=y]) │ │ Selects: HAS_SUBTARGETS [=y] && mips [=y]
  10. I was actually using just any old hex editor (in my case 'Bless') to do the patching, however yes you can actually use radare2 for that as well. Here's an example of using it to do that branch instruction patch. The first byte from 0x10 to 0x14 is what flips a beqz to a bnez For moving to addresses with 's' you have to add the 0x in front for hexadecimal, but when patching with wx [sequence of bytes] you don't put the 0x in front is what I've figured out... You also need to re-open the file as read-write as it opens it as read only at first, type "oo+" to do that. Alf@UNKNOWN:~/Downloads/PenTest$ cp webproc webproc-mypatch1 Alf@UNKNOWN:~/Downloads/PenTest$ radare2 -e -b 32 -a mips webproc-mypatch1 Warning: read (strtab) at 0x20 Warning: Cannot initialize strings table [0x00401b70]> oo+ File webproc-mypatch1 reopened in read-write mode [0x00401b70]> s 0x401fcc [0x00401fcc]> pd 1 ,=< 0x00401fcc 10400026 beqz v0, 0x00402068 [0x00401fcc]> wx 14400026 [0x00401fcc]> pd 1 ,=< 0x00401fcc 14400026 bnez v0, 0x00402068 [0x00401fcc]> wx 10 [0x00401fcc]> pd 1 ,=< 0x00401fcc 10400026 beqz v0, 0x00402068 [0x00401fcc]> wx 14 [0x00401fcc]> pd 1 ,=< 0x00401fcc 14400026 bnez v0, 0x00402068 [0x00401fcc]> exit As for assembling to actually know what the bytes are to write using 'wx' with the above method you can use rasm2 like this... I think it's important to differentiate between radare2 and rasm2 though, rasm2 assembles and radare2 disassembles. Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips "addiu v0, zero, zero" 24020000 Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips "jr ra" 03e00008 The first one 'addiu v0, zero, zero' is really the same as 'li v0, 0' This is because radare2 and most disassemblers use a pseudo syntax (as described here: http://www.howardhuang.us/teaching/cs232/03-More-MIPS-instructions.pdf)for cleaner looking code, but it really is the same as what the actual code is. If you instead put bytes into rasm2 instead of an instruction in quotes it'll do the reverse: (so I guess technically it does disassemble too, but a byte sequence rather than an entire binary file) Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -d 24020000 li v0, 0 Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -d 03e00008 jr ra Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -d 2402000003e00008 li v0, 0 jr ra I did however have trouble getting rasm2 to assemble any branch instructions with the instruction in quotes form: Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "beq v0, zero, 0x402068" Cannot assemble 'beq v0, zero, 0x402068' at line 3 invalid Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "bne v0, zero, 0x402068" Cannot assemble 'bne v0, zero, 0x402068' at line 3 invalid Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "bne v0, zero, 0x26" Cannot assemble 'bne v0, zero, 0x26' at line 3 invalid Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "bne v0, zero, +0x26" Cannot assemble 'bne v0, zero, +0x26' at line 3 invalid Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "bne v0, zero, 26" Cannot assemble 'bne v0, zero, 26' at line 3 invalid Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "bne v0, zero, 402068" Cannot assemble 'bne v0, zero, 402068' at line 3 invalid Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc "bne v0, 0, 402068" Cannot assemble 'bne v0, 0, 402068' at line 3 invalid There should be and probably is a way to get them to assemble properly, I'm just not sure how it wants me to type it for it to like it. You can however like described above do it the other way, give it bytes and it'll show you what it will produce :) So I used an online mips assembler here to know what bytes I should use: http://alanhogan.com/asu/assembler.php You can enter some test code like this: and then you generate the assembled code at the bottom, then on the second similar page you copy the blue colored output into it, and select verbose/debug + submit and you can see what it would do As you can see from part of the verbose output: Loading 0x00400044 : 1440fff0 ; <input:52> bne $v0, $zero, VZeroIsNotZero #branch if v0 does not equal 0 NOT branching [bne], because 0 does equal 0 Loading 0x00400048 : 1040ffef ; <input:54> beq $v0, $zero, VZeroIsZero #branch if v0 is 0 Branching [beq], because 0 does equal 0 1440fff0 -> 14 40 ff f0 1040ffef -> 10 40 ff ef The difference in the first two bytes is only the first one, from 0x14 (bnez) to 0x10 (beqz) The second byte I believe is the register, so if v0 was v1 or a2 or whatever that byte would be different. The last two bytes are the relative offset where the branch is going to actually jump to! So knowing that we can assemble our new branch instruction: Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc -d 10400026 beqz v0, 0x00402068 Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0x401fcc -d 14400026 bnez v0, 0x00402068 Notice I add the -o parameter with the address the branch is being taken from, this is important at showing the right result, as like I said above branching is relative so based on the address you branch from + the offset is where it will go to. So for example if you didn't provide the address with the offset, it'll be the same as using offset 0: Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -d 14400026 bnez v0, 0x0000009c Alf@UNKNOWN:~/Downloads/PenTest$ rasm2 -e -b 32 -a mips -o 0 -d 14400026 bnez v0, 0x0000009c It'll still be the right code at the proper location that you place it (since branching is relative to that location), but using the offset here will show you that it's going to be correct! There we are, that should do it for now. I'm going to see if any of my old routers can be OpenWrt'd or at least if there's a telnet available or way to access the filesystem like yours so I could experiment with my own router as well, though last time I checked for OpenWrt support the site said it was possible but limited space and memory made it difficult, I wonder if there's been any progress made! As for the hashes, ah I see you used johnny to help you with them! So is it the right place or not? So what kind of hash is it? Just curious about that. ~Alf
  11. Well I've done it, at least for the nano I believe so: Does this look good? (Yes certainly, you can take a look and see if I did it correctly and test it for me, compiling it yourself, then let me know how I can do the same for the Tetra!) Look I don't want you to have to do everything for me, see I'm putting the effort in here! I should add: Thank you ahead of time. Alf@UNKNOWN:~/pineapple-builder/MK5/package/uploadwpa/package/bin$ readelf -a -d uploadwpa ELF Header: Magic: 7f 45 4c 46 01 02 01 00 01 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, big endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 1 Type: EXEC (Executable file) Machine: MIPS R3000 Version: 0x1 Entry point address: 0x401770 Start of program headers: 52 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x70001005, noreorder, cpic, o32, mips32r2 Since the MK5 and nano have a similar mips architecture is that correct? The Tetra on the other hand is different... Where can I download the firmware and cross compiler toolkit for it? See now this wasn't so hard was it, my github has been updated but the ipk isn't there just the updated source with the new makefiles and instructions on what I did to compile it. I did successfully generate an ipk though and extracted it and checked the binary to confirm it is in fact compiled for mips! As DataHead posted It previously when he's done this, I have to post this here too: I cant put enough emphasis on this, this is not an official package provided from the hak5 team, and there for is NOT supported by them. Until if and or when they add them into their official repos, and you download it from their official repos, this is all installed at YOUR OWN RISK. so using this provided ipk, do not go to the hak5 team for support for which are not officially provided by them. i also hold no responsibility for any damage or for your usage that may occur, i can provide the sources and installable ipk, and can give you my word that their is no malicious code added to these ipk, they are clean and no infection. it is your choice and responsibility if you want to use them or not. You've been warned, now here is the goods :) ------------------------------------------------------------ the main github has been updated to reflect successful compilation in a openwrt environment, if you would like to compile it yourself -> https://github.com/Alf-Alfa/uploadwpa [iPK link will be placed here shortly] Once copied to to your MK5 or nano: opkg install uploadwpa-1-ar71xx.ipk Then if nano you can also copy the 'UploadWPA' to /pineapple/modules for the GUI Otherwise you must use it from the command line once you have a terminal to your pineapple! Tetra version coming soon, as soon as I get the proper environment setup to cross compile for RISC.
  12. Well that just means I still haven't made it to pineapple module status yet ;)! I really thought you were going to help get my code compiled for the pineapple archs, but I guess you aren't proficient in native code cross compiling or just didn't want to accept a payment for just compiling someone else's module so you re-built it entirely yourself so you felt more like you earned it. That's understandable, however I'm going to do it bigger and better and enough work that you won't want to rebuild it entirely again this time! :) I'll let you have the capturing handshakes module though how about that! I'm also working on a completely different idea for a module that I don't want to let on to yet. I'll have to figure out how to cross compile though myself it seems... I'm just not sure if I need to link to libstdcpp or uclibcxx and which sdk to use is it Kamikaze or White Russian? Or a more pineapple specific sdk for cross compilation? this program uses strings and iostreams which are a feature of the C++ standard template library (STL). However, because memory is so critical in an embedded application like OpenWrt, the standard template library is not available by default. What needs to be done to fix the problem depends on which version of OpenWrt you are running. If you are running Kamikaze, the problem is much easier to fix than if you are running White Russian. If you are running Kamikaze, you only need to install the libstdcpp library. If you are running White Russian, as I am, you must install the uclibcxx library, as well as make certain changes to the Makefiles to use this library, which is a special implementation of the standard library for embedded devices I'll figure it out, I'm confident of that :) EDIT: Found this great post here by Darren https://forums.hak5.org/index.php?/topic/36422-cross-compile-c-code-to-mips/?hl=%2Bcross+%2BcompileThe thread starter was wanting to cross compile for the turtle, but this should get me set up so I can cross compile for the pineapple as well and there is a pineapple specific guide (though for the MK5) All I should need to do though is use the RISC and MIPS arch of the newer pineapples and it'll help me out to get there! Thanks Darren for that post, this should keep me busy for a while. Turns out it's libstdcpp selected Y to that on the configuration and I'm now building the MK5 firmware and toolkit with it: Almost there!
  13. @WIFIJuice: I think he meant to try specify eth1 / eth0... Do you mean it still wants a wlanX interface even when you do so? # wifite -i eth1 .;' `;, .;' ,;' `;, `;, WiFite v2 (r87) .;' ,;' ,;' `;, `;, `;, :: :: : ( ) : :: :: automated wireless auditor ':. ':. ':. /_\ ,:' ,:' ,:' ':. ':. /___\ ,:' ,:' designed for Linux ':. /_____\ ,:' / \ [+] set interface: eth1 [+] scanning for wireless devices... [!] could not find wireless interface "eth1" [+] quitting Mine says I can't find eth1 since I dont have that interface but if your eth1 is really a wireless interface I think it should work. I also like to use it with --wps and/or --pixie and/or --wpa switches to focus on wps / wps pixie / wpa handshakes or any combination of the three when I do actually use this tool, but I prefer to use the individual tools manually, like reaver for wps and wps pixie, and airdoump-ng for capturing handshakes! wifite -i eth1 --pixie --wpa (favorite combo) :)
  14. For this reason, Leonardo Nve Egea presented sslstrip+ ( or sslstrip2 ) during BlackHat Asia 2014. 2014? Is that right? I thought this was new... So it still works this method? Perhaps this one wouldn't be so easy for the browsers to just fix since it's technically changing the subdomain to a completely invalid one, but then you redirect it anyway since you're in control! Wouldn't it be more noticeable though if you catch an extra w in that url! :) wwwW dot! (well it would only be if you looked at the link where it points to right?) Or it could be anything but probably that would blend in the most. Yea DataHead said he uses it on his pineapple, so definitely ruby can work on them!
  15. Not exactly... That helped me figure out the architecture but it doesn't disassemble (I don't think, at least not mips) and objdump will disassemble but it doesn't support mips either. First I found this online tool similar to what you used call Retargetable Decompiler: https://retdec.com/decompilation/it disassembles as well as trying to provide a C or Python source code which isn't perfect but does help to find your way around in the disassembled mips code, and even gives you nice graphs of the code flow. I did see where it does in fact call the getenv function with the CONTENT_LENGTH string (which is contained inside it like I thought it would be) Then I found what I think is what determines if you typed the correct password or not. It's called "CheckAuth" :) However with only static analysis and not being able to debug, I had to do my best to create a couple "best shot at it" patches: I'll get to that in a minute, I should say that I think I found where the router stores the administration panel password and it appears to be hashed, along with where the wpa passphrase, wep key (if used) and WPS pin are also stored along with all the other router settings. It's in /etc/config.xml and /etc/config_full.xml the two settings / configuration files! Alf@UNKNOWN:~/Downloads/PenTest/FileSystem$ cat etc/config_full.xml | grep KeyPassphrase <KeyPassphrase t="s"></KeyPassphrase> <X_TWSZ-COM_PSKExpression t="s" >KeyPassphrase</X_TWSZ-COM_PSKExpression> <KeyPassphrase t="s"></KeyPassphrase> <KeyPassphrase t="s">wpatestpass</KeyPassphrase> Alf@UNKNOWN:~/Downloads/PenTest/FileSystem$ cat etc/config.xml | grep Password <DevicePassword t="s">12345670</DevicePassword> <X_TWSZ-COM_PeerPassword t="s" Stat="1"></X_TWSZ-COM_PeerPassword> <WEPKey t="s" Password="2">1111111111</WEPKey> <WEPKey t="s" Password="2">2222222222</WEPKey> <WEPKey t="s" Password="2">3333333333</WEPKey> <WEPKey t="s" Password="2">4444444444</WEPKey> <PreSharedKey t="s" Password="2"></PreSharedKey> <KeyPassphrase t="s" Password="2"></KeyPassphrase> <WEPKey t="s" Password="2"></WEPKey> <Passphrase t="s" Password="2"></Passphrase> <Password t="s" >$1$TW$W4EX5n8uMLE15bpd62uqD.</Password> <Password t="s" >$1$TW$3q69ksdrX7zaaLg54vFxN0</Password> <SmtpPassword t="s" ></SmtpPassword> <Password t="s">Pass</Password> <Password t="s"></Password> Alf@UNKNOWN:~/Downloads/PenTest/FileSystem$ wpatestpass was your wpa test passphrase wasn't it? DevicePassword is in both configs and is the WPS pin, so both would probably have to be changed if editing them manually. Finally after the WEP keys the Password fields containing $1$TW$ are the 'admin' and 'user' passwords, did you know there was even a login for 'user'? seems like a backdoor perhaps but maybe with not as many permissions as the admin login. The first one is for admin, the second for user. $1$TW$ seems to be a constant, probably because it's called a TWSZ-COM so that's where I seee the TW coming from. It seems to be a Chinese device as in some areas in the filesystem there's plenty of Chinese. I also realized you could've probably done the CRCs/MD5s not on the actual device itself, but pulling the filesystem running the CRCs, then changing the administration password, pulling it again and CRCing again! That would've made that easier than trying to do it on the device, but if this is where the passwords are stored as it appears so, that won't be necessary anymore! I'm not sure how that's encoded / encrypted though and you might want to change the password and check that admin password again and see if it indeed changes like I think it will. Now let's check out some mips code, the C pseudo code is nice to look at to get some bearings, but we'll have to actually patch the mips machine code in order to change it's behavior. My goal was to try my best using just static analysis to figure out where to patch in order to make it so you can enter any admin password and it will be accepted. I take no responsibility if you end up bricking your router, however I think the webproc process isn't vital to the routers functioning and you should be able to just telnet back over the unpatched / original binary if anything goes wrong and you're not able to access the admin panel anymore. (that should be the only side effect, if even that) I also found a place where other services could be enabled like ftp but they were commented out and maybe not truly available on the device. The telnet probably they forgot to remove it as they were still using it when last working on it, unlike the other ones. Some C pseudo code of the main function where the CheckAuth function is called: / Address range: 0x401d90 - 0x4024ab int main(int argc, char ** argv) { <-- snip --> mallopt(-3, 0x1000); MSG_RegModule(769); unknown_401de0(); int32_t v59; // 0x454ce0 int32_t v60 = v59; MSG_AllModStartOK(1); int32_t v61 = v59; srand(time(NULL)); // <-- seeding the pseudo random number generator I see with the time rand(); rand(); int32_t v62; int32_t v63; // 0x454e18 int32_t v64; OM_ValSet((int32_t *)v63, v61 - 0x2df4, My_getenv((char *)(v60 - 0x2e00)), v62, v64, 0); <-- where it calls their custom version of getenv (your decompilation attempt only did that function) int32_t v65 = v59 - 0x2dcc; // 0x401ec4 OM_ValSet((int32_t *)v63, v59 - 0x2de0, v65, v62, v64, 0); int32_t v66 = WEB_GetEnv(); // 0x401edc int32_t v67 = v66; int32_t v68 = -1; int32_t v69; // 0x402438 int32_t v70; // 0x402458 int32_t v71; // 0x454eb4 if (v66 == -1) { // 0x402438 ((int32_t (*)())v69)(); ((int32_t (*)(struct struct__IO_FILE *))v71)((struct struct__IO_FILE *)v70); // branch -> 0x402464 } else { // 0x401ef4 int32_t v72; // 0x454e60 OM_ValGet((int32_t *)v72, v59 - 0x2db4, v65); int32_t v73; int32_t * v74 = (int32_t *)(v73 + 0x52f50); // 0x401f64_0 int32_t * v75 = (int32_t *)(v73 + 0x53088); // 0x401f6c_0 int32_t v76; // 0x401f68 ((int32_t (*)())v76)(); int32_t v77; OM_ValGet((int32_t *)v63, v61 - 0x2df4, v77); int32_t v78; // 0x454ed8 OM_ValFind((struct struct_15 *)v78, v59 - 0x2d8c, v77); int32_t v79 = v68; // 0x401fc0 v77 = v79; CheckAuth((char *)0, (char *)v60, v79, v62); // <-- This looks interesting So after perusing that pseudo C code generated by retdec, and the actual disassembled mips code provided by it as well. I also was looking for an offline disassembler for mips, and it turns out kali already comes with one called radare2 / rasm2! I use it like this: (-e for big endian, -b 32 for 32 bit code, -a mips for mips architecture and then the binary file to work with) radare2 -e -b 32 -a mips webproc Then you can use pd [length] (optional length) to print out the disassembled code in a nice color coded format that even shows the relative jumps. or 's [address]' ex. 's 0x401fcc' where 0x401fcc is the place I believe might be what I've tried to accomplish. You can also see one of the nice graphs that shows how the main function links to the others, and most things seem to branch out from the CheckAuth function so it's definitely important. This is my first patch: This is right after the CheckAuth function is called which is at 0x401fc0... Just after returning from that function is makes a branch decision based on whether the return value is zero (which is usually success, and I believe that to be the case as it seemed to return -1 or a higher than 0 value in most returns from CheckAuth and only returned 0 in one place I believe [which should mean a successful authentication]) The instruction I patched: beqz v0, 0x402068 (branch if equal to zero [if v0 is equal to zero]) So here was the plan, currently it checks if v0 (the return value from CheckAuth) is 0 and if it is zero and only zero it follows the branch and goes to what I think is the successful login code. What i've done with my patch is to reverse / inverse the branch and made it: bnez v0, 0x402068 (branch if not equal to zero [if v0 is anything else but zero]) In theory if this works, any admin password that IS NOT the correct password should be a successful login. Funnily enough if it works, the actual correct password would be the only thing that would give you an unsuccessful login! lol hows that for a reversal. If I had the router for example, I would keep making patches and test until I got the result I was looking for. Also I would try to get a debugger going, so I could actually see how the program is behaving while it's executing which would help tremendously at finding the results I'm after! I used a simple hex editor once I knew what I wanted to patch, to find the bytes within the file to patch and then modifying them with the new instruction(s). I used rasm2 and online assemblers in conjunction along with a MIPS instruction set reference guide in order to what bytes to replace the original bytes with to create the valid instructions I wanted. Most machine code is relatively simple, move / load instructions, branch instructions / jump instructions, and stack manipulating instructions. This next patch is a bit more of a gamble, instead of changing that branch instruction after CheckAuth is called, I instead went into the CheckAuth function and made it immediately before doing anything setting the return value (v0) to 0 and then just return. This is a bit more risky, because the things that happen in the CheckAuth function might be more important then just returning successful or not, and it may set some other things up but I thought it might still be worth a shot since I'm just using static analysis and can't debug. The first one almost for sure won't have any real bad side effects, it'll either do what I hope it will or just seem like nothing's different or have a hidden side effect that'll be unnoticeable. This second one might have a more noticeable side effect if it doesn't work. However I don't think either of them should crash per say since I did use valid instructions that replaced the original instructions! So I recommend trying the first one, branch inversed first if you're going to try these! Also when you do make sure you type an incorrect password and see if it accepts it, then type the correct password and see if it accepts it. With the second patch: set return value and just return, I may have it backwards and it might make all passwords not be accepted. The first patch: branch inverse, however should just do something complete opposite of normally, like successful logging in with an incorrect password and failing to login with a correct password. Here's the disassembled and pseudo decompiled output I got from retdec, and the two patched versions if you're willing to try them and remember I recommend the branch invert one first if you are, you'll have to rename them from 'webproc-inversed-branch' and 'webproc-patched-justreturnzero' to 'webproc' the original and actual name! Also you can only try one at a time just to be clear as it will replace the current original webproc binary. In the inverted branch patch it ends up being like I said a SINGLE BYTE PATCH :) funny how I knew that in my post earlier and the the second just return zero patch is an 8 byte patch, two instructions overwriting the beginning of the CheckAuth function! Link: http://www.speedyshare.com/H7UYA/webproc-disassembled-and-patched-versions.zip
  16. Never gonna give you upNever gonna let you downNever gonna run around and.... no, just no... lol
  17. Heck yea Whistle Master! Thanks for making it into an actual pineapple module! So wait a minute though does this count as my first module? and it's a shell script now? If that's the case you just used cURL or something like it to send the http posts? Maybe it doesn't count as my first module since you had to rebuild it as a shell script, however I'd still like to see how you did that with only a shell script so PM me a way how I can download it and take a look! (without a pineapple) Still either way I like that it's at least made it's way onto the module manager :) @WIFIjuice: I was feeling that you wouldn't want to just upload every single handshake you have to an online site, and people would only use it in cases where for example the company you need to get the passphrase for doesn't care how you get it, just that you get it! So you'd only upload a handshake in circumstances like that, and that's why I wanted to have it separate from capturing them. As others were saying it is relatively simple and there's plenty of software to capture a handshake. You basically just need to be listening with an interface in monitor mode to a particular access point, and as soon as any client authenticates or re-authenticates with the access point you'll get the handshake (if you are close enough, or your antenna 'gets' you close enough) You just have to be patient and wait for it, or you can de-authenticate a client to try to get it quicker. When it tells you you have the handshake that capture file you were capturing packets to is what you can use with this module!
  18. On another note I figured out what the architecture is Alf@UNKNOWN:~/Downloads/PenTest$ readelf -a -W webproc ELF Header: Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, big endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: MIPS R3000 Version: 0x1 Entry point address: 0x401b70 Start of program headers: 52 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x1007, noreorder, pic, cpic, o32, mips1 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 7 Size of section headers: 0 (bytes) Number of section headers: 0 Section header string table index: 0 A MIPS R3000 big endian and an ELF32 binary! MIPS I haven't reverse engineered before, but this should be fun! Of course it wasn't going to be x86 or ARM but I now at least know how I need to look at it as! I also determined that your disassembled output was just of one function not the whole executable and it looks more like it tried to decompile it rather than disassemble so it's more like pseudo code. I'm at least looking at the actual MIPS code now!
  19. Alright that's a deal Foxtrot, after this one that is! I'll save C++ for the real l33t applications from now on and gain some more experience with python. It's easy but I'm a lot less familiar with it than C++ so that's why C++ is generally easier for me. You're right though so I'm not going to code every single thing in it from now on. [Here though there really isn't that much code in this I'll help with the review process here] Including the http client class and setting up some global variables and my pointer where I'll create my http object and a printHelp function which just prints the usage information: /* uploadwpa 1.1 ~ AlfAlfa */ #include "HTTPClient.hpp" std::unique_ptr<HTTPClient> http; std::string email, hashes, capture_file, file_name, boundary, useThisUserAgent; int success = 0, verbose = 0; Then in main I'm just grabbing the passed in arguments if they have been passed in: (email, capture file path, capture file name extracted from it, hashes extracted depending on how many there are, whether you passed in a custom user agent string, verbose mode, and checking if you want to just print the help screen) int main(int argcount, char *args[]) { for(int i = 0; i < argcount; i++) { if(strcmp(args[i],"-e") == 0 || strcmp(args[i],"--email") == 0) { if(i < (argcount - 1)) email = args[i+1]; } if(strcmp(args[i],"-c") == 0 || strcmp(args[i],"--capture-file") == 0) { if(i < (argcount - 1)) { capture_file = args[i+1]; size_t lastSlash = capture_file.rfind('/'); if(lastSlash != std::string::npos) file_name = capture_file.substr(lastSlash+1); else file_name = capture_file; } } if(strcmp(args[i],"-a") == 0 || strcmp(args[i],"--hashes") == 0) { int z = i; while(*args[++z] != '-') { hashes += args[z]; if(z == (argcount - 1) || *args[z+1] == '-') break; hashes += "\r\n"; } } if(strcmp(args[i],"-u") == 0 || strcmp(args[i],"--user-agent") == 0) { if(i < (argcount - 1)) useThisUserAgent = args[i+1]; } if(strcmp(args[i],"-v") == 0 || strcmp(args[i],"--verbose") == 0) { verbose = 1; } if(strcmp(args[i],"-h") == 0 || strcmp(args[i],"--help") == 0) { printHelp(); return 2; } } Finally the main piece of code that does the thing! If the email argument wasn't passed in it'll also just print the help. If it has been create the http client object. If it has successfully been created (should always but you never know lol) then set the user agent that member function will only actually change it if it has been passed in, otherwise it uses iceweasel kali user agent string. verbosity, then if we have hashes passed in post the hashes as urlencoded form data with provided email and / or if we have a capture file path post multipart form data containing the passed in email and binary of that capture file. Successful will have a 0 if any of the two that were tried failed and 1 if either one succeeded and 2 if both succeeded. Return 0 for success as long as one was a success or 1 for failure. if(!email.empty()) { http = HTTPClient::make(); if(http.get()) { http->setUserAgent(useThisUserAgent); http->setVerbosity(verbose); if(!hashes.empty()) success += postHashesTo_onlinehashcrack(); if(!capture_file.empty()) success += postWPAHandshakeTo_onlinehashcrack(); if(success > 0) { std::cout << "Successful! " << success << "\n"; return 0; } } return 1; } printHelp(); return 2; The postHashesTo function just creates a string with the post variables the site requires with the hashes and email urlencoded, then uses the http client object to connect to the site on port 80 and finally it does a http post for x-www-form-urlencoded data with the concatenated data string to the /hash-cracking.php page: int postHashesTo_onlinehashcrack() { std::string postData = "textareaHashes="; postData += HTTPClient::urlEncode(hashes) + "&emailHashes="; postData += HTTPClient::urlEncode(email) + "&submit=Submit"; //if(!http->Connect("127.0.0.1",80)) return 0; if(!http->Connect("www.onlinehashcrack.com",80)) return 0; bool successful = http->Post("/hash-cracking.php", postData.c_str()); http->Close(); return successful; } postWPAHandshake function is a bit more complex, where you take a named 'boundary' and use that between the different pieces of data as boundaries which tell the server where things begin and where they end in this certain format of 'multipart formdata'. I emulated firefox/iceweasal's method of generating a random number appended to a number of dashes as best I could so it would be like firefox for the most part. Following the format of "--" (two dashes) then boundary start and proper amounts of \r\n / CR+LF's in between, then reading the capture file passed in and appending it where it should go. Connect and post that data along with the boundary we used to the proper php page that expects the data this way. Then close the connection and return whether it was successful or not! bool postWPAHandshakeTo_onlinehashcrack() { boundary = HTTPClient::getRandomBoundary(); std::string postData = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"emailWpa\"\r\n\r\n" + email + "\r\n"; postData += "--" + boundary + "\r\nContent-Disposition: form-data; name=\"wpaFile\"; filename=\"" + file_name + "\""; postData += "\r\nContent-Type: application/vnd.tcpdump.pcap\r\n\r\n"; FILE *file = fopen(capture_file.c_str(), "rb"); if(!file) { http->Log("ERROR Cannot open file"); return false; } fseek(file, 0, SEEK_END); long fileLen = ftell(file); rewind(file); size_t previousLen = postData.size(); postData.resize(previousLen + fileLen); fread((void*)&postData.data()[previousLen], fileLen, 1, file); fclose(file); postData += "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"submit\"\r\n\r\nSubmit\r\n"; postData += boundary + "--\r\n\r\n"; //if(!http->Connect("127.0.0.1",80)) return false; if(!http->Connect("www.onlinehashcrack.com",80)) return false; bool successful = http->PostMultiPart("/wifi-wpa-rsna-psk-crack.php", postData, boundary); http->Close(); return successful; } [Now the HTTPClient code] Connect function creates a unix socket tcp type and then dns queries the ip for the hostname and turns it into a server and then server address / sock address structure that we can use with the socket connect function. If all is well set the host and port of the object to match what we've established our connection with and set a default referrer which in this case happens to be the referrer that the site expects and return true. bool HTTPClient::Connect(const char *host, int port) { sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { Log("ERROR opening socket"); return false; } server = gethostbyname(host); if (server == 0) { Log("ERROR no such host"); return false; } bzero((char*)&serverAddress, sizeof(serverAddress)); bcopy((char*)server->h_addr, (char*)&serverAddress.sin_addr.s_addr, server->h_length); serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); if(connect(sock,(struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) { Log("ERROR connecting"); return false; } this->host = host; this->port = port; setReferer("http://" + this->host + "/"); //default referer return true; } HTTP Get: that I didn't end up using but still wrote anyway since It's a necessity for an http client to have. bool HTTPClient::Get(const char *page) { if(!page) return false; request = "GET "; request += page; request += " HTTP/1.1\r\n"; if(!host.empty()) request += "Host: " + host + "\r\n"; request += userAgent + "\r\n"; request += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; request += "Accept-Language: en-US,en;q=0.5\r\n"; request += "Accept-Encoding: gzip, deflate\r\n"; if(!referer.empty()) request += "Referer: " + referer + "\r\n"; request += "Connection: keep-alive\r\n\r\n"; requestHeaders = request; Log("\n[Request: ]"); Log(request, true); return WriteRequestReadResponse(); } HTTP Post just posts the x-www-form-urlencoded as described above as used for the space separated hashes... bool HTTPClient::Post(const char *page, const char *data) { if(!page || !data) return false; request = "POST "; request += page; request += " HTTP/1.1\r\n"; if(!host.empty()) request += "Host: " + host + "\r\n"; request += userAgent + "\r\n"; request += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; request += "Accept-Language: en-US,en;q=0.5\r\n"; request += "Accept-Encoding: identity\r\n"; //gzip, deflate if(!referer.empty()) request += "Referer: " + referer + "\r\n"; request += "Connection: keep-alive\r\n"; request += "Content-Type: application/x-www-form-urlencoded\r\n"; request += "Content-Length: "; char dataLenStr[21]{0}; sprintf(dataLenStr, "%lu", strlen(data)); request += dataLenStr; request += "\r\n\r\n"; requestHeaders = request; request += data; request += "\r\n\r\n"; Log("\n[Request: ]"); Log(request, true); return WriteRequestReadResponse(); } Same as above except posts multipart from data with the boundary style format... bool HTTPClient::PostMultiPart(const char *page, std::string &data, std::string &boundary) { if(!page || data.empty()) return false; request = "POST "; request += page; request += " HTTP/1.1\r\n"; if(!host.empty()) request += "Host: " + host + "\r\n"; request += userAgent + "\r\n"; request += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; request += "Accept-Language: en-US,en;q=0.5\r\n"; request += "Accept-Encoding: identity\r\n"; if(!referer.empty()) request += "Referer: " + referer + "\r\n"; request += "Connection: keep-alive\r\n"; request += "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n"; request += "Content-Length: "; char dataLenStr[21]{0}; sprintf(dataLenStr, "%lu", data.size()); request += dataLenStr; request += "\r\n\r\n"; requestHeaders = request; Log("\n[Request: ]"); Log(request.c_str(), true); request += data; request += "\r\n\r\n"; return WriteRequestReadResponse(); } WriteRequestReadResponse is just exactly as described writes all data of the request and get's back all or at least the start of the response up to a 4kb buffer. bool HTTPClient::WriteRequestReadResponse() { int wroteNum = Write((char*)request.c_str(), request.size()); if(wroteNum > 0) { int readNum = Read(4096); if(readNum > 0) { interpretResponse(); return true; } } return false; } Interpret response extracts the response headers from the response and I didn't fully implement it yet as it wasn't necessary for this application but it would be simple to finish it off and just after getting the content length keep reading from the socket until all the bytes are received and perhaps send a keep alive packet in between successive reads to ensure the connection stays alive if it's a large transfer (like downloading a large file, also I'd have to support chunked encoding as well) size_t HTTPClient::interpretResponse() { char *startOfHeader = response.get(); char *endOfHeader = strstr(startOfHeader, "\r\n\r\n"); if(endOfHeader == 0) return 0; size_t headerSize = (endOfHeader - startOfHeader) + 4; responseHeaders.resize(headerSize); bcopy(response.get(), (void*)responseHeaders.data(), headerSize); offset = headerSize; Log("\n[Response Headers: ]"); //more work needs to be done here, to make sure to get the whole response Log(responseHeaders.c_str()); //eg. get the content length and however many bytes received of it so far, then get the rest if necessary. return headerSize; } Read+Write pretty self explanatory, read upto a certain number of bytes from socket, write all bytes in write buffer to socket. int HTTPClient::Read(int maxBytes) { if(!response.get() || (bufferSize < maxBytes)) { response = std::unique_ptr<char[]>(new char[maxBytes]); bufferSize = maxBytes; } if(!response.get()) return -1; bzero(response.get(), bufferSize); Log("recieving..."); int num = recv(sock, response.get(), maxBytes, 0); if(num <= 0) { Log("ERROR reading from socket"); return 0; } responseSize = num; return num; } int HTTPClient::Write(char *writeBuffer, int writeSize) { int num, total = 0, bytesLeft = writeSize; while(total < writeSize) { num = send(sock, writeBuffer+total, bytesLeft, 0); if(num <= 0) break; total += num; bytesLeft -= num; } if(total < writeSize) { Log("ERROR writing to socket"); return 0; } return total; } Creates the randomized boundary from /dev/urandom this could have been done better, but it's good enough and the boundary could really be anything you want since the client chooses it. I just didn't want to make it static and wanted it to at least be mostly like firefox/iceweasal. std::string HTTPClient::getRandomBoundary() { std::string randomBoundary = "---------------------------"; { uint64_t random128bits[2]; FILE *randomness = fopen("/dev/urandom", "rb"); if(randomness) { fread(&random128bits[0], 16, 1, randomness); fclose(randomness); for(int i = 0; i < 2; i++) { char randomNum[30]; sprintf(randomNum,"%lu",random128bits[i]); randomBoundary += randomNum; } srand(time(0)); int losehowmanydigits = rand() % 3 + 11; randomBoundary.resize(randomBoundary.size()-losehowmanydigits); //resulting in a 23 - 29 digit number appended to 27 dashes (like how iceweasal does it) return randomBoundary; } } return ""; } url encode and url decode... url encode necessary for the hashes data post but not the multi-part form data post. Should an http client have a url decode? Perhaps only and http server object should but even though I didn't have a use for it it could be used possibly. std::string HTTPClient::urlEncode(std::string str) { std::string new_str = ""; char c; int ic; const char* chars = str.c_str(); char bufHex[10]; int len = strlen(chars); for(int i=0;i<len;i++) { c = chars[i]; ic = c; // uncomment this if you want to encode spaces with + /*if (c==' ') new_str += '+'; else */ if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') new_str += c; else { sprintf(bufHex,"%X",c); if(ic < 16) new_str += "%0"; else new_str += "%"; new_str += bufHex; } } return new_str; } std::string HTTPClient::urlDecode(std::string str) { std::string ret; char ch; int i, ii, len = str.length(); for (i=0; i < len; i++) { if(str[i] != '%') { if(str[i] == '+') ret += ' '; else ret += str[i]; } else { sscanf(str.substr(i + 1, 2).c_str(), "%x", &ii); ch = static_cast<char>(ii); ret += ch; i = i + 2; } } return ret; } Finally a templated log function for the client object that just takes any object that can be put through cout and automatically concatenates a newline unless you specify not to! template<class T> void HTTPClient::Log(T str, bool noNewline) { if(verbosity > 0) { std::cout << str; if(!noNewline) std::cout << "\n"; } } There! See nothing at all malicious or nefarious in the code it just does what it does and that's it! This should help to get it reviewed and accepted as a legitimate module although not useful to everyone for some that are willing to use online services for wpa handshakes this can be helpful indeed. Customization of sites and variables coming soon, along with SSL/TLS support so it can work with practically any site!
  20. Good to know that it is possible to get into the repo, so I'll work towards that, and in the meantime let's get it going on our own! I also just committed a newer version (I forgot to remove an extra comma in an $api.request call although that was still probably okay syntax, and I was using tabs and it was spaces originally so that screwed my formatting, that's fixed now too) Yes cross compilation is required, I've just discovered that as well when I went searching for how to create a OpenWrt standardized Makefile. Also it seems the STL will possibilty require the libstdcpp or uclibcxx according to this page I'm reading: http://gargoyle-router.com/old-openwrt-coding.html Here's what I have in terms of my make file so far: (I need HTTPClient.cpp compiled first, then uploadwpa.cpp then I can compile both object files.o into the uploadwpa binary. from how I understand it) My application is only a tiny bit more complex then the example hello world on that web page. I also need c++11 features since I use some of them, I was using -std=c++0x but it seems to be the same as passing -std=c++11 or -std=gnu++11 # build uploadwpa executable when user executes "make" uploadwpa.o: uploadwpa.cpp $(CXX) $(CXXFLAGS) -std=c++11 -c HTTPClient.cpp uploadwpa.cpp $(CXX) $(LDFLAGS) -std=c++11 HTTPClient.o uploadwpa.o -o uploadwpa # remove object files and executable when user executes "make clean" clean: rm *.o uploadwpa Lets get this working Whistle Master, I know you know how to compile this tiny c++ application. This compiles on my linux machine, but now it has to be expanded and set up to compile for the architecture of the pineapple Nano and Tetra... So the Tetra is a "A 533 MHz RISC CPU from Atheros is running the WiFi Pineapple firmware" and Nano "CPU: 400 MHz MIPS Atheros AR9331 SoC" So each will have to have it's own cross compilation makefile and will result in two binaries one of RISC architecture and other of MIPS for the respective devices... :)
  21. Thank you whistle master! That clarifies most of it. Except you said I can't use that installDependency / checkDependency stuff, but then you said it would work if it's an approved source code? That's what I was aiming for, to get it approved and I was under the impression that if it did it would be available through those methods. I wasn't able to find the sources of all the modules though, and I got that from one of the modules that I did happen to find on github that I was using to help me build mine (as a more full example than just the sample.tar.gz). I would python it, but I have my heart set on C/C++ code! I'll look into creating a standard OpenWrt makefile, so if I did though pineapples have built in the "build-essential" or whatever's needed for building a c++ binary right on the pineapple itself? So I could just have Wifijuice (after creating the makefile) do a make && make install? Or would you recommend cross compilation? Right now the code is short and clean and the binary isn't there only the source, so yes the user does have to build it themselves as of now. I've already got SSL working in my other branch and that opens the door for making it work with other sites too so it's not just limited to one. However instead of having to maintain the list of sites and parameters for them myself I am going to go with the customizable route, where you could run it to try to automatically scrape the parameters / post variables in order to upload the wpa handshake as long as the site uses the same method "multi-part form data" Or if that fails manually enter into your list of sites the variables that particular site wants. Thanks again, and keep me posted for when the verification process gets set up and in the meantime I'll have to help Wifijuice build it from source. Then further work on my improvements I've talked about! It's great that you only found that stuff wrong with it, so the code actually worked on a pineapple except for the dependencies that aren't existent yet right?! Awesome!
  22. Okay this may seem like a silly question but I can't find where to actually submit a module for the approval process?! WiFiJuice requested a certain module and I basically created it for him, but unlike I thought he should be able to he wasn't able to or even sure that he was supposed to compile it on his pineapple. So perhaps if it was made into an actual module that would make it easier since you guys would have it compiled for the right architecture and easily installable through the module manager. So I put the next step in at actually taking a crack (no pun intended lol) at the GUI part of the module (which was covered in Let's Code: Session 1) It's here on my github, hopefully I got the php and javascript right at least for getting it working on the most basic level. Which it connects to the cli binary to exec what actually makes it work. https://github.com/Alf-Alfa/uploadwpa Since it's my first module and knowing that I haven't gotten my pineapple yet, if the gui code is not quite right then helping me fix it would be appreciated. Also if I perhaps included something in my cpp source that isn't available on the pineapple let me know. Although I feel like I just used standard unix stuff so that part of it should be alright. I just tested it again as well to make sure it still works and it does. Thanks, Alf
  23. Ok well I haven't gotten a pineapple yet, so I was finding it a little difficult to make it into a module since I'm coding blind basically. (At least with the GUI part which I can't test)... Also the pineapple site seems to only have mk 4 & 5 listed infusions and not the latest modules (I guess you have to have a pineapple to get at them, or even to know where they're at). I've uploaded what I have so far to github... How do I even submit my module to be accepted? I wanted to also make it support customizable data inputs of sites, so instead of me having to maintain a list of supported sites to upload the WPA handshakes to the user could set up their own. Also I was adding SSL support as well (which is pretty much done but the customizable input not). https://github.com/Alf-Alfa/uploadwpa Since you're interested in this module, and even though I don't have a pineapple, you can test it and if there's anything wrong I'll fix it and you test it again :) I think I've got the php code and javascript and html down right, but I'm not 100% sure! (The actual binary / main application does work, I just tested it again to make sure and nothing changed that would break it, so all is good with the functioning part of it, now it's just connecting the gui to it) Also I'm not entirely sure how to cross compile it, so if you can get a c++ compiler onto the pineapple itself that'll probably be the easiest way to compile it for the pineapple. Download the zip from my github, and copy the "UploadWPA" folder to /pineapple/modules Then you have to build the .cpp source files into uploadwpa cli binary... -> g++ -std=c++0x HTTPClient.cpp uploadwpa.cpp -o uploadwpa Finally I think but I'm not sure that you then copy it to /usr/bin or /usr/local/bin and that way the php script can use "exec" which calls the uploadwpa cli binary! Let me know how it goes, or if somethings wrong or if you need more help! EDIT: Just to clarify, no this isn't a hypothetical pseudo code, it is a tested and functioning application. The pseudo HTTP requests were what I typed up first to give myself a reference to work on it, then I actually created the application and made it work. The only difference is I made it a linux application, but I didn't use anything linux specific, it should compile for say a pineapple as well! So let's get it going on one! :D See it works -> (Email and Path To WPA Handshake Capture File entered as parameters of the app in the terminal, then wait for it... email pops up in the background showing they did in fact receive it and it started processing...) The gui module I just took a stab at will call the this cli application to do the thing!
  24. Pretty amazing yea haicen? I mean you have root access, but yet you still feel somewhat powerless in terms of resetting or grabbing the password for the administration web interface! l8igmac will help you with what he said, and I'll see about reverse engineering that C cgi-bin binary. That is if it is a cgi-bin binary written in C. cgi-bin's can also be scripts like in perl (.pl files) but in this case it does appear to be a C binary instead as you've mentioned. You're going to have to figure out how the password is being stored and retrieved to check against. Could it be stored in an sql database for example and the binary grabs it from there or maybe a hashed version of the password. So are there actual web page files or does the router itself actually just return html back from requests it gets? You say it does an http POST/GET(you didn't clarify but I assume it's a POST) with the password passed to a cgi-bin C binary. In a C compiled version of a cgi-bin there are two ways that it uses to get the POST or GET data. In a GET request received a "getenv("QUERY_STRING");" (function of stdlib) retrieves the passed string and in the case of a POST request received, getenv("CONTENT_LENGTH"); retrieves the length of the posted data, and stdin (standard input) will get the posted data! So in either case looking for the function "getenv" being called in the disassembled code is a good starting point of seeing where it's initially taking the posted data and following what it does with it. (since it has to base64 decode the input and then most likely hash the passed in password and get the stored hashed admin password to compare it to). If and since it does seem to be an older router it might have the password stored in plaintext even. It may even be possible to make the admin control panel accept any password at all by patching only 1 single byte of the binary, but that might be a little dangerous to play with, but as long as you back up the original binary you should always still be able to telnet back over the original and everything will be back to normal. You said you can upload the firmware if that's helpful sure that indeed might be, but I'd be more interested in the cgi-bin binary and having a look at that if you would upload that. (since I have an idea of where to start looking) EDIT: Also I just thought of another way you should be able to determine where the password for the admin cp is being stored. -> Do a CRC or MD5 of every file you have access to (since you're root pretty much everything) then quickly change or reset the password (just changing it is probably better unless you start with a resetted and only password changed device, since resetting is also going to change other things back to default) then CRC or MD5 everything again and check for which files have changed and what is still the same. Probably less will be going on if it isn't connected to the internet and routing packets as well so that would probably be the better time to try this. You'll get some files that happened to change but you should also be able to determine which file contains the password! What kind of architecture is the router? x86 or ARM or etc? I did a brief search but couldn't determine what your router's architecture actually is. For the above mentioned you'll need either a bash script or perl script or compiled binary for that architecture with a way to CRC or MD5 complete files of all files in "/" and enough space to hold those CRC's temporarily to compare against the new CRCs once the password has been changed. It shouldn't take up much space for that, but I know routers like yours can be very limited in memory and available space and might already be packed pretty tightly. In which case it would benefit to not store the hashes on the router but send them over the telnet connection or another port to be stored and compared against on your end (basically like a DIFF)
  25. I'm not sure if this is the best way to do it, but I think you could just use the firewall to forward IP packets from your ethernet interface to the wireless interface that clients connect to. It works from a wireless interface to another wireless interface so I don't see why it wouldn't work for a wired interface to a wireless interface. sysctl -w net.ipv4.ip_forward=1 #enable forwarding iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE #forward from eth0 (has internet) iptables --append FORWARD --in-interface wlan0 -j ACCEPT #to wlan0 (needs internet) That is assuming you are connected to your router on eth0 and need to share on wlan0 so adjust that accordingly if that isn't the case. Then if that works and so you don't have to type that everytime or execute a script with it, you can edit /etc/config/firewall and place the settings to have that already configured and ready to go on boot. There's also the way where you actually create a bridge between the two interfaces which is described in this post: https://forum.openwrt.org/viewtopic.php?id=39077which Darren linked to earlier. Though it to deals with a wireless to wireless interface I'm sure it can be configured to go from wired to wireless with little modification. Also might the wp6.sh script help with this? I know it's meant for the new pineapples but you could look through the script and see what it's doing to set things up which still may apply even to your pineapple.
×
×
  • Create New...