Fix stack-based buffer overflow in "lf em 4x05 sniff" command

This commit is contained in:
Hanno Heinrichs 2022-12-29 12:52:19 +01:00
commit 9e0fe3ca36
5 changed files with 54 additions and 28 deletions

View file

@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Fixed buffer overflow in "lf em 4x05 sniff" (@HeinrichsH)
- Fixed potential NULL array printing (@jmichel) - Fixed potential NULL array printing (@jmichel)
- Added PIV aid to resource file (@jmichel) - Added PIV aid to resource file (@jmichel)
- Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel) - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel)

View file

@ -41,6 +41,7 @@
#include "generator.h" #include "generator.h"
#include "cliparser.h" #include "cliparser.h"
#include "cmdhw.h" #include "cmdhw.h"
#include "util.h"
//////////////// 4205 / 4305 commands //////////////// 4205 / 4305 commands
@ -1996,8 +1997,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
const char *cmdText; const char *cmdText;
char dataText[100]; char dataText[100];
char blkAddr[4]; char blkAddr[4];
char bits[80]; int i;
int i, bitidx;
int ZeroWidth; // 32-42 "1" is 32 int ZeroWidth; // 32-42 "1" is 32
int CycleWidth; int CycleWidth;
size_t pulseSamples; size_t pulseSamples;
@ -2018,6 +2018,10 @@ int CmdEM4x05Sniff(const char *Cmd) {
PrintAndLogEx(SUCCESS, "offset | Command | Data | blk | raw"); PrintAndLogEx(SUCCESS, "offset | Command | Data | blk | raw");
PrintAndLogEx(SUCCESS, "-------+-------------+----------+-----+------------------------------------------------------------"); PrintAndLogEx(SUCCESS, "-------+-------------+----------+-----+------------------------------------------------------------");
smartbuf bits = { 0 };
bits.ptr = malloc(EM4X05_BITS_BUFSIZE);
bits.size = EM4X05_BITS_BUFSIZE;
bits.idx = 0;
size_t idx = 0; size_t idx = 0;
// loop though sample buffer // loop though sample buffer
while (idx < g_GraphTraceLen) { while (idx < g_GraphTraceLen) {
@ -2037,8 +2041,8 @@ int CmdEM4x05Sniff(const char *Cmd) {
if (ZeroWidth <= 50) { if (ZeroWidth <= 50) {
pktOffset -= ZeroWidth; pktOffset -= ZeroWidth;
memset(bits, 0x00, sizeof(bits)); memset(bits.ptr, 0, bits.size);
bitidx = 0; bits.idx = 0;
while ((idx < g_GraphTraceLen) && !eop) { while ((idx < g_GraphTraceLen) && !eop) {
CycleWidth = idx; CycleWidth = idx;
@ -2047,7 +2051,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
CycleWidth = idx - CycleWidth; CycleWidth = idx - CycleWidth;
if ((CycleWidth > 300) || (CycleWidth < (ZeroWidth - 5))) { // to long or too short if ((CycleWidth > 300) || (CycleWidth < (ZeroWidth - 5))) { // to long or too short
eop = true; eop = true;
bits[bitidx++] = '0'; // Append last zero from the last bit find sb_append_char(&bits, '0'); // Append last zero from the last bit find
cmdText = ""; cmdText = "";
// EM4305 command lengths // EM4305 command lengths
@ -2059,76 +2063,77 @@ int CmdEM4x05Sniff(const char *Cmd) {
// -> disable 1010 11111111 0 11111111 0 11111111 0 11111111 0 00000000 0 // -> disable 1010 11111111 0 11111111 0 11111111 0 11111111 0 00000000 0
// Check to see if we got the leading 0 // Check to see if we got the leading 0
if (((strncmp(bits, "00011", 5) == 0) && (bitidx == 50)) || if (((strncmp(bits.ptr, "00011", 5) == 0) && (bits.idx == 50)) ||
((strncmp(bits, "00101", 5) == 0) && (bitidx == 57)) || ((strncmp(bits.ptr, "00101", 5) == 0) && (bits.idx == 57)) ||
((strncmp(bits, "01001", 5) == 0) && (bitidx == 12)) || ((strncmp(bits.ptr, "01001", 5) == 0) && (bits.idx == 12)) ||
((strncmp(bits, "01100", 5) == 0) && (bitidx == 50)) || ((strncmp(bits.ptr, "01100", 5) == 0) && (bits.idx == 50)) ||
((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) { ((strncmp(bits.ptr, "01010", 5) == 0) && (bits.idx == 50))) {
memmove(bits, &bits[1], bitidx - 1); memmove(bits.ptr, &bits.ptr[1], bits.idx - 1);
bitidx--; bits.idx--;
PrintAndLogEx(INFO, "Trim leading 0"); PrintAndLogEx(INFO, "Trim leading 0");
} }
bits[bitidx] = 0; sb_append_char(&bits, 0);
bits.idx--;
// logon // logon
if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) { if ((strncmp(bits.ptr, "0011", 4) == 0) && (bits.idx == 49)) {
haveData = true; haveData = true;
pwd = true; pwd = true;
cmdText = "Logon"; cmdText = "Logon";
strncpy(blkAddr, " ", sizeof(blkAddr)); strncpy(blkAddr, " ", sizeof(blkAddr));
tmpValue = em4x05_Sniff_GetBlock(&bits[4], fwd); tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue); snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
} }
// write // write
if ((strncmp(bits, "0101", 4) == 0) && (bitidx == 56)) { if ((strncmp(bits.ptr, "0101", 4) == 0) && (bits.idx == 56)) {
haveData = true; haveData = true;
cmdText = "Write"; cmdText = "Write";
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
if (tmpValue == 2) { if (tmpValue == 2) {
pwd = true; pwd = true;
} }
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue); snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
} }
// read // read
if ((strncmp(bits, "1001", 4) == 0) && (bitidx == 11)) { if ((strncmp(bits.ptr, "1001", 4) == 0) && (bits.idx == 11)) {
haveData = true; haveData = true;
pwd = false; pwd = false;
cmdText = "Read"; cmdText = "Read";
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
strncpy(dataText, " ", sizeof(dataText)); strncpy(dataText, " ", sizeof(dataText));
} }
// protect // protect
if ((strncmp(bits, "1100", 4) == 0) && (bitidx == 49)) { if ((strncmp(bits.ptr, "1100", 4) == 0) && (bits.idx == 49)) {
haveData = true; haveData = true;
pwd = false; pwd = false;
cmdText = "Protect"; cmdText = "Protect";
strncpy(blkAddr, " ", sizeof(blkAddr)); strncpy(blkAddr, " ", sizeof(blkAddr));
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue); snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
} }
// disable // disable
if ((strncmp(bits, "1010", 4) == 0) && (bitidx == 49)) { if ((strncmp(bits.ptr, "1010", 4) == 0) && (bits.idx == 49)) {
haveData = true; haveData = true;
pwd = false; pwd = false;
cmdText = "Disable"; cmdText = "Disable";
strncpy(blkAddr, " ", sizeof(blkAddr)); strncpy(blkAddr, " ", sizeof(blkAddr));
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue); snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
} }
// bits[bitidx] = 0; // bits[bitidx] = 0;
} else { } else {
i = (CycleWidth - ZeroWidth) / 28; i = (CycleWidth - ZeroWidth) / 28;
bits[bitidx++] = '0'; sb_append_char(&bits, '0');
for (int ii = 0; ii < i; ii++) { for (int ii = 0; ii < i; ii++) {
bits[bitidx++] = '1'; sb_append_char(&bits, '1');
} }
} }
} }
@ -2139,11 +2144,13 @@ int CmdEM4x05Sniff(const char *Cmd) {
// Print results // Print results
if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){ if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){
if (pwd) if (pwd)
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits.ptr);
else else
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits.ptr);
} }
} }
free(bits.ptr);
bits.ptr = NULL;
// footer // footer
PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------"); PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------");

View file

@ -27,6 +27,8 @@
#define EM4305_PROT2_BLOCK 15 #define EM4305_PROT2_BLOCK 15
#define EM4469_PROT_BLOCK 3 #define EM4469_PROT_BLOCK 3
#define EM4X05_BITS_BUFSIZE 128
// config blocks // config blocks
#define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/MAN , data rate 32, 4 data blocks #define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/MAN , data rate 32, 4 data blocks
//#define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/BIPHASE , data rate 32, 4 data blocks //#define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/BIPHASE , data rate 32, 4 data blocks

View file

@ -1261,3 +1261,12 @@ int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen) {
} }
return -1; return -1;
} }
void sb_append_char(smartbuf *sb, unsigned char c) {
if (sb->idx >= sb->size) {
sb->size *= 2;
sb->ptr = realloc(sb->ptr, sb->size);
}
sb->ptr[sb->idx] = c;
sb->idx++;
}

View file

@ -146,4 +146,11 @@ uint32_t leadingzeros32(uint32_t a);
uint64_t leadingzeros64(uint64_t a); uint64_t leadingzeros64(uint64_t a);
int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen); int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen);
struct smartbuf {
char *ptr;
size_t size;
size_t idx;
} typedef smartbuf;
void sb_append_char(smartbuf *sb, unsigned char c);
#endif #endif