opensips sip invite header forward with string instead of number - opensips

I am trying to forward call from opensips to PBX. but opensips is forward call with below invite
INVITE sip:s#197.237.56.175:5160 SIP/2.0
Record-Route: <sip:41.72.194.63;lr;did=bb.b18255a4>
Via: SIP/2.0/UDP 41.72.194.63:5060;branch=z9hG4bK4ee8.d7681d24.1
Via: SIP/2.0/UDP 41.72.194.48;received=41.72.194.48;rport=5060;branch=z9hG4bKUttKpDXZ34XUS
Max-Forwards: 28
From: "Ankit" <sip:25420570101#41.72.194.48>;tag=6Bjgy3y22Nvpm
To: <sip:254205700263#41.72.194.63>
Here issue in 1st line its forward invite with s#ip but i want to convert into number#ip like 254205700263#ip
Any ideas,Any suggestions?

In your OpenSIPS script, you can use the $rU variable, which will directly overwrite the "username" part. Here is an example:
...
$rU = "254205700263";
...
t_relay(); # send it out
The core variables may prove to be a useful learning tool, especially if you're new to the script.

Related

Why is the SIP ACK sent from our PBX not received by Twilio?

Our outbound calls through Twilio are all being dropped after 32 seconds (inbound calls are fine). The error we receive from Twilio is Error 32022 "Ack not received from your SIP endpoint." I have been going through tutorials and the RFC but I must really be missing something.
The calls are encrypted TLS. SIP ALG has been disabled in our gateway router and our Grandstream PBX is configured for NAT.
Any help is appreciated!
Here is the 200 OK and the ACK that never arrives:
<--- Received SIP response (1177 bytes) from TLS:54.172.60.2:5061 --->
SIP/2.0 200 OK
CSeq: 2218 INVITE
Call-ID: b9e1de31-ce44-4d34-b63b-4c8636e151bf
From: <sip:+13049487110#XXXX>;tag=814fce4e-a1dc-49c7-a917-59496ad182a7
To: <sip:+15132607811#xxxx.pstn.twilio.com>;tag=84858964_c3356d0b_d52c7a82-314f-4be6-88f4-e73110bdbdd8
Via: SIP/2.0/TLS 74.195.14.236:5061;received=74.195.14.236;rport=52191;branch=z9hG4bKPj42ac7abe-f4b7-40dc-a314-8c6a90584481;alias
Record-Route: <sip:54.172.60.2:5060;r2=on;lr;twnat=sip:74.195.14.236:52191>
Record-Route: <sip:54.172.60.2:5061;transport=tls;r2=on;lr;twnat=sip:74.195.14.236:52191>
Server: Twilio
Contact: <sip:172.25.75.195:5060>
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,NOTIFY
Content-Type: application/sdp
X-Twilio-CallSid: CAb39a1e013e6ad6c03bd5bd2827612646
X-Twilio-TlsPolicy: TLSv1.0+
Content-Length: 362
v=0
o=root 1866335776 1866335776 IN IP4 172. ...
<--- Transmitting SIP request (1010 bytes) to TLS:54.172.60.2:5061 --->
ACK sip:54.172.60.2:5061;transport=TLS SIP/2.0
Via: SIP/2.0/TLS 74.195.14.236:5061;rport;branch=z9hG4bKPj483e2dff-e510-4908-89ee-25ec200a4072;alias
From: <sip:+13049487110#XXXX>;tag=814fce4e-a1dc-49c7-a917-59496ad182a7
To: <sip:+15132607811#xxxx.pstn.twilio.com>;tag=84858964_c3356d0b_d52c7a82-314f-4be6-88f4-e73110bdbdd8
Call-ID: b9e1de31-ce44-4d34-b63b-4c8636e151bf
CSeq: 2218 ACK
Route: <sip:54.172.60.2:5061;transport=tls;lr;r2=on;twnat=sip:74.195.14.236:52191>
Route: <sip:54.172.60.2:5060;lr;r2=on;twnat=sip:74.195.14.236:52191>
...
The ACK request s addressed incorrectly: per 3261 with loose routing it should be addressed to the Contact URI, but sent to the topmost Route (built from the bottommost Record-Route, the route-set in your ACK appears to be correct). Correct the request URI for the ACK, that should help.

FastAPI RedirectResponse gets {"message": "Forbidden"} when redirecting to a different route

Please bare with me for a question for which it's nearly impossible to create a reproducible example.
I have an API setup with FastAPI using Docker, Serverless and deployed on AWS API Gateway. All routes discussed are protected with an api-key that is passed into the header (x-api-key).
I'm trying to accomplish a simple redirect from one route to another using fastapi.responses.RedirectResponse. The redirect works perfectly fine locally (though, this is without api-key), and both routes work perfectly fine when deployed on AWS and connected to directly, but something is blocking the redirect from route one (abc/item) to route two (xyz/item) when I deploy to AWS. I'm not sure what could be the issue, because the logs in CloudWatch aren't giving me much to work with.
To illustrate my issue let's say we have route abc/item that looks like this:
#router.get("/abc/item")
async def get_item(item_id: int, request: Request, db: Session = Depends(get_db)):
if False:
redirect_url = f"/xyz/item?item_id={item_id}"
logging.info(f"Redirecting to {redirect_url}")
return RedirectResponse(redirect_url, headers=request.headers)
else:
execution = db.execute(text(items_query))
return convert_to_json(execution)
So, we check if some value is True/False and if it's False we redirect from abc/item to xyz/item using RedirectResponse(). We pass the redirect_url, which is just the xyz/item route including query parameters and we pass request.headers (as suggested here and here), because I figured we need to pass along the x-api-key to the new route. In the second route we again try a query in a different table (other_items) and return some value.
I have also tried passing status_code=status.HTTP_303_SEE_OTHER and status_code=status.HTTP_307_TEMPORARY_REDIRECT to RedirectResponse() as suggested by some tangentially related questions I found on StackOverflow and the FastAPI discussions, but that didn't help either.
#router.get("/xyz/item")
async def get_item(item_id: int, db: Session = Depends(get_db)):
execution = db.execute(text(other_items_query))
return convert_to_json(execution)
Like I said, when deployed I can successfully connect directly to both abc/item and get a return value if True and I can also connect to xyz/item directly and get a correct value from that, but when I pass a value to abc/item that is False (and thus it should redirect) I get {"message": "Forbidden"}.
In case it can be of any help, I try debugging this using a "curl" tool, and the headers I get returned give the following info:
Content-Type: application/json
Content-Length: 23
Connection: keep-alive
Date: Wed, 27 Jul 2022 08:43:06 GMT
x-amzn-RequestId: XXXXXXXXXXXXXXXXXXXX
x-amzn-ErrorType: ForbiddenException
x-amz-apigw-id: XXXXXXXXXXXXXXXX
X-Cache: Error from cloudfront
Via: 1.1 XXXXXXXXXXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: XXXXX
X-Amz-Cf-Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
So, this is hinting at a CloudFront error. Unfortunately I don't see anything slightly hinting at this API when I look into my CloudFront dashboard on AWS, there literally is nothing there (I do have permissions to view the contents though...)
The API logs in CloudWatch look like this:
2022-07-27T03:43:06.495-05:00 Redirecting to /xyz/item?item_id=1234...
2022-07-27T03:43:06.495-05:00 [INFO] 2022-07-27T08:43:06.495Z Redirecting to /xyz/item?item_id=1234...
2022-07-27T03:43:06.496-05:00 2022-07-27 08:43:06,496 INFO sqlalchemy.engine.Engine ROLLBACK
2022-07-27T03:43:06.496-05:00 [INFO] 2022-07-27T08:43:06.496Z ROLLBACK
2022-07-27T03:43:06.499-05:00 END RequestId: 6f449762-6a60189e4314
2022-07-27T03:43:06.499-05:00 REPORT RequestId: 6f449762-6a60189e4314 Duration: 85.62 ms Billed Duration: 86 ms Memory Size: 256 MB Max Memory Used: 204 MB
I have been wondering if my issue could be related to something I need to add to somewhere in my serverless.yml, perhaps in the functions: part. That currently looks like this for these two routes:
events:
- http:
path: abc/item
method: get
cors: true
private: true
request:
parameters:
querystrings:
item_id: true
- http:
path: xyz/item
method: get
cors: true
private: true
request:
parameters:
querystrings:
item_id: true
Finally, it's probably good to note that I have added custom middleware to FastAPI to handle the two different database connections I need for connecting to other_items and items tables, though I'm not sure how relevant this is, considering this functions fine when redirecting locally. For this I implemented the solution found here. This custom middleware is the reason for the redirect in the first place (we change connection URI based on route with that middleware), so I figured it's good to share this bit of info as well.
Thanks!
As noted here and here, it is mpossible to redirect to a page with custom headers set. A redirection in the HTTP protocol doesn't support adding any headers to the target location. It is basically just a header in itself and only allows for a URL (a redirect response though could also include body content, if needed—see this answer). When you add the authorization header to the RedirectResponse, you only send that header back to the client.
A suggested here, you could use the set-cookie HTTP response header:
The Set-Cookie HTTP response header is used to send a cookie from the
server to the user agent (client), so that the user agent can send it back to
the server later.
In FastAPI—documentation can be found here and here—this can be done as follows:
from fastapi import Request
from fastapi.responses import RedirectResponse
#app.get("/abc/item")
def get_item(request: Request):
redirect_url = request.url_for('your_endpoints_function_name') #e.g., 'get_item'
response = RedirectResponse(redirect_url)
response.set_cookie(key="fakesession", value="fake-cookie-session-value", httponly=True)
return response
Inside the other endpoint, where you are redirecting the user to, you can extract that cookie to authenticate the user. The cookie can be found in request.cookies—which should return, for example, {'fakesession': 'fake-cookie-session-value-MANUAL'}—and you retrieve it using request.cookies.get('fakesession').
On a different note, request.url_for() function accepts only path parameters, not query parameters (such as item_id in your /abc/item and /xyz/item endpoints). Thus, you can either create the URL in the way you already do, or use the CustomURLProcessor suggested here, here and here, which allows you to pass both path and query parameters.
If the redirection takes place from one domain to another (e.g., from abc.com to xyz.com), please have a look at this answer.

Terminating Pexip in Twilio

We are attempting to set up our Pexip Account to make outbound calls to our Twilio account. We successfully have Pexip connecting to Twilio, but are receiving a "407 Proxy Authentication Required". Has anyone successfully been able to have their Pexip account call out to Twilio over SIP?
2021-02-04T14:58:20.140+00:00 pexipconf 2021-02-04 14:58:20,140 Level="INFO" Name="support.sip" Message="Received SIP response" Src-address="XXX.XXX.XXX.XXX" Src-port="5060" Dst-address="10.0.0.11" Dst-port="5060" Transport="UDP" Received-time="2021-02-04T14:58:20,137446" Detail="
SIP/2.0 100 trying -- your call is important to us
Via: SIP/2.0/UDP XXX.XXX.XXX.XXX:5060;branch=z9hG4bKf6XLw5U0Ib3YViSKD71cZkM82EoBeQvJ;rport=5060;received=XXX.XXX.XXX.XXX
From: "ROOM1" <sip:meet.room1#10.0.0.11>;tag=vtHb5o3sipqLRM9d;epid=jWcA8h3fGrxnbv26
To: <sip:+XXXXXXXXXX#XXXXX.pstn.twilio.com>
CSeq: 1710901904 INVITE
Call-ID: 3d3600ea-62bb-4252-aae7-8b243c22fb12
Server: Twilio Gateway
Content-Length: 0
"
2021-02-04T14:58:20.150+00:00 pexipconf 2021-02-04 14:58:20,150 Level="INFO" Name="support.sip" Message="Received SIP response" Src-address="XXX.XXX.XXX.XXX" Src-port="5060" Dst-address="10.0.0.11" Dst-port="5060" Transport="UDP" Received-time="2021-02-04T14:58:20,147110" Detail="
SIP/2.0 407 Proxy Authentication required
CSeq: 1710901904 INVITE
Call-ID: 3d3600ea-62bb-4252-aae7-8b243c22fb12
From: "ROOM1" <sip:meet.room1#10.0.0.11>;tag=vtHb5o3sipqLRM9d;epid=jWcA8h3fGrxnbv26
To: <sip:+XXXXXXXXXX#xyvid.pstn.twilio.com>;tag=90026019_6772d868_2f8d0dd6-90f4-42aa-a165-2e00e5964f5a
Via: SIP/2.0/UDP XXX.XXX.XXX.XXX:5060;received=XXX.XXX.XXX.XXX;branch=z9hG4bKf6XLw5U0Ib3YViSKD71cZkM82EoBeQvJ;rport=5060
Server: Twilio
Contact: <sip:XXX.XXX.XXX.XXX:5060>
Proxy-Authenticate: Digest realm="sip.twilio.com",qop="auth",nonce="mac-Uxca9fW-9FggC2z8lZSbd2KgmidgS66hPf-NStrNhtY1",opaque="b90d5a4f4492449aecc8caf7bc58e864"
Content-Length: 0
"
2021-02-04T14:58:20.153+00:00 pexipconf 2021-02-04 14:58:20,152 Level="INFO" Name="support.sip" Message="Sending SIP request" Src-address="10.0.0.11" Src-port="5060" Dst-address="XXX.XXX.XXX.XXX" Dst-port="5060" Transport="UDP" Detail="
ACK sip:+XXXXXXXXXX#xyvid.pstn.twilio.com SIP/2.0
From: "ROOM1" <sip:meet.room1#10.0.0.11>;tag=vtHb5o3sipqLRM9d;epid=jWcA8h3fGrxnbv26
Call-ID: 3d3600ea-62bb-4252-aae7-8b243c22fb12
To: <sip:+XXXXXXXXXX#xyvid.pstn.twilio.com>;tag=90026019_6772d868_2f8d0dd6-90f4-42aa-a165-2e00e5964f5a
Via: SIP/2.0/UDP XXX.XXX.XXX.XXX:5060;branch=z9hG4bKf6XLw5U0Ib3YViSKD71cZkM82EoBeQvJ;rport
CSeq: 1710901904 ACK
Content-Length: 0
"
Phone numbers and IP addresses changed to protect the innocent.
We do have our Pexip IP address listed in the IP ACL of our Twilio account.
Did you defined a Credential List on your Elastic SIP Trunk? The 407 Proxy Authentication required is asking your SIP User Agent to respond back with its authentication credentials (username and password).

Metasploit: send_request_cgi returns nil for HTTPS connections

I am currently trying to write an auxiliary module for Metasploit. The module basically tries multiple default credentials to get access to the router's management page. The authentication is done via web, i.e. HTTP POST.
Currently, the module works as expected for plain HTTP connections, i.e. unsecured connections, however every connection attempt via HTTPS (port 443), returns nil. Below is the function used within the Metasploit class to retrieve the login page:
def get_login_page(ip)
begin
response = send_request_cgi(
'uri' => '/',
'method' => 'GET'
)
# Some models of ZyXEL ZyWALL return a 200 OK response
# and use javascript to redirect to the rpAuth.html page.
if response && response.body =~ /changeURL\('rpAuth.html'\)/
vprint_status "#{ip}- Redirecting to rpAuth.html page..."
response = send_request_cgi(
'uri' => '/rpAuth.html',
'method' => 'GET'
)
end
rescue ::Rex::ConnectionError
vprint_error "#{ip} - Failed to connect to Web management console."
end
return response
end
When trying to connect via HTTPS, the first send_request_cgi call returns nil. No exception are caught or thrown. I have tried with 3 different hosts to make sure the issue was not with a specific endpoint. All my 3 attempts failed to return a response. At every attempt, I set the RPORT option to 443;
RHOSTS 0.0.0.0 yes The target address range or CIDR identifier
RPORT 443 yes The target port
Note that I have replaced the real IP with 0.0.0.0. Using a web browser, I can actually connect to the router via HTTPS with no issue (other than having to add an exception since the certificate is untrusted) and am presented the login page. With Wireshark, I tried to look at the generated traffic. I can clearly see that nothing is sent by the router. I notice the 3-way handshake being completed and the HTTP GET request being made:
GET / HTTP/1.1
Host: 0.0.0.0
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
There are 3-4 ACK after and then a FIN/PUSH sent by the server.
Based on this page on Metasploit's GitHub, I was under the impression that connections to HTTPS websites were handled by the underlying framework. I have not seen any articles/tutorial/source that leads me to believe otherwise. The doc about the send_request_cgi does not specify any specific requirement to establish a HTTPS connection. Other posts did not had the exact same issue I'm having. At this point I suspect either the OS, the framework or me forgetting to enable something. Other modules I have looked at either only targets HTTP websites - which I doubt - or do not have any special handling for HTTPS connections.
Any help determining the cause would be greatly appreciated.
Version of Metasploit:
Framework: 4.9.3-2014060501
Console : 4.9.3-2014060501.15168
Version of OS:
SMP Debian 3.14.5-1kali1 (2014-06-07)
As per this post on SecurityStreet, the solution was to set SSL to true in the DefaultOptions in the initialize function:
def initialize
super(
...
'DefaultOptions' =>
{
...
'SSL' => true
}
)
...
end
Connections to routers using HTTPS worked afterwards.

How to configure route for oauth callback

I'm using the gem OAuth2 to communicate with Google services. I don't understand how to implement a callback, which receives the response with the OAuth code to get an access token. When I set a breakpoint in the callback method, it never seems to get called.
Here is my code:
Routes:
match '/oauth2/callback' => 'reports#callback'
Actual redirected url:
http://localhost/oauth2/callback?code=111111
ReportsController:
def new
client = OAuth2::Client.new(ENV['GA_CLIENT_ID'], ENV['GA_SECRET_KEY'], {
:authorize_url => 'https://accounts.google.com/o/oauth2/auth',
:token_url => 'https://accounts.google.com/o/oauth2/token'
})
redirect_to client.auth_code.authorize_url({
:scope => 'https://www.googleapis.com/auth/analytics.readonly',
:redirect_uri => 'http://localhost/oauth2/callback',
:access_type => 'offline'
})
end
def callback
oauth_code = params[:code]
# Create access token with oauth_code
end
Google server is trying to access this url http://localhost/oauth2/callback?code=111111 which is not valid.
You need a domain name to use a service like OAuth, because the google server must be able to find your computer over the internet.
To be able to do this from your development machine you should:
Set a name on a known DNS server: The easiest way to do this is through a Dynamic DNS server like dyndns or no-ip
If you are behind a router using NAT, you might need to redirect the requests to your modem on port 80 to your computer: If you don't do this, your modem will receive a package on port 80 from google and will say "not for me", discarding it. You can do this in your modem menu - look for port forwarding or NAT section on it.
The redirect_url passed to google must match exactly the callback url as seen from client's browser. No problem to use localhost in the url (fotanus sentence about DNS and NAT is wrong). If you are running your container in a different port (e.g. 8080) you have to:
Specify the url in google cloud: http://localhost:8080/oauth2/callback
Specify that same return url in the client request.

Resources