NikolaiT / zardaxt

Passive TCP/IP Fingerprinting Tool. Run this on your server and find out what Operating Systems your clients are *really* using.
Other
295 stars 35 forks source link

Interesting fingerprinting .. but how to counter back the fingerprinting by server #9

Open assegaf opened 2 years ago

assegaf commented 2 years ago

Hi it seem this fingerprinting method used by service provider to detect us, and fingerprinting us by our uptime by tcp_timestamp. the request "may" from single machine ..

we mostly use linux, how to counter back that our request cant be tracked uptime, I dont want they detect our uptime is 0, something like random .. every request session will be good.

I know this is not issue, but as user we want the experience as "random" user

NikolaiT commented 2 years ago

Great comment.

Currently, zardaxt.py does not allow to infer the uptime from clients. I will implement this soon.

assegaf commented 2 years ago

infer

sure it does, "tcp_seq": 41798829, "tcp_timestamp": 1082970574,

second and so on request, timestamp is increasing (almost like by seconds), but it sure conclude our (client) uptime

NikolaiT commented 2 years ago

As of https://floatingoctothorpe.uk/2018/detecting-uptime-from-tcp-timestamps.html, most modern Linux Kernels add a random offset, which effectively prevents getting uptime information:

On Linux the TCP timestamp feature can be controlled with the net.ipv4.tcp_timestamp kernel parameter. Normally the option can either be enabled (1) or disabled (0), however more recent kernels also have an option to add a random offset which will effectively hide the systems uptime.

Do you think it is still possible with other OS such as Mac OS or Windows?

assegaf commented 2 years ago

As of https://floatingoctothorpe.uk/2018/detecting-uptime-from-tcp-timestamps.html, most modern Linux Kernels add a Do you think it is still possible with other OS such as Mac OS or Windows?

I believe billion of users use linux kernel on mobile phone android and derivative os, and mostly behind nat, public ip used shared by people. maybe 1 public ip used by thousand users, I understand google or vendor use this method to fingerprint request (tcp timestamp -> uptime), so they know if the activity may came from single phone user. I support their method, but sometime detecting uptime is I believe violating internet neutrality, I support if they catch our serial number phone, msisdn or imei, and said so, that will be better and will be 100% match.

update : I checked most linux kernel on android dont add such random offset, purely detected our timestamp, tested. on 3.x kernel and 4.x, not sure 5.xx which is rarely

NikolaiT commented 2 years ago

You know what? You always answer immediately, I will now finally put some effort into implementing the uptime detection lol :)

NikolaiT commented 2 years ago

Hey there

I now implemented the TCP Timestamp Uptime detection method.

For example, this is an Android client visiting my API:

  "xxx": {
    "avgScoreOsClass": {
      "Android": "avg=8.63, N=230",
      "Linux": "avg=7.4, N=360",
      "Windows": "avg=3.82, N=1378",
      "iOS": "avg=6.21, N=152",
      "macOS": "avg=6.03, N=791"
    },
    "bestNGuesses": [
      {
        "os": "Android",
        "score": "11.5/11.5"
      },
      {
        "os": "Android",
        "score": "11.5/11.5"
      },
      {
        "os": "Android",
        "score": "11.5/11.5"
      }
    ],
    "fp": {
      "dst_ip": "167.99.241.135",
      "dst_port": "443",
      "ip_df": 1,
      "ip_frag_off": 16384,
      "ip_hdr_length": 20,
      "ip_mf": 0,
      "ip_opts": [],
      "ip_ttl": 47,
      "packet_received": 271287.240251633,
      "src_ip": "xxx",
      "src_port": "8663",
      "tcp_ack": 0,
      "tcp_flags": 2,
      "tcp_header_length": 160,
      "tcp_mss": 1400,
      "tcp_options": "M1400,S,T,N,W9,",
      "tcp_seq": 1169439206,
      "tcp_timestamp": 5113137,
      "tcp_timestamp_echo_reply": 0,
      "tcp_urp": 0,
      "tcp_window_scaling": 9,
      "tcp_window_size": 65535,
      "ts": 1661523812,
      "uptime_interpolation": {
        "hz": 100,
        "hz_observed": 100.00921106899875,
        "num_timestamps": 5,
        "uptime": "14:12:11.610000"
      }
    },
    "perfectScore": 11.5
  },

And this is another Android client visiting:

  "xxx": {
    "avgScoreOsClass": {
      "Android": "avg=8.5, N=230",
      "Linux": "avg=7.36, N=360",
      "Windows": "avg=3.75, N=1378",
      "iOS": "avg=6.12, N=152",
      "macOS": "avg=5.99, N=791"
    },
    "bestNGuesses": [
      {
        "os": "Android",
        "score": "11.5/11.5"
      }
    ],
    "fp": {
      "dst_ip": "167.99.241.135",
      "dst_port": "443",
      "ip_df": 1,
      "ip_frag_off": 16384,
      "ip_hdr_length": 20,
      "ip_mf": 0,
      "ip_opts": [],
      "ip_ttl": 56,
      "packet_received": 271093.331470479,
      "src_ip": "xxx",
      "src_port": "56176",
      "tcp_ack": 0,
      "tcp_flags": 2,
      "tcp_header_length": 160,
      "tcp_mss": 1318,
      "tcp_options": "M1318,S,T,N,W9,",
      "tcp_seq": 1123668072,
      "tcp_timestamp": 9224529,
      "tcp_timestamp_echo_reply": 0,
      "tcp_urp": 0,
      "tcp_window_scaling": 9,
      "tcp_window_size": 65535,
      "ts": 1661523618,
      "uptime_interpolation": {
        "hz": 100,
        "hz_observed": 100.02616967315814,
        "num_timestamps": 7,
        "uptime": "1 day, 1:37:25.480000"
      }
    },
    "perfectScore": 11.5
  }

Many (older?) Android clients have a timestamp tick of 100hz (10ms), whereas most newer clients have a timestamp tick of 1000hz (1ms). Some also seem to have 250hz (2.5ms). It seems like uptime detection shows reasonable numbers for the above two Android samples.

Can you confirm?

assegaf commented 2 years ago

awesome ...

assegaf commented 2 years ago

Based on the tcp_timestamp, its calculation is correct, if its start with 0.

I am more interested on if possible detection to assume that two request with same public ip address, (remember that 4g/mobile use shared public ipv4), its coming from same device or not, like percentage possibility, based on just tcp_sequence, and I am compiling custom kernel on android linux to make sure detection like that will be 0% possibility. That's it.