Captive Portal Page with MITM - android

I have a micro-computer designed to show customers a portal page when they sign-in the Wi-Fi network.
The problem is that for some reason they don't get the usual popup from the phone/pc where as when I do the same with my router it works.
I'm doing the whole process by transferring all dns request to a local network (i.e 10.0.0.2).
When going to the browser they get the portal page, but the behaviour is missing. (connecting to the Wi-Fi then an automatic popup appears saying that you need to log in to the network).
on the local apache i have a simple index.php file with status code of 401 (unauthorised).
The micro-computer is connected via Ethernet port to the router, and I have full-control of the router, yet I want the captive portal be managed from the micro-computer itself, thats why I'm not using router based captive portals.
Tal.

Your question isn't very clear to me.
Are you using a browser on the phone/pc or an application? Can you provide a screenshot of the expected behavior?
I'll try to answer it from what I think you are asking:
For a browser, you can use your DNS or ICMP to redirect a client to your Captive Portal. ICMP is layer 3 protocol and some platforms (like Android) might automatically trigger a native notification to the user, like "Hey you need to sign in". But the DNS redirect won't trigger this, it requires user interaction with a browser after connecting to the network. They'll open a browser, try to go to stack overflow.com and get redirect to your captive portal.
Also, for an application on Android, you have to check a URL connection. Here is an example taken from AOSP:
private static final String mWalledGardenUrl = "http://clients3.google.com/generate_204";
private static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
private boolean isWalledGardenConnection() {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(mWalledGardenUrl); // "http://clients3.google.com/generate_204"
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setInstanceFollowRedirects(false);
urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
urlConnection.setUseCaches(false);
urlConnection.getInputStream();
// We got a valid response, but not from the real google
return urlConnection.getResponseCode() != 204;
} catch (IOException e) {
if (DBG) {
log("Walled garden check - probably not a portal: exception "
+ e);
}
return false;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}

Solutions :
Possibility 1 :
You need to have a very specific configuration on your router because he is the relay to your Micro-Computer, plus as i guess your micro-computer is going to internet through the router, you also need to take that in consideration
Disable DNS Service on your router
Set DNS on your router to 10.0.0.2
Disable gateway to Internet on your router or set it to 10.0.0.2
Set all real servers/gateway manually on your Micro-Computer, and also routes are very important in this case.
Possibility 2 :
Don't forget that some devices have their DNS set manually or with specific network configuration or having a specific firewall that watch uncommon DNS server/request then you have to take that in consideration, best solution to avoid that is running the DNS Server on the gateway ip it mean that your DHCP Server need to be on the Mini-Computer or use a gateway on the Mini-Computer or use possibility 3... this imply checking the gateway that you are using i guess it's the router gateway.
Also you could have a conflict between router job and Micro-Computer Job, and ip conflict like communication between client and Micro-Computer blocked in some case, then check your ip configuration.
Possibility 3 :
If your router is open-source ou open-source convertible you can use DDWRT or OpenWRT to manage your hotspot there are a plenty of configurable hotspots in just few click and you can link them to your Micro-Computer server for users data base or dns or proxy or dhcp or redirect the request to your Micro-Computer or whatever.
Possibility 4 :
Have a look at this MITM Guide and check if you are missing something
Note :
If my answer did not help please provide more technical debugging infos because other than just a description of the configuration we don't know much... i'll be pleased to help :)... also give full config of your network it seems that it's a network issue.

Related

Why is my Android phone sending data through an unknown server?

I've been creating an app to learn how Android works and just playing around with various features like the sensors, SMS listeners, phone listeners, wifi listeners, etc.
I recently added a bit of code from the Android Volley library to send a request to my website every time it connects to a wifi network (I don't have a cellular data plan).
It sends a GET request to a very sparse text file that returns back:
hello
The odd thing is that after connecting to open public wifi networks, oftentimes the response that the phone gets from this same request will be:
<html>
<title>Redirecting...</title>
<script language="javascript">
document.location.href="http://den-80202-7200.localdomain:8000/index.php?zone=pms&redurl=http://my-personal-server.com/hello
</script>
</html>
Which is really strange to me, as it will return this even the next day, connecting to other networks, connecting to my secured network at home, etc.
And I have no idea what this URL is:
http://den-80202-7200.localdomain:8000
It appears to me, (still learning about how this all works), that my phone is sending my GET request to my website, but somehow my website is returning back this possibly infected response, which, if I was in a browser may harm me. Maybe my website server is infected with something?
Or, my phone has malware that is sending all my requests through this unknown server?
Is that what is going on? How to prevent my phone from keep sending requests through this unknown server? I did a virus scan and it comes up clean. Is there a way to flush the phone's DNS cache or something similar?
While in general it's good to be suspicious about hijacked or modified requests on open wifi networks, in this case it appears to be expected behavior for public wifi networks.
Specifically, many public wifi networks require authentication either for paid access or to accept terms of service. To accomplish this, they will often intercept HTTP requests from unauthenticated clients and return a response which redirects them to a captive portal.
Since .localdomain is not a valid TLD, this URL will not work outside a network without a local DNS entry for it. This appears similar to the use of .local as a reserved TLD for local-network only DNS entries. Again, this is indicative of public wifi networks using .localdomain URLs to redirect to a locally hosted captive portal.
Note also that the redirect URL has the parameter "redurl=http://my-personal-server.com/hello", this specifies the URL that you'll be redirected to after your authenticate. As expected, this was the original URL you requested.
NOTE: As for this showing up on your private wifi networks afterwards, I suspect this is a caching issue. Again, since .localdomain isn't a valid TLD the request to "http://den-80202-7200.localdomain:8000" will fail outside of the public wifi network with support for this specific DNS entry.
Maybe your system is infected with Malware or SpyBots.
Check out below link:
http://www.speedguide.net/port.php?port=8000

How prevent Chrome mobile routing packets through US Compression proxy

I'm debugging an API on my home development environment with the IP range 192.168.0.0-255.
I'm in Australia (relevant for reasons below), the API's written in PHP, and I'm running Apache.
My server IP = 192.168.0.20
My router is configured to forward HTTP requests to this IP.
My router's internal IP is 192.168.0.1 and external IP is, for this example, 123.123.123.123
For the following cases:
Laptop, all browsers, over wi-fi
Android tablet, all browsers, over wifi
Android phone, using Internet browser, over wifi
the server detects $_SERVER['REMOTE_ADDR'] = 123.123.123.123.
The latency is effectively zero and no caching occurs. So far, all as expected.
However, when I submit the same query from an Android mobile phone (assigned the IP of 192.168.0.10) in Chrome over the same wi-fi connection, the server detects:
$_SERVER['HTTP_X_FORWARDED_FOR']: 123.123.123.123
$_SERVER['HTTP_FORWARDED']: 123.123.123.123
$_SERVER['REMOTE_ADDR'] : 66.249.84.217`
The 'REMOTE_ADDR' also takes on the values 66.249.84.223 and 66.249.84.229
There is a delay of ~400ms and my API is being cached - hence not returning correct/latest values.
Relevant parts of HTTP header:
Forwarded: for=123.123.123.123
Scheme: http
Via: 1.1 Chrome-Compression-Proxy
I see 66.249.84.0-255 belongs to Google, and understand why compression may often be useful in mobile context. But in my case I'd rather avoid the extra latency of a round-world-trip.
When I run the same queries over HTTPS, no re-routing through Googles's servers occurs.
Is there any way to avoid Chrome mobile re-routing my packets?
Your request is, presumably, being routed through Google's Data Compression Proxy.
Since Google does not try to hijack your SSL certificates, no such rerouting is being done for SSL connections.
On the client side, a user can simply disable this in settings with Settings > Bandwidth Management > Reduce data usage.
On the server side, it's too late to "undo" the routing, though you can indicate with a Cache-Control: no-transform header that you don't want your response transcoded.
From the Google Developer Docs:
As a site owner, how do I opt-out from content optimization?
Data compression proxy respects the standard Cache-Control: no-transform directive. Site owners can mark individual resources with this directive and the proxy will pass them through directly to the mobile browser.
https://developer.chrome.com/multidevice/data-compression
Yes, same answer for me. I have a network camera in New Zealand I access from Canada. I noticed a bunch of suspicious access in the Access Log in the range 66-xx-xx-xx, and believing the camera had been hacked I immediately added an access denial for that range (at the time I knew the range was owned by google ... but as far as I was concerned at the time it could have been a cloud machine of unknown purpose.)
Then noticing I could no longer access the netcam on chrome on my mobile (but could on the default browser, and any windows browser) It became clear that there was some kind of proxy in the middle. Further research led me here.
Here's some more info -
https://developer.chrome.com/multidevice/data-compression
Turning off Reduce Data Usage in chrome settings immediately restored access to my netcam
I have to wonder what's in it for google ? what valuable info are the mining from my traffic as it passes through their proxy?

Android: HTTP connection to localhost web site

I am developing a tablet application which needs to connect to a web site to collect online content.
I have seen that we can indeed connect to a web server on a local system by addressing it via it's IP address.
However, I am using virtual hosts on my system, so as to use virtual domains.
This is setup on my system in the apache httpd-vhosts.conf file like this -
#
# Project wordpress dev site
#
<VirtualHost *:80>
DocumentRoot "C:/web/www/boutique"
ServerName boutique.project.dev
</VirtualHost>
with my hosts file having the following entry
127.0.0.1 boutique.project.dev # project woocommerce site
I am using the HttpPost and HttpClient classes and I cannot see how I can provide the real IP address whilst still transmitting the host name in the URL request.
So, what I need to know is how can I make queries from my application using the virtual address " boutique.project.dev " ?
Is this possible ?
Edit :
Following one comment, I need to make things more clearer.
I am wanting to do this in code. Each time we make a connection to a site, the URL does a DNS lookup to determine the IP address to use. I need to intercept this and provide the IP address of my local system. I have seen some examples for proxy's using HttpHost, but I am unclear as to how to use this or even if it is relevant.
I think you don't do that unless you modify host file in android device (with root permissions)
This is a similar question: Apache Virtual Host (Subdomain) access with different computer on LAN
You also could setup a DNS server in your computer (i.e bind9) and set entries for your apache virtualhost and configure android in order to use that DNS server.
Here is the solution which I hope will avoid some useless "banging the head against a wall" for those of you who might have the same need.
Two or three steps are necessary.
1st step : Open the firewall to allow connections.
This is obviously necessary or else, whatever you do the connection will not be made. I use Comodo and so I added a rule in the firewall permitting all connections coming from the local LAN.
2nd step : Tell your server, apache in my case, to listen on its IP address.
I added the following entry in my httpd.conf file :
Listen [my ip address]:80
3rd step : Code the connection
The key to getting this to work is to tell which virtual server is needed. So, without further boring details, here is the code :
// setup the needed objects
HttpClient client = new DefaultHttpClient();
// create the request using the IP address of the server machine
HttpGet request = new HttpGet("http://[target ip address]:80/testpage.php");
// here is the code magic - manually set the host header
request.setHeader(HttpHeaders.HOST, "boutique.project.dev");
// now execute the request
HttpResponse response = client.execute(request);
// read back the response as normal
....
The result is that the apache server will map the request to the virtual host.
I hope this will be useful for others here !
Oh, I almost forgot, don't forget to enable the WiFi on your tablet - can save hours of wondering why it doesn't work !

Rest client logging for AndroidAnnotations

I am attempting to use AndroidAnnotation's rest client to access a web service. I am receiving the following error:
org.springframework.http.converter.HttpMessageNotReadableException:
Could not read JSON: Unexpected character ('f' (code 102)):
was expecting double-quote to start field name
How can I make the rest client log the actual response it received? I can't imagine why my web service is returning this response, but I can't debug it unless I can see the full response. Do I have to set some kind of option at the level of the Spring framework?
I would also like to see the body of the request I am sending.
Thanks for your help!
Here we see that AndroidAnnotations is a wrapper around the Spring Android RestTemplate Module. The code for the RestTemplate is here. So we can find out which TAG is used for logging:
private static final String TAG = "RestTemplate";
Are you not able to see log entries for this TAG? Which converter / extractor are you using? Please post the call stack.
In the wiki they recommend to use a Interceptor for logging request / response. So you could implement your own interceptor like:
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] data, ClientHttpRequestExecution execution) throws IOException {
logRequest(request);
ClientHttpResponse response = execution.execute(request, data);
logResponse(response);
return response;
}
private void logRequest(HttpRequest request) {
// log it
}
private void logResponse(ClientHttpResponse response) {
// log it
}
}
You enable the interceptor in the #Rest annotation (field interceptors).
While I do not use AndroidAnnotations and cannot answer your question directly, I would like to propose an alternative solution. You could use a great little utility program called Fiddler. It can do wonders for debugging networking activity, whether it be requests, responses, HTTP headers or practically anything else that would matter in a REST API communication.
You can find a full tutorial on how to setup your environment to use Fiddler here, but to name a few crucial steps (credit goes to the linked page, you can also find helpful pictures there)
Setup Fiddler:
Click menu Tools | Fiddler Options, then select the Connections tab
Make note of the “Fiddler listens on” port (normally it’s 8888)
Make sure the check box for “Allow remote computer to connect” is checked
Switch to the HTTPS tab
Make sure the check boxes for “Capture HTTPS Connects” and “Decrypt HTTPS traffic” are both checked
Restart Fiddler
Make note of the PC’s IP address Close non essential apps on the Windows PC (to minimize web traffic being routed through Fiddler)
Setup your device:
Tap on Settings, then Wi-Fi
Find the network on which you’re connected (normally the first one listed), then tap and hold
Choose Modify network from the pop-up
Scroll down and enable “Show advanced options”
Change “Proxy settings” to Manual
Under “Proxy host name” enter the Windows PC IP address from above
Under “Proxy port” enter the Fiddler port from above (usually 8888)
Tap Save and wait a moment for the network to reconnect
Now you will see all the needed details for your REST API calls which makes debugging much easier.

Client Server Programming In Unity using JavaScript

I'm new to Network programming in Unity3D and basically I would like to make a connection between two android devices, through WiFi using the Client Server Model. And I have some questions.. such as
How it is possible to make a server with a specific IP Address?
How can I make a client, who will connect to that server?
How can I transfer messages between client(s) and server?
Any help would be appreciated..
.......
I have write this simple code...
function OnGUI()
{
if(GUILayout.Button(" Initlized server"))
{
Network.InitializeServer(32,25001,false);
Debug.Log("Server has been Initlized");
}
if(GUILayout.Button("connect to server"))
{
Network.Connect("127.0.0.1",25001);
}
}
function OnConnectedToServer() {
Debug.Log("Connected to server");
// Send local player name to server ...
}
I have write this simple code but OnConnectedToServer doesnot give me any responce...
How it is possible to make a server with a specific IP Address?
For the IP address part, you will need a static IP. If you are behind a router, that means you will have to first ensure your ISP gives you a static IP. If they don't, you should try a service such as FreeDNS, which will route your dynamic IP to a web address. You will then need to port forward the specific ports to the server, which should have a static local IP for easy port forwarding.
As for the code itself, I would highly recommend you take a look at THIS website. It has great video tutorials on making a client-server game using Unity's built in networking.
http://www.gamertogamedeveloper.com/
As for your code, you don't state how you run that code. You SHOULD NOT have the client and server being run in the SAME instance. What you need to do to test this is run the Server inside the Unity3d debugger then build the client and run it as a standalone app.
Raknet seems interesting,
have a look here:
RakNet
unity-Raknet

Categories

Resources