Working test api (wifi mode), firmware download, key extractor

master
Cole Deck 6 months ago
commit 181a3b0fd3

7
.gitignore vendored

@ -0,0 +1,7 @@
*.bin
firmware/
firmware/*
*.csv
listing.txt
*.pyc
__pycache__

@ -0,0 +1,24 @@
import requests
def call_api(api_url, method, params):
"""
Function to make an API call.
Parameters:
- api_url (str): The URL of the API endpoint.
- method (str): The HTTP method to use ('POST' or 'GET').
- params (dict): Dictionary of parameters.
Returns:
- response: The response from the API call.
"""
print("Calling API",api_url,"with method",method,"and parameters",params)
if method.upper() == 'POST':
response = requests.post(api_url, data=params, verify=False)
elif method.upper() == 'GET':
response = requests.get(api_url, params=params, verify=False)
else:
raise ValueError("Method must be 'POST' or 'GET'")
return response

@ -0,0 +1,3 @@
#!/bin/sh
rm -rfv firmware *.bin* fwname listing.txt

@ -0,0 +1,2 @@
tool_directory: ./firmware/www/tool/
app_config_directory: .

@ -0,0 +1,27 @@
#!/bin/sh
# Firmware downloader
DEVICE=NE1D
SERIAL=1133001
VERSION=194
BASEURL=https://updates.netool.io/bin/
wget -O listing.txt $BASEURL
filename=$DEVICE-$VERSION-UP-$SERIAL.bin
rm *.bin*
if cat listing.txt | grep $filename && wget $BASEURL$filename; then
# exact version match
echo $filename > fwname
else
filename=$DEVICE-$VERSION-UP-1133333.bin
if cat listing.txt | grep $filename && wget $BASEURL$filename; then
echo $filename > fwname
else
echo "ERROR: Unable to find firmware!"
rm fwname
fi
fi

@ -0,0 +1,21 @@
#!/bin/sh
# Define the paths to the SquashFS images
IMAGE="$1"
echo $IMAGE
# Define the mount points
MOUNTPOINT="./firmware"
# Create the mount points if they don't exist
mkdir -p $MOUNTPOINT
# Mount the SquashFS images
7z x -o$MOUNTPOINT $IMAGE
# Perform the diff and show only the differences
#diff --no-dereference -r $MOUNTPOINT
# Remove the mount points
#rm -rf $MOUNTPOINT

@ -0,0 +1,94 @@
import yaml
import os
import re
def read_php_files(input, output):
# Load the directory path from the YAML file
search_list=['sec', 'code', 'id', 'post_key', 'pass', 'key'] # why is there so many?
param_list=['POST','GET','DELETE','PUT'] # so far looks like only POST and GET, include the others just in case
directory_path = input
# Check if the directory exists
if not os.path.isdir(directory_path):
print(f"The directory {directory_path} does not exist.")
return
# List all .php files in the directory
php_files = [f for f in os.listdir(directory_path) if f.endswith('.php')]
if not php_files:
print("No PHP files found in the directory.")
return
out = ""
# Process each .php file
for filename in php_files:
file_path = os.path.join(directory_path, filename)
with open(file_path, 'r', encoding='utf-8') as file:
contents = file.read()
add = filename
found_params = []
for paramtype in param_list:
for match in re.finditer("_" + paramtype, contents):
start_line = contents.rfind('\n', 0, match.start()) + 1
end_line = contents.find('\n', match.end(), -1)
line = contents[start_line:end_line]
if "[" in line and "]" in line:
quoted_strings = re.findall(r'["\'](.*?)["\']', line)
if len(quoted_strings) == 1:
found_params.append((quoted_strings[0], line[line.find("$")+1:line.find('=')].strip()))
add += ",PARAM:," + quoted_strings[0] + "," + paramtype
for codetype in search_list:
for match in re.finditer("\$" + codetype, contents):
# Extract the line containing the matched string
start_line = contents.rfind('\n', 0, match.start()) + 1
end_line = contents.find('\n', match.end(), -1)
line = contents[start_line:end_line]
if '==' in line and not "POST" in line and not "GET" in line:
#print(line)
quoted_strings = re.findall(r'["\'](.*?)["\']', line)
if len(quoted_strings) == 1:
if codetype not in [x[0] for x in found_params]:
# non-matching variable & key!
found = False
for val in found_params:
if codetype == val[1]:
found = True
codetype2 = val[0]
print("NOTE: Alternate parameter variable used!", codetype, "-->", codetype2, "in file", filename)
add += ",KEY:," + codetype2 + "," + quoted_strings[0]
break
if not found:
print("WARNING: No matching parameter variable found!" , codetype, "--> ??? in file", filename)
add += ",KEY:," + codetype + "," + quoted_strings[0]
else:
add += ",KEY:," + codetype + "," + quoted_strings[0]
if add == filename:
out += add + ",null"
else:
out += add
out += "\n"
print(out)
with open(output + "/apidetails.csv", 'w', encoding='utf-8') as file:
# Write the string to the file
file.write(out)
# Example usage
if __name__ == "__main__":
with open('config.yml', 'r') as file:
config = yaml.safe_load(file)
directory_path = config['tool_directory']
output_path = config['app_config_directory']
read_php_files(directory_path, output_path)

@ -0,0 +1,52 @@
from call_api import call_api
from read_api_details import parse_csv_to_dict
import json
def main():
base_url = "https://192.168.49.1/tool/" # Replace with your actual base URL
details = parse_csv_to_dict("apidetails.csv")
print(details.keys())
# Prompt the user for the API call
api_call = input("Enter the API call (e.g., about.php): ").strip()
full_url = base_url + api_call
print(details[api_call])
# Prompt the user for the method
method = input("Enter the HTTP method (POST/GET): ").strip().upper()
auto_include = []
if 'PARAM' in details[api_call]:
for param, val in details[api_call]["PARAM"].items():
# print(param, val)
if val == method:
print(param, end="")
if 'KEY' in details[api_call]:
for keyname, key in details[api_call]["KEY"].items():
if keyname == param:
print("=" + key, end="")
auto_include.append((keyname, key))
print("")
# Prompt the user for parameters
params = {}
while True:
param_name = input("Enter parameter name (or press enter to finish): ").strip()
if param_name == "":
break
param_value = input(f"Enter value for '{param_name}': ").strip()
params[param_name] = param_value
for param in auto_include:
params[param[0]] = param[1]
# Call the API
try:
response = call_api(full_url, method, params)
print("Response Status Code:", response.status_code)
try:
print("Response JSON:", json.dumps(response.json(), indent=2))
except ValueError:
print("Response Text:", response.text)
except Exception as e:
print("Error:", str(e))
if __name__ == "__main__":
main()

@ -0,0 +1,55 @@
import csv
def parse_csv_to_dict(csv_file_path):
"""
Parses a CSV file into a dictionary.
Parameters:
- csv_file_path (str): The path to the CSV file.
Returns:
- dict: A dictionary representation of the CSV file.
"""
parsed_dict = {}
with open(csv_file_path, mode='r', newline='', encoding='utf-8') as csvfile:
reader = csv.reader(csvfile)
for row in reader:
if len(row) < 2:
continue # Skip rows that do not have at least two columns
name = row[0].strip()
if name not in parsed_dict:
parsed_dict[name] = {}
index = 1
while index < len(row):
field_type = row[index].strip() if len(row) > index else None
#print(field_type, end=" ")
if not field_type:
break # End of relevant columns for this row
if field_type in ('KEY:', 'PARAM:') and len(row) > index + 2:
key_or_param_name = row[index + 1].strip()
key_or_param_value = row[index + 2].strip()
if field_type == 'KEY:':
if 'KEY' not in parsed_dict[name]:
parsed_dict[name]['KEY'] = {}
parsed_dict[name]['KEY'][key_or_param_name] = key_or_param_value
elif field_type == 'PARAM:':
if 'PARAM' not in parsed_dict[name]:
parsed_dict[name]['PARAM'] = {}
parsed_dict[name]['PARAM'][key_or_param_name] = key_or_param_value
index += 3
#print("")
# If no valid field_type was found, set the entry to None
if name not in parsed_dict:
parsed_dict[name] = None
return parsed_dict
if __name__ == "__main__":
csv_file_path = 'apidetails.csv'
result = parse_csv_to_dict(csv_file_path)
print(result)

@ -0,0 +1,15 @@
#!/bin/sh
if ! [ -e apidetails.csv ]; then
./download-fw.sh
./extract.sh $(cat fwname)
DIR=./firmware/www/tool/
echo "tool_directory: $DIR
app_config_directory: ." > config.yml
python get_codes.py
./cleanup.sh
fi
Loading…
Cancel
Save