-
Notifications
You must be signed in to change notification settings - Fork 481
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
Issue with windows.strings plugin #876
Comments
Your expected output doesn't match what the plugin does. All plugins within volatility 3 return a table of the results data, usually that could be used by another tool. The plugin found three hits at three of the four offsets (as you can see in example 1, they're interspersed between the progress callbacks, one is directly after The plugin yields these values here and offset is part of the loop it's traversing so I can't see how that value isn't being output, but we can investigate further, thanks for letting us know... |
Hi @kookiecrack, since the default output renderer is the quick output, which doesn't gather the data, but returns it as quickly as possible, it may return it whilst the scans are still ongoing. If you wish the output to be uninterrupted you can choose a different renderer (such as the pretty output) you can use |
thank you! That's useful to know, i will test them out. |
hi, I'm experiencing an issue related to the windows.strings plugin. here command I used output always shows FREE MEMORY instead PID of related precess(es) any idea? |
Hiya, probably worth checking the output of |
thanks @ikelos , I tried using pslist and I confirm it recognizes pid of processes. |
Hiya, given that Theoretically you could change this line to just |
hi,this is how I changed pslist.py by your tip:
then I used the command python3 vol.py -f mem_file -r pretty windows.strings.Strings --strings-file 'strings_file' > output_file same result: output always shows FREE MEMORY instead PID of related precess(es) and nothing else |
Hmmm, then it gets more tricky... Since we basically disabled the filter function (or made it always return False) then this line should mean that the process list is traversed completely. And you're not even getting a process id of Could you please attach the output from running your command without the redirect (or making sure to redirect stderr as well) and with |
volatility-debug.txt |
hi @ikelos,did you find any useful information? |
I'm afraid not, there's nothing unusual in the debug output, so it's possible the contents of the strings file don't accurately reflect the correct offsets? It might also be worth checking that the offsets in the strings text file and in decimal? |
before using the command: in 'string_file' I put the output of the strings sysinternal tool in the form I checked on strings tool docs for useful option to achieve the result you suggested but there is no way to change for decimal or other offset formats. |
I was concerned that strings might output hex offsets, or something, but they need to be in decimal. I think strings takes |
thanks @ikelos for your tip.I confirm that offsets I used were in decimal. last three days I stressed volatility and myself!!! ;) based on this findings,It looks that offsets addresses association is right even if the windows.strings.Strings plugin doesn't give the expected output.It looks really weird to me |
Hi all,any good news? |
OK, Think I have the solution to this one. Or at least part of it. If i Check using Vol2.6 i get one match and two misses, which is what i expect.
In Vol 3 I get
The progress bar here gets in the way a lot switching to
Dumping the revmap object that is being created (extract below)
Looking at
I convert the known offset
and can not find it anywhere in the mapping. If i convert the offset using
I find my offset in the revmap but it's not the key its in the tuple. So I made a couple of changes,
The result is
This is a lot closer its giving me the correct page for the virtual address I need to get a vol2.6 dev instance up and running so i can check what the revmap in vol2 actually looks like |
Ok revmap in Vol 2.6 is pretty different
|
Will open a PR but have a functional Vol 2.6
Vol 3
|
I've given it a review and it needs a couple of things smoothing over, but just to add here. Matching 2.6 isn't necessarily the goal, the goal is to get something accurate. If 2.6 is accurate, that's fine, but striving to get identical results isn't what we're after if there's something wrong with what 2.6 was doing. 2.6 may be perfect, in which case matching it is awesome, but I don't want to forget that the goal is returning accurate results, not necessarily exactly what 2.6 returns... 5:) |
Hello all, I remember looking into this a while ago while trying to make a generic strings plugin and a linux version. I haven't quite finished, but I did come across something similar to this issue. It looks like I didn't make quite enough notes at the time, so I think there is still more to test. I'd normally do more testing before commenting, but given the discussion I thought it might be useful. I think the issue might be here:
Notice that In my work in progress (probably buggy) generic strings plugin I had this. I'm not sure if this actually fixes things properly, my notes are good enough, but this is where I got to trying to look into this.
I also renamed the variables returned from the .mapping function to match what it returns there rather than being swapped link
I'm not 100% sure this is the issue, but hopefully these notes might be useful. I'll still chip away here to see if I can finish my testing and try to remember what I'd worked out at the time. Again I'm not sure if my "fix" is correct - but I think that it's not using 🦊 just a random internet vol user |
Hello @kevthehermit and @ikelos, I've been digging into why the revmap doesn't seem right, and I think this patch here is all that's needed. Here is a worked example using the
The strings file used in this example is:
However as you can see it's not found by the strings plugin as it currently is:
When applying the patch below it now shows the correct location:
I tried to add comments to explain what is happening and I renamed the values returned from the mapping call - just to make it easier to see what exactly they are. Including naming the ones that aren't used. The problem I think was how later pages in a mapping were not making it into the revmap so they were later not found - hence a lot of 'FREE MEMORY' results. Then when the results were displayed to the user it didn't offset the virtual address into the page and would just show the address for the start of the page where the result was. Let me know what you think of this. Does this also work on your sample @kevthehermit ? Once we do come up with a working solution for this issue I'd like to then take it and make a strings plugins that work without an OS, and then linux and mac versions. Just like the yarascan plugins. So it would be good to fix this for the long term, either with something like this or #1043. I personally don't mind what approach we take. I can make a PR with these changes if it is useful - but I don't want to take away from all the great work that @kevthehermit has put into this! 🦊 just a random internet vol user
|
Nice work 😁 I can test your changes against my samples when I get home but testing a random sample I have here looks accurate to me. I can add those changes in to my PR, of if you want to open your own my only suggestion would be to add some extra cols to the output so we have I like the idea of a global strings plugin that is OS-independent as well |
Yes - I'm easy on changing the output columns - either works for me. If other plugins want to they can work from the Looking over your PR more closely @kevthehermit it looks like we've basically ended up fixing the same bits in different, but similar, ways really. If it's helpful I figured I'd make a diagram and explanation as to how rev_map is working. Imagine this mini mem sample with two processes.
That works out to this mapping: Physical page 0 = Process A page 0 So a call to layer.mapping on Process A would give you: and a call for Process B would give you: The "bug" is that when the reverse map was being made in the past both when a mapping spans multiple pages the rev map didn't have that information in it. So under Physical page 0 in the rev map you'd get Process A page 0, but under Physical page 1 you would not have anything. If the string you wanted is in Physical page 1 it would come back as Free Memory because of this. (Edit: to add the rev map) For the rev map to work it would need to come out as below. Note that physical pages 2 and 5 don't exist, and 4 has the mappings for both processes.
Next when the results came to be displayed the offset shown to the user would be the start of page rather than the exact location. It would read from the rev map and show the address for the start of the page. e.g. for a string in Process B at 0xa2123 the result would show 0xa2000. We know the offset into the page from the matching physical address 0x7123. If we mask the physical address to get the lower bits we can then add that to the virtual offset to get the exact location. This all means that the rev map gets quite large - every single page for every process + kernel that maps to a physical page will have an entry. It might be worthwhile just testing how quickly we could get results by not trying to build a revmap at all, and just iterate through all the strings we're searching for and go through each mapping per process once to see if there is a hit. I suspect it's a trade off depending on the number of strings you're looking for, smaller number of strings might favour just looping through all the mappings to find results - while a large number of strings might favor the pre computed revmap. |
This issue is stale because it has been open for 200 days with no activity. |
This issue was closed because it has been inactive for 60 days since being marked as stale. |
I believe @eve-mem and/or @kevthehermit are still working on improving this? There is a far more efficient version, but I'm not sure whether it solves your issue (and it hasn't yet been put forward as a PR, although you can find a branch with it in under feature/ever-string-speedup... |
@ikelos the faster version should also fix this issue. Sorry it's taking me so long to get around to finishing it. |
No problem, we're all volunteers here, just trying to make sure it doesn't get buried under dust... 5;P |
@ikelos thanks for understanding. I don't want to forget it either. @atcuno just a quick FYI for vol2 parity this needs to be fixed too. Currently strings will miss a lot of results. I'm working on it, but I don't think I'll be done in 2 weeks. If someone else wants to fix it I'm okay with that. This comment explains what's going on: #876 (comment) There was a user in slack recently that was struggling with strings and these changes did help. |
Ok two things:
|
Describe the bug
windows.strings plugin does not display a message when a specific string is identified in the memory of a process
Context
Volatility Version: Volatility 3 Framework 2.4.1
Operating System: Windows 10
Python Version: 3.9.9
Suspected Operating System: Windows 10 Build 1809
Command: python vol.py -f ..\DESKTOP-N81KBM0-20221121-235651.dmp windows.strings --strings-file=..\extracted_strings.txt
Details of experiment
Step 1: Acquiring the memory dump
On a Windows 10 computer, a text file was opened in notepad.exe. The text file contained the target string mysupersecretfancypassword. The process ID of notepad.exe is 6896. Another text file opened in wordpad.exe contained the same target string. For now, the focus is only on notepad.
Memory was acquired from this computer as DESKTOP-N81KBM0-20221121-235651.dmp using DumpIt.exe.
Step 2: Extracting target string with offset from the memory dump
Strings.exe was used to extract all the strings from this memory dump into a text file. The command used was:
Four lines from strings_from_dump.txt that contained the target string and its offset were copied into extracted_strings.txt
The contents of extracted_strings.txt is as follows:
Step 3: Attempting to find context for strings in extracted_strings.txt
The goal was to use windows.strings plugin to prove that the strings in extracted_strings.txt can be found within the memory of notepad.exe with PID 6896.
Since the following command took a long time to complete,
The PID of notepad was included in the previous command, as:
Expected behavior
The expected output was a message like 'String found'. However, there was only a message indicating that the string search is progressing.
Example output
Output 1:
Output 2:
Volatility 3 Framework 2.4.1
INFO volatility3.cli: Volatility plugins path: ['C:\Users\ten\Documents\volatility3\volatility3\plugins', 'C:\Users\ten\Documents\volatility3\volatility3\framework\plugins']
INFO volatility3.cli: Volatility symbols path: ['C:\Users\ten\Documents\volatility3\volatility3\symbols', 'C:\Users\ten\Documents\volatility3\volatility3\framework\symbols']
INFO volatility3.framework.automagic: Detected a windows category plugin
INFO volatility3.framework.automagic: Running automagic: ConstructionMagic
INFO volatility3.framework.automagic: Running automagic: SymbolCacheMagic
INFO volatility3.framework.automagic: Running automagic: LayerStacker
INFO volatility3.schemas: Dependency for validation unavailable: jsonschema
DEBUG volatility3.schemas: All validations will report success, even with malformed input
INFO volatility3.schemas: Dependency for validation unavailable: jsonschema
DEBUG volatility3.schemas: All validations will report success, even with malformed input
DEBUG volatility3.framework.automagic.windows: Detecting Self-referential pointer for recent windows
DEBUG volatility3.framework.automagic.windows: DtbSelfRef64bit test succeeded at 0x1aa000
DEBUG volatility3.framework.automagic.windows: DTB was found at: 0x1aa000
INFO volatility3.schemas: Dependency for validation unavailable: jsonschema
DEBUG volatility3.schemas: All validations will report success, even with malformed input
INFO volatility3.schemas: Dependency for validation unavailable: jsonschema
DEBUG volatility3.schemas: All validations will report success, even with malformed input
DEBUG volatility3.framework.automagic.stacker: Stacked layers: ['IntelLayer', 'WindowsCrashDump64Layer', 'FileLayer']
INFO volatility3.framework.automagic: Running automagic: WinSwapLayers
INFO volatility3.framework.automagic: Running automagic: KernelPDBScanner
DEBUG volatility3.framework.automagic.pdbscan: Kernel base determination - searching layer module list structure
DEBUG volatility3.framework.automagic.pdbscan: Setting kernel_virtual_offset to 0xf80767a1f000
DEBUG volatility3.framework.symbols.windows.pdbutil: Using symbol library: ntkrnlmp.pdb\99DE394F56795BA4DDAEBA33444A9F1A-1
INFO volatility3.schemas: Dependency for validation unavailable: jsonschema
DEBUG volatility3.schemas: All validations will report success, even with malformed input
INFO volatility3.framework.automagic: Running automagic: SymbolFinder
INFO volatility3.framework.automagic: Running automagic: KernelModule
String Physical Address Result
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_PO_PROCESS_ENERGY_CONTEXT
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_EPROCESS_QUOTA_BLOCK
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_PAGEFAULT_HISTORY
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_JOB_ACCESS_STATE
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_JOB_CPU_RATE_CONTROL
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_JOB_NET_RATE_CONTROL
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_JOB_NOTIFICATION_INFORMATION
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_PSP_STORAGE
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_ACTIVATION_CONTEXT_DATA
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_FLS_CALLBACK_INFO
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_ASSEMBLY_STORAGE_MAP
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_DBGKP_ERROR_PORT
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_CI_NGEN_PATHS
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_WNF_SCOPE_MAP
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_EX_WNF_SUBSCRIPTION
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_ETW_EVENT_CALLBACK_CONTEXT
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_EX_TIMER
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_ETW_SOFT_RESTART_CONTEXT
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_ETW_STACK_CACHE
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_ETW_PERFECT_HASH_FUNCTION
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_HAL_PMC_COUNTERS
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_DEVICE_NODE_IOMMU_EXTENSION
DEBUG volatility3.framework.symbols: Unresolved reference: symbol_table_name1!_SCSI_REQUEST_BLOCK
Progress: 0.00 Creating mapping for task 6896
mysupersecretfancypassword\par
Progress: 25.00 Matching strings in memory
mysupersecretfancypassword
Progress: 50.00 Matching strings in memory
mysupersecretfancypassword
Progress: 75.00 Matching strings in memory
Progress: 100.00 Matching strings in memory
Additional information
All the pages in memory associated with notepad.exe were dumped using windows.memmap:
Strings.exe was used against the dumped process memory, and the extracted strings were stored in strings_from_dumped_process.txt
Within strings_from_dumped_process.txt, when a simple find operation was performed in Notepad++, it is possible to find the instance of mysupersecretfancypassword.
The target string mysupersecretfancypassword is present within the memory of notepad.exe, but is not identified by windows.strings plugin.
Could you please look into this?
The text was updated successfully, but these errors were encountered: