While you don't give the necessary details in your question, I decided to give it a go with the R6250-V220.127.116.11_10.1.23.zip from the Netgear website. I don't know how close that is to whatever target you are currently looking at, but the environment look superficially rather similar (especially contents of
First I used firmware-mod-kit to extract the
.chk file inside the downloaded
$ extract-firmware.sh R6250-V18.104.22.168_10.1.23.chk
Firmware Mod Kit (extract) 0.99, (c)2011-2013 Craig Heffner, Jeremy Collake
Scan Time: 2018-06-13 17:23:43
Target File: /home/user/netgear/R6250-V22.214.171.124_10.1.23.chk
MD5 Checksum: fbb0ddc095cbca7abebe90a19a1b39b7
DECIMAL HEXADECIMAL DESCRIPTION
58 0x3A TRX firmware header, little endian, image size: 19345408 bytes, CRC32: 0xE9FDE7D3, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x23F01C, rootfs offset: 0x0
86 0x56 LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 5467936 bytes
2355286 0x23F056 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 16983563 bytes, 1244 inodes, blocksize: 131072 bytes, created: 2018-04-02 13:08:38
Extracting 2355286 bytes of header image at offset 0
Extracting squashfs file system at offset 2355286
Extracting squashfs files...
Firmware extraction successful!
Firmware parts can be found in '/home/user/netgear/fmk/*'
Then I started to explore the contents of
fmk/rootfs using standard Linux tools. For example only a single
.cgi file existed in the whole rootfs.
$ find -name '*.cgi'
grep -R \.cgi www I was able to find a whole bunch of references to different "files" named
.cgi used inside forms of the router's web interface.
I then attempted to filter down the list a little further (inside
grep -RPho '[^"]+\.cgi'|sort -u
There were some outliers in the resulting list, but the outcome was useful nevertheless.
Armed with that knowledge I turned back to the rootfs in order to look for the web server. I could have used
find -name httpd, as it turns out, but in reality I was looking through
/usr/sbin in that order and found a binary named
httpd in the last one.
strings httpd from inside
fmk/rootfs/usr/sbin gave me further clues and definitely proved that this was no Nginx or Apache. With
strings httpd|grep \.cgi I was also able to verify that the quote:
apply.cgi is not really a script, but a function that is invoked in the HTTP server
appears to hold true.
readelf -d httpd I figured out the dependencies (excerpt):
$ readelf -d httpd
Dynamic section at offset 0xae00c contains 31 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libnat.so]
0x00000001 (NEEDED) Shared library: [libnvram.so]
0x00000001 (NEEDED) Shared library: [libacos_shared.so]
0x00000001 (NEEDED) Shared library: [libcrypt.so.0]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libssl.so.1.0.0]
0x00000001 (NEEDED) Shared library: [libcrypto.so.1.0.0]
0x00000001 (NEEDED) Shared library: [libc.so.0]
to know which libraries to look at, should the need come up.
Last but not least I loaded the ELF file
httpd into IDA Pro 7.1, turned to the Strings subview using Shift+F12 and started looking for the
.cgi names. The
apply.cgi you mentioned does not exist (verified by using
grep -R apply\.cgi fmk/rootfs/www). So I needed to pick another CGI as an example.
I went for
userlogin.cgi, which was one of the first names to come up when searching for text
.cgi from top down using Alt+T in IDA View-A.
Listing the cross-references (x) to the string containing
.rodata:000823DC aUserloginCgi DCB "userlogin.cgi",0
turned up several references to
.text:0001289C), which - when following these cross-references - turned out to be one central "mega-function" for parsing HTTP requests and handling the requests to any number of hardcoded
.htm "file names". (NB: make sure to look for references to strings containing
cgi-bin as well.)
So your suspicion, based on that quote, was true and with the sole exception of the
genie.cgi found on the file system, all other
.cgi "files" are handled directly by the massive 1.3 MiB
The binary contains strings aplenty and apparently even some assertion strings among them.