A Journey to the Firmware of ZTE H267A: Part II

In the previous post, I explained how I’ve got the proof that leads me to get the root password and the firmware of the ZTE H267A router. In this part of the series, I will explain the techniques I used and how I configured the environment. But before explaining the successful approach, I want to mention about failed ones briefly.

The Failures

At first, I tried the golang code here. Unfortunately, it didn’t work well. I saw lots of malformed, retransmitting, or dropped packets, and the router couldn’t connect to the configuration server.

As a second solution, I tried iptables to forward packets going through the bridged network. This way, I could be able to modify the response, but none of the packets forwarded to the proxy server. I thought, how come iptables interact with a network interface without an IP assigned. With that thought in mind, I assigned an IP address to the bridge interface, but this time, the router lost its connection to the internet.

I don’t have enough knowledge in this area, and my assumption might be wrong. But what I was sure is I needed to find another way to alter the response returning from the configuration server.

Successful Technique

After all of these failures, I wanted to mimic both the router and the ISP. So in this way, I could bind those mimicked connections on another network interface, and finally, I could use iptables in this scenario.

/a-journey-to-the-firmware-of-zte-h267a/working-technique-chart.png
Working Technique Chart
Remove the Bridge

If you create a bridge connection like I did in previous post, you need to remove it first.

1
2
# remove br0
$ brctl delbr br0

Configuring the PPPoE Server

If we configure the PPPoE server, we can deceive the router to connect to our machine, instead of ISP.

I installed ppp and required packages by running the below commands.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# install ppp, ppp-dev, pppoeconf, build-essential
$ apt install ppp ppp-dev pppoeconf build-essential
# download and install rp-pppoe
$ wget -O rp-pppoe.tar.gz https://dianne.skoll.ca/projects/rp-pppoe/download/rp-pppoe-3.13.tar.gz
$ tar xvf rp-pppoe.tar.gz
$ cd rp-pppoe-3.13/src
$ ./configure
$ make && make install
# this will ask a couple of questions but you can just press enter, for firewall question, you should type 0
$ pppoe-setup

The configuration of pppoe-server utility took me a while to understand. I tried with different configurations, watched the logs, fixed the problems, and eventually, I built the correct configuration.

/etc/ppp/allip

1
10.0.0.6-20

/etc/ppp/pppoe-server-options

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
require-pap
login
lcp-echo-interval 10
lcp-echo-failure 2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
netmask 255.255.255.0
defaultroute
noipdefault
usepeerdns
debug
logfile /var/log/pppoe-server-log

/etc/ppp/pap-secrets

1
2
fiber@fiber         *       fiber               *
YOUR_USERNAME_HERE  *       YOUR_PASSWORD_HERE  *

One of the interesting things about pppoe-server is that it requires you to create a user on Ubuntu for each user you added in the pap-secrets file. Based on that information, I created fiber@fiber and YOUR_USERNAME_HERE users by running following command.

1
2
3
4
5
6
7
# create users defined under pap-secrets file
$ useradd fiber@fiber
# when it asks password type fiber
$ passwd fiber@fiber
$ useradd YOUR_USERNAME_HERE
# when it asks password type YOUR_PASSWORD_HERE
$ passwd YOUR_USERNAME_HERE

Before going forward, I wanted to test if the router can connect to the PPPoE server. I run the command below to start the server, and to verify it, I opened the web interface of the router and checked if it has an IP like 10.0.0.X

1
2
# start server with specified network interface
$ pppoe-server -C isp -L 10.0.0.1 -I YOUR_INTERFACE_NAME -F

Configuring the PPPoE Client Connection

Confession
To be honest, this part might not be necessary at all. If you have an active internet connection, shared by other devices or wifi etc, you can assign that interface as a default route, and this way you won’t need the second ethernet interface.

To connect with the ISP over PPPoE, I used the built-in pppoe tool. So, after connecting the ethernet cable coming from the ISP, I executed pppoeconf first and followed the instructions. After configuration is done, I run pon dsl-provider to actually start the connection between my machine and the ISP. And to check if I really connected to the internet, I executed ping.

1
2
3
4
5
6
7
8
9
# run pppoe configuration and follow the instructions
$ pppoeconf
# start pppoe connection
$ pon dsl-provider
# check if we have internet connection
$ ping 8.8.8.8

# ping should print some values like this
# 64 bytes from 8.8.8.8: icmp_seq=0 ttl=53 time=26.323 ms

Connecting PPPoE Client and Server

To bridge the connections using iptables, I needed to find out which interface is created by pppoe client. To see the name of the interface, I checked by running ifconfig, and I saw that there were 2 connections like ppp. One of them was the PPPoE Server named ppp0 and the other for PPPoE Client named ppp1.

So, to be able to connect my router to internet, I needed iptables to forward all packets through ppp1 interface, and I executed the following commands.

1
2
3
4
# enable forwarding
$ sysctl -w net.ipv4.ip_forward=1
# forward all packets through ppp1 interface
$ iptables -t nat -A POSTROUTING -o ppp1 -j MASQUERADE