-
-
Save pascal-schetelat/4e31697a4c7e5fe7aeebe35d9053136b to your computer and use it in GitHub Desktop.
my_char = "PzLaM2ZqOx5Ks3NwIcJ1Sd6NeUvH7WfBrY9AbGgVtTnGhVyTmG8EjVu0TkFi4QClRoDpX" | |
mac_addr = '00:80:F4:xx:xx:xx' | |
replaceAll = mac_addr.replace(':', '') | |
def generatePasswd(str1=replaceAll, i=len(replaceAll), str2=my_char): | |
str3 = str1 | |
i2 = i | |
str4 = str2 | |
cArr = ['']*12 # 12 elements | |
if str3 != '': | |
i3 = 6 | |
if i2 >= 6: | |
substring = str3[-6:] | |
i4 = 0 | |
while (i4 < i2) & (i4 < i3): | |
hexToInt = int(f"0x{substring[i4]}",0) | |
i5 = 15 - (hexToInt % 15) | |
d2 = float(hexToInt) | |
i6 = i4 | |
d3 = float(i5) | |
round_ = int( | |
round(d3 ** 3.0) * 8 + | |
round(d3 ** 2.0) * 3 + | |
(i5 * 5)) % (len(str2) + 1) | |
i7 = i6 * 2 | |
idx = int(round(d2 ** 3.0) * 6 + | |
round(d2 ** 2.0) * 9 + | |
(hexToInt * 7) )% (len(str2) + 1) | |
cArr[i7] = str4[idx] | |
cArr[i7 + 1] = str4[round_] | |
i4 = i6 + 1 | |
i3 = 6 | |
return ''.join(cArr) | |
if __name__ == '__main__': | |
import requests | |
key = generatePasswd() | |
r = requests.get('https://192.168.xx.xx/rsa1/MeterInstantData', verify=False, auth=('m2madmin', key)) | |
r.json() | |
paths = { | |
"DELETE_INSTANCE_MIO_INPUT" : "/rsa1/MioInput;channel=", | |
"DELETE_INSTANCE_MIO_OUTPUT" : "/rsa1/MioOutput;channel=", | |
"DELETE_INSTANCE_MPR" : "/rsa1/MprEndpoint;channel=", | |
"DELETE_WIRELESS_INPUT" : "/rsa1/MioWirelessInput;slaveId=%d;channel=%d", | |
"DELETE_WIRELESS_METER" : "/rsa1/WirelessMeter;deviceAddress=", | |
"DELETE_WIRELESS_OUTPUT" : "/rsa1/MioWirelessOutput;slaveId=%d;channel=%d", | |
"DELETE_WIRELESS_PRO" : "/rsa1/WirelessProChannel;deviceAddress=", | |
"DELETE_WIRELESS_SENSOR" : "/rsa1/WirelessSensor;deviceAddress=", | |
"GET_BRANCH_METERS" : "/rsa1/BranchMeters", | |
"GET_CONNECTION_STATISTICS" : "/rsa1/WiserConnectionStatistics", | |
"GET_CONTROLLER" : "/rsa1/Controller", | |
"GET_EP_CONFIG_UPDATE_STATUS" : "/rsa1/EpConfigUpdateStatus ", | |
"GET_GATEWAY_KEY" : "/rsa1/GateWayKey", | |
"GET_INSTANCES_MPR" : "/rsa1/MprEndpoint/instances", | |
"GET_INSTANCE_MIO_INPUT" : "/rsa1/MioInput/instances", | |
"GET_INSTANCE_MIO_OUTPUT" : "/rsa1/MioOutput/instances", | |
"GET_MEASUREMENT_DATA" : "/rsa1/MeasurementData;sId=%d;ch=%d", | |
"GET_METER_CUMULATED_DATA" : "/rsa1/MeterCumulatedData", | |
"GET_METER_INSTANT_DATA" : "/rsa1/MeterInstantData", | |
"GET_PRODUCT_DETAILS" : "/rsa1/ProductDetails", | |
"GET_PRODUCT_INTERFACE" : "/fct/ProductInterface", | |
"GET_SYSTEM_UPGRADE_STATUS" : "/rsa1/SystemUpgradeStatus", | |
"GET_USAGE_METERS" : "/rsa1/UsageMeters", | |
"GET_USER_PREPAIRING" : "/rsa1/UserPreparing", | |
"GET_WIRELESS_DIAGNOSTIC" : "/rsa1/WirelessDiagnostic", | |
"GET_WIRELESS_INPUT" : "/rsa1/MioWirelessInput;slaveId=%d;channel=%d", | |
"GET_WIRELESS_INPUTS" : "/rsa1/MioWirelessInput/instances", | |
"GET_WIRELESS_METER" : "/rsa1/WirelessMeter;deviceAddress=", | |
"GET_WIRELESS_METERS" : "/rsa1/WirelessMeter/instances", | |
"GET_WIRELESS_METERS_LITE" : "/rsa1/WirelessMeterList/instances", | |
"GET_WIRELESS_METER_LITE" : "/rsa1/WirelessMeterInfo;dA=", | |
"GET_WIRELESS_OUTPUT" : "/rsa1/MioWirelessOutput;slaveId=%d;channel=%d", | |
"GET_WIRELESS_OUTPUTS" : "/rsa1/MioWirelessOutput/instances", | |
"GET_WIRELESS_PRO_LIST" : "/rsa1/WirelessProChannel/instances", | |
"GET_WIRELESS_PRO_LITE" : "/rsa1/WirelessProInfo;dA=", | |
"GET_WIRELESS_SENSOR" : "/rsa1/WirelessSensor;deviceAddress=", | |
"GET_WIRELESS_SENSORS" : "/rsa1/WirelessSensor/instances", | |
"GET_WIRELESS_SENSOR_LITE" : "/rsa1/WirelessSensorInfo;dA=", | |
"GET_WIRELESS_SENSOR_TEMPERATURE" : "/rsa1/TemperatureInfo;sId=", | |
"POST_BLINK_DEVICE" : "/rsa1/WirelessManager/methods/blinkDevice", | |
"POST_BUSINESS_INFO" : "/api/v1/fesb/provision", | |
"POST_EVE_METER" : "/rsa1/LoadStatus/methods/SetStandbyThreshold", | |
"POST_FIRMWARE_UPLOAD" : "/FirmwareUpload", | |
"POST_INIT_SYSTEM_UPGRADE" : "/rsa1/Controller/methods/initSystemUpgrade", | |
"POST_INSTANCE_MIO_CONTROL" : "/rsa1/Controller/methods/operateMio", | |
"POST_INSTANCE_MIO_INPUT" : "/rsa1/MioInput/instances", | |
"POST_INSTANCE_MIO_OUTPUT" : "/rsa1/MioOutput/instances", | |
"POST_INSTANCE_MPR" : "/rsa1/MprEndpoint/instances", | |
"POST_STATUS" : "/rsa1/LoadStatus/methods/GetStatus", | |
"PUT_BRANCH_METERS" : "/rsa1/BranchMeters", | |
"PUT_INSTANCE_MIO_INPUT" : "/rsa1/MioInput;channel=", | |
"PUT_INSTANCE_MIO_OUTPUT" : "/rsa1/MioOutput;channel=", | |
"PUT_INSTANCE_MPR" : "/rsa1/MprEndpoint;channel=", | |
"PUT_USER_PREPAIRING" : "/rsa1/UserPreparing", | |
"PUT_WIRELESS_CHANNEL" : "/rsa1/WirelessManager", | |
"PUT_WIRELESS_INPUT" : "/rsa1/MioWirelessInput;slaveId=%d;channel=%d", | |
"PUT_WIRELESS_METER" : "/rsa1/WirelessMeter;deviceAddress=", | |
"PUT_WIRELESS_OUTPUT" : "/rsa1/MioWirelessOutput;slaveId=%d;channel=%d", | |
"PUT_WIRELESS_SENSOR" : "/rsa1/WirelessSensor;deviceAddress=", | |
"SEM_IDENTIFICATION" : "/rsa1/SemIdentificationOpt", | |
"START_COMISSIONING" : "/rsa1/WirelessManager/methods/startCommissioning", | |
"STOP_COMISSIONING" : "/rsa1/WirelessManager/methods/stopCommissioning", | |
} |
my_char is that a static value? Can it be changed? I used this like it is, and it was working great. But now I'm getting 401 Unauthorized with the passwords generated here. Any ideas?
Hello,
I've got the same problem since yesterday.
It seems the class has changed (firmware update?)
package com.schneiderelectric.plugin.fwupdate;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class AdminPasswordService {
private static final String M2M_PASSWORD_HASH_ARAMIS = "PzLaM2ZqOx5Ks3NwIcJ1Sd6NeUvH7WfBrY9AbGgVtTnGhVyTmG8EjVu0TkFi4QClRoDpX";
private static final int M2M_PASSWORD_LENGTH = 12;
private static final int M2M_PASSWORD_MAX_SEED_LENGTH = 6;
private static String hashSHA(String string2) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance((String)"SHA-256");
}
catch (NoSuchAlgorithmException noSuchAlgorithmException) {
noSuchAlgorithmException.printStackTrace();
messageDigest = null;
}
messageDigest.update(string2.getBytes(StandardCharsets.UTF_8));
byte[] arrby = messageDigest.digest();
Object[] arrobject = new Object[]{new BigInteger(1, arrby)};
return String.format((String)"%064x", (Object[])arrobject);
}
public static String m2mAdminPassword(String string2) {
return AdminPasswordService.passwordFromMacAddress(string2);
}
public static String newM2mAdminPassword(String string2, String string3) {
String string4 = AdminPasswordService.passwordFromMacAddress(string2);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(string4);
stringBuilder.append(string3);
return AdminPasswordService.hashSHA(stringBuilder.toString());
}
private static String passwordFromMacAddress(String string2) {
int n;
int n2 = string2.length();
char[] arrc = new char[12];
if (string2 != null && n2 >= (n = 6)) {
String string3 = string2.substring(string2.length() - n);
int n3 = 0;
while (n3 < n2 && n3 < n) {
char c = string3.charAt(n3);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("");
stringBuilder.append(c);
int n4 = Integer.parseInt((String)stringBuilder.toString(), (int)16);
int n5 = 15 - n4 % 15;
double d = n4;
long l = 6L * Math.round((double)Math.pow((double)d, (double)3.0));
int n6 = n3;
int n7 = (int)(l + 9L * Math.round((double)Math.pow((double)d, (double)2.0)) + (long)(n4 * 7)) % 70;
double d2 = n5;
int n8 = (int)(8L * Math.round((double)Math.pow((double)d2, (double)3.0)) + 3L * Math.round((double)Math.pow((double)d2, (double)2.0)) + (long)(n5 * 5)) % 70;
int n9 = n6 * 2;
arrc[n9] = M2M_PASSWORD_HASH_ARAMIS.charAt(n7);
arrc[n9 + 1] = M2M_PASSWORD_HASH_ARAMIS.charAt(n8);
n3 = n6 + 1;
n = 6;
}
}
return new String(arrc);
}
}
I can see a new method newM2mAdminPassword
I tired to get GateWayKey from this URL (not protected by auth) but it returns an 503 Service Unavailable error.
https://<wiser_ip>/rsa1/GateWayKey
I extracted it from the APK Wiser Energy 3.9.1
Hmm.. On my phone, I have version 6.7.1 of the app. It can still connect to the device, and it doesn't have that AdminPasswordService class.
So must be possible to connect without that. But maybe it will provide another way in..
Anyway, here are my findings from earlier today:
NicolaiPetri/wiser2mqtt#2 (comment)
You need to press the button before accessing /rsa1/GateWayKey
The key changes every time.
Hello,
Thanks you very much for your findings.
I was takling about the Wiser Energy app; not the eSetup which is 6.7.1.
At the moment the access through Wiser Energy app is working (by the Cloud).
I'll give some tries tonight when i'll be at home, but I think the m2madmin password is reset each time you press the button.
The output of the newM2mAdminPassword method is very long now.
So the request could be something like that :
curl -k --user m2madmin:0c1e9718b65aa7c444fb78c1ace930c044ae6ce1b5609816f00a5835e5d4fd79 https://<wiser_ip>/rsa1/MeterInstantData
Check the class here :
https://pastebin.com/t59VjMkf
You can execute it with java and it'll output the password generated from MAC and GateWayKey.
Kind regards.
Waiting eagerly, just got all the readings to work with python after NicolaiPetri nice work.
Thx for doing this work
But this AdminPasswordService is for the Wiser Energy app, right? So for cloud connection? We're not sure that it will even work with the local api?
The eSetup app does work with the local api, so I think it best to try to focus around the source code from that app to figure out a way in.
How did u generate the new password, I can't get the java from u'r pastebin to work?
1/ Push the button on the EER31800
2/ Get the key via HTTP GET on this URL : https://<wiser_ip>/rsa1/GateWayKey
3/ Convert the key and the MAC address to a password
Use this website : https://www.tutorialspoint.com/compile_java_online.php
Copy paste the class here : https://pastebin.com/raw/t59VjMkf
Add your MAC and GateWayKey.
String MAC = "<PUT_MAC_HERE>";
String GateWayKey = "<PUT_GATEWAYKEY_HERE>";
4/ Send JSON data via HTTP POST to https://<wiser_ip>/rs/login
For exemple :
{
"username": "m2madmin",
"password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
5/ A cookie is returned named SID, get the value of it (SID=yyyyyy)
6/ Make subsequent requests with that cookie by adding it in headers :
Cookie: SID=yyyyyy
It is now working for me 👍
Thanks alot man, u guys are the best!
btw, i figured out what was wrong when i wrote the last post. MAC is of course without ":"
my_char is that a static value? Can it be changed?
I used this like it is, and it was working great. But now I'm getting 401 Unauthorized with the passwords generated here. Any ideas?