Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Still have FritzBox authentication error on 1.6.2 #74

Closed
mattiarainieri opened this issue Oct 18, 2022 · 32 comments
Closed

Still have FritzBox authentication error on 1.6.2 #74

mattiarainieri opened this issue Oct 18, 2022 · 32 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@mattiarainieri
Copy link

mattiarainieri commented Oct 18, 2022

Hi,
I've updated the library to the last 1.6.2 version but I still have problems authenticating to my fritz box.

Schermata 2022-10-18 alle 16 25 38

Schermata 2022-10-18 alle 16 26 09

@AndreySozonov
Copy link

AndreySozonov commented Oct 18, 2022

i have the same error:

  1. pyVoIP:
REGISTER sip:192.168.11.7 SIP/2.0
Via: SIP/2.0/UDP 192.168.11.88:5060;branch=z9hG4bK088986c7b2844e5797488dd0f;rport
From: "101" <sip:[email protected]>;tag=13639361
To: "101" <sip:[email protected]>
Call-ID: [email protected]:5060
CSeq: 1 REGISTER
Contact: <sip:[email protected]:5060;transport=UDP>;+sip.instance="<urn:uuid:533EA043-3D65-47B8-A23B-D4345D7B3071>"
Allow: INVITE, ACK, BYE, CANCEL
Max-Forwards: 70
Allow-Events: org.3gpp.nwinitdereg
User-Agent: pyVoIP 1.6.2
Expires: 120
Content-Length: 0
  1. Asterisk:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.11.88:5060;branch=z9hG4bK088986c7b2844e5797488dd0f;received=192.168.11.88;rport=5060
From: "101" <sip:[email protected]>;tag=13639361
To: "101" <sip:[email protected]>;tag=as7f240d2c
Call-ID: [email protected]:5060
CSeq: 1 REGISTER
Server: FPBX-13.0.74(11.21.0)
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
WWW-Authenticate: Digest algorithm=**MD5**, **realm**="asterisk", **nonce**="0c943d28"
Content-Length: 0
  1. pyVoIP:
REGISTER sip:192.168.11.7 SIP/2.0
Via: SIP/2.0/UDP 192.168.11.88:5060;branch=z9hG4bKd95ce81ab1e54bcaa1150c8b3;rport
From: "101" <sip:[email protected]>;tag=13639361
To: "101" <sip:[email protected]>
Call-ID: [email protected]:5060
CSeq: 2 REGISTER
Contact: <sip:[email protected]:5060;transport=UDP>;+sip.instance="<urn:uuid:533EA043-3D65-47B8-A23B-D4345D7B3071>"
Allow: INVITE, ACK, BYE, CANCEL
Max-Forwards: 70
Allow-Events: org.3gpp.nwinitdereg
User-Agent: pyVoIP 1.6.2
Expires: 120
Authorization: Digest **username**="101",**realm**="asterisk",**nonce**="0c943d28",uri="sip:192.168.11.7;transport=UDP",**response**="8c8fff877ffa698a19bada31ed1fa46d",algorithm=MD5
Content-Length: 0

(password = "123123")

  1. Asterisk:
SIP/2.0 401 **Unauthorized**
Via: SIP/2.0/UDP 192.168.11.88:5060;branch=z9hG4bKd95ce81ab1e54bcaa1150c8b3;received=192.168.11.88;rport=5060
From: "101" <sip:[email protected]>;tag=13639361
To: "101" <sip:[email protected]>;tag=as55b5d463
Call-ID: [email protected]:5060
CSeq: 2 REGISTER
Server: FPBX-13.0.74(11.21.0)
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="3bb11a60"
Content-Length: 0
  1. pyVoIP:
    Invalid Username or Password for SIP server 192.168.11.7:5060

how to check the response?

@tayler6000
Copy link
Owner

I did all the hashing myself and it all checks out so I'm not sure what the issue is here @AndreySozonov There seems to have been some semi recent RFCs updating the WWW-Authenticate scheme but they recommend not using algorithm=MD5 and the use of additional parameters, so it does not seem to be using it. Did a previous version of pyVoIP work for you?

Also you can use the following code for easier debugging on registry, but you may need to install from source instead of PyPI.

import pyVoIP
pyVoIP.DEBUG = True

Also, please be sure to use code blocks with posting code with Ctrl+e.

@tayler6000
Copy link
Owner

I've gotten to the point where I have downloaded the source code to Asterisk 11 to see where the error is happening. However my C is rusty, if anyone can figure out why some people are getting an error while other's are not, I would be greatly appreciative.

@tayler6000 tayler6000 added bug Something isn't working help wanted Extra attention is needed labels Oct 19, 2022
@mattiarainieri
Copy link
Author

mattiarainieri commented Oct 19, 2022

I've also reinstalled it from the source and enabled debugging.
This is the message

SENT
REGISTER sip:fritz.box SIP/2.0
Via: SIP/2.0/UDP 0.0.0.0:5060;branch=z9hG4bK138a8aa6cabd4b8c92c2b325d;rport
From: "alarmnegozio" <sip:[email protected]>;tag=2a7547e5
To: "alarmnegozio" <sip:[email protected]>
Call-ID: [email protected]:5060
CSeq: 1 REGISTER
Contact: <sip:[email protected]:5060;transport=UDP>;+sip.instance="<urn:uuid:DA030FE3-24AE-4ADE-86DD-AC5FD0A37397>"
Allow: INVITE, ACK, BYE, CANCEL
Max-Forwards: 70
Allow-Events: org.3gpp.nwinitdereg
User-Agent: pyVoIP 1.6.2
Expires: 120
Content-Length: 0

RECEIVED
Status: 401 Unauthorized
Headers:
Via: [{'type': 'SIP/2.0/UDP', 'address': ('0.0.0.0', '5060'), 'branch': 'z9hG4bK138a8aa6cabd4b8c92c2b325d', 'rport': '5060', 'received': '192.168.1.200'}]
From: {'raw': '"alarmnegozio" <sip:[email protected]>', 'tag': '2a7547e5', 'address': '[email protected]', 'number': 'alarmnegozio', 'caller': 'alarmnegozio" ', 'host': 'fritz.box'}
To: {'raw': '"alarmnegozio" <sip:[email protected]>', 'tag': '6DC5C2CCC210248B', 'address': '[email protected]', 'number': 'alarmnegozio', 'caller': 'alarmnegozio" ', 'host': 'fritz.box'}
Call-ID: [email protected]:5060
CSeq: {'check': '1', 'method': 'REGISTER'}
WWW-Authenticate: {'realm': 'fritz.box', 'nonce': '0648C4E9C7FDC385'}
User-Agent: FRITZ!OS
Content-Length: 0


Body:
Raw:
b'SIP/2.0 401 Unauthorized\r\nVia: SIP/2.0/UDP 0.0.0.0:5060;branch=z9hG4bK138a8aa6cabd4b8c92c2b325d;rport=5060;received=192.168.1.200\r\nFrom: "alarmnegozio" <sip:[email protected]>;tag=2a7547e5\r\nTo: "alarmnegozio" <sip:[email protected]>;tag=6DC5C2CCC210248B\r\nCall-ID: [email protected]:5060\r\nCSeq: 1 REGISTER\r\nWWW-Authenticate: Digest realm="fritz.box", nonce="0648C4E9C7FDC385"\r\nUser-Agent: FRITZ!OS\r\nContent-Length: 0\r\n\r\n'

RECEIVED
Status: 401 Unauthorized
Headers:
Via: [{'type': 'SIP/2.0/UDP', 'address': ('0.0.0.0', '5060'), 'branch': 'z9hG4bK658a06ae91aa4db3a3b094cc7', 'rport': '5060', 'received': '192.168.1.200'}]
From: {'raw': '"alarmnegozio" <sip:[email protected]>', 'tag': '2a7547e5', 'address': '[email protected]', 'number': 'alarmnegozio', 'caller': 'alarmnegozio" ', 'host': 'fritz.box'}
To: {'raw': '"alarmnegozio" <sip:[email protected]>', 'tag': '68CE7BCC0655CAE8', 'address': '[email protected]', 'number': 'alarmnegozio', 'caller': 'alarmnegozio" ', 'host': 'fritz.box'}
Call-ID: [email protected]:5060
CSeq: {'check': '2', 'method': 'REGISTER'}
WWW-Authenticate: {'realm': 'fritz.box', 'nonce': 'AB140D882868700D'}
User-Agent: FRITZ!OS
Content-Length: 0

@tayler6000
Copy link
Owner

@mattiarainieri @AndreySozonov What is the username associated with these numbers?

@tayler6000
Copy link
Owner

I don't see any instance of this check in Asterisk 11 that I found, however it may be worth noting that this is said in RFC 3261 Section 8.1.1.4

Note that when requests are retried after certain failure responses that solicit an amendment to a request (for example, a challenge for authentication), these retried requests are not considered new requests, and therefore do not need new Call-ID header fields; see Section 8.1.3.5.

This doesn't use any keywords from BCP 14 but that doesn't mean that an engineer hasn't relied on this behavior for routing messages, and we do not currently do this. Will be implementing this in 2.0.

@mattiarainieri
Copy link
Author

@tayler6000 the voip username is “alarmnegozio”

@AndreySozonov
Copy link

User "101". The registration error occurred when connecting to different versions of Asterisk (I tested 11 and 13). MicroSip softphone with the same credentials connected without problems. Perhaps the reason is related to the OS used: me and @mattiarainieri used Asterisk on Raspberry Pi.
Tomorrow i will test pyVoIP on another server with an asterisk.

@TecDroiD
Copy link

TecDroiD commented Oct 21, 2022

Hello again. I'm wondering what's going wrong there. Since I'm not that good at reading foreign code but much better in implementing my own I experimented with a simple protocol class structure for SIP and there, authentication against my fritz.box works fine. What's missing here now is RTP protocol so my experiments are pretty useless so far. I don't really want to build a concurrent library so I don't think that I'll complete that thing.. unless someone tells me how to send and receive audio data via rtp..

Maybe my source helps you to figure out what's wrong with yours: https://github.com/TecDroiD/simple_voip

Edit: didn't clean up my files.. this one should be the interesting part: https://github.com/TecDroiD/simple_voip/blob/master/voip/sipmessage.py

@tayler6000
Copy link
Owner

@TecDroiD Thank you, this will help a lot

@tayler6000
Copy link
Owner

@TecDroiD Our authentication systems are the same so I'm still unsure what the issue is. Could you maybe upload a packet capture of each system trying to authenticate?

@TecDroiD
Copy link

well.. there seems to be some more binary data in your capture
pyvoip.txt
simple_voip.txt

@tayler6000
Copy link
Owner

well.. there seems to be some more binary data in your capture

pyvoip.txt

simple_voip.txt

Can you merge my PR and then get me the simple_voip again? Your code has some significantly malformed headers and I'm genuinely concerned you stumbled across a vulnerability in fritz.box.

@TecDroiD
Copy link

simple_voip.txt
here it is. I end up unauthorized now

@tayler6000
Copy link
Owner

simple_voip.txt

here it is. I end up unauthorized now

Ok, I don't have access to a Fritz box to test, but I have a feeling if you delete the comma before the response it'll work on your box because it'll fail to read it and assume it's right. If deleting that comma makes it work I highly recommend you contact fritz box and tell them they have a vulnerability in their code.

@tayler6000
Copy link
Owner

Honestly, they'll probably give you a bounty for it.

@TecDroiD
Copy link

We'll see..
still, I cannot make any call yet

@TecDroiD
Copy link

Just found something else: in my sipmessage.py, line 160 you changed t3cDr01d to z9hG4bKt3cDr01d. When I roll this back, I can make a call.. Also when I remove only one character from your id text.
currently looking for that entry in your code but maybe the entry is too long for fritzbox?

@tayler6000
Copy link
Owner

Hmm, weird. It's a RFC requirement to have that prefix for the branch. I'm pretty sure I referenced it in the commit but if you just search for magic cookie in the RFC you'll find it.

@tayler6000
Copy link
Owner

def gen_branch(self, length=32) -> str:
        """
        Generate unique branch id according to
        https://datatracker.ietf.org/doc/html/rfc3261#section-8.1.1.7
        """
        branchid = uuid.uuid4().hex[: length - 7]
        return f"z9hG4bK{branchid}"

@TecDroiD
Copy link

as far as i understood, that magic cookie identifies the newer version of SIP RFC. Maybe it enables some extra checks on fritzos? I already found out that there are some optional entries (think it was Contact) which are required by fritzbox.. What if there's just something stupid missing, just because its optional?

@tayler6000
Copy link
Owner

I think you're right about the extra checks. The RFC says the branch should be globally unique if following the new standard. So maybe the second register needs to use a different branch not the same one from the original request?

@tayler6000
Copy link
Owner

@xyc0815 Welcome back, please, do you have any thoughts on this?

@xyc0815
Copy link
Collaborator

xyc0815 commented Nov 3, 2022

When I use web SIP services I had problems with username in contact in the first request (def gen_first_response(self, deregister=False))

        regRequest += (
            "Contact: "
            + f"<sip:{self.username}@{self.bind_ip}:{self.bind_port};"
            + "transport=UDP>;+sip.instance="
            + f'"<urn:uuid:{self.urnUUID}>"\r\n'
        )

So I don't use the username in this function. Because I've can also use a SIP proxy in between, I've other functions to get the right IP and port.

        regRequest += 'Contact: ' + \
                      f'<sip:{self.get_my_ip()}:{self.get_my_port()};' + \
                      'transport=UDP>;+sip.instance=' + \
                      f'"<urn:uuid:{self.urnUUID}>"\r\n'

With the second register call I've also send the username in the contact element. Maybe we have here the same problem.

@philipp-fischer
Copy link

philipp-fischer commented Dec 10, 2022

I also wasn't able to register or make a call with FritzBox. I debugged this a lot and compared packet captures with those from MicroSIP client.
I modified pyVoip until I could make it work. Eventually, it was all about the Call-ID field and the branch.

For REGISTER with authorization there are two requests. The Call-ID needs to be the same for first request without and for the second request with authorization.

For INVITE I figured, the Call-ID should also remain the same troughout the whole transaction (first and second request) however the branch needs to be different when doing authentication with the second INVITE request. The current implementation keeps the same branch for both.

@hartwigt
Copy link
Contributor

hartwigt commented Jan 11, 2023

Hi @philipp-fischer , could you please share your changes? I'm trying to authenticate pyvoip to my fritz box just to receive the signalling for detecting calls from a dect doorbell. The fritz internal call monitor does not log or signal internal calls, but I would like to log them and maybe add smart home actions such as "doorbell rings --> turn on light if it's dark"

@philipp-fischer
Copy link

Hi @philipp-fischer , could you please share your changes? I'm trying to authenticate pyvoip to my fritz box just to receive the signalling for detecting calls from a dect doorbell. The fritz internal call monitor does not log or signal internal calls, but I would like to log them and maybe add smart home actions such as "doorbell rings --> turn on light if it's dark"

In the end I resorted to an entirely new mini-implementation I created. I can share that when I return from vacation.

@nicofpunkt
Copy link

nicofpunkt commented Jan 13, 2023

Hello,

As far as I understand, the connection runs via UDP. In the following project, the connection runs via TCP by default:
https://github.com/astoeckel/femtosip
For me it works perfectly on the Fritz!Box 7490 with TCP. With UDP it gives me an authentication error. I am called anyway, but with an error message. That might solve the problem. An optional choice for UDP or TCP would be desirable.

Good luck

EDIT: I am called NOT if I use UDP with femtosip. Only TCP

@philipp-fischer
Copy link

@hartwigt: Here is the code I created for the purpose of making a call: https://gist.github.com/philipp-fischer/d7fa8df8541955863aebcf24291af007
It also contains a stub to register with the server to receive calls, but I never tested this.
Maybe this femtosip that @epicbananana posted above is worth a try?

@nicofpunkt
Copy link

I will test it

@Koshkodav
Copy link

Koshkodav commented Jan 18, 2023

I updated pyVoIP to 1.6.3, but i still have the authentification error. I tried tinyvoip from @philipp-fischer and it passed authentification.
I hope this error will be fixed in next release pyVoIP.

upd: pyVoIP works with Asterisk 18, but don't work with Asterisk 13.

@hartwigt
Copy link
Contributor

Hi @tayler6000, I found a small fix that makes registration on a fritzbox successful.
in sip.py - SIPClient - gen_register:
#regRequest += f"Call-ID: {self.genCallID()}\r\n"
regRequest += f"Call-ID: {request.headers['Call-ID']}\r\n"

The first register without authentication against the fritzbox gives 401 Unauthorized. The old code correctly sent another REGISTER with authentication, but generated a new CallID - that made the fritzbox with another 401 unauthorized with a new Nonce.
The above change keeps the CallID from the original unauthenticated REGISTER, and now registration is successful.

Thanks to @philipp-fischer and @epicbananana, those two tools did not really work for me, because all I need is notification of incoming calls, but they showed me successful SIP examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

9 participants