Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hikvision, WFS and DHFS File System parser - DVR videos #1776

Draft
wants to merge 57 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
29f8034
add hikvisionfs media type
gfd2020 Jul 17, 2023
3a60cdf
add custom signature to hikvisionfs
gfd2020 Jul 17, 2023
bfa15c0
disable parserUnknown files
gfd2020 Jul 17, 2023
48a63ad
install hikvisionfs task
gfd2020 Jul 17, 2023
109f4f0
add hivisionfstask enable and disable entroytest
gfd2020 Jul 17, 2023
f003f80
disable fragmentlargebinarytask since it is always on
gfd2020 Jul 17, 2023
f236574
hivisionfstask initial commit.
gfd2020 Jul 17, 2023
47810e4
hivisionfs extractor. The logic of the parser of FS is here
gfd2020 Jul 17, 2023
a3ab2e2
Verify hikvisionfs media type. Don't let sleuthkit change mediatype
gfd2020 Jul 17, 2023
c2f0b52
Flag changed to allow reading and processing bytes of raw image
gfd2020 Jul 17, 2023
5792deb
Reversing change
gfd2020 Sep 14, 2023
7b57e39
Reversing change
gfd2020 Sep 14, 2023
884d197
Reversing change
gfd2020 Sep 14, 2023
b867548
Create a new constructor. Reversing change from old one.
gfd2020 Sep 14, 2023
02dd920
Major Change. Verify if a FS has a implemented task.
gfd2020 Sep 14, 2023
fc041a1
add system logs extraction
gfd2020 Sep 15, 2023
7469e17
add system logs parser
gfd2020 Sep 15, 2023
209d09e
Workaround for not call fragmentLargeBinaryTask task
gfd2020 Sep 15, 2023
7379b3a
Workaround for not call fragmentLargeBinaryTask and entropy tasks
gfd2020 Sep 15, 2023
1aa9c73
New info from log data fields, only smart info decoded, for now
gfd2020 Sep 18, 2023
190656f
add more minor types, fix last log not parserd, fix rats field variab…
gfd2020 Sep 19, 2023
09c9982
add more minor type parser.
gfd2020 Sep 20, 2023
f48dfd6
revert to original
gfd2020 Nov 17, 2023
24cdfaf
add hikvision config file
gfd2020 Nov 17, 2023
3072b3a
add comentary to enablehikvisionfs
gfd2020 Nov 17, 2023
0e9c424
create hikvisionFSConfig
gfd2020 Nov 17, 2023
ef54c44
add some gets and sets, fix clear, set description logs,
gfd2020 Nov 17, 2023
20612f2
add video file type constant
gfd2020 Nov 17, 2023
0e4b82a
add hikvisionConfig class, fix get properties ..
gfd2020 Nov 17, 2023
d36d3f5
fix conflicts
gfd2020 Jul 8, 2024
0bff3c2
Merge branch 'sepinf-inc:master' into hikvision-fs
gfd2020 Jul 8, 2024
4ba598a
add hikvision custom mime again
gfd2020 Jul 8, 2024
da0f053
remove this, replaced by dvrconfig
gfd2020 Jul 17, 2024
56c3e4c
change to enableDVR
gfd2020 Jul 17, 2024
092ed14
remove hikvisionFS, chante to DVRtask file
gfd2020 Jul 17, 2024
056385d
changed to DVRConfig, remove this file
gfd2020 Jul 17, 2024
e0d6cf9
add new DVRTaskConfig class
gfd2020 Jul 17, 2024
baf13f3
remove hik task and add DVR Task
gfd2020 Jul 17, 2024
1dd61f3
add wfs and dhfs signatures
gfd2020 Jul 17, 2024
c59f546
new file DVR Task Config. FS configuration parameters
gfd2020 Jul 17, 2024
afac88d
add new media types wfs and dhfs
gfd2020 Jul 17, 2024
f474a02
add util methods
gfd2020 Jul 17, 2024
122a78b
change this class to stand alone file
gfd2020 Jul 17, 2024
8d84eb4
remove classes, add util methods
gfd2020 Jul 17, 2024
bf48a6f
create new task DVR task
gfd2020 Jul 17, 2024
7a26779
new class to handle special file systems
gfd2020 Jul 17, 2024
a5e4bc5
handle special file system as needed
gfd2020 Jul 17, 2024
b222e28
change special file system method test to another class
gfd2020 Jul 17, 2024
1868b7d
create a new input stream factory to handle WFS
gfd2020 Jul 17, 2024
f673319
add synchronizes method
gfd2020 Jul 18, 2024
48a76f9
add author info
gfd2020 Jul 19, 2024
bfa4822
add author info
gfd2020 Jul 19, 2024
3f53dbc
add author info, add util methods
gfd2020 Jul 19, 2024
21b2e4c
call util methods from Util class
gfd2020 Jul 19, 2024
fee678b
remove indexof method and call from Util class
gfd2020 Jul 22, 2024
4e2cde1
first commit of Descriptor Class
gfd2020 Jul 22, 2024
2455f35
first commit of WFSExtractor class
gfd2020 Jul 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions iped-api/src/main/java/iped/properties/MediaTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public class MediaTypes {
public static final MediaType VHDX = MediaType.application("x-vhdx"); //$NON-NLS-1$
public static final MediaType VDI = MediaType.application("x-vdi"); //$NON-NLS-1$
public static final MediaType MS_PUBLISHER = MediaType.application("x-mspublisher"); //$NON-NLS-1$
public static final MediaType HIKVISIONFS = MediaType.application("hikvisionfs"); //$NON-NLS-1$
public static final MediaType WFS = MediaType.application("wfs"); //$NON-NLS-1$
public static final MediaType DHFS = MediaType.application("dhfs"); //$NON-NLS-1$

public static final String UFED_MIME_PREFIX = "x-ufed-"; //$NON-NLS-1$

Expand Down
5 changes: 4 additions & 1 deletion iped-app/resources/config/IPEDConfig.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,7 @@ enableDocThumbs = false

# Enables HTML report generation on automatic extractions or from selected items.
# Generation settings can be modified in file "conf/HTMLReportConfig.txt"
enableHTMLReport = true
enableHTMLReport = true

# Enables extraction of video files from DVR (Digital Video Recorder) File Systems
enableDVR = true
29 changes: 29 additions & 0 deletions iped-app/resources/config/conf/CustomSignatures.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1643,4 +1643,33 @@
<glob pattern="vlc-qt-interface.ini"/>
</mime-type>

<mime-type type="application/hikvisionfs">
<magic priority="60">
<match value="HIKVISION@HANGZHOU" type="string" offset="0:1024"/>
</magic>
<sub-class-of type="application/octet-stream"/>
</mime-type>

<mime-type type="application/wfs">
<magic priority="50">
<match value="WFS0.4" type="string" offset="0:1024"/>
</magic>
<sub-class-of type="application/octet-stream"/>
</mime-type>

<mime-type type="application/wfs">
<sub-class-of type="application/wfs"/>
<magic priority="50">
<match value="WFS0.5" type="string" offset="0:1024"/>
</magic>
<sub-class-of type="application/octet-stream"/>
</mime-type>

<mime-type type="application/dhfs">
<magic priority="50">
<match value="DHFS4.1" type="string" offset="0:1024"/>
</magic>
<sub-class-of type="application/octet-stream"/>
</mime-type>

</mime-info>
24 changes: 24 additions & 0 deletions iped-app/resources/config/conf/DVRConfig.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
###############################################
# DVR Task Configuration #
###############################################

#It is recommended to disable 'parseUnknownFiles' to speed up the processing time of this task

###############################################
# Hikvision FS Configuration #
###############################################

#Video files are usually saved in 1GB blocks. The task will separate these videos based on the metadata data
#To also index the entire video block, this option must be activated
extractDataBlockHVFS = false

# Parse and extract system logs as log files in text mode
extractSystemLogsHVFS = true

###############################################
# WFS Configuration #
###############################################

###############################################
# DHFS Configuration #
###############################################
1 change: 1 addition & 0 deletions iped-app/resources/config/conf/TaskInstaller.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<task class="iped.engine.task.similarity.ImageSimilarityTask"></task>
<task class="iped.engine.task.PhotoDNATask"></task>
<task class="iped.engine.task.PhotoDNALookup"></task>
<task class="iped.engine.task.dvr.DVRTask"></task>
<task script="NSFWNudityDetectTask.py"></task>
<task script="FaceRecognitionTask.py"></task>
<task script="SearchHardwareWallets.py"></task>
Expand Down
67 changes: 67 additions & 0 deletions iped-engine/src/main/java/iped/engine/config/DVRTaskConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package iped.engine.config;

import iped.utils.UTF8Properties;

/*

* WFSExtractor.
*
* @author guilherme.dutra

*/

public class DVRTaskConfig extends AbstractTaskPropertiesConfig {

private static final long serialVersionUID = 1L;


private static final String CONFIG_FILE = "DVRConfig.txt";

private static final String ENABLED_PROP = "enableDVR";

private static final String EXTRACT_DATA_BLOCK_HVFS = "extractDataBlockHVFS";

private static final String EXTRACT_SYSTEM_LOG_HVFS = "extractSystemLogsHVFS";


private boolean extractDataBlockHVFS = false;

private boolean extractSystemLogsHVFS = false;


public Boolean getExtractDataBlockHVFS() {
return extractDataBlockHVFS;
}

public Boolean getExtractSystemLogsHVFS() {
return extractSystemLogsHVFS;
}


@Override
public String getTaskEnableProperty() {
return ENABLED_PROP;
}

@Override
public String getTaskConfigFileName() {
return CONFIG_FILE;
}

@Override
public void processProperties(UTF8Properties properties) {

String value = properties.getProperty(EXTRACT_DATA_BLOCK_HVFS);
if (value != null && value.trim().equalsIgnoreCase("true")) {
this.extractDataBlockHVFS = true;
}

value = properties.getProperty(EXTRACT_SYSTEM_LOG_HVFS);
if (value != null && value.trim().equalsIgnoreCase("true")) {
this.extractSystemLogsHVFS = true;
}


}

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
import iped.engine.sleuthkit.SleuthkitClient;
import iped.engine.sleuthkit.SleuthkitInputStreamFactory;
import iped.engine.task.carver.BaseCarveTask;
import iped.engine.task.ThumbTask;
import iped.engine.task.index.IndexItem;
import iped.engine.util.UIPropertyListenerProvider;
import iped.engine.util.Util;
Expand All @@ -92,6 +93,10 @@
import iped.utils.IOUtil;
import iped.utils.UTF8Properties;

import iped.io.SeekableInputStream;
import java.util.Arrays;
import iped.engine.sleuthkit.SpecialFileSystem;

public class SleuthkitReader extends DataSourceReader {

private static Logger LOGGER = LoggerFactory.getLogger(SleuthkitReader.class);
Expand Down Expand Up @@ -1097,9 +1102,18 @@ private IItem addEvidenceFile(Content content) throws Exception {
evidence.setPath(inheritedPath + path);
}

evidence.setIdInDataSource(Long.toString(content.getId()));
SleuthkitInputStreamFactory objSleuthkitInputStreamFactory = new SleuthkitInputStreamFactory(sleuthCase, null,false);
evidence.setInputStreamFactory(objSleuthkitInputStreamFactory);
boolean isSpecialFileSystem = SpecialFileSystem.isSpecialFileSystem(evidence.getSeekableInputStream());

if (isSpecialFileSystem) //Workaround for not call fragmentLargeBinaryTask task
objSleuthkitInputStreamFactory.setPassthroughContent(true);

if (content instanceof Image) {
evidence.setRoot(true);
evidence.setMediaType(getMediaType(evidence.getExt()));
if (!isSpecialFileSystem)
evidence.setMediaType(getMediaType(evidence.getExt()));
} else {
evidence.setIsDir(true);
}
Expand All @@ -1108,9 +1122,12 @@ private IItem addEvidenceFile(Content content) throws Exception {

// evidence.setSleuthFile(content);
evidence.setHash(""); //$NON-NLS-1$
evidence.setIdInDataSource(Long.toString(content.getId()));
// below is used to don't process images, partitions or file systems raw data
evidence.setInputStreamFactory(new SleuthkitInputStreamFactory(sleuthCase, null));
if (!isSpecialFileSystem){
evidence.setIdInDataSource(Long.toString(content.getId()));
// below is used to don't process images, partitions or file systems raw data
evidence.setInputStreamFactory(new SleuthkitInputStreamFactory(sleuthCase, null));
}


boolean first = true;
Integer tskId = (int) content.getId();
Expand All @@ -1130,6 +1147,9 @@ private IItem addEvidenceFile(Content content) throws Exception {

addToProcessingQueue(caseData, evidence);

if (isSpecialFileSystem) //Workaround for not call entropy task
evidence.setExtraAttribute(ThumbTask.HAS_THUMB, true);

return evidence;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package iped.engine.io;

import iped.utils.SeekableInputStreamFactory;
import iped.engine.task.dvr.wfs.WFSExtractor;
import iped.utils.SeekableFileInputStream;
import iped.io.SeekableInputStream;
import java.io.IOException;

/*

* WFSExtractor.
*
* @author guilherme.dutra

*/

public class WFSInputStreamFactory extends SeekableInputStreamFactory {

WFSExtractor wfs;
SeekableInputStream is;

public WFSInputStreamFactory(SeekableInputStream is) {

super(null);
this.is = is;
}

private synchronized void init() throws IOException {
if (wfs == null){
wfs = new WFSExtractor();
wfs.init(is);
}
}

@Override
public SeekableInputStream getSeekableInputStream(String identifier) throws IOException {
if (wfs == null)
init();
return wfs.getDescriptorFromIdentifier(identifier);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class SleuthkitInputStreamFactory extends SeekableInputStreamFactory {
private SleuthkitCase sleuthkitCase;
private Content content;
private boolean emptyContent = false;
private boolean passthroughContent = false;

public SleuthkitInputStreamFactory(Path dataSource) {
super(dataSource.toUri());
Expand Down Expand Up @@ -56,9 +57,26 @@ public SleuthkitInputStreamFactory(SleuthkitCase sleuthkitCase, Content content)
}
}

public SleuthkitInputStreamFactory(SleuthkitCase sleuthkitCase, Content content, boolean emptyContent) {
this(sleuthkitCase);
if (content != null) {
this.content = content;
} else {
this.emptyContent = emptyContent;
}
}

public void setPassthroughContent(boolean value){
this.passthroughContent = value;
}

@Override
public boolean returnsEmptyInputStream() {
return this.emptyContent;

if (passthroughContent)
return true;
else
return this.emptyContent;
}

public SleuthkitCase getSleuthkitCase() {
Expand Down Expand Up @@ -116,14 +134,36 @@ public SeekableInputStream getSeekableInputStream(String identifier) throws IOEx
return new EmptyInputStream();
}
FileSystemConfig fsConfig = ConfigurationManager.get().findObject(FileSystemConfig.class);
long tskId = Long.valueOf(identifier);

boolean isSpecialFileSystem = false;
long identifier_number = Long.valueOf(identifier);
long type = (identifier_number >> 63) & 1L;
String address = "0";
long tskId = 0;

if (type == 0){
tskId = identifier_number;
}else{
tskId = (identifier_number & (8191L << 50)) >> 50;
address = Long.toString((identifier_number & (1125899906842623L)));
isSpecialFileSystem = true;
}

Content tskContent = getContentById(tskId);
if (SleuthkitReader.sleuthCase == null || !fsConfig.isRobustImageReading()) {
return new SleuthkitInputStream(tskContent);
if (!isSpecialFileSystem){
return new SleuthkitInputStream(tskContent);
}else{
return SpecialFileSystem.getSeekableInputStream(new SleuthkitInputStream(tskContent),tskId,address);
}
} else {
SleuthkitClient sleuthProcess = SleuthkitClient.get();
try {
return sleuthProcess.getInputStream((int) tskId, tskContent.getUniquePath());
if (!isSpecialFileSystem){
return sleuthProcess.getInputStream((int) tskId, tskContent.getUniquePath());
}else{
return SpecialFileSystem.getSeekableInputStream(sleuthProcess.getInputStream((int) tskId, tskContent.getUniquePath()),tskId,address);
}
} catch (TskCoreException e) {
throw new IOException(e);
}
Expand Down
Loading