Commit 851618cf by yinqidi

Emulation

parent e25f0abc
[DEFAULT]
sudo_password=yinqidi
firmadyne_path=/home/yinqidi/Desktop/EmuFuzz/Emulation
#! /usr/bin/python
import os
import os.path
import pexpect
import sys
import argparse
from configparser import ConfigParser
config = ConfigParser()
config.read("emu.config")
firmadyne_path = config["DEFAULT"].get("firmadyne_path", "")
sudo_pass = config["DEFAULT"].get("sudo_password", "")
def get_next_unused_iid():
for i in range(1, 1000):
if not os.path.isdir(os.path.join(firmadyne_path, "scratch", str(i))):
return str(i)
return ""
def run_extractor(firm_name):
print ("[+] Firmware:", os.path.basename(firm_name))
print ("[+] Extracting the firmware...")
extractor_cmd = os.path.join(firmadyne_path, "extractor/extractor.py")
extractor_args = [
"-np",
"-nk",
firm_name,
os.path.join(firmadyne_path, "images")
]
child = pexpect.spawn(extractor_cmd, extractor_args, timeout=None)
child.expect_exact("Tag: ")
tag = child.readline().strip().decode("utf8")
child.expect_exact(pexpect.EOF)
image_tgz = os.path.join(firmadyne_path, "images", tag + ".tar.gz")
if os.path.isfile(image_tgz):
iid = get_next_unused_iid()
if iid == "" or os.path.isfile(os.path.join(os.path.dirname(image_tgz), iid + ".tar.gz")):
print ("[!] Too many stale images")
print ("[!] Please run reset.py or manually delete the contents of the scratch/ and images/ directory")
return ""
os.rename(image_tgz, os.path.join(os.path.dirname(image_tgz), iid + ".tar.gz"))
print ("[+] Image ID:", iid)
return iid
return ""
def identify_arch(image_id):
print ("[+] Identifying architecture...")
identfy_arch_cmd = os.path.join(firmadyne_path, "scripts/getArch.sh")
identfy_arch_args = [
os.path.join(firmadyne_path, "images", image_id + ".tar.gz")
]
child = pexpect.spawn(identfy_arch_cmd, identfy_arch_args, cwd=firmadyne_path)
child.expect_exact(":")
arch = child.readline().strip().decode("utf8")
print ("[+] Architecture: " + arch)
try:
child.expect_exact(pexpect.EOF)
except Exception as e:
child.close(force=True)
return arch
def make_image(image_id, arch):
print ("[+] Building QEMU disk image...")
makeimage_cmd = os.path.join(firmadyne_path, "scripts/makeImage.sh")
makeimage_args = ["--", makeimage_cmd, image_id, arch]
child = pexpect.spawn("sudo", makeimage_args, cwd=firmadyne_path)
child.sendline(sudo_pass)
child.expect_exact(pexpect.EOF)
def infer_network(image_id, arch):
print ("[+] Setting up the network connection, please standby...")
network_cmd = os.path.join(firmadyne_path, "scripts/inferNetwork.sh")
network_args = [image_id, arch]
child = pexpect.spawn(network_cmd, network_args, cwd=firmadyne_path)
child.expect_exact("Interfaces:", timeout=None)
interfaces = child.readline().strip().decode("utf8")
print ("[+] Network interfaces:", interfaces)
child.expect_exact(pexpect.EOF)
def final_run(image_id, arch, qemu_dir):
runsh_path = os.path.join(firmadyne_path, "scratch", image_id, "run.sh")
if not os.path.isfile(runsh_path):
print ("[!] Cannot emulate firmware, run.sh not generated")
return
print ("[+] All set! Press ENTER to run the firmware...")
input ("[+] When running, press Ctrl + A X to terminate qemu")
print ("[+] Command line:", runsh_path)
run_cmd = ["--", runsh_path]
child = pexpect.spawn("sudo", run_cmd, cwd=firmadyne_path)
child.sendline(sudo_pass)
child.interact()
def main():
parser = argparse.ArgumentParser()
parser.add_argument("firm_path", help="The path to the firmware image", type=str)
args = parser.parse_args()
image_id = run_extractor(args.firm_path)
if image_id == "":
print ("[!] Image extraction failed")
else:
arch = identify_arch(image_id)
make_image(image_id, arch)
infer_network(image_id, arch)
# final_run(image_id, arch)
# final_run("1", "mipseb")
if __name__ == "__main__":
main()
FROM python:2-wheezy
WORKDIR /root
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y git-core wget build-essential liblzma-dev liblzo2-dev zlib1g-dev unrar-free && \
pip install -U pip
RUN git clone https://github.com/firmadyne/sasquatch && \
cd sasquatch && \
make && \
make install && \
cd .. && \
rm -rf sasquatch
RUN git clone https://github.com/devttys0/binwalk.git && \
cd binwalk && \
./deps.sh --yes && \
python setup.py install && \
pip install 'git+https://github.com/ahupp/python-magic' && \
pip install 'git+https://github.com/sviehb/jefferson' && \
cd .. && \
rm -rf binwalk
RUN \
adduser --disabled-password \
--gecos '' \
--home /home/extractor \
extractor
USER extractor
WORKDIR /home/extractor
RUN git clone https://github.com/firmadyne/extractor.git
The MIT License (MIT)
Copyright (c) 2015 - 2016, Daming Dominic Chen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Introduction
============
This is a recursive firmware extractor that aims to extract a kernel image
and/or compressed filesystem from a Linux-based firmware image. A number of
heuristics are included to avoid extraction of certain blacklisted file types,
and to avoid unproductive extraction beyond certain breadth and depth
limitations.
Firmware images with multiple filesystems are not fully supported; this tool
cannot reassemble them and will instead extract the first filesystem that has
sufficient UNIX-like root directories (e.g. `/bin`, `/etc/`, etc.)
For the impatients: Dockerize all the things!
=============================================
1. Install [Docker](https://docs.docker.com/engine/getstarted/)
2. Run the dockerized extractor
```
git clone https://github.com/firmadyne/extractor.git
cd extractor
./extract.sh path/to/firmware.img path/to/output/directory
```
Dependencies
============
* [fakeroot](https://fakeroot.alioth.debian.org)
* [psycopg2](http://initd.org/psycopg/)
* [binwalk](https://github.com/devttys0/binwalk)
* [python-magic](https://github.com/ahupp/python-magic)
Please use the latest version of `binwalk`. Note that there are two
Python modules that both share the name `python-magic`; both should be usable,
but only the one linked above has been tested extensively.
Binwalk
-------
* [jefferson](https://github.com/sviehb/jefferson)
* [sasquatch](https://github.com/firmadyne/sasquatch) (optional)
When installing `binwalk`, it is optional to use the forked version of the
`sasquatch` tool, which has been modified to make SquashFS file extraction
errors fatal to prevent false positives.
Usage
=====
During execution, the extractor will temporarily extract files into `/tmp`
while recursing. Since firmware images can be large, preferably mount this
mount point as `tmpfs` backed by a large amount of memory, to optimize
performance.
To preserve filesystem permissions during extraction, while avoiding execution
with root privileges, wrap execution of this extractor within `fakeroot`. This
will emulate privileged operations.
`fakeroot python3 ./extractor.py -np <infile> <outdir>`
Notes
=====
This tool is beta quality. In particular, it was written before the
`binwalk` API was updated to provide an interface for accessing information
about the extraction of each signature match. As a result, it walks the
filesystem to identify the extracted files that correspond to a given
signature match. Additionally, parallel operation has not been thoroughly
tested.
Pull requests are greatly appreciated!
#! /bin/bash
infile=$1
outdir=$2
# override 65535k docker default size with tmpfs default
mem=$(($(free | awk '/^Mem:/{print $2}') / 2))k
indir=$(realpath $(dirname "${infile}"))
outdir=$(realpath "${outdir}")
infilebn=$(basename "${infile}")
docker run --rm -t -i --tmpfs /tmp:rw,size=${mem} \
-v "${indir}":/firmware-in:ro \
-v "${outdir}":/firmware-out \
"ddcc/firmadyne-extractor:latest" \
fakeroot /home/extractor/extractor/extractor.py \
-np \
/firmware-in/"${infilebn}" \
/firmware-out
![logo](https://github.com/craigz28/firmwalker/blob/master/firmwalker-logo.jpg)
# firmwalker
A simple bash script for searching the extracted or mounted firmware file system.
It will search through the extracted or mounted firmware file system for things of interest such as:
* etc/shadow and etc/passwd
* list out the etc/ssl directory
* search for SSL related files such as .pem, .crt, etc.
* search for configuration files
* look for script files
* search for other .bin files
* look for keywords such as admin, password, remote, etc.
* search for common web servers used on IoT devices
* search for common binaries such as ssh, tftp, dropbear, etc.
* search for URLs, email addresses and IP addresses
* Experimental support for making calls to the Shodan API using the Shodan CLI
## Usage
* If you wish to use the static code analysis portion of the script, please install eslint: `npm i -g eslint`
* `./firmwalker {path to root file system} {path for firmwalker.txt}`
* Example: `./firmwalker linksys/fmk/rootfs ../firmwalker.txt`
* A file `firmwalker.txt` will be created in the same directory as the script file unless you specify a different filename as the second argument
* Do not put the firmwalker.sh file inside the directory to be searched, this will cause the script to search itself and the file it is creating
* `chmod 0700 firmwalker.sh`
## How to extend
* Have a look under 'data' where the checks live or add eslint rules - http://eslint.org/docs/rules/ to eslintrc.json
## Example Files - https://1drv.ms/f/s!AucQMYXJNefdvGZyeYt16H72VCLv
* squashfs-root.zip - contains files from random extracted router firmware. Firmwalker can be run against this file system.
* rt-ac66u.txt - firmwalker output file
* xc.txt - firmwalker output file from Ubiquiti device
### Script created by Craig Smith and expanded by:
* Athanasios Kostopoulos
* misterch0c
### Links
* https://craigsmith.net
* https://woktime.wordpress.com
* https://www.owasp.org/index.php/OWASP_Internet_of_Things_Project#tab=Firmware_Analysis
ssh
sshd
scp
sftp
tftp
dropbear
busybox
telnet
telnetd
openssl
upgrade
admin
root
password
passwd
pwd
dropbear
ssl
private key
telnet
secret
pgp
gpg
token
api key
oauth
authorized_keys
*authorized_keys*
host_key
*host_key*
id_rsa
*id_rsa*
id_dsa
*id_dsa*
*.pub
*.crt
*.pem
*.cer
*.p7b
*.p12
*.key
apache
lighttpd
alphapd
httpd
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"no-eval": 2,
"no-alert": 2,
"no-console": 2
}
}
#!/usr/bin/env bash
set -e
set -u
function usage {
echo "Usage:"
echo "$0 {path to extracted file system of firmware}\
{optional: name of the file to store results - defaults to firmwalker.txt}"
echo "Example: ./$0 linksys/fmk/rootfs/"
exit 1
}
function msg {
echo "$1" | tee -a $FILE
}
function getArray {
array=() # Create array
while IFS= read -r line
do
array+=("$line")
done < "$1"
}
# Check for arguments
if [[ $# -gt 2 || $# -lt 1 ]]; then
usage
fi
# Set variables
FIRMDIR=$1
if [[ $# -eq 2 ]]; then
FILE=$2
else
FILE="firmwalker.txt"
fi
# Remove previous file if it exists, is a file and doesn't point somewhere
if [[ -e "$FILE" && ! -h "$FILE" && -f "$FILE" ]]; then
rm -f $FILE
fi
# Perform searches
msg "***Firmware Directory***"
msg $FIRMDIR
msg "***Search for password files***"
getArray "data/passfiles"
passfiles=("${array[@]}")
for passfile in "${passfiles[@]}"
do
msg "##################################### $passfile"
find $FIRMDIR -name $passfile | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg "***Search for Unix-MD5 hashes***"
egrep -sro '\$1\$\w{8}\S{23}' $FIRMDIR | tee -a $FILE
msg ""
if [[ -d "$FIRMDIR/etc/ssl" ]]; then
msg "***List etc/ssl directory***"
ls -l $FIRMDIR/etc/ssl | tee -a $FILE
fi
msg ""
msg "***Search for SSL related files***"
getArray "data/sslfiles"
sslfiles=("${array[@]}")
for sslfile in ${sslfiles[@]}
do
msg "##################################### $sslfile"
find $FIRMDIR -name $sslfile | cut -c${#FIRMDIR}- | tee -a $FILE
certfiles=( $(find ${FIRMDIR} -name ${sslfile}) )
: "${certfiles:=empty}"
# Perform Shodan search. This assumes Shodan CLI installed with an API key.
if [ "${certfiles##*.}" = "pem" ] || [ "${certfiles##*.}" = "crt" ]; then
for certfile in "${certfiles[@]}"
do
serialno=$(openssl x509 -in $certfile -serial -noout) || echo "Incorrect File Content:Continuing"
serialnoformat=(ssl.cert.serial:${serialno##*=})
if type "shodan" &> /dev/null ; then
shocount=$(shodan count $serialnoformat)
if (( $shocount > 0 )); then
msg "################# Certificate serial # found in Shodan ####################"
echo $certfile | cut -c${#FIRMDIR}- | tee -a $FILE
echo $serialno | tee -a $FILE
echo "Number of devices found in Shodan =" $shocount | tee -a $FILE
cat $certfile | tee -a $FILE
msg "###########################################################################"
fi
else
echo "Shodan cli not found."
fi
done
fi
msg ""
done
msg ""
msg "***Search for SSH related files***"
getArray "data/sshfiles"
sshfiles=("${array[@]}")
for sshfile in ${sshfiles[@]}
do
msg "##################################### $sshfile"
find $FIRMDIR -name $sshfile | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg ""
msg "***Search for files***"
getArray "data/files"
files=("${array[@]}")
for file in ${files[@]}
do
msg "##################################### $file"
find $FIRMDIR -name $file | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg ""
msg "***Search for database related files***"
getArray "data/dbfiles"
dbfiles=("${array[@]}")
for dbfile in ${dbfiles[@]}
do
msg "##################################### $dbfile"
find $FIRMDIR -name $dbfile | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg ""
msg "***Search for shell scripts***"
msg "##################################### shell scripts"
find $FIRMDIR -name "*.sh" | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
msg "***Search for other .bin files***"
msg "##################################### bin files"
find $FIRMDIR -name "*.bin" | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
msg "***Search for patterns in files***"
getArray "data/patterns"
patterns=("${array[@]}")
for pattern in "${patterns[@]}"
do
msg "-------------------- $pattern --------------------"
grep -lsirnw $FIRMDIR -e "$pattern" | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg ""
msg "***Search for web servers***"
msg "##################################### search for web servers"
getArray "data/webservers"
webservers=("${array[@]}")
for webserver in ${webservers[@]}
do
msg "##################################### $webserver"
find $FIRMDIR -name "$webserver" | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg ""
msg "***Search for important binaries***"
msg "##################################### important binaries"
getArray "data/binaries"
binaries=("${array[@]}")
for binary in "${binaries[@]}"
do
msg "##################################### $binary"
find $FIRMDIR -name "$binary" | cut -c${#FIRMDIR}- | tee -a $FILE
msg ""
done
msg ""
msg "***Search for ip addresses***"
msg "##################################### ip addresses"
grep -sRIEho '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b' --exclude-dir='dev' $FIRMDIR | sort | uniq | tee -a $FILE
msg ""
msg "***Search for urls***"
msg "##################################### urls"
grep -sRIEoh '(http|https)://[^/"]+' --exclude-dir='dev' $FIRMDIR | sort | uniq | tee -a $FILE
msg ""
msg "***Search for emails***"
msg "##################################### emails"
grep -sRIEoh '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' "$@" --exclude-dir='dev' $FIRMDIR | sort | uniq | tee -a $FILE
#Perform static code analysis
#eslint -c eslintrc.json $FIRMDIR | tee -a $FILE
/usr/script/fw_start.sh/usr/script/alpha_wifi_schedule_5g.sh/usr/script/ipv6_filter_forward_stop.sh/usr/script/alpha_wireless_eapinfo_5G.sh/usr/script/ipv6_filter_forward_start.sh/usr/script/nat_start.sh/usr/script/restart_boa.sh/usr/script/AppFilterStop.sh/usr/script/urlfilter_start.sh/usr/script/alpha_wireless_stainfo_5G_for_statistics.sh/usr/script/ppp_start.sh/usr/script/wan_start_ipv4.sh/usr/script/spi_fw_stop.sh/usr/script/vserver.sh/usr/script/udhcpc.sh/usr/script/wan_start_ipv6.sh/usr/script/dslite_start.sh/usr/script/alpha_wireless_stainfo_5G.sh/usr/script/ipv6rd_start.sh/usr/script/udhcpc_nodef.sh/usr/script/alpha_usb_umount.sh/usr/script/usb_insmod.sh/usr/script/alpha_firewall.sh/usr/script/spi_fw_start.sh/usr/script/wan_start.sh/usr/script/dmz.sh/usr/script/ipv6_acl_stop.sh/usr/script/alpha_usbinfo.sh/usr/script/alpha_urlfilter.sh/usr/script/before_web_download_remove_wifi.sh/usr/script/br_conf.sh/usr/script/alpha_wireless_5G_bin_to_flash.sh/usr/script/alpha_wireless_channelscan_5G.sh/usr/script/before_web_download.sh/usr/script/dongle_dial_off.sh/usr/script/alpha_lanhost.sh/usr/script/ipmacfilter_stop.sh/usr/script/samba.sh/usr/script/UrlFilterStop.sh/usr/script/samba_add_dir.sh/usr/script/ipfilter_stop.sh/usr/script/filter_forward_stop.sh/usr/script/alpha_dsl_support.sh/usr/script/dlnaOff.sh/usr/script/filter_forward_start.sh/usr/script/channel_period.sh/usr/script/lanAlias_stop.sh/usr/script/alpha_cfm.sh/usr/script/alpha_klogd.sh/usr/script/ipaddr_mapping.sh/usr/script/ddns_run.sh/usr/script/alpha_upnp_scan.sh/usr/script/ntpclient.sh/usr/script/alpha_dlna_start.sh/usr/script/dlnaOn.sh/usr/script/settime.sh/usr/script/alpha_macfilter.sh/usr/script/lanAlias_start.sh/usr/script/alpha_wireless_stainfo.sh/usr/script/ipfilter_start.sh/usr/script/acl_stop.sh/usr/script/fw_stop.sh/usr/script/alpha_diag.sh/usr/script/ipfilter.sh/usr/script/alpha_wireless_stainfo_to_LanHost.sh/usr/script/before_web_upgrade.sh/usr/script/alpha_wifi_schedule.sh/usr/script/alpha_wireless_channelscan.sh/usr/script/alpha_wireless_eapinfo.sh/usr/script/ddns.sh/usr/script/5g_channel_period.sh/usr/script/nat_stop.sh/usr/script/upgrade_firmware.sh/usr/script/before_tr069_download.sh/usr/script/alpha_ipfilter.sh/usr/script/alpha_fun_lib.sh/usr/script/dongle_dial_on.sh/usr/script/ether_mac.sh/usr/script/alpha_usbcheck.sh/usr/script/wan_stop.sh/usr/script/alpha_syslogd.sh/usr/script/urlfilter_stop.sh/usr/script/getnow.sh/usr/etc/8021xaction.sh/usr/etc/igd/igd.sh/usr/etc/ppp/peers/ppp_on_dialer.sh/firmadyne/preInit.sh
\ No newline at end of file
text='''
e/usr/script/fw_start.sh
e/usr/script/alpha_wifi_schedule_5g.sh
e/usr/script/ipv6_filter_forward_stop.sh
e/usr/script/alpha_wireless_eapinfo_5G.sh
e/usr/script/ipv6_filter_forward_start.sh
e/usr/script/nat_start.sh
e/usr/script/restart_boa.sh
e/usr/script/AppFilterStop.sh
e/usr/script/urlfilter_start.sh
e/usr/script/alpha_wireless_stainfo_5G_for_statistics.sh
e/usr/script/ppp_start.sh
e/usr/script/wan_start_ipv4.sh
e/usr/script/spi_fw_stop.sh
e/usr/script/vserver.sh
e/usr/script/udhcpc.sh
e/usr/script/wan_start_ipv6.sh
e/usr/script/dslite_start.sh
e/usr/script/alpha_wireless_stainfo_5G.sh
e/usr/script/ipv6rd_start.sh
e/usr/script/udhcpc_nodef.sh
e/usr/script/alpha_usb_umount.sh
e/usr/script/usb_insmod.sh
e/usr/script/alpha_firewall.sh
e/usr/script/spi_fw_start.sh
e/usr/script/wan_start.sh
e/usr/script/dmz.sh
e/usr/script/ipv6_acl_stop.sh
e/usr/script/alpha_usbinfo.sh
e/usr/script/alpha_urlfilter.sh
e/usr/script/before_web_download_remove_wifi.sh
e/usr/script/br_conf.sh
e/usr/script/alpha_wireless_5G_bin_to_flash.sh
e/usr/script/alpha_wireless_channelscan_5G.sh
e/usr/script/before_web_download.sh
e/usr/script/dongle_dial_off.sh
e/usr/script/alpha_lanhost.sh
e/usr/script/ipmacfilter_stop.sh
e/usr/script/samba.sh
e/usr/script/UrlFilterStop.sh
e/usr/script/samba_add_dir.sh
e/usr/script/ipfilter_stop.sh
e/usr/script/filter_forward_stop.sh
e/usr/script/alpha_dsl_support.sh
e/usr/script/dlnaOff.sh
e/usr/script/filter_forward_start.sh
e/usr/script/channel_period.sh
e/usr/script/lanAlias_stop.sh
e/usr/script/alpha_cfm.sh
e/usr/script/alpha_klogd.sh
e/usr/script/ipaddr_mapping.sh
e/usr/script/ddns_run.sh
e/usr/script/alpha_upnp_scan.sh
e/usr/script/ntpclient.sh
e/usr/script/alpha_dlna_start.sh
e/usr/script/dlnaOn.sh
e/usr/script/settime.sh
e/usr/script/alpha_macfilter.sh
e/usr/script/lanAlias_start.sh
e/usr/script/alpha_wireless_stainfo.sh
e/usr/script/ipfilter_start.sh
e/usr/script/acl_stop.sh
e/usr/script/fw_stop.sh
e/usr/script/alpha_diag.sh
e/usr/script/ipfilter.sh
e/usr/script/alpha_wireless_stainfo_to_LanHost.sh
e/usr/script/before_web_upgrade.sh
e/usr/script/alpha_wifi_schedule.sh
e/usr/script/alpha_wireless_channelscan.sh
e/usr/script/alpha_wireless_eapinfo.sh
e/usr/script/ddns.sh
e/usr/script/5g_channel_period.sh
e/usr/script/nat_stop.sh
e/usr/script/upgrade_firmware.sh
e/usr/script/before_tr069_download.sh
e/usr/script/alpha_ipfilter.sh
e/usr/script/alpha_fun_lib.sh
e/usr/script/dongle_dial_on.sh
e/usr/script/ether_mac.sh
e/usr/script/alpha_usbcheck.sh
e/usr/script/wan_stop.sh
e/usr/script/alpha_syslogd.sh
e/usr/script/urlfilter_stop.sh
e/usr/script/getnow.sh
e/usr/etc/8021xaction.sh
e/usr/etc/igd/igd.sh
e/usr/etc/ppp/peers/ppp_on_dialer.sh
e/firmadyne/preInit.sh
'''
if __name__ =='__main__':
with open("result.txt", "w")as file:
for line in text.split():
file.write(line[1:])
#!/usr/bin/env python3
import pexpect
import os.path
from configparser import ConfigParser
config = ConfigParser()
config.read("emu.config")
firmadyne_path = config["DEFAULT"].get("path", "")
sudo_pass = config["DEFAULT"].get("sudo_password", "")
print ("[+] Cleaning previous images and created files by firmadyne")
child = pexpect.spawn("/bin/sh" , ["-c", "sudo rm -rf " + os.path.join(firmadyne_path, "images/*.tar.gz")])
child.sendline(sudo_pass)
child.expect_exact(pexpect.EOF)
child = pexpect.spawn("/bin/sh", ["-c", "sudo rm -rf " + os.path.join(firmadyne_path, "scratch/*")])
child.sendline(sudo_pass)
child.expect_exact(pexpect.EOF)
print ("[+] All done. Go ahead and run emu.py to continue firmware analysis")
#!/bin/bash
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: $0 <image ID>"
echo "This script deletes a whole project"
exit 1
fi
IID=${1}
#Check that no qemu is running:
echo "checking the process table for a running qemu instance ..."
PID=`ps -ef | grep qemu | grep "${IID}" | grep -v grep | awk '{print $2}'`
if ! [ -z $PID ]; then
echo "killing process ${PID}"
sudo kill -9 ${PID}
fi
PID1=`ps -ef | grep "${IID}\/run.sh" | grep -v grep | awk '{print $2}'`
if ! [ -z $PID1 ]; then
echo "killing process ${PID1}"
sudo kill ${PID1}
fi
#Check that nothing is mounted:
echo "In case the filesystem is mounted, umount it now ..."
sudo ./scripts/umount.sh ${IID}
#Check network config
echo "In case the network is configured, reconfigure it now ..."
for i in 0 .. 4; do
sudo ifconfig tap${IID}_${i} down
sudo tunctl -d tap${IID}_${i}
done
#Cleanup database:
echo "Remove the database entries ..."
psql -d firmware -U firmadyne -h 127.0.0.1 -t -q -c "DELETE from image WHERE id=${IID};"
#Cleanup filesystem:
echo "Clean up the file system ..."
if [ -f "/tmp/qemu.${IID}*" ]; then
sudo rm /tmp/qemu.${IID}*
fi
if [ -f ./images/${IID}.tar.gz ]; then
sudo rm ./images/${IID}.tar.gz
fi
if [ -f ./images/${IID}.kernel ]; then
sudo rm ./images/${IID}.kernel
fi
if [ -d ./scratch/${IID}/ ]; then
sudo rm -r ./scratch/${IID}/
fi
echo "Done. Removed project ID ${IID}."
#!/bin/bash
#The paths of the directories are specified here
ROOT_DIR="$HOME"
HOME_DIR="$ROOT_DIR/Desktop/EmuFuzz/Emulation"
export EMU_DIR=$HOME_DIR
export WORK_DIR="$HOME_DIR/scratch"
export KERNEL_DIR="$HOME_DIR/source/Kernel-mips/build"
export KERNEL_DIR_ARMEL="$HOME_DIR/source/Kernel-armel/build"
export LIB_DIR="$HOME_DIR/source/LIB"
export SCRIPT_DIR="$HOME_DIR/scripts"
export TARBALL_DIR="$HOME_DIR/images"
#!/bin/sh
# use busybox statically-compiled version of all binaries
BUSYBOX="/busybox"
# print input if not symlink, otherwise attempt to resolve symlink
resolve_link() {
TARGET=$($BUSYBOX readlink $1)
if [ -z "$TARGET" ]; then
echo "$1"
fi
echo "$TARGET"
}
# make /etc and add some essential files
mkdir -p "$(resolve_link /etc)"
if [ ! -s /etc/TZ ]; then
echo "Creating /etc/TZ!"
mkdir -p "$(dirname $(resolve_link /etc/TZ))"
echo "EST5EDT" > "$(resolve_link /etc/TZ)"
fi
if [ ! -s /etc/hosts ]; then
echo "Creating /etc/hosts!"
mkdir -p "$(dirname $(resolve_link /etc/hosts))"
echo "127.0.0.1 localhost" > "$(resolve_link /etc/hosts)"
fi
if [ ! -s /etc/passwd ]; then
echo "Creating /etc/passwd!"
mkdir -p "$(dirname $(resolve_link /etc/passwd))"
echo "root::0:0:root:/root:/bin/sh" > "$(resolve_link /etc/passwd)"
fi
# make /dev and add default device nodes if current /dev does not have greater
# than 5 device nodes
mkdir -p "$(resolve_link /dev)"
FILECOUNT="$($BUSYBOX find ${WORKDIR}/dev -maxdepth 1 -type b -o -type c -print | $BUSYBOX wc -l)"
if [ $FILECOUNT -lt "5" ]; then
echo "Warning: Recreating device nodes!"
mknod -m 660 /dev/mem c 1 1
mknod -m 640 /dev/kmem c 1 2
mknod -m 666 /dev/null c 1 3
mknod -m 666 /dev/zero c 1 5
mknod -m 444 /dev/random c 1 8
mknod -m 444 /dev/urandom c 1 9
mknod -m 666 /dev/armem c 1 13
mknod -m 666 /dev/tty c 5 0
mknod -m 622 /dev/console c 5 1
mknod -m 666 /dev/ptmx c 5 2
mknod -m 622 /dev/tty0 c 4 0
mknod -m 660 /dev/ttyS0 c 4 64
mknod -m 660 /dev/ttyS1 c 4 65
mknod -m 660 /dev/ttyS2 c 4 66
mknod -m 660 /dev/ttyS3 c 4 67
mknod -m 644 /dev/adsl0 c 100 0
mknod -m 644 /dev/ppp c 108 0
mknod -m 666 /dev/hidraw0 c 251 0
mkdir -p /dev/mtd
mknod -m 644 /dev/mtd/0 c 90 0
mknod -m 644 /dev/mtd/1 c 90 2
mknod -m 644 /dev/mtd/2 c 90 4
mknod -m 644 /dev/mtd/3 c 90 6
mknod -m 644 /dev/mtd/4 c 90 8
mknod -m 644 /dev/mtd/5 c 90 10
mknod -m 644 /dev/mtd/6 c 90 12
mknod -m 644 /dev/mtd/7 c 90 14
mknod -m 644 /dev/mtd/8 c 90 16
mknod -m 644 /dev/mtd/9 c 90 18
mknod -m 644 /dev/mtd/10 c 90 20
mknod -m 644 /dev/mtd0 c 90 0
mknod -m 644 /dev/mtdr0 c 90 1
mknod -m 644 /dev/mtd1 c 90 2
mknod -m 644 /dev/mtdr1 c 90 3
mknod -m 644 /dev/mtd2 c 90 4
mknod -m 644 /dev/mtdr2 c 90 5
mknod -m 644 /dev/mtd3 c 90 6
mknod -m 644 /dev/mtdr3 c 90 7
mknod -m 644 /dev/mtd4 c 90 8
mknod -m 644 /dev/mtdr4 c 90 9
mknod -m 644 /dev/mtd5 c 90 10
mknod -m 644 /dev/mtdr5 c 90 11
mknod -m 644 /dev/mtd6 c 90 12
mknod -m 644 /dev/mtdr6 c 90 13
mknod -m 644 /dev/mtd7 c 90 14
mknod -m 644 /dev/mtdr7 c 90 15
mknod -m 644 /dev/mtd8 c 90 16
mknod -m 644 /dev/mtdr8 c 90 17
mknod -m 644 /dev/mtd9 c 90 18
mknod -m 644 /dev/mtdr9 c 90 19
mknod -m 644 /dev/mtd10 c 90 20
mknod -m 644 /dev/mtdr10 c 90 21
mkdir -p /dev/mtdblock
mknod -m 644 /dev/mtdblock/0 b 31 0
mknod -m 644 /dev/mtdblock/1 b 31 1
mknod -m 644 /dev/mtdblock/2 b 31 2
mknod -m 644 /dev/mtdblock/3 b 31 3
mknod -m 644 /dev/mtdblock/4 b 31 4
mknod -m 644 /dev/mtdblock/5 b 31 5
mknod -m 644 /dev/mtdblock/6 b 31 6
mknod -m 644 /dev/mtdblock/7 b 31 7
mknod -m 644 /dev/mtdblock/8 b 31 8
mknod -m 644 /dev/mtdblock/9 b 31 9
mknod -m 644 /dev/mtdblock/10 b 31 10
mknod -m 644 /dev/mtdblock0 b 31 0
mknod -m 644 /dev/mtdblock1 b 31 1
mknod -m 644 /dev/mtdblock2 b 31 2
mknod -m 644 /dev/mtdblock3 b 31 3
mknod -m 644 /dev/mtdblock4 b 31 4
mknod -m 644 /dev/mtdblock5 b 31 5
mknod -m 644 /dev/mtdblock6 b 31 6
mknod -m 644 /dev/mtdblock7 b 31 7
mknod -m 644 /dev/mtdblock8 b 31 8
mknod -m 644 /dev/mtdblock9 b 31 9
mknod -m 644 /dev/mtdblock10 b 31 10
mkdir -p /dev/tts
mknod -m 660 /dev/tts/0 c 4 64
mknod -m 660 /dev/tts/1 c 4 65
mknod -m 660 /dev/tts/2 c 4 66
mknod -m 660 /dev/tts/3 c 4 67
fi
# create a gpio file required for linksys to make the watchdog happy
if ($BUSYBOX grep -sq "/dev/gpio/in" /bin/gpio) ||
($BUSYBOX grep -sq "/dev/gpio/in" /usr/lib/libcm.so) ||
($BUSYBOX grep -sq "/dev/gpio/in" /usr/lib/libshared.so); then
echo "Creating /dev/gpio/in!"
mkdir -p /dev/gpio
echo -ne "\xff\xff\xff\xff" > /dev/gpio/in
fi
# prevent system from rebooting
#echo "Removing /sbin/reboot!"
#rm -f /sbin/reboot
echo "Removing /etc/scripts/sys_resetbutton!"
rm -f /etc/scripts/sys_resetbutton
# add some default nvram entries
if $BUSYBOX grep -sq "ipv6_6to4_lan_ip" /sbin/rc; then
echo "Creating default ipv6_6to4_lan_ip!"
echo -n "2002:7f00:0001::" > /firmadyne/libnvram.override/ipv6_6to4_lan_ip
fi
if $BUSYBOX grep -sq "time_zone_x" /lib/libacos_shared.so; then
echo "Creating default time_zone_x!"
echo -n "0" > /firmadyne/libnvram.override/time_zone_x
fi
if $BUSYBOX grep -sq "rip_multicast" /usr/sbin/httpd; then
echo "Creating default rip_multicast!"
echo -n "0" > /firmadyne/libnvram.override/rip_multicast
fi
if $BUSYBOX grep -sq "bs_trustedip_enable" /usr/sbin/httpd; then
echo "Creating default bs_trustedip_enable!"
echo -n "0" > /firmadyne/libnvram.override/bs_trustedip_enable
fi
if $BUSYBOX grep -sq "filter_rule_tbl" /usr/sbin/httpd; then
echo "Creating default filter_rule_tbl!"
echo -n "" > /firmadyne/libnvram.override/filter_rule_tbl
fi
if $BUSYBOX grep -sq "rip_enable" /sbin/acos_service; then
echo "Creating default rip_enable!"
echo -n "0" > /firmadyne/libnvram.override/rip_enable
fi
#!/bin/bash
set -e
set -u
function getArch() {
if (echo ${FILETYPE} | grep -q "MIPS64")
then
ARCH="mips64"
elif (echo ${FILETYPE} | grep -q "MIPS")
then
ARCH="mips"
elif (echo ${FILETYPE} | grep -q "ARM64")
then
ARCH="arm64"
elif (echo ${FILETYPE} | grep -q "ARM")
then
ARCH="arm"
elif (echo ${FILETYPE} | grep -q "Intel 80386")
then
ARCH="intel"
elif (echo ${FILETYPE} | grep -q "x86-64")
then
ARCH="intel64"
elif (echo ${FILETYPE} | grep -q "PowerPC")
then
ARCH="ppc"
else
ARCH=""
fi
}
function getEndian() {
if (echo ${FILETYPE} | grep -q "LSB")
then
END="el"
elif (echo ${FILETYPE} | grep -q "MSB")
then
END="eb"
else
END=""
fi
}
INFILE=${1}
BASE=$(basename "$1")
IID=${BASE%.tar.gz}
mkdir -p "/tmp/${IID}"
set +e
FILES="$(tar -tf $INFILE | grep -e "/busybox\$") "
FILES+="$(tar -tf $INFILE | grep -E "/sbin/[[:alpha:]]+")"
FILES+="$(tar -tf $INFILE | grep -E "/bin/[[:alpha:]]+")"
set -e
for TARGET in ${FILES}
do
SKIP=$(echo "${TARGET}" | fgrep -o / | wc -l)
tar -xf "${INFILE}" -C "/tmp/${IID}/" --strip-components=${SKIP} ${TARGET}
TARGETLOC="/tmp/$IID/${TARGET##*/}"
if [ -h ${TARGETLOC} ] || [ ! -f ${TARGETLOC} ]
then
continue
fi
FILETYPE=$(file ${TARGETLOC})
echo -n "${TARGET}: "
getArch
getEndian
if [ -n "${ARCH}" ] && [ -n "${END}" ]
then
# ARCHEND=${ARCH}${END}
# echo ${ARCHEND}
# #psql -d firmware -U firmadyne -h 127.0.0.1 -q -c "UPDATE image SET arch = '$ARCHEND' WHERE id = $IID;"
# rm -fr "/tmp/${IID}"
# exit 0
# else
echo -n ${ARCH}
echo ${END}
fi
done
rm -fr "/tmp/${IID}"
exit 1
#!/bin/bash
set -e
set -u
source scripts/env.config
IID=${1}
ARCH=${2}
WORK_DIR="${WORK_DIR}/${IID}"
if [ "$ARCH" == "mipseb" ]; then
cp "${KERNEL_DIR}/${ARCH}/vmlinux" "${WORK_DIR}/vmlinux"
chmod a+x "${WORK_DIR}/vmlinux"
elif [ "$ARCH" == "mipsel" ]; then
cp "${KERNEL_DIR}/${ARCH}/vmlinux" "${WORK_DIR}/vmlinux"
chmod a+x "${WORK_DIR}/vmlinux"
elif [ "$ARCH" == "armel" ]; then
cp "${KERNEL_DIR_ARMEL}/${ARCH}/arch/arm/boot/zImage" "${WORK_DIR}/zImage"
chmod a+x "${WORK_DIR}/zImage"
else
echo "Unsupported architecture"
fi
echo "Running firmware ${IID}: terminating after 60 secs..."
timeout --preserve-status --signal SIGINT 60 "${SCRIPT_DIR}/run.${ARCH}.sh" "${IID}" "${ARCH}"
sleep 1
echo "Inferring network..."
"${SCRIPT_DIR}/makeNetwork.py" -i "${IID}" -q -o -a "${ARCH}" -S "${WORK_DIR}"
echo "Done!"
# Kernel Information Module via gdb
First. Go read the normal kernelinfo [readme](https://github.com/panda-re/panda/blob/master/panda/plugins/osi_linux/utils/kernelinfo/README.md).
## Requirements
- GDB 8 or above. This is needed for the GDB API to support `gdb.execute(to_string=True)`.
- Python 3.6 or above. This is to support fstrings.
- A kernel vmlinux file for linux 3.0.0 or later that is *not stripped and has debug symbols*.
## Where does this apply?
Kernels with debug symbols. Likely one that you built. If it's stripped go back to the other method.
Example: `vmlinux: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, BuildID[sha1]=181ca40a44bef701cf0559b185180053a152029d, with debug_info, not stripped`
## How does this work?
This crux of this is python script run inside of gdb to gather DWARF symbols.
That script creates a command `kernel_info` which runs a bunch of GDB commands to gather information from the DWARF symbols and output it.
## How do I use it?
Run `run.sh` with a vmlinux and an output file.
`./run.sh vmlinux file.out`
Alternatively,
- start up gdb on the `vmlinux` file: `gdb ./vmlinux`
- load our python script: `source extract_kernelinfo.py`
- run our python script: `kernel_info output.file`
- quit: `q`
import gdb
import sys
import re
file_out = sys.stdout
def print_size(structv, cfgmemb, cfgname):
size = gdb.execute(f'printf "%u",(size_t) sizeof({structv})',to_string=True)
print(f"{cfgname}.{cfgmemb} = {size}",file=file_out)
def print_offset(structp, memb, cfgname):
offset = gdb.execute(f'printf "%d",(int)&(({structp}*)0)->{memb}',to_string=True)
print(f"{cfgname}.{memb}_offset = {offset}",file=file_out)
def print_offset_from_member(structp, memb_base, memb_dest, cfgname):
offset = gdb.execute(f'printf "%lld", (int64_t)&(({structp})*0)->{memb_dest} - (int64_t)&(({structp})*0)->{memb_base}',to_string=True)
print(f"{cfgname}.{memb_dest}_offset = {offset}",file=file_out)
def get_symbol_as_string(name):
return gdb.execute(f'printf "%s",{name}',to_string=True)
class KernelInfo(gdb.Command):
def __init__(self):
super(KernelInfo, self).__init__("kernel_info", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
global file_out
if arg:
file_out = open(arg, "w+")
print(f"Printing output to {arg}")
print(f"[kernelinfo]",file=file_out)
uts_release = get_symbol_as_string("init_uts_ns->name->release")
uts_version = get_symbol_as_string("init_uts_ns->name->version")
uts_machine = get_symbol_as_string("init_uts_ns->name->machine")
print(f"name = {uts_release}|{uts_version}|{uts_machine}",file=file_out)
release = get_symbol_as_string("init_uts_ns->name->release")
versions = release.split(".")
# version.c can have a bunch of junk - just extract a number
versions[2] = re.search("\d+",versions[2]).group(0)
print(f"version.a = {versions[0]}",file=file_out)
print(f"version.b = {versions[1]}",file=file_out)
print(f"version.c = {versions[2]}",file=file_out)
# TODO: we should use this to generate the file. See issue 651
print(f"#arch = {uts_machine}", file=file_out)
try:
per_cpu_offset_addr = gdb.execute('printf "%llu", &__per_cpu_offset',to_string=True)
per_cpu_offset_0_addr = gdb.execute('printf "%llu", __per_cpu_offset[0]',to_string=True)
except:
# This should be an arch-specific requirement, arm/mips don't have it (#651)
assert("x86" not in uts_machine), "Failed to find __per_cpu_offset_data"
per_cpu_offset_addr = 0
per_cpu_offset_0_addr = 0
print(f"task.per_cpu_offsets_addr = {per_cpu_offset_addr}",file=file_out)
print(f"task.per_cpu_offset_0_addr = {per_cpu_offset_0_addr}",file=file_out)
init_task_addr = gdb.execute('printf "%llu", &init_task',to_string=True)
# current_task is only an x86 thing
# It's defined in /arch/x86/kernel/cpu/common.c
if "x86" in uts_machine:
current_task_addr = gdb.execute('printf "%llu", &current_task',to_string=True)
else:
current_task_addr = init_task_addr
print(f"task.current_task_addr = {current_task_addr}",file=file_out)
print(f"task.init_addr = {init_task_addr}",file=file_out)
print(f"#task.per_cpu_offsets_addr = {hex(int(per_cpu_offset_addr))[2:]}",file=file_out)
print(f"#task.per_cpu_offset_0_addr = {hex(int(per_cpu_offset_0_addr))}",file=file_out)
print(f"#task.current_task_addr = {hex(int(current_task_addr))}",file=file_out)
print(f"#task.init_addr = {hex(int(init_task_addr))}",file=file_out)
print_size("struct task_struct", "size", "task");
print_offset("struct task_struct", "tasks", "task");
print_offset("struct task_struct", "pid", "task");
print_offset("struct task_struct", "tgid", "task");
print_offset("struct task_struct", "group_leader", "task");
print_offset("struct task_struct", "thread_group", "task");
print_offset("struct task_struct", "real_parent", "task");
print_offset("struct task_struct", "parent", "task");
print_offset("struct task_struct", "mm", "task");
print_offset("struct task_struct", "stack", "task");
print_offset("struct task_struct", "real_cred", "task");
print_offset("struct task_struct", "cred", "task");
print_offset("struct task_struct", "comm", "task");
print_size("((struct task_struct*)0)->comm", "comm_size", "task");
print_offset("struct task_struct", "files", "task");
print_offset("struct task_struct", "start_time", "task");
print_offset("struct cred", "uid", "cred");
print_offset("struct cred", "gid", "cred");
print_offset("struct cred", "euid", "cred");
print_offset("struct cred", "egid", "cred");
print_size("struct mm_struct", "size", "mm");
print_offset("struct mm_struct", "mmap", "mm");
print_offset("struct mm_struct", "pgd", "mm");
print_offset("struct mm_struct", "arg_start", "mm");
print_offset("struct mm_struct", "start_brk", "mm");
print_offset("struct mm_struct", "brk", "mm");
print_offset("struct mm_struct", "start_stack", "mm");
print_size("struct vm_area_struct", "size", "vma");
print_offset("struct vm_area_struct", "vm_mm", "vma");
print_offset("struct vm_area_struct", "vm_start", "vma");
print_offset("struct vm_area_struct", "vm_end", "vma");
print_offset("struct vm_area_struct", "vm_next", "vma");
print_offset("struct vm_area_struct", "vm_flags", "vma");
print_offset("struct vm_area_struct", "vm_file", "vma");
# used in reading file information
# This is gross because the name doesn't match the symbol identifier.
fstruct = "struct file"
f_path_offset = gdb.execute(f'printf "%d",(int)&(({fstruct}*)0)->f_path.dentry',to_string=True)
print(f"fs.f_path_dentry_offset = {f_path_offset}",file=file_out)
offset = gdb.execute(f'printf "%d",(int)&(({fstruct}*)0)->f_path.mnt',to_string=True)
print(f"fs.f_path_mnt_offset = {offset}",file=file_out)
print_offset("struct file", "f_pos", "fs");
print_offset("struct files_struct", "fdt", "fs");
print_offset("struct files_struct", "fdtab", "fs");
print_offset("struct fdtable", "fd", "fs");
# used for resolving path names */
print_size("struct qstr", "size", "qstr");
print_offset("struct qstr", "name", "qstr");
print_offset("struct dentry", "d_name", "path");
print_offset("struct dentry", "d_iname", "path");
print_offset("struct dentry", "d_parent", "path");
print_offset("struct dentry", "d_op", "path");
print_offset("struct dentry_operations", "d_dname", "path");
print_offset("struct vfsmount", "mnt_root", "path");
if int(versions[0]) >= 3:
# fields in struct mount
print_offset_from_member("struct mount", "mnt", "mnt_parent", "path");
print_offset_from_member("struct mount", "mnt", "mnt_mountpoint", "path");
else:
# fields in struct vfsmount
print_offset("struct vfsmount", "mnt_parent", "path");
print_offset("struct vfsmount", "mnt_mountpoint", "path");
if file_out != sys.stdout:
file_out.close()
# This registers our class to the gdb runtime at "source" time.
KernelInfo()
#!/bin/bash
if [ "$#" -lt 1 ]; then
echo "run.sh [debuggable vmlinux file] [output file]"
exit
fi
VMLINUX=$1
OUTPUT_FILE=$2
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
gdb $VMLINUX -ex "source ${SCRIPTDIR}/extract_kernelinfo.py" -ex "kernel_info $OUTPUT_FILE" -ex "q"
#!/bin/bash
set -e
set -u
source scripts/env.config
IID=${1}
ARCH=${2}
echo "----Running----"
WORK_DIR="${WORK_DIR}/${IID}"
IMAGE="${WORK_DIR}/image.raw"
IMAGE_DIR="${WORK_DIR}/image"
LIBNVRAM="${LIB_DIR}/libnvram.so.${ARCH}"
CONSOLE="${LIB_DIR}/console.${ARCH}"
echo "----Copying Filesystem Tarball----"
mkdir -p "${WORK_DIR}"
chmod a+rwx "${WORK_DIR}"
chown -R "${USER}" "${WORK_DIR}"
chgrp -R "${USER}" "${WORK_DIR}"
if [ ! -e "${WORK_DIR}/${IID}.tar.gz" ]; then
if [ ! -e "${TARBALL_DIR}/${IID}.tar.gz" ]; then
echo "Error: Cannot find tarball of root filesystem for ${IID}!"
exit 1
else
cp "${TARBALL_DIR}/${IID}.tar.gz" "${WORK_DIR}/${IID}.tar.gz"
fi
fi
echo "----Creating QEMU Image----"
qemu-img create -f raw "${IMAGE}" 1G
chmod a+rw "${IMAGE}"
echo "----Creating Partition Table----"
echo -e "o\nn\np\n1\n\n\nw" | /sbin/fdisk "${IMAGE}"
echo "----Mounting QEMU Image----"
kpartx_out="$(kpartx -a -s -v "${IMAGE}")"
DEVICE="$(echo $kpartx_out | cut -d ' ' -f 3)"
DEVICE="/dev/mapper/$DEVICE"
echo $DEVICE
sleep 1
echo "----Creating Filesystem----"
mkfs.ext2 "${DEVICE}"
sync
echo "----Making QEMU Image Mountpoint----"
if [ ! -e "${IMAGE_DIR}" ]; then
mkdir "${IMAGE_DIR}"
chown "${USER}" "${IMAGE_DIR}"
fi
echo "----Mounting QEMU Image Partition 1----"
mount "${DEVICE}" "${IMAGE_DIR}"
echo "----Extracting Filesystem Tarball----"
tar -xf "${WORK_DIR}/$IID.tar.gz" -C "${IMAGE_DIR}"
rm "${WORK_DIR}/${IID}.tar.gz"
echo "----Creating FIRMADYNE Directories----"
mkdir "${IMAGE_DIR}/firmadyne/"
mkdir "${IMAGE_DIR}/firmadyne/libnvram/"
mkdir "${IMAGE_DIR}/firmadyne/libnvram.override/"
echo "----Patching Filesystem (chroot)----"
cp $(which busybox) "${IMAGE_DIR}"
cp "${SCRIPT_DIR}/fixImage.sh" "${IMAGE_DIR}"
chroot "${IMAGE_DIR}" /busybox ash /fixImage.sh
rm "${IMAGE_DIR}/fixImage.sh"
rm "${IMAGE_DIR}/busybox"
echo "----Setting up FIRMADYNE----"
cp "${CONSOLE}" "${IMAGE_DIR}/firmadyne/console"
chmod a+x "${IMAGE_DIR}/firmadyne/console"
mknod -m 666 "${IMAGE_DIR}/firmadyne/ttyS1" c 4 65
cp "${LIBNVRAM}" "${IMAGE_DIR}/firmadyne/libnvram.so"
chmod a+x "${IMAGE_DIR}/firmadyne/libnvram.so"
cp "${SCRIPT_DIR}/preInit.sh" "${IMAGE_DIR}/firmadyne/preInit.sh"
chmod a+x "${IMAGE_DIR}/firmadyne/preInit.sh"
# cp -r "${IMAGE_DIR}" "${EMU_DIR}/image_${IID}"
echo "----Unmounting QEMU Image----"
sync
umount "${DEVICE}"
kpartx -d "${IMAGE}"
cd ${WORK_DIR}
qemu-img convert -f raw -O qcow2 image.raw image.qcow2
\ No newline at end of file
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: mount.sh <image ID>"
exit 1
fi
IID=${1}
if check_root; then
echo "Error: This script requires root privileges!"
exit 1
fi
echo "----Running----"
WORK_DIR=`get_scratch ${IID}`
IMAGE=`get_fs ${IID}`
IMAGE_DIR=`get_fs_mount ${IID}`
echo "----Adding Device File----"
DEVICE=$(get_device "$(kpartx -a -s -v "${IMAGE}")")
sleep 1
echo "----Making image directory----"
if [ ! -e "${IMAGE_DIR}" ]
then
mkdir "${IMAGE_DIR}"
fi
echo "----Mounting----"
#sudo /bin/mount /dev/nbd0p1 "${IMAGE_DIR}"
mount "${DEVICE}" "${IMAGE_DIR}"
#!/bin/sh
[ -d /dev ] || mkdir -p /dev
[ -d /root ] || mkdir -p /root
[ -d /sys ] || mkdir -p /sys
[ -d /proc ] || mkdir -p /proc
[ -d /tmp ] || mkdir -p /tmp
mkdir -p /var/lock
mount -t sysfs sysfs /sys
mount -t proc proc /proc
ln -sf /proc/mounts /etc/mtab
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
mount -t tmpfs tmpfs /run
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: run-debug.sh <image ID> [<architecture>]"
exit 1
fi
IID=${1}
if [ $# -gt 1 ]; then
if check_arch "${2}"; then
echo "Error: Invalid architecture!"
exit 1
fi
ARCH=${2}
else
echo -n "Querying database for architecture... "
ARCH=$(psql -d firmware -U firmadyne -h 127.0.0.1 -t -q -c "SELECT arch from image WHERE id=${1};")
ARCH="${ARCH#"${ARCH%%[![:space:]]*}"}"
echo "${ARCH}"
if [ -z "${ARCH}" ]; then
echo "Error: Unable to lookup architecture. Please specify {armel,mipseb,mipsel} as the second argument!"
exit 1
fi
fi
${SCRIPT_DIR}/run.${ARCH}-debug.sh ${IID}
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: run.armel-debug.sh <image ID>"
exit 1
fi
IID=${1}
WORK_DIR=`get_scratch ${IID}`
IMAGE=`get_fs ${IID}`
KERNEL=`get_kernel "armel"`
QEMU_AUDIO_DRV=none qemu-system-arm -m 256 -M virt -kernel ${KERNEL} -drive if=none,file=${IMAGE},format=raw,id=rootfs -device virtio-blk-device,drive=rootfs -append "firmadyne.syscall=0 root=/dev/vda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1 user_debug=31" -nographic -device virtio-net-device,netdev=net1 -netdev socket,listen=:2000,id=net1 -device virtio-net-device,netdev=net2 -netdev socket,listen=:2001,id=net2 -device virtio-net-device,netdev=net3 -netdev socket,listen=:2002,id=net3 -device virtio-net-device,netdev=net4 -netdev socket,listen=:2003,id=net4
#!/bin/bash
set -e
set -u
source scripts/env.config
IID=${1}
ARCH=${2}
WORK_DIR="${WORK_DIR}/${IID}"
IMAGE="${WORK_DIR}/image.raw"
KERNEL="${WORK_DIR}/zImage"
QEMU_AUDIO_DRV=none qemu-system-arm -m 256 -M virt -kernel ${KERNEL} -drive if=none,file=${IMAGE},format=raw,id=rootfs -device virtio-blk-device,drive=rootfs -append "firmadyne.syscall=1 root=/dev/vda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1 user_debug=31" -serial file:${WORK_DIR}/qemu.initial.serial.log -serial unix:/tmp/qemu.${IID}.S1,server,nowait -monitor unix:/tmp/qemu.${IID},server,nowait -display none -device virtio-net-device,netdev=net1 -netdev socket,listen=:2000,id=net1 -device virtio-net-device,netdev=net2 -netdev socket,listen=:2001,id=net2 -device virtio-net-device,netdev=net3 -netdev socket,listen=:2002,id=net3 -device virtio-net-device,netdev=net4 -netdev socket,listen=:2003,id=net4
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: run.mipseb-debug.sh <image ID>"
exit 1
fi
IID=${1}
WORK_DIR=`get_scratch ${IID}`
IMAGE=`get_fs ${IID}`
KERNEL=`get_kernel "mipseb"`
qemu-system-mips -m 256 -M malta -kernel ${KERNEL} -drive if=ide,format=raw,file=${IMAGE} -append "firmadyne.syscall=0 root=/dev/sda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1" -nographic -net nic,vlan=0 -net socket,vlan=0,listen=:2000 -net nic,vlan=1 -net socket,vlan=1,listen=:2001 -net nic,vlan=2 -net socket,vlan=2,listen=:2002 -net nic,vlan=3 -net socket,vlan=3,listen=:2003
#!/bin/bash
set -e
set -u
source scripts/env.config
IID=${1}
ARCH=${2}
WORK_DIR="${WORK_DIR}/${IID}"
IMAGE="${WORK_DIR}/image.raw"
KERNEL="${WORK_DIR}/vmlinux"
qemu-system-mips -m 256 -M malta -kernel ${KERNEL} -drive if=ide,format=raw,file=${IMAGE} -append "firmadyne.syscall=1 root=/dev/sda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1" -serial file:${WORK_DIR}/qemu.initial.serial.log -serial unix:/tmp/qemu.${IID}.S1,server,nowait -monitor unix:/tmp/qemu.${IID},server,nowait -display none -netdev socket,id=s0,listen=:2000 -device e1000,netdev=s0 -netdev socket,id=s1,listen=:2001 -device e1000,netdev=s1 -netdev socket,id=s2,listen=:2002 -device e1000,netdev=s2 -netdev socket,id=s3,listen=:2003 -device e1000,netdev=s3
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: run.mipsel-debug.sh <image ID>"
exit 1
fi
IID=${1}
WORK_DIR=`get_scratch ${IID}`
IMAGE=`get_fs ${IID}`
KERNEL=`get_kernel "mipsel"`
qemu-system-mipsel -m 256 -M malta -kernel ${KERNEL} -drive if=ide,format=raw,file=${IMAGE} -append "firmadyne.syscall=0 root=/dev/sda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1" -nographic -net nic,vlan=0 -net socket,vlan=0,listen=:2000 -net nic,vlan=1 -net socket,vlan=1,listen=:2001 -net nic,vlan=2 -net socket,vlan=2,listen=:2002 -net nic,vlan=3 -net socket,vlan=3,listen=:2003
#!/bin/bash
set -e
set -u
source scripts/env.config
IID=${1}
ARCH=${2}
WORK_DIR="${WORK_DIR}/${IID}"
IMAGE="${WORK_DIR}/image.raw"
KERNEL="${WORK_DIR}/vmlinux"
qemu-system-mipsel -m 256 -M malta -kernel ${KERNEL} -drive if=ide,format=raw,file=${IMAGE} -append "firmadyne.syscall=1 root=/dev/sda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1" -serial file:${WORK_DIR}/qemu.initial.serial.log -serial unix:/tmp/qemu.${IID}.S1,server,nowait -monitor unix:/tmp/qemu.${IID},server,nowait -display none -netdev socket,id=s0,listen=:2000 -device e1000,netdev=s0 -netdev socket,id=s1,listen=:2001 -device e1000,netdev=s1 -netdev socket,id=s2,listen=:2002 -device e1000,netdev=s2 -netdev socket,id=s3,listen=:2003 -device e1000,netdev=s3
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: run.sh <image ID> [<architecture>]"
exit 1
fi
IID=${1}
if [ $# -gt 1 ]; then
if check_arch "${2}"; then
echo "Error: Invalid architecture!"
exit 1
fi
ARCH=${2}
else
echo -n "Querying database for architecture... "
ARCH=$(psql -d firmware -U firmadyne -h 127.0.0.1 -t -q -c "SELECT arch from image WHERE id=${1};")
ARCH="${ARCH#"${ARCH%%[![:space:]]*}"}"
echo "${ARCH}"
if [ -z "${ARCH}" ]; then
echo "Error: Unable to lookup architecture. Please specify {armel,mipseb,mipsel} as the second argument!"
exit 1
fi
fi
${SCRIPT_DIR}/run.${ARCH}.sh ${IID}
#!/usr/bin/env python
import tarfile
import getopt
import sys
import re
import hashlib
import psycopg2
import six
def getFileHashes(infile):
t = tarfile.open(infile)
files = list()
links = list()
for f in t.getmembers():
if f.isfile():
# we use f.name[1:] to get rid of the . at the beginning of the path
files.append((f.name[1:], hashlib.md5(t.extractfile(f).read()).hexdigest(),
f.uid, f.gid, f.mode))
elif f.issym():
links.append((f.name[1:], f.linkpath))
return (files, links)
def getOids(objs, cur):
# hashes ... all the hashes in the tar file
hashes = [x[1] for x in objs]
hashes_str = ",".join(["""'%s'""" % x for x in hashes])
query = """SELECT id,hash FROM object WHERE hash IN (%s)"""
cur.execute(query % hashes_str)
res = [(int(x), y) for (x, y) in cur.fetchall()]
existingHashes = [x[1] for x in res]
missingHashes = set(hashes).difference(set(existingHashes))
newObjs = createObjects(missingHashes, cur)
res += newObjs
result = dict([(y, x) for (x, y) in res])
return result
def createObjects(hashes, cur):
query = """INSERT INTO object (hash) VALUES (%(hash)s) RETURNING id"""
res = list()
for h in set(hashes):
cur.execute(query, {'hash':h})
oid = int(cur.fetchone()[0])
res.append((oid, h))
return res
def insertObjectToImage(iid, files2oids, links, cur):
query = """INSERT INTO object_to_image (iid, oid, filename, regular_file, uid, gid, permissions) VALUES (%(iid)s, %(oid)s, %(filename)s, %(regular_file)s, %(uid)s, %(gid)s, %(mode)s)"""
cur.executemany(query, [{'iid': iid, 'oid' : x[1], 'filename' : x[0][0],
'regular_file' : True, 'uid' : x[0][1],
'gid' : x[0][2], 'mode' : x[0][3]} \
for x in files2oids])
cur.executemany(query, [{'iid': iid, 'oid' : 1, 'filename' : x[0],
'regular_file' : False, 'uid' : None,
'gid' : None, 'mode' : None} \
for x in links])
def process(iid, infile):
dbh = psycopg2.connect(database="firmware", user="firmadyne",
password="firmadyne", host="127.0.0.1")
cur = dbh.cursor()
(files, links) = getFileHashes(infile)
oids = getOids(files, cur)
fdict = dict([(h, (filename, uid, gid, mode)) \
for (filename, h, uid, gid, mode) in files])
file2oid = [(fdict[h], oid) for (h, oid) in six.iteritems(oids)]
insertObjectToImage(iid, file2oid, links, cur)
dbh.commit()
dbh.close()
def main():
infile = iid = None
opts, argv = getopt.getopt(sys.argv[1:], "f:i:")
for k, v in opts:
if k == '-i':
iid = int(v)
if k == '-f':
infile = v
if infile and not iid:
m = re.search(r"(\d+)\.tar\.gz", infile)
if m:
iid = int(m.group(1))
process(iid, infile)
if __name__ == "__main__":
main()
#!/bin/bash
set -e
set -u
if [ -e ./firmadyne.config ]; then
source ./firmadyne.config
elif [ -e ../firmadyne.config ]; then
source ../firmadyne.config
else
echo "Error: Could not find 'firmadyne.config'!"
exit 1
fi
if check_number $1; then
echo "Usage: umount.sh <image ID>"
exit 1
fi
IID=${1}
if check_root; then
echo "Error: This script requires root privileges!"
exit 1
fi
echo "----Running----"
WORK_DIR=`get_scratch ${IID}`
IMAGE=`get_fs ${IID}`
IMAGE_DIR=`get_fs_mount ${IID}`
DEVICE=$(get_device "$(kpartx -u -s -v "${IMAGE}")")
echo "----Unmounting----"
umount "${DEVICE}"
echo "----Disconnecting Device File----"
kpartx -d "${IMAGE}"
losetup -d "${DEVICE}" &>/dev/null
dmsetup remove $(basename "${DEVICE}") &>/dev/null
#!/bin/sh
set -e
sudo apt update
sudo apt install -y python-pip python3-pip python3-pexpect unzip busybox-static fakeroot kpartx snmp uml-utilities util-linux vlan qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils
echo "Installing binwalk"
git clone --depth=1 https://github.com/devttys0/binwalk.git
cd binwalk
sudo ./deps.sh
sudo python3 ./setup.py install
sudo -H pip3 install git+https://github.com/ahupp/python-magic
sudo -H pip install git+https://github.com/sviehb/jefferson
cd ..
echo "Setting up firmware analysis toolkit"
chmod +x emu.py
chmod +x reset.py
#Set firmadyne_path in fat.config
sed -i "/firmadyne_path=/c\firmadyne_path=$firmadyne_dir" fat.config
# Comment out psql -d firmware ... in getArch.sh
sed -i 's/psql/#psql/' ./scripts/getArch.sh
#Setting up the toolchains
sudo mkdir -p /opt/cross
sudo cp toolchains/* /opt/cross
cd /opt/cross
sudo tar -xf arm-linux-musleabi.tar.xz
sudo tar -xf mipseb-linux-musl.tar.xz
sudo tar -xf mipsel-linux-musl.tar.xz
cd -
mkdir -p ./source/Kernel-mips/build/mipseb
mkdir -p ./source/Kernel-mips/build/mipsel
mkdir -p ./source/Kernel-armel/build/armel
cp ./source/Kernel-mips/config.mipseb ./source/Kernel-mips/build/mipseb/.config
cp ./source/Kernel-mips/config.mipsel ./source/Kernel-mips//build/mipsel/.config
cp ./source/Kernel-armel/config.armel ./source/Kernel-armel/build/armel/.config
# Adding toolchains to PATH
echo "PATH=$PATH:/opt/cross/mipsel-linux-musl/bin:/opt/cross/mipseb-linux-musl/bin:/opt/cross/arm-linux-musleabi/bin" >> ~/.profile
source ~/.profile
# Make the kernels
cd ./source/Kernel-mips/
make ARCH=mips CROSS_COMPILE=mipseb-linux-musl- O=./build/mipseb -j8
make ARCH=mips CROSS_COMPILE=mipsel-linux-musl- O=./build/mipsel -j8
cd - && cd ./source/Kernel-armel/
make ARCH=arm CROSS_COMPILE=arm-linux-musleabi- O=./build/armel zImage -j8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment