From ac0d27e62d271bc5bbf1168da3231b39820ebb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valent=C3=ADn=20Blanco?= Date: Wed, 31 Mar 2021 17:35:56 +0200 Subject: [PATCH 1/5] PoC changes to be Android compatible --- osflags | 6 +++++- src/main.cpp | 8 +++++++- src/tun.cpp | 12 +++++++++--- src/tun_dev_linux.c | 8 +++++++- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/osflags b/osflags index fb41a49..3515718 100644 --- a/osflags +++ b/osflags @@ -16,7 +16,11 @@ ld) c) case $OS in LINUX) - echo $FLAGS -DHAVE_LINUX_IF_TUN_H -DLINUX + if [ `uname -o | tr "a-z" "A-Z"` = "ANDROID" ]; then + echo $FLAGS -DHAVE_LINUX_IF_TUN_H -DLINUX -DANDROID + else + echo $FLAGS -DHAVE_LINUX_IF_TUN_H -DLINUX + fi ;; CYGWIN*) echo $FLAGS -DWIN32 diff --git a/src/main.cpp b/src/main.cpp index 99b1226..e5d1624 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,6 +41,12 @@ #define AI_V4MAPPED 0 #endif +#ifdef ANDROID +#define AI_FLAGS (AI_ADDRCONFIG) +#else +#define AI_FLAGS (AI_V4MAPPED | AI_ADDRCONFIG) +#endif + using std::string; static Worker *worker = NULL; @@ -226,7 +232,7 @@ int main(int argc, char *argv[]) struct addrinfo *res = NULL; hints.ai_family = AF_INET; - hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; + hints.ai_flags = AI_FLAGS; int err = getaddrinfo(serverName.data(), NULL, &hints, &res); if (err) diff --git a/src/tun.cpp b/src/tun.cpp index 8bfeb58..3beb092 100644 --- a/src/tun.cpp +++ b/src/tun.cpp @@ -36,6 +36,12 @@ #include #endif +#ifdef ANDROID +#define IFCONFIG_PATH "ifconfig " +#else +#define IFCONFIG_PATH "/sbin/ifconfig " +#endif + typedef ip IpHeader; using std::string; @@ -77,7 +83,7 @@ Tun::Tun(const string *device, int mtu) << "\" mtu=" << mtu; winsystem(cmdline.str().data()); #else - cmdline << "/sbin/ifconfig " << this->device << " mtu " << mtu; + cmdline << IFCONFIG_PATH << this->device << " mtu " << mtu; if (system(cmdline.str().data()) != 0) syslog(LOG_ERR, "could not set tun device mtu"); #endif @@ -102,11 +108,11 @@ void Tun::setIp(uint32_t ip, uint32_t destIp) if (!tun_set_ip(fd, ip, ip & 0xffffff00, 0xffffff00)) syslog(LOG_ERR, "could not set tun device driver ip address: %s", tun_last_error()); #elif LINUX - cmdline << "/sbin/ifconfig " << device << " " << ips << " netmask 255.255.255.0"; + cmdline << IFCONFIG_PATH << device << " " << ips << " netmask 255.255.255.0"; if (system(cmdline.str().data()) != 0) syslog(LOG_ERR, "could not set tun device ip address"); #else - cmdline << "/sbin/ifconfig " << device << " " << ips << " " << destIps + cmdline << IFCONFIG_PATH << device << " " << ips << " " << destIps << " netmask 255.255.255.255"; if (system(cmdline.str().data()) != 0) syslog(LOG_ERR, "could not set tun device ip address"); diff --git a/src/tun_dev_linux.c b/src/tun_dev_linux.c index 0179eac..6e7bfc4 100644 --- a/src/tun_dev_linux.c +++ b/src/tun_dev_linux.c @@ -37,6 +37,12 @@ /* #include "vtun.h" #include "lib.h" */ +#ifdef ANDROID +#define TUN_PATH "/dev/tun" +#else +#define TUN_PATH "/dev/net/tun" +#endif + /* * Allocate TUN device, returns opened fd. * Stores dev name in the first arg(must be large enough). @@ -87,7 +93,7 @@ static int tun_open_common(char *dev, int istun) struct ifreq ifr; int fd; - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) + if ((fd = open(TUN_PATH, O_RDWR)) < 0) return tun_open_common0(dev, istun); memset(&ifr, 0, sizeof(ifr)); From 1f46f550c884c304e1a3bab27ca8406bdfb8d1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valent=C3=ADn=20Blanco?= Date: Wed, 31 Mar 2021 17:36:24 +0200 Subject: [PATCH 2/5] Added optimization flags to Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 332f3d4..27c382e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ LDFLAGS = `sh osflags ld $(MODE)` -CFLAGS = -c -g `sh osflags c $(MODE)` -CPPFLAGS = -c -g -std=c++98 -pedantic -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers `sh osflags c $(MODE)` +CFLAGS = -c -g -O2 `sh osflags c $(MODE)` +CPPFLAGS = -c -g -O2 -std=c++98 -pedantic -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers `sh osflags c $(MODE)` TUN_DEV_FILE = `sh osflags dev $(MODE)` GCC = gcc GPP = g++ From 23ddf9f6cfe9dc397a7fbd6fe19c37a801e0d490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valent=C3=ADn=20Blanco?= Date: Wed, 31 Mar 2021 17:37:37 +0200 Subject: [PATCH 3/5] Added example Bash script for launching Hans in Termux --- hans_android.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 hans_android.sh diff --git a/hans_android.sh b/hans_android.sh new file mode 100644 index 0000000..6a9bb83 --- /dev/null +++ b/hans_android.sh @@ -0,0 +1,9 @@ +#!/data/data/com.termux/files/usr/bin/bash + +hans="/data/data/com.termux/files/home/hans/hans" + +$hans -c 172.16.0.1 -p change_this_password -v +ip rule add from all lookup main pref 1 +bash -c "trap 'exit 0' INT; logcat -v color | grep $hans" +killall $hans +ip rule del from all lookup main pref 1 \ No newline at end of file From 517183f4cbf36b51795de232bd2691e737b123f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valent=C3=ADn=20Blanco?= Date: Wed, 31 Mar 2021 17:38:41 +0200 Subject: [PATCH 4/5] Added example systemd service unit file and conf file --- hans-server.service | 13 +++++++++++++ hans.conf | 3 +++ 2 files changed, 16 insertions(+) create mode 100644 hans-server.service create mode 100644 hans.conf diff --git a/hans-server.service b/hans-server.service new file mode 100644 index 0000000..f5c2c52 --- /dev/null +++ b/hans-server.service @@ -0,0 +1,13 @@ +[Unit] +Description=Hans IP over ICMP tunneling daemon +After=syslog.target network-online.target +Wants=network-online.target + +[Service] +Type=forking +EnvironmentFile=/opt/hans/hans.conf +Restart=on-abort +ExecStart=/opt/hans/hans -s $IP -p $PASS -u $USER + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/hans.conf b/hans.conf new file mode 100644 index 0000000..e1baefd --- /dev/null +++ b/hans.conf @@ -0,0 +1,3 @@ +IP=10.0.0.1 +PASS=change_this_password +USER=nobody \ No newline at end of file From 9c6de522322b065ddfa0161851a12f8472602bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valent=C3=ADn=20Blanco?= Date: Wed, 31 Mar 2021 18:01:03 +0200 Subject: [PATCH 5/5] Updated README to include info about Android compiling --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 9ab9e2e..3e2ffbf 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,22 @@ Hans - IP over ICMP Hans makes it possible to tunnel IPv4 through ICMP echo packets, so you could call it a ping tunnel. This can be useful when you find yourself in the situation that your Internet access is firewalled, but pings are allowed. http://code.gerade.org/hans/ + +This repo adds the minimal necessary code changes for the code to be able to compile inside a [Termux](https://github.com/termux/termux-app) Android environment (inside the own device!). + +Building and running instructions: +* For manipulating ICMP packets you need a rooted device. +* Install [Termux app](https://github.com/termux/termux-app), and then install the clang compiler and make: `pkg install clang make` +* Clone this repo and then you should be able to compile a binary from within your device with `make` +* Adapt and exec the hans_android.sh script (as root!) inside the repo, in my experience the "main" routing table needs to be added to `ip rule` for the Hans tunnel packets to be routed correctly. Also the binary outputs to logcat, this is handled in the script as well (good for debugging). +* These changes have not been tested with multiple devices or Android versions, it has been tested with an Android 10 device. If you encounter problems you'll possibly need to debug them with strace or ltrace. +* Systemd example service unit file and conf file are included as convenience. + +Refs: +* https://github.com/friedrich/hans +* http://code.gerade.org/hans/ +* https://github.com/raidenii/hans-android +* https://nethack.ch/2016/12/10/how-to-use-openvpn-over-an-ip-over-icmp-tunnel-hans/ +* https://hundeboll.net/internet-tunneling-through-icmp.html + +Happy ICMP tunneling ;)