Skip to content

Instantly share code, notes, and snippets.

@shirriff
Created January 4, 2018 02:33
Show Gist options
  • Save shirriff/e333b99b521bd8dbddbbd40868245011 to your computer and use it in GitHub Desktop.
Save shirriff/e333b99b521bd8dbddbbd40868245011 to your computer and use it in GitHub Desktop.
Use brute force to crack the password on a Xerox Alto disk.
#include <stdint.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
int64_t count = 0;
// Password vector from sys.boot. Must be big-endian.
// Disk 47
uint16_t passvec[] = {0xffff, 0xcfa7, 0x9f3d, 0x669a, 0xf2bb, 0xf193, 0x6d09, 0x4571, 0xe1d1};
// Disk 72
// uint16_t passvec[] = {0xffff, 0x8341, 0x772c, 0x249b, 0x1be2, 0xf71f, 0x5b87, 0x9fce, 0x0581};
void testPasswd(const char *password, uint16_t *passvec) {
count += 1;
uint16_t x[2];
uint16_t y[2];
x[0] = 0;
x[1] = 0;
y[0] = 0;
y[1] = 0;
int length = strlen(password);
for (int i = 0; i < length; i++) {
char c = password[i];
if (c >= 'a' && c <= 'z') {
c = c - 'a' + 'A';
}
uint16_t *p;
if ((i % 3) == 0) {
p = x;
} else {
p = y;
}
p[1] = (p[0] << 9) + (p[1] >> 7);
p[0] = (c << 9) + (p[0] >> 7);
}
uint32_t yval = (y[0] << 16) + y[1];
uint32_t a = (passvec[1] << 16) | passvec[2];
uint32_t b = (passvec[3] << 16) | passvec[4];
uint64_t t = (uint32_t)((uint32_t)x[0] * (uint32_t)x[0]);
t = t * a;
t ^= 0xffffffff00000000;
t += 1;
uint64_t s = (uint64_t)b * (uint64_t)yval;
uint64_t c = t + s;
uint64_t wanted = ((uint64_t)passvec[5] << 48) | ((uint64_t)passvec[6] << 32) | ((uint64_t)passvec[7] << 16) | passvec[8];
if (wanted == c) {
printf("Password match: %s\n", password);
// exit(1);
} else {
// printf("%llx %llx\n", wanted, c);
}
}
// Try password from stdin.
void crack() {
// From disk 37
FILE *f = stdin;
char pass[80];
while (fgets(pass, 80, f)) {
pass[strlen(pass)-1] = '\0';
// printf("Password: %s\n", pass);
testPasswd(pass, passvec);
}
}
// char *chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=_+,.<>?;':";
char *chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// char *chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int nchars;
// Generate all strings from "chars" recursively. max is the length.
void generateString(uint16_t *passvec, char *pass, int idx, int max) {
for (int i = 0; i < nchars; i++) {
pass[idx] = chars[i];
if (idx >= max-1) {
testPasswd(pass, passvec);
} else {
generateString(passvec, pass, idx + 1, max);
}
}
}
// Brute force generate passwords from character set.
void crack2() {
char pass[80];
for (int max = 1; max < 12; max++) {
printf("Len %d\n", max);
pass[max] = '\0';
generateString(passvec, pass, 0, max);
}
}
void crack3() {
FILE *f = stdin;
char pass0[80];
char *pass = pass0 + 1;
while (fgets(pass, 80, f)) {
int len = strlen(pass);
pass[len] = '\0';
for (int i = 0; i < nchars; i++) {
pass[len-1] = chars[i];
testPasswd(pass, passvec);
pass[len-1] = '\0';
pass[-1] = chars[i];
testPasswd(pass0, passvec);
}
}
}
int main(int argc, char **argv) {
nchars = strlen(chars);
crack2();
printf("Total count: %lld\n", count);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment