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

feat: show match context #396 #436

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Conversation

mickol34
Copy link
Collaborator

@mickol34 mickol34 commented Nov 4, 2024

Your checklist for this pull request

  • I've read the contributing guideline.
  • I've tested my changes by building and running mquery, and testing changed functionality (if applicable)
  • I've added automated tests for my change (if applicable, optional)
  • I've updated documentation to reflect my change (if applicable)

What is the current behaviour?
Currently there's no feature to show match context in search results.

What is the new behaviour?
This PR introduces "Show match context" action to search results using newly introduced backend Match field.

Test plan
Query some YARA, look at results, toggle modal with match context and check styling in various cases.

Closing issues

fixes #396

@michalkrzem
Copy link
Collaborator

Screencast.from.14.11.2024.12.18.49.webm

@mickol34
Copy link
Collaborator Author

mickol34 commented Dec 4, 2024

New modals are draggable and index themselves properly in front of everything else. New data structure allows to present data like in attached photo:
image

@msm-cert
Copy link
Member

msm-cert commented Dec 5, 2024

Looks good! (just looking at screenshots, didn't review the code yet)

Can you align the byte and text views? (such that text and byte lines contain the same data, just encoded differently).

Can you separate bytes with spaces? I mean 70 79 74 68 6f 6e 0a instead of 707974686f6e0a. Unless it looks bad for some reason.

Nitpick: it's customary to show bytes first, so could you reorder the "bytes" and "text" columns?

Finally, a question just in case - did you test this with non-printable bytes? When displaying, you can probably replace every character < 32 and >= 127 with a dot ..

@mickol34
Copy link
Collaborator Author

Current styling and implementation with new API:
image
Works after removing stub content, but it would be great to test some various cases with multiple identifiers, weird data, bigger contexts and also multiple screen sizes and settings.

@mickol34 mickol34 force-pushed the feat/show-match-context-396 branch from f84d210 to 8dd4305 Compare December 19, 2024 15:54
@mickol34 mickol34 marked this pull request as ready for review December 19, 2024 15:57
@mickol34 mickol34 changed the title Draft: feat: show match context #396 feat: show match context #396 Dec 19, 2024
@mickol34 mickol34 requested a review from msm-cert December 19, 2024 15:57
@msm-cert
Copy link
Member

Looks good!

Some small comments:

Consider changing the close button to: (change class to btn-close and remove custom x icon inside)

image

Text still doesn't align properly:

image

This may be an issue with my browser, but since people use various browers it's better to be resilient. I think the easiest solution would be to wrap this manually (use white-space: pre or <br> elements)

}
return ".";
})
.join(" ") + " "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe remove the whitespace between letters? So (" "). I understand that now spacing depends on this, but this should be solved anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, now there's no spaces in between bytes or chars.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This time I was probably unclear. The usual hexdump format, that it would be nice to have:

image

The important parts are:

  • (usually) spaces between bytes
  • no spaces between characters (to make plaintext easy to read)
  • 16 characters per line
  • optionally hexadecimal addresses on the left (we don't have that)

So spaces between bytes are OK (they make bytes easier to read). And the really important thing is 16 bytes per line. It may sound like I'm nitpicking, but I'm not ;)

As a POC:

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To I think this is the required change, but please verify:

❯ git diff --unified=1
diff --git a/src/mqueryfront/src/components/ActionShowMatchContext.js b/src/mqueryfront/src/components/ActionShowMatchContext.js
index 68e8955..096d0a5 100644
--- a/src/mqueryfront/src/components/ActionShowMatchContext.js
+++ b/src/mqueryfront/src/components/ActionShowMatchContext.js
@@ -33,4 +33,4 @@ function base64ToHex(str64) {
         })
-        .join("")
-        .toUpperCase();
+        .join(" ")
+        .toUpperCase() + " ";
 }
@@ -103,3 +103,3 @@ const ActionShowMatchContext = (props) => {
                     <>
-                        <td scope="row" style={{ width: "10%" }}>
+                        <td scope="row">
                             <span className="badge rounded-pill bg-info ms-1 mt-1">
@@ -110,3 +110,3 @@ const ActionShowMatchContext = (props) => {
                             {ReactHtmlParser(
-                                cellHTML(foundSample, 20, base64ToHex)
+                                cellHTML(foundSample, 48, base64ToHex)
                             )}
@@ -115,3 +115,3 @@ const ActionShowMatchContext = (props) => {
                             {ReactHtmlParser(
-                                cellHTML(foundSample, 10, base64ToSanitizedUtf8)
+                                cellHTML(foundSample, 16, base64ToSanitizedUtf8)
                             )}
@@ -129,3 +129,2 @@ const ActionShowMatchContext = (props) => {
                         rowSpan={Object.keys(props.context[rulename]).length}
-                        style={{ width: "15%" }}
                     >
@@ -178,3 +177,3 @@ const ActionShowMatchContext = (props) => {
                         >
-                            <div className="modal-dialog modal-lg">
+                            <div className="modal-dialog modal-xl">
                                 <div className="modal-content">

);
}

function base64ToUtf8(str64) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same goes for this function. I suggest sanitize and

sanitize(atob(str)) instead of
base64ToUtf8(str)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, I think that sanitize is too vague. If there will be another use case for such decryption in the project, it would be easier to get to know what was it's original purpose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, base64ToUtf8 is wrong:

  • atob already returns an unicode string
  • the string has no particular encoding (the underlying interpreter must encode the string to bytes somehow, and may or may not use utf8, but for JS this is just a unicode string, without any encoding assigned)

I suggested sanitize because it's short, but it's true that it's a bit vogue . Consider:

  • safeText(text), toSafeText(text), toPrintableString(text), replaceUnprintableCharacters(text), as an alternative to sanitize
  • base64ToSafeText(text), base64ToSafeText(text), base64ToPrintableString(text), base64DecodeAndReplaceUnprintableCharacters(text) as an alternative to base64ToUtf8

(or another variation that describes "replacing unprintable characters in a string with dots" succintly)

Copy link
Contributor

@msm-code msm-code Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed in the source that the name is already base64ToSanitizedUtf8. That's much better (though utf8 is still technically incorrect - maybe text or string?)

src/mqueryfront/src/components/ActionShowMatchContext.js Outdated Show resolved Hide resolved
Copy link
Contributor

@msm-code msm-code left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only the one comment about a function name, and about modal width, and we're ready to merge

);
}

function base64ToUtf8(str64) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, base64ToUtf8 is wrong:

  • atob already returns an unicode string
  • the string has no particular encoding (the underlying interpreter must encode the string to bytes somehow, and may or may not use utf8, but for JS this is just a unicode string, without any encoding assigned)

I suggested sanitize because it's short, but it's true that it's a bit vogue . Consider:

  • safeText(text), toSafeText(text), toPrintableString(text), replaceUnprintableCharacters(text), as an alternative to sanitize
  • base64ToSafeText(text), base64ToSafeText(text), base64ToPrintableString(text), base64DecodeAndReplaceUnprintableCharacters(text) as an alternative to base64ToUtf8

(or another variation that describes "replacing unprintable characters in a string with dots" succintly)

}
return ".";
})
.join(" ") + " "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This time I was probably unclear. The usual hexdump format, that it would be nice to have:

image

The important parts are:

  • (usually) spaces between bytes
  • no spaces between characters (to make plaintext easy to read)
  • 16 characters per line
  • optionally hexadecimal addresses on the left (we don't have that)

So spaces between bytes are OK (they make bytes easier to read). And the really important thing is 16 bytes per line. It may sound like I'm nitpicking, but I'm not ;)

As a POC:

image

}
return ".";
})
.join(" ") + " "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To I think this is the required change, but please verify:

❯ git diff --unified=1
diff --git a/src/mqueryfront/src/components/ActionShowMatchContext.js b/src/mqueryfront/src/components/ActionShowMatchContext.js
index 68e8955..096d0a5 100644
--- a/src/mqueryfront/src/components/ActionShowMatchContext.js
+++ b/src/mqueryfront/src/components/ActionShowMatchContext.js
@@ -33,4 +33,4 @@ function base64ToHex(str64) {
         })
-        .join("")
-        .toUpperCase();
+        .join(" ")
+        .toUpperCase() + " ";
 }
@@ -103,3 +103,3 @@ const ActionShowMatchContext = (props) => {
                     <>
-                        <td scope="row" style={{ width: "10%" }}>
+                        <td scope="row">
                             <span className="badge rounded-pill bg-info ms-1 mt-1">
@@ -110,3 +110,3 @@ const ActionShowMatchContext = (props) => {
                             {ReactHtmlParser(
-                                cellHTML(foundSample, 20, base64ToHex)
+                                cellHTML(foundSample, 48, base64ToHex)
                             )}
@@ -115,3 +115,3 @@ const ActionShowMatchContext = (props) => {
                             {ReactHtmlParser(
-                                cellHTML(foundSample, 10, base64ToSanitizedUtf8)
+                                cellHTML(foundSample, 16, base64ToSanitizedUtf8)
                             )}
@@ -129,3 +129,2 @@ const ActionShowMatchContext = (props) => {
                         rowSpan={Object.keys(props.context[rulename]).length}
-                        style={{ width: "15%" }}
                     >
@@ -178,3 +177,3 @@ const ActionShowMatchContext = (props) => {
                         >
-                            <div className="modal-dialog modal-lg">
+                            <div className="modal-dialog modal-xl">
                                 <div className="modal-content">

@mickol34 mickol34 requested a review from msm-cert January 9, 2025 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show the information about matches in the frontend.
4 participants