How to increase privacy on spy phones with your Librem5

Hello,

This tutorial and script is useful only for people who have to use a spy phone for specific apps and are motivated enough to diminish the constant privacy violation
It can also be used to check what any device with wifi is doing behind your back

Here are some advices :

  1. You should buy a “Silent pocket” Phone Faraday Sleeve (out of stock now …) / Phone Faraday Sleeve – Purism
    I got one from purism, I tested only GPS and Wifi 2.4G, but both are blocked if you close correctly the pocket (open = not blocking)
    And take the phone out of the pocket only when you really need it

  2. You should try to install LineageOS on the spy phone (if compatible), and use an alternative app store, it will be much better than the not up-to-date OS provided by default (lineageOS propose regular updates)

  3. You should put your SIM card in the Librem5, use Wi-Fi tethering to provide Internet to your SIMless spy phone
    In this post, I provide a script to ease the way to block all traffic and authorize only a whitelist of IP for your apps to work

How does it work ? it uses iptables, so you will need to use sudo to start or stop blocking
by default it will block all connection to all IP on all port coming from the tethering, so by default your spy phone cannot access anything on internet using your Librem5 wifi

So, to authorize an application YOU need to analyze which IP address the phone want to connect to when the app start or try to connect somewhere

To help you with this task, the script will configure iptable to log any attempt to any IP address on any port
So by default every attempt is logged and is visible with journalctl
I made 2 options :
./block_connections.sh live
./block_connections.sh logs

the option ‘live’ is printing any live attempt (ctrl+c to stop)
the option ‘logs’ deduplicate and print the IP addresses from the last 50 attempts, so maybe you can see only 13 IP addresses

Now you can see some IP, cool but what IP is related to your app ?

  1. you can use some web tools like abuseipdb.com or dnschecker.org/reverse-dns.php?query= to give you an hint, but sometimes it’s not giving any hint
  2. So, you can also use the command ‘host’ on your linux to check if the IP address correspond to the website of the app you use
    example :
    52.142.124.215 is not recognize with the web tools, but I know the app is using DuckDuckGo
    when I do
    host duckduckgo.com
    I can see
    duckduckgo.com has address 52.142.124.215
  3. If you didn’t find anything about the IP, you need to try many time you application and see, which IP appears again and again at every attempts, try to authorize it and see if it help or not

Ok now that we have validated 52.142.124.215 is related to duckduckgo.com
We can do 3 things :

  • Add the IP 52.142.124.215 to the ‘IP_blacklist’ variable in the script if you want it to stay blocked and disappear from the log when an attempt to this IP is made
  • Add the IP 52.142.124.215 to the ‘IP_whitelist’ variable in the script if you want it to be authorized always and disappear from the log when an attempt to this IP is made
  • Add a new profile so you can authorize or block at will any IP for your duckduckgo app
    There are examples in the script for those 3 possibilities

If you are still interested after this, then copy the following script in your Librem5

#!/bin/bash

if [ "$1" == "-h" ] || [ "$1" == "--help" ] ; then
    echo -e "Usage : script <start|stop|switch|profil> [profil_option]
OPTIONS:                                                                                                                                                                    
  start               Start blocking - Initialise and insert the iptable chain CLIENT_WHITELIST in first position in FORWARD                                                
  stop                Stop blocking - Remove CLIENT_WHITELIST from FORWARD                                                                                                  
  switch              Act like 'stop' or 'start' if CLIENT_WHITELIST is in or not in FORWARD                                                                                
  reset               Update iptables with the changes you mabe in IP_whitelist and/or IP_blacklist                                                                         
  logs                Show the last IP adresses in the last 50 connection attempt                                                                                           
  live                Show the current connection attempts, ctrl+c to stop                                                                                                  
  profil start <name> Authorize access to the IP addresses of the profil <name>                                                                                             
  profil stop <name>  Remove access to the IP addresses of the profil <name>                                                                                                
"
    exit 0
fi

# -------------------- init --------------------------                                                                                                                      
iptables -L FORWARD | grep -q "CLIENT_WHITELIST"
flg_is_present=$?

# -------------------- lists --------------------------                                                                                                                     
# Whitelist                                                                                                                                                                 
IP_whitelist="192.168.1.0/24                                                                                                                                                
138.68.253.24
128.140.118.223
"

# profil LineageOS update                                                                                                                                                   
profils="LINEAGE 104.26.14.42 104.26.15.42 116.202.242.188 130.225.254.116 172.67.69.209 128.112.18.21 89.102.0.150 141.70.124.1"

# profil duckduckgo                                                                                                                                                         
profils="${profils}                                                                                                                                                         
DUCK 52.142.124.215"

# profil F-DROID store                                                                                                                                                      
profils="${profils}                                                                                                                                                         
FDROID 89.149.59.178"

# Blacklist Google                                                                                                                                                          
IP_blacklist="                                                                                                                                                              
35.227.200.0                                                                                                                                                                
35.244.172.51                                                                                                                                                               
34.54.163.57                                                                                                                                                                
34.89.151.119                                                                                                                                                               
34.102.162.219                                                                                                                                                              
34.102.213.67                                                                                                                                                               
34.117.147.68                                                                                                                                                               
142.251.39.195                                                                                                                                                              
142.251.142.3                                                                                                                                                               
142.251.152.119                                                                                                                                                             
142.251.153.119                                                                                                                                                             
142.251.154.119                                                                                                                                                             
142.251.155.119                                                                                                                                                             
142.251.156.119                                                                                                                                                             
142.251.157.119                                                                                                                                                             
172.217.20.35
172.217.22.35
216.239.32.223
216.239.34.223
216.239.36.223
216.239.38.223
"

# Blacklist Facebook
IP_blacklist="${IP_blacklist}
157.240.202.14"

# Blacklist useless IP I don't need for my profils to work
IP_blacklist="${IP_blacklist}
"

# ------------------ functions -----------------------                                                                                                                      
init_chain() {
    # Test if chain exist and add if not                                                                                                                                    
    iptables -L CLIENT_WHITELIST > /dev/null
    [ $? -ne 0 ] && iptables -N CLIENT_WHITELIST

    # ACCEPT Whitelist                                                                                                                                                      
    for IP in ${IP_whitelist} ; do
        iptables -A CLIENT_WHITELIST -d ${IP} -j ACCEPT
    done

    # DROP Blacklist                                                                                                                                                        
    #for IP in ${IP_blacklist} ; do                                                                                                                                         
#       iptables -A CLIENT_WHITELIST -d ${IP} -j DROP                                                                                                                       
 #   done                                                                                                                                                                   

    # Log everything else (non-whitelisted destinations)                                                                                                                    
    #iptables -A CLIENT_WHITELIST -j LOG --log-prefix "CLIENT_BLOCKED: " --log-level 4                                                                                      

    # Drop non-whitelisted traffic                                                                                                                                          
    iptables -A CLIENT_WHITELIST -j DROP
}

reset_chain() {
    # Flush all the rules in the chain                                                                                                                                      
    iptables -F CLIENT_WHITELIST

    init_chain
}

start_blocking() {
    echo "- Start blocking"
    # Test if chain exist and initialize it if not                                                                                                                          
    iptables -L CLIENT_WHITELIST > /dev/null
    [ $? -ne 0 ] && init_chain

    # Insert custom chain in first position in FORWARD                                                                                                                      
    iptables -I FORWARD 1 -i wlan0 -j CLIENT_WHITELIST
}

stop_blocking() {
    echo "- Stop blocking"
    # Determine the exact line to delete the right one, in case it's not in first position                                                                                  
    local line=$(iptables -L FORWARD -n --line-numbers | grep "CLIENT_WHITELIST" | awk '{print $1}')
    iptables -D FORWARD "${line}"
}

profil_start() {
    local PROFIL=$1
    [ "${PROFIL}" == "" ] && echo -e "\e[031mError\e[0m : Option 'profil start' must be followed by profil name" && exit 1

    local list=$(echo "${profils}" | grep "^${PROFIL} ")
    [ "${list}" == "" ] && echo -e "\e[031mError\e[0m : Profil inconnu : '${PROFIL}'" && exit 1

    local verif=$(iptables -L --line-numbers | grep "${PROFIL}")
    [ "${verif}" != "" ] && echo -e "\e[031mError\e[0m : Profil already set : '${PROFIL}'" && exit 1

    for IP in ${list} ; do
        [[ "${IP}" =~ ^[1-9] ]] && iptables -I CLIENT_WHITELIST 1 -d "${IP}" -j ACCEPT -m comment --comment "${PROFIL}"
    done
}

profil_stop() {
    local PROFIL=$1
    [ "${PROFIL}" == "" ] && echo -e "\e[031mError\e[0m : Option 'profil stop' must be followed by profil name" && exit 1

    echo "${profils}" | grep -q "^${PROFIL} "
    [ $? -ne 0 ] && echo -e "\e[031mError\e[0m : Profil inconnu : '${PROFIL}'" && exit 1

    local list=$(iptables -L --line-numbers | grep "ACCEPT" | grep "/\* ${PROFIL} \*/" | awk '{ print $1}' | sort -rn)
    local rule_nb
    for rule_nb in ${list} ; do
        [[ "${rule_nb}" =~ ^[1-9] ]] && iptables -D CLIENT_WHITELIST "${rule_nb}"
    done
}

# -------------------- main --------------------------                                                                                                                      
if [ "$1" == "start" ] ; then
    [ ${flg_is_present} -eq 0 ] && echo -e "\e[031mError\e[0m : Rules already set" && exit 1
    start_blocking
elif [ "$1" == "stop" ] ; then
    [ ${flg_is_present} -ne 0 ] && echo -e "\e[031mError\e[0m : Rules not set" && exit 1
    stop_blocking
elif [ "$1" == "switch" ] ; then
    if [ ${flg_is_present} -eq 0 ] ; then
        stop_blocking
    else
        start_blocking
    fi
elif [ "$1" == "profil" ] ; then
    if [ "$2" == "start" ] ; then
        [ ${flg_is_present} -ne 0 ] && start_blocking
        profil_start "$3"
    elif [ "$2" == "stop" ] ; then
        profil_stop "$3"
    else
        echo -e "\e[031mError\e[0m : Option profil must be followed by start or stop"
        exit 1
    fi
elif [ "$1" == "reset" ] ; then
    reset_chain
elif [ "$1" == "logs" ] ; then
    echo "- Last blocked IPs :"
    journalctl -n 50 -g "CLIENT_BLOCKED: " | awk '{ print $11 }' | cut -d'=' -f2 | sort | uniq
elif [ "$1" == "live" ] ; then
    journalctl -f -g "CLIENT_BLOCKED: "| awk '{ print $3 " " $11 }'
else
    echo -e "\e[031mError\e[0m : Missing or unknown parameter"
    exit 1
fi

#iptables -L                                                                                                                                                                
exit 0

make sure you a have the right to execute :
chmod u+x ./block_connections.sh

Now, hands-on work :

  • Start your tethering
  • Execute ‘sudo ./block_connections.sh start’
  • Execute ‘sudo ./block_connections.sh live’
  • Connect the spy phone to your Librem5 WiFi
  • You will probably see a lots IP address appearing
  • Stop the script with ctrl+c
  • Try to determine if you want to block or authorize those IP, and add them to ‘IP_blacklist’, ‘IP_whitelist’, or in ‘profils’
  • If you add something to ‘IP_blacklist’ or ‘IP_whitelist’, you need to do ‘sudo ./block_connections.sh reset’, it will apply your changes
  • If you add a new profile (example DUCK), you just need to execute sudo ./block_connections.sh profil start DUCK to authorize the IPs of the profil and sudo ./block_connections.sh profil stop DUCK to block those IPs again
  • Now execute sudo ./block_connections.sh live, start the application you want to authorize and try to determine if you want to block or authorize those IP
  • If you want to stop blocking you just have to execute sudo ./block_connections.sh stop, or sudo ./block_connections.sh switch

Once you have, configure everything you can disable the logs, by adding a # in front of the line :
iptables -A CLIENT_WHITELIST -j LOG --log-prefix "CLIENT_BLOCKED: " --log-level 4
you can also disable the 3 lines of the ‘for’ loop just before this line which handle IP_blacklist, which is useful only for reducing logs and knowing what you already disapprove

Some remarks :

  • You can enable the iptables -L at the end of the script to see every changes made to iptables after every execution
  • I put 192.168.0.0/24 in the IP_whitelist just to show you can put your own LAN if you need it, remove this if useless…, same with 138.68.253.24 (puri.sm) and 128.140.118.223 (forums.puri.sm) only here for example
  • For ease, you should SSH on your Librem5 from your computer

/!\ One last important thing : you need to execute sudo ./block_connections.sh start AFTER activating the tethering
every time AFTER you reactivate tethering : sudo ./block_connections.sh stop + sudo ./block_connections.sh start
because when you activate the tethering, it adds an iptable rule which authorize everything and is acting BEFORE the rule added by my script, so we need to put the rule of my script in first position

Feel free to criticize/copy/modify/redistribute the script

3 Likes

This means no sim or the modem goes crazy pinging about for a tower in a Faraday sack and burns off battery% though I guess it still pings away for emergency services calls. There is a non-root command to ignore modem etc in the phone and not have the android calling app show,

setprop gsm.radio.enabled true(or false)

then I recall it needing a reboot for the change to take hold. I am not sure exactly how much that truly affects modem though since the modem is super tightly tied into android hardware to the point that it shares RAM DMA.

I posted a few weeks ago how to BT tether from your Librem, that saves some battery on both devices. Bluetooth PAN network tethering - #4 by biketool

You can also use e.g.
whois $ip
and/or
nslookup $ip

(and really these days you are supposed to use dig instead of nslookup, specifically dig -x in this case). They may provide no useful info or they may be helpful. So they are just extra tools to investigate an IP address.

However I would have some concerns about blocking that is based on IP address - because IP addresses can change or even be completely dynamic.

So longer term I would probably look at supplementing this with DNS poisoning (like PiHole). If nothing else, logging DNS requests on the Librem 5 would show you what domain name, if any, the dodgy app looked up in order to arrive at the IP address that you now may want to block.

This is an interesting take.