Giter VIP home page Giter VIP logo

dmtrong / iphonessh Goto Github PK

View Code? Open in Web Editor NEW

This project forked from rcg4u/iphonessh

0.0 0.0 0.0 119 KB

iPhone using SSH only works using wireless, this method does not use wireless, this method used a tcprelay through your USB by using a port and 127.0.0.1 or localhost in order to connect to an existing OpenSSH on your iPhone or Ipod touch. This does require a jailbroken iPhone. I am not the creator of this program, but I see its no longer being maintained. I figured I would introduce it to the github community and see if we can get some ideas brewing on it.

License: GNU General Public License v2.0

Python 100.00%

iphonessh's Introduction

Background
==========

These scripts are taken (with permission) from the usbmuxd distribution found at: http://marcansoft.com/blog/iphonelinux/usbmuxd/ and created by
HŽctor Mart’n Cantero with credits to 
Nikias Bassen
Hector Martin
Bastien Nocera
Paul Sladen
Martin Szulecki.

This readme is modified from the original to be more concise in using the python implementation on OS X.

If you want the full-blown version for linux, try the link above.
What we're doing here is using Apple's usbmuxd responsible to maintain the connection to the iTouch-device. What the linux version does is -in layman's terms- emulate Apple's usbmuxd, on systems without iTunes (and thus, without Apple's usbmuxd).

This is a distribution of the Python implementation of the client library and an example tcprelay.py which performs the actual tunneling (along with usbmuxd).
This implementation supports OSX and Windows and the new iTunes plist-based
usbmuxd protocol, so it is portable and will run on those operating systems with no modification, using Apple's native usbmuxd. This is useful if you need to tunnel to your phone from another OS in a pinch. 
Run "python tcpclient.py --help" for usage information.

License
=======

The contents of this package are licensed under the GNU General Public License,
versions 2 or 3 (see COPYING.GPLv2 and COPYING.GPLv3).
If a more permissive
license is specified at the top of a source file, it takes precedence over this.

Usage
========

  (Unplug + replug your jailbroken iPhone)
  python tcprelay.py -t 22:2222 &
  ssh -p 2222 root@localhost

Hopefully you get the normal SSH login prompt.  You may still see lots of debugging output for the moment. If this is getting in the way of your ssh login, then run the 'ssh' command from a different terminal-window.

You can define additional ports separated by space, i.e.

python tcprelay.py -t 22:2222 5900:2223
then connect ssh over port 2222 localhost and 
VNC (i.e. for veency) over localhost:2223

Marcan: "You can forward any ports where the iPhone is the server, and the PC the client. if you want to do the opposite, you could use socat to reverse the client/server roles or just use ssh forwarding/reverse forwarding (which will be slower though, due to the encryption). TCP only!"

Tip: Starting SSH if disabled
=============================

If your iphone is rooted, but SSH isn't started and you _cannot_ (for instance,
cracked/broken screen) get to the Services control panel on the device, then you
can start the SSH service over the USB by
mounting the (jailbroken) filesystem.

You will need to mount it usbing 'ifuse --afc2' (to access the root directory of the device), and then edit:

  /Library/LaunchDaemons/com.openssh.sshd.plist

to _remove_ the lines:

  <key>Disabled</key>
  <true/>

Reboot the device and then sshd should be running.

iFuse can be obtained here:
http://matt.colyer.name/projects/iphone-linux/

TODO
====

The server currently assumes that the phone is well-behaved and does not do a
bunch of checks like looking for the expected SEQ and ACK numbers from it. This
is normally not an issue, but it's annoying for debugging because lost packets
(which shouldn't happen, but can happen if the code is buggy) mean that stuff
gets out of sync and then might crash and burn dozens of packets later.

The server needs more testing, and some optimizing.

Someone should probably do some edge-case testing on the TCP stuff.

The outgoing ACK handling on the server probably needs some thought. Currently,
when there's an outstanding ACK, we send it after a timeout (to avoid sending
a no-payload ACK packet for everything the phone sends us). However, there's
probably a better way of doing this.

Architecture information
========================

The iPhone / iPod Touch basically implements a rather strange USB networking
system that operates at a higher level. It is of course completely proprietary.
Generally speaking, this is what goes on in a typical usage scenario:

0. iTunes opens a connection to usbmuxd and asks it for device notifications
1. User inserts phone into computer
2. usbmuxd notices the phone and pings it with a version packet
3. phone replies
4. usbmuxd now considers the phone to be connected and tells iTunes
5. iTunes opens another separate connection to usbmuxd and asks it to connect
   to, say, the afc port on the device
6. usbmuxd sends a pseudo-TCP SYN packet to the phone
7. the phone's kernel driver receives the SYN packet and itself opens a
   TCP connection to localhost on the afc port
8. the phone replies with a pseudo-TCP SYN/ACK indicating that the port is open
   and the connection can proceed
7. usbmuxd sends a final ACK to the phone
8. usbmuxd replies to iTunes with a "connection successful" message
9. any data that iTunes writes to the usbmuxd socket from now on is forwarded,
   through pseudo-TCP, through USB, back into a more regular TCP connection to
   localhost, to the afc daemon on the phone, and vice versa

The usbmuxd protocol is a relatively simple binary message protocol documented
here:

http://wikee.iphwn.org/usb:usbmux

Note that once a connection is established the UNIX socket essentially becomes
a dedicated pipe to the TCP connction and no more high-level control is
possible (closing the socket closes the TCP connection). Ditto for the "listen
for devices" mode - usbmuxd will reject any commands in such mode, and the
socket essentially becomes a dedicated device notification pipe. This means
that you need, at minimum, TWO connections to usbmuxd to do anything useful.

On Windows, usbmuxd works the same way but a TCP connection to localhost port
27015 replaces the UNIX socket. On OSX, the UNIX socket is /var/run/usbmuxd. The
server and client implemented here default to /tmp/usbmuxd at the moment.

The phone protocol operates over a pair of USB bulk endpoints. There is an outer
layer used for packet size info and a "protocol" (version and TCP are the only
two options), and that header is followed by TCP headers for actual data comms.
However, the protocol isn't actual TCP, just a custom protocol which for some
reason uses a standard TCP header and leaves most fields unused.

There is no reordering or retransmission. There are no checksums, no URG, no
PSH, no non-ACK, no FIN. What there *is* is the SEQ/ACK/window mechanism used
for flow control, and RST is used as the only connection teardown mechanism (and
also for "connection refused"), and the connection startup is SYN/SYNACK/ACK.

Windows are constant-scaled by 8 bits. This is legal TCP as long as the
corresponding option is negotiated. Of course, no such negotiation happens on
this protocol.

Note that, since there are no retransmissions, there is some overlap between ACK
and window for flow control. For example, the server doesn't ever touch its
window size, and just refuses to ACK stuff if its buffers are full and the
client isn't reading data. The phone happily seems to stop sending stuff.

Also, if the phone RSTs you out of nowhere, look at the packet payload for a
textual error message. Note: if it claims to suffer from amnesia, that probably
means you overflowed its input buffer by ignoring its flow control / window
size. Go figure. Probably a logic bug in the kernel code.

Note that all normal packets need to have flags set to ACK (and only ACK). There
is no support for, erm, not-acking. Keep the ack number field valid at all
times.

The usbmuxd CONNECT request port field is byte-swapped (network-endian). This is
even more annoying for the plist based protocol, since it's even true there
(where the field is plain text). So even for the plain text int, you need to
swap the bytes (port 22 becomes <integer>5632</integer>). I have no clue if this
is the case on the new plist protocol on PPC macs (is the newer iTunes available
for those?)

There are a bunch of gotchas due to the USB framing, and this is even worse
because implementations tend to get it wrong (i.e. libusb, and this is the
reason for the patch). Basically, USB Bulk offers, at the low level, the ability
to transfer packets from 0 to wMaxPacketSize (512 here) bytes, period. There is
no other support for higher level framing of transfers. The way you do those is
by breaking them up into packets, and the final shorter packet marks the end of
the transfer. The critical bit is that, if the transfer happens to be divisible
by 512, you send a zero-length packet (ZLP) to indicate the end of the transfer.
Libusb doesn't set this option by default and the iPhone gets packets stuck to
each other, which it doesn't like. Actually, this framing is sort of redundant
because the usbmux packet header includes a length field, but the phone still
wants the ZLPs or else it breaks. To make matters worse, usbdevfs imposes a max
transfer size of 16k, so libusb breaks transfers into that size. This is okay
for sending as long as the ZLP is only added to the last transfer (the patch
does that), but it can easily cause nasty race conditions on RX due to libusb
doing multiple outstanding reads at the same time and then cancelling the rest
when shorter data arrives (but what if some data got into the other requests
already?), so we only do 16k reads and stick them together ourselves by looking
at the packet size header. We still depend on ZLPs being sent to end transfers
at non-16k boundaries that are multiples of 512, but that seems to work fine. I
guess the ZLPs might cause spurious 0-byte transfers to show up on RX if things
line up right, but we ignore those. By the way, the maximum packet/transfer size
is 65535 bytes due to the 16-bit length header of the usbmux protocol.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.