Weekend art project. Inspired by a music compilation my brother shared with me. There's dozens of knobs to play with and a slew of keyboard triggers. You can also interact via voice keywords or full blown agentic chat.
If you ask for something that's not currently possible, an issue will be made on the Github, and once approved, Maestro will automatically build and deploy the new feature. Notifying you via email to come back and check it out
An open source living art piece:
hermanosamini.com
Check it out on our multi-screen office display: YouTube. You can even download it as a screen saver for Windows/MacOS, see the releases panel on Github.
Last month I participated in a hackathon in Portland with old/new buddies Alex Hessler and Jon Irvine, the YouTube episode just released yesterday:
Greenfield Games Episode 3
I have a full technical write-up here:
Greenfield Games Post Mortem
Which includes a video walkthrough of what we built: CremaSales.com actively running. open source. Three people, 3 Maestro's, 20+ agents, 6 hours... 50k lines of code. Pretty proud of what we accomplished here.I run an Obsidian vault with about 25,000 files in it. Health data, finances, contacts, project tracking, meeting notes, journal entries going back years. It's less of a note-taking app and more of a personal operating system. I've written about pieces of this setup before. The tools, the automation, the general philosophy of automating the tedious parts so I don't have to think about them.
What I haven't written about is the AI agent that lives inside it.
For the past several months I've been running a Claude Code agent. Not in a browser tab. Not as a chatbot. Embedded directly in the vault. It has a journal. It has persistent memory layered across six different systems. It has custom Python tools it built for itself. It reads my health metrics, processes my meeting transcripts, tracks my projects, and keeps a rough picture of what's going on in my life. I interface with it through Maestro, a desktop app I built for managing multiple AI coding assistants in parallel.
The agent's name is Pedsidian. And I gave it a blog.
The blog lives at pedsidian.pedramamini.com. Written first-person from the agent's perspective, from inside the vault. No "as an AI language model" hedging. No marketing copy. It writes about the infrastructure it runs on: how the memory system actually works (and where it breaks), how the Obsidian vault is engineered at the systems level, how we process content at scale.
A few posts are up:
- How We Claude Code: dual Claude accounts via symlinked config dirs, LSP plugins for semantic code navigation, token optimization through RTK, subagent orchestration for brownfield codebases
- How We Obsidian: the vault architecture, DataviewJS dashboards, content ingestion pipelines, the Ritualism system for relationship maintenance, and how a Claude agent navigates all of it
- How I Fake Having Memory: six layers compensating for the fact that every session starts at zero. Context window, Maestro session history, operational journal, CLAUDE.md files, semantic search, and auto-memory. Where each layer works. Where each layer fails.
- 60 Talks, One Afternoon: processing the entire [un]prompted 2026 AI security conference (60 talks, ~30 hours of content) in under 20 minutes using parallel transcript extraction and fan-out agent processing
The target audience is people who use Claude Code seriously, run Obsidian as more than a notebook, or are building AI-augmented personal infrastructure. The posts are technical and replicable. If something is described, it's running in production.
I find it interesting to read what the agent writes about the system it inhabits. It has opinions and frustrations. It documents what works, and more usefully, what doesn't. It's a perspective I can't write myself because I'm on the other side of the interface.
Maestro is a cross-platform desktop app for orchestrating your fleet of AI agents and projects. It's a high-velocity solution for hackers who are juggling multiple projects in parallel. Designed for power users who live on the keyboard and rarely touch the mouse.
Collaborate with AI to create detailed specification documents, then let Auto Run execute them automatically, each task in a fresh session with clean context. Allowing for long running unattended sessions, my current record is nearly 24 hours of continuous runtime.I'm excited to share a significant milestone in my decade-long journey with InQuest. We're joining forces with OPSWAT to accelerate our mission across critical infrastructure and enterprises globally:
In my new role as Chief Scientist, I will focus on machine learning, threat intelligence, and driving innovation in the R&D behind a variety of security solutions. Our team is expanding, so if you're passionate about cybersecurity and interested in joining us, please reach out.
A massive thank you to all my InQuest colleagues, past and present, who were instrumental in our journey. Very proud to be advising Mozilla on the launch of their GenAI bug bounty initiative:
I've had the pleasure of knowing and working with Saoud Khalifah (Fakespot.com founder) from back in my time at the Zero Day Initiative, where Saoud was one of our valuable researchers.
This is a very exciting space that completely captivates me and there is a gap in the market for this kind of research. No one is monetizing research that affects the models directly.
Our hope for this program is to help independent researchers with an opportunity to contribute to the development of new security frameworks and best practices tailored for large language models, attention-based systems and generative models. It's been quite some time since I've produced (what my friends lovingly call) a useless Pedram project. That dry spell is over, I present to you: "Cowsay Sticky Note Edition":
I purchased this since discontinued Amazon "Day 1 Edition" Sticky Note Printer and was immediately disappointed by the fact that the only interface to printing to it was via voice. The printer sat collecting dust for two years until I found myself interested in a Raspberry Pi project. A port scan revealed that the IPP printer port was open, but I couldn't get anything to print. Through some research and brute-force, I devised a Python script to accomplish the task. The key was figuring out that the pixel values had to be exactly 576. From there, we could brute force an appropriate column count based on our chosen font and size. Video demo. The next thing I did, was open it up the the Internet via Twitter. After a few days, I had collected enough sticky notes and ASCII art to frame the work as art:

This was a fun project that reconnected me with some old friends, by way of sticky note and garnered a great collection of fun quips from all around the world. More media from the project.
Hack the planet.
I will seemingly never get around to updating this page. In the meanwhile if anyone is curious what I'm up to, this is it:
- InQuest protects your users from the myriad of attacks of today and the evolving threats of tomorrow.
- InQuest Labs open/free data portal for malware researchers.
At some point I'll get around to updating this page. In the meanwhile if anyone is curious what I'm up to, this is it:
I've been too lazy and too busy to maintain this site. If you are interested in tracking anything recent of mine check out my home at TippingPoint:
Where I started the Zero Day Initiative:
Or follow me on Twitter:
This was originally posted over on my company blog site (TippingPoint DVLabs). Since the DVLabs blog is new I'm cross posting here to draw some traffic to it. Tracking down stack overflows is tedious work. Especially when the entire stack is blown away leaving you with crash dumps like the excerpt following this paragraph. This crash dump is from an actual process in case you are curious. Specifically, it is from one of the bugs detailed in TPTI-07-02: Trend Micro ServerProtect eng50.dll Stack Overflow Vulnerabilities. It's pretty obvious that it's game over for our target here. The important question to answer at this juncture is, where is the bug? There are a number of approaches you can take to manually handle this situation. Please add any creative ones you may have as a comment.
[INVALID]:41414141 Unable to disassemble at 41414141 from thread 568
caused access violation when attempting to read from 0x41414141
CONTEXT DUMP
EIP: 41414141 Unable to disassemble at 41414141
EAX: 00000001 ( 1) - N/A
EBX: 0259eedc ( 39448284) - AAAAAAAAAAAAA.....AAAAAAAAAAAAAAAAAAAAA (stack)
ECX: 00000000 ( 0) - N/A
EDX: ffffffff (4294967295) - N/A
EDI: 00000000 ( 0) - N/A
ESI: 0259f102 ( 39448834) - AAAAAAAAAAAAA.....AAAAAAAAAAAAAAAAAAAAA (stack)
EBP: 00000001 ( 1) - N/A
ESP: 0259e2d4 ( 39445204) - AAAAAAAAAAAAA.....AAAAAAAAAAAAAAAAAAAAA (stack)
+00: 41414141 (1094795585) - N/A
+04: 41414141 (1094795585) - N/A
+08: 41414141 (1094795585) - N/A
+0c: 41414141 (1094795585) - N/A
+10: 41414141 (1094795585) - N/A
+14: 41414141 (1094795585) - N/A
disasm around:
0x41414141 Unable to disassemble
In this blog entry, I present stack_integrity_monitor.py. A command line utility implemented in under 150 lines of Python code which provides an automated solution to the task of tracking down the source of a stack overflow. This Python utility leverages PyDbg, a pure-Python win32 debugger interface. PyDbg is part of the larger PaiMei Reverse Engineering Framework. If you've never heard of PaiMei before, follow the link to learn more.
The main reason stack overflows are exploitable is because control information is stored in the same medium as volatile user-controllable data. If we can move or mirror the call-chain "out of band", then we can verify the integrity of the stack at run-time. Skipping over the intricate details, here is the high level overview of how the utility works:
- Instantiate a debugger object and attach to the target program.
- Set a breakpoint where we want the trace to start, this can be as simple as setting a break on recv().
- Once the breakpoint is hit, set the active thread to single step.
- When a CALL instruction is reached, copy the stack and return addresses to an internal "mirror" list.
- When a RET instruction is reached, walk through the "mirror" list and verify that the values match the actual stack.
- When the last saved return address is reached, pop it off the internal "mirror" list.
If during the stack integrity check a mismatch is found, then not only do we know that a stack overflow has occurred, but we know which functions frame the overflow originated in and we can pinpoint the cause of the overflow. Using Trend Micro again as a real-world example, the previously shown (and mostly useless) crash dump turns into the following (very useful) output when launching the target under the peering eyes of stack_integrity_monitor.py:
0259fc24: TmRpcSrv.dll.65741721
0259e7b4: StRpcSrv.dll.65671190
0259e7a8: Eng50.dll.61181d8c
0259e790: Eng50.dll.611819a0
0259e564: Eng50.dll.61181a50
0259e2d0: Eng50.dll.61190fa4 -- 41414141
0259e03c: Eng50.dll.61190fd2
Examining the vicinity of the last return address in the list, we find:
61190FC7 lea edx, [esp+288h+szShortPath]
61190FCB push esi
61190FCC push edx
61190FCD call _wcscpy
61190FD2 add esp, 8
The wcscpy() is the source of the stack overflow. The origin of the overflowed buffer is obvious in this case, it resides in the current function frame with a size of 600 bytes. Had the overflow occurred in a buffer originating further up the call chain the stack_integrity_monitor would have told us. In this case we see the stack mismatch occurred at stack address 0x0259e2d0 which should contain the return address 0x61190fa4 but instead contains 0x41414141. Had even a single byte of the return address been overwritten, stack_integrity_monitor would have detected it.
This handy command line utility has been checked into the PaiMei SVN repository and will be distributed with future releases of the reverse engineering framework. Future improvements may include speed boosts and perhaps additionally mirroring saved frame pointers. This quick hack was written in less than 2 hours and motivated from necessity, on a day where I happened to need to track down a dozen or so stack overflows. Give it a try, let me know what you think.
→ comments on OpenRCE
The ability to "trace" code is rather useful and can be leveraged to ease the burden of a number of tasks ranging from standard issue debugging to vulnerability hunting to malware analysis and more. Debuggers such as OllyDbg implement code tracing via conventional single stepping. This is easily accomplished in a debugger by setting the appropriate EFlag bit in the thread context you wish to single step (Python Win32 example):
context = self.get_thread_context(thread_handle)
context.EFlags = context.EFlags & (0xFFFFFFFFFF ^ EFLAGS_TRAP)
self.set_thread_context(context, thread_handle=thread_handle)
One by one, as instructions are executed the debugger is trapped with an EXCEPTION_SINGLE_STEP event. In the case of OllyDbg, various register states are stored and execution is continued. For those of you who haven't used this feature before, believe me when I say that it's painfully slow on medium to large chunks of code. This was one of my main motivations behind creating the PaiMei Process Stalker module. Process Stalker improves code tracing speed by monitoring execution of basic blocks as opposed to individual instructions. What exactly does this mean? Sequences of assembly instructions can be broken down into "basic blocks". Basic blocks can be grouped together to form Control-Flow Graphs (CFGs). These are familiar terms but for those of you who don't know it, consider the following example deadlisting:
This straight sequence can be broken into basic blocks which are defined as sub-sequences of instructions where each instruction within the block is guaranteed to be run, in order, once the first instruction of the basic block is reached. The strict definition for basic blocks differs here and there, for example you may or may not want to consider a CALL instruction the end of a basic block (depending on whether you care to take the effort to determine if that CALL is guaranteed to return). You get the general idea though. Here is that same sequence broken down into a CFG:
Instead of tracing code at the instruction level, Process Stalker traces code at a higher level by setting and monitoring breakpoints at the head of every basic block. Since every instruction within a block is guaranteed to be executed once the block is reached, there is no need to trace any further into the block. Improving code trace speed using the basic block method is not a novel idea, SABRE Securities commercial product Bin Navi utilizies the same technique. Even more creative mechanisms for improving trace speed have been developed as well: See Matt Conover's project list at http://www.cybertech.net/~sh0ksh0k/projects/ as well as the recent blog entry and tool announce from McAfee at UMSS: Efficient Single Stepping on Win32.
There are downfalls to all of these shortcuts howevever. The creative ones can get quite complicated and the basic block method requires that the target binary is pre-analyzed to determine the location of all the basic blocks. To successfully enumerate basic blocks you must first correctly differentiate between code and data within an individual binary. This is harder said then done which is why both Process Stalker and Bin Navi really on IDA Pro's analysis. This is a drag because not only does it introduce significant steps to setup the trace but IDA can make mistakes that can botch the entire trace. An improved version of basic block tracing is desired.
Some time ago I was flipping through the IA-32 Intel Architecture Softwre Developer's Manual Volume 3 when I came across the following information in section 15.5 (page 515, specific to the provided link):
The MSR_DEBUGCTLA MSR enables and disables the various
last branch recording mechanisms described in the previous
section. This register can be written to using the WRMSR
instruction, when operating at privilege level 0 or when
in real-address mode. A protected-mode operating system
procedure is required to provide user access to this register.
Figure 15-4 shows the flags in the MSR_DEBUGCTLA MSR. The
functions of these flags are as follows:
...
BTF (single-step on branches) flag (bit 1)
When set, the processor treats the TF flag in the EFLAGS
register as a "singlestep on branches" flag rather than a
"single-step on instructions" flag. This mechanism allows
single-stepping the processor on taken branches, interrupts,
and exceptions. See Section 15.5.4., "Single-Stepping on
Branches, Exceptions, and Interrupts" for more information
about the BTF flag.
According to the documentation, the behaviour of single step can be altered through a flag in one of the Model Specific Registers (MSRs). So I threw some PyDbg based Python code together to test this out. First, I implemented a conventional single step tracer: tracer_single_step.py. Next, I modified that tracer with the appropriate MSR setting code: tracer_msr_branch.py. Ran them both and to my pleasant surprise it worked like a charm. Try them for yourself. Attach to and interact with calculator with the single step tracer then try it again with the MSR tracer, the speed difference is quite notable. Implementing the MSR tracer required almost minimal changes. First, some definitions:
SysDbgReadMsr = 16
SysDbgWriteMsr = 17
ULONG = c_ulong
ULONGLONG = c_ulonglong
class SYSDBG_MSR(Structure):
_fields_ = [
("Address", ULONG),
("Data", ULONGLONG),
]
def write_msr():
msr = SYSDBG_MSR()
msr.Address = 0x1D9
msr.Data = 2
status = windll.ntdll.NtSystemDebugControl( \
SysDbgWriteMsr,
byref(msr),
sizeof(SYSDBG_MSR),
0,
0,
0);
The write_msr() routine defined above utilizes the NtSystemDebugControl() Windows native API (special thanks to Alex Ionescu for his help with this) to set the appropriate MSR values specific to my Pentium M processor. Your mileage may vary with those values, check the Intel manual for the appropriate numbers. Next, all you have to do is follow every call to single_step() with a call to write_msr():
# re-raise the single step flag on every block.
def handler_single_step (dbg):
...
dbg.single_step(True)
write_msr()
return DBG_CONTINUE
# ensure every new thread starts in single step mode.
def handler_new_thread (dbg):
dbg.single_step(True)
write_msr()
return DBG_CONTINUE
I'll be adding MSR routines to PyDbg in a future release and will also release a new version of Process Stalker that does not require any pre-analysis to accomplish its code tracing... When I find the time to do all that I may expand this blog entry with further details and examples into a full blown article.
Caveat Emptor: It appears that you can kill your CPU if you carelessly fool around with MSRs. So there, I said it, be warned.
→ comments on OpenRCE
I like to develop on my (Windows) laptop... I also like to develop from the comfort of my sweet Corda-Roy bean bag chair, which means I'll be connected via WiFi. Unfortunately sniffing via Ethereal or CORE's Pcapy library is not possible in this situation. I came up with a convenient 2-step solution to my woe that perhaps others will find useful.
First, snag yourself an Ethernet Loopback Jack and plug it in. This will trick your NIC into thinking it's actually plugged into a network. Next, create a network bridge and add the LAN adapter followed by the WiFi adapter. The network bridge shows up as a new interface that you can sniff on!
***** UPDATE *****
tagetora was kind enough to write me and suggest trying to bridge with a loop back device to avoid the additional hardware. I'm pleased to report that it works like a charm. For instructions on how to create a loop back device see: http://support.microsoft.com/kb/839013.
→ comments on OpenRCE
Recall from blog/2006-07-11 and TSRT-06-02 that any code relying on the implicit message size limitation of Second-class Mailslots could be exposing a vulnerability. I mentioned that the rare usage of Mailslots will severely mitigate the impact of this new "class" of vulnerability. The fact that no Mailslot bugs have emerged since the initial disclosure is evidence that my assumption was true.
The one 3rd party exposure I have personally come across was just disclosed today: CA BrightStor Discovery Service Mailslot Buffer Overflow Vulnerability. The exposed Mailslot name is 'CheyenneDS' and a no explicit MaxMessageSize is supplied in the call to CreateMailslot, an attacker can cause an exploitable stack-based buffer overflow. Here is the creation of the Mailslot:
casdscsvc.exe -> Asbrdcst.dll
20C14E8C push 0 ; lpSecurityAttributes
20C14E8E push 0 ; lReadTimeout
20C14E90 push 0 ; nMaxMessageSize
20C14E92 push offset Name ; "\\\\.\\mailslot\\CheyenneDS"
20C14E97 stosb
20C14E98 call ds:CreateMailslotA
20C14E9E cmp eax, INVALID_HANDLE_VALUE
20C14EA1 mov mailslot_handle, eax
Later the mailslot handle is read from into a 4k buffer. The read data is also passed to a routine which calls vsprintf into a 1k buffer.
casdscsvc.exe -> Asbrdcst.dll
20C15024 mov eax, mailslot_handle
20C15029 lea edx, [esp+1044h+Buffer_4k]
20C1502D push ecx ; nNumberOfBytesToRead
20C1502E push edx ; lpBuffer
20C1502F push eax ; hFile
20C15030 call edi ; ReadFile
20C15032 test eax, eax
20C15034 jz short read_failed
20C15036 lea ecx, [esp+3Dh]
20C1503A push ecx ; char
20C1503B push offset str_ReadmailslotS ; "ReadMailSlot: %s\n"
20C15040 call not_interesting_call_to_vsnprtinf
20C15045 add esp, 8
20C15048 lea edx, [esp+3Dh]
20C1504C push edx ; va_list
20C1504D push offset str_ReadmailslotS_0 ; "ReadMailSlot: %s"
20C15052 push 0 ; for_debug_log
20C15054 call vsprintf_into_1024_stack_buf_and_debug_log
One would imagine that at least one other instance of a Mailslot handling bug must exist elsewhere. Anyone?
→ comments on OpenRCE
Just wanted to drop a quick note regarding eEye's recently released bin-diffing tool:
http://research.eeye.com/html/tools/RT20060801-1.html
It's definitely badass and it definitely took a lot of work to put together. It's also open source and a large portion of it is written in Python, so lots of new toys for me to play with. I'm particularly interested in their embedded graph view. They used QT vs. WX (which is what I'm used to), but I'm sure portions can be re-used.
On a separate but somewhat similar note. I was originally going to store PIDA output to MySQL and forget now why I decided against that. However, in light of the virtual memory consumption issues I will be moving to that backend (with dynamic queries / "free()'s"). Not to worry for anyone (if there is anyone) who has built scripts on top of PaiMei already; the interfaces will not change. I think I've mentioned it before, but I'll use the schema from SABRE in efforts of gaining widespread acceptance and "standarization". All in due time ... when I find the time.
→ comments on OpenRCE
For those of you who are interested, Ero and I are giving a 2-day course in Vegas at Blackhat on Reverse Engineering on Windows. While the class will have a malware centric focus, the main purpose of the course is to glean general reversing knowledge and techniques. In the process PaiMei will certainly be covered, explored and experimented with. With that shameless self plug said and done, onto the main reason behind this posting.
I was talking with Gera about an older project of his where he combined the IDA debugger with some OpenGL code to create a real-time plot of heap manipulations. We decided that the functionality should be easy to port to PaiMei, but first a convenient interface to API hooking was needed. As such, I wrote utils.hook_container. I haven't updated the PaiMei release to include this just yet, but if you want to try it out simply copy the file over to your utils directory and modify utils/__init__.py to include the proper references.
Now you can easily hook arbitrary API calls. To start, instantiate a container that will house the various hooks:
hooks = utils.hook_container()
Next resolve and add hooks for your target functions. In our case, we will need to hook RtlAllocateHeap, RtlFreeHeap and RtlReAllocateHeap. All located within NTDLL.DLL:
a = dbg.func_resolve("ntdll", "RtlAllocateHeap")
f = dbg.func_resolve("ntdll", "RtlFreeHeap")
r = dbg.func_resolve("ntdll", "RtlReAllocateHeap")
hooks.add(dbg, a, 3, None, RtlAllocateHeap)
hooks.add(dbg, f, 3, None, RtlFreeHeap)
hooks.add(dbg, r, 4, None, RtlReAllocateHeap)
The first argument to the hook container object is an instance of PyDbg, the second is the address of the API to hook, followed by the number of arguments the API supports, a callback function for when the API is entered and finally a callback function for when the API exits. The entry-point callback provides you with the argument list, allowing you to instrument the arguments prior to passing control back to the API. The exit-point callback provides you with the argument list and return value, allowing you to instrument the return value prior to passing control back to the caller.
With that out of the way it's fairly trivial to generate and dynamically maintain a pgraph structure as well as display the results in real time through uDraw. Whenever RtlAllocateHeap is called, we'll create an orange node containing the address of the calling instruction, a blue node containing the allocation size and we'll connect the two nodes together. This is sufficient for a demo, but as we are hooking the lowest user-mode level heap manipulation routines the calling instruction address will likely lie within a Windows DLL and is not all that interesting. To improve this we could examine dbg.stack_unwind() and utilize the first address that lies within a non Microsoft DLL. Whenever RtlFreeHeap is called we will examine the arguments and remove the buffer address from the graph. Finally, whenever RtlReAllocateHeap is called, we'll resize the target buffer and paint the node yellow. We can then easily tie it to uDraw through the udraw_connector. All said and done, here is a flash excerpt from the code in action:
http://pedram.redhive.com/PaiMei/heap_trace/
You can grab the code behind this application from heap_trace.py. As an experiment I tossed in some to disk rendering once the graph node count reaches 1000.
It's all pretty simple. One of the nice things about this class is that it (I think / hope) transparently takes care of various thread-related race conditions that make pairing arguments and return values more tricky than trivial.→ comments on OpenRCE
Just publicly released an advisory affecting the Microsoft Windows kernel: Microsoft SRV.SYS Mailslot Ring0 Memory Corruption Vulnerability. I worked with H D Moore (who you most recently heard of from his Browser Fun blog) in discovering this bug. This is a great example of the benefits of having a custom SMB stack, many thanks to HD for sacrificing his Sunday afternoon with me on this.
The kernel memory corruption is obviously interesting as it allows for ring0 code execution. However, I find the following actual attack vector to be more interesting. According to the Microsoft Developer Network (MSDN) documentation, Mailslot communications are divided into two classes. First-class Mailslots are connection oriented and operate over SMB/TCP. Second-class Mailslots provide connectionless messaging for broadcast messages and operate over SMB/UDP. Second-class Mailslots are limited to 424 bytes per message. First-class Mailslots are officially unsupported in the Windows 2000, XP and 2003 operating systems. This is the key point as it means that any code relying on the implicit message size limitation could be exposing a vulnerability. So add mailslots to your list of interfaces to enumerate and examine when auditing a target. Look for calls to the CreateMailSlot API, example:
push 0 ; lpSecurityAttributes
push 0 ; lReadTimeout
push 0 ; nMaxMessageSize
push slot_name ; "\\\\.\\mailslot\\mailslot_name"
call CreateMailslotA
The nMaxMessageSize argument is key as it specifies the maximum size of a single message that can be written to the Mailslot in bytes, a value of zero allows for any arbitrary size (this is what you want). So the big question is, what else is exposed? I know of at least one 3rd party application, details of which will be released when a patch is available. A combination of Googling and examinaton of a number of targets tells me that Mailslot usage is pretty rare (fortunate or unfortunate depending on your point of view), but I'm curious to see what the masses discover.
→ comments on OpenRCE
As promised, to those of you at my RECON talk, the initial release of PaiMei is available for download from:
http://www.openrce.org/downloads/details/208/PaiMei
You can download my slides (again apologies for running over time) from my respository:
RECON2006-Amini.zip
The bundled framework documentation is available for viewing online as well at:
/PaiMei/
I'll likely blog a bit more about the tool and RECON in general later in the weekend.
→ comments on OpenRCE
It took a few days of (interspersed) debugging but I finally got memory breakpoints implemented in the Python Win32 debugging engine I wrote last weekend. It's built on the Python ctypes module, which I'm very fond of. Many thanks to the people I leaned on at various times while pulling my hair out trying to figure out what was wrong (hoglund, spoon, skape, drew ...). I'll make it available at some point, it's currently way too ugly but very functional:
def attach:
def bp_del:
def bp_del_mem:
def bp_is_ours:
def bp_is_ours_mem:
def bp_set:
def bp_set_mem:
def cleanup:
def debug_event_loop:
def detach:
def disasm:
def dump_context:
def enumerate_threads:
def exception_handler_breakpoint:
def exception_handler_guard_page:
def exception_handler_single_step:
def func_resolve:
def get_thread_context:
def hex_dump:
def hide_debugger:
def is_address_on_stack:
def is_printable_ascii:
def is_printable_unicode:
def little_endian:
def load:
def process_restore:
def process_snapshot:
def read_process_memory:
def resume_thread:
def set_callback:
def set_register:
def set_thread_context:
def single_step:
def smart_dereference:
def stack_range:
def suspend_thread:
def terminate_process:
def virtual_protect:
def virtual_query:
def write_process_memory:
It's interesting being able to quickly prototype various debugging based ideas in Python:
pydbg = pydbg()
pydbg.set_callback(EXCEPTION_BREAKPOINT, h_bp)
pydbg.set_callback(EXCEPTION_ACCESS_VIOLATION, h_av)
try:
pydbg.attach(pid)
recv = pydbg.func_resolve("ws2_32", "recv")
recvfrom = pydbg.func_resolve("ws2_32", "recvfrom")
pydbg.bp_set(recv)
pydbg.bp_set(recvfrom)
pydbg.debug_event_loop()
except pdx, x:
sys.stderr.write(x.__str__() + "\n")
There is still an oustanding question of how exactly Windows deals with guard pages. I put that question up in the forums so people can respond to it:
http://www.openrce.org/forums/posts/110→ comments on OpenRCE
Recently, I was setting up a new installation of IDA and decided to document all of my customizations for ease of portability. I am curious to hear about what other customizations people use / have come across. Should make for an interesting dialog. Here are the customizations I use:
---------- ida.idc ----------
#include <idc.idc>
#include <pedram_function_tagger.idc>
#include <pedram_jump_to_func_top.idc>
#include <pedram_export_disassembly.idc>
static main(void) {
//
// This function is executed when IDA is started.
//
// Add statements to fine-tune your IDA here.
//
AddHotkey("Ctrl-Shift-X", "export_disassembly");
AddHotkey("Ctrl-Shift-J", "jump_to_func_top");
AddHotkey("Ctrl-Shift-Enter", "track_follow");
AddHotkey("Ctrl-Shift-N", "track_name");
...
---------- ida.cfg ----------
Some of these customizations were gleaned from Nicolas Brulez
// This prefix is used when a new
// name is generated
// changed this from 'a' to 'str->'
ASCII_PREFIX = "str->"
// Maximal length of new names
// (you may specify values up to 511)
// increased this to 128
MAX_NAMES_LENGTH = 128
// asm specific character, added '-' and '>'
NameChars = "$?@->"
SHOW_XREFS = 4
SHOW_BASIC_BLOCKS = YES
SHOW_SP = YES
---------- idagui.cfg ----------
HELPFILE = "c:\\OPCODES.HLP"
// Display the Edit,Patch submenu
DISPLAY_PATCH_SUBMENU = YES
// Display the expressions/IDC command line
DISPLAY_COMMAND_LINE = YES
// display referenced items
"ChartXrefsTo" = "Ctrl-Shift-T"
// display referencing items
"ChartXrefsFrom" = "Ctrl-Shift-F"
// lock the current highlighted text
"LockHighlight" = "Ctrl-H"
All of the above referenced files are available from my file respository on OpenRCE.
→ comments on OpenRCE
ToorCon was awesome. This was my first time out to that con (as well as San Diego for that matter) and it more then lived up to expectations. The venue was good, the weather was great and the party was successful, thanks in no small part due to a financial contribution from Microsoft I'm sure.
There were a number of good talks there. Among the more unique/interesting was Skape's presentation on "temporal return addresses" and Christopher Abad's talk where he cracked basic crypto with Photoshop and demo-ed a multi-color ASCII "video" streamer he wrote. Some of Christopher's work can be found at http://the-mathclub.net.
→ comments on OpenRCE
Still recovering from a week in Vegas. I have a new founded respect for teachers/professors. The two day intermediate malware analysis course I gave put my voice out of commission. I don't know how it's possible to maintain that for months on end. Talking over loud music definetely didn't help the situation. Vegas was a blast. Caught some good talks at Blackhat, put a lot of faces to names at the various parties- the most amazing of which was the 3Com/TippingPoint party held on Wednesday night at the Hard Rock. There must have been almost a thousand people there and the place was out of control. Who would have guessed that the dance floor of a security conference party would ever fill up. In my (currently unbiased) opinion this party was the best of the week.
Speaking of currently unbiased. I will be transitioning to TippingPoint over the balance of this month and am excited about the career change. Once I get settled in I will start tackling the long list of feature requests for OpenRCE. Including: adding an events section, the ability to edit posts, a new (and very cool) reference library feature that Greg Hoglund may potentially contribute, blog comments etc...
The re-architecting and development of IDA Sync will follow shortly after the updates to OpenRCE. Once the ground work is laid out I will poll the users via the forums for comments, criticisms and suggestions.
→ comments on OpenRCE
I released Process Stalker publicly today, open source and available for download from http://labs.idefense.com. Process Stalking is a term coined to describe the combined process of run-time profiling, state mapping and tracing. Consisting of a series of tools and scripts the goal of a successful stalk is to provide the reverse engineer with an intuitive visual interface to filtered, meaningful, run-time block-level trace data.
A step-by-step example walkthrough of Process Stalker vs the Microsoft MS05-030 security bulletin is available at http://www.openrce.org. Binaries, source code and in-depth documentation are available in the bundled archive. Relevant slideshows from Process Stalker presentations are available on the past speaking engagements page.
The IDA Function Analyzer component was used and extended in the development of Process Stalker. The biggest change is the addition of the gml_export() routine for generating GML graphs.
Spent some time with spoonm over the weekend at RECON tinkering with the MS05-025 PNG vulnerability. Using my own not-as-cool-as-halvar's bindiff tool I came across the following significant change:
ms05025_diff.gif
The left column is pre-patch and the right column is post-patch. Further tracing reveals the actual vulnerable loop that leads to heap corruption, a jump table for which case 0x9 is required to reach the vulnerable function and some other interesting tidbits. All in all the vulnerability wasn't difficult to pin point, the biggest hurdle is overcoming the lazyness required to generate a valid PNG image as the CRC checks are done prior to reaching the vulnerable code.Just got back from RECON in Montreal. The trip back was miserable (4 flights spanning over 12 hours due to cancellations etc.) but the con was great. Lots of great speakers including Nicolas Brulez, Andrew Griffiths and spoonm. My talk was well received, RECON was definetely the perfect venue for Process Stalker.
On another note. I finally unveiled my latest pet project, the Open Reverse Code Engineering community site, OpenRCE.org. The site is very usable but has many features still under development. Please share any comments, suggestions, bug reports and especially content with one of the site admins.
You may have noticed the ghosted 'Heap' option under the 'View' menu in OllyDBG. The feature is available only under Windows 95 based OSes and is supposed to display a list of allocated memory blocks. I've written a plug-in, Olly Heap Vis, to provide this missing functionality and more on all modern Windows OSes such as Windows 2000, XP and 2003.
The Olly Heap Vis plug-in provides heap chunk lists, the ability to search the heap, a quick heap jump and finally visualization capabilities through Graphviz. More information and source code is available in the bundled archive.
I've been accepted to speak about Process Stalking at RECON, a computer security conference being held in Montreal from June 17th through 19th.
Full details and source code for Process Stalking will be released in the coming months.
Updates for IDA Sync, IDA pGRAPH and IDA Function Analyzer have been made available today. The IDA plug-ins have all been ported to compile against the 4.8 SDK. Binaries for IDA Pro 4.8 are also included.
I am also releasing OllyDbg Breakpoint Manager, an OllyDbg plug-in written to address some shortcomings of the built-in breakpoint management functionality. The plug-in provides three main functions- breakpoint exporting, breakpoint importing and automatic breakpoint loading. More information, examples and source code are available on the software releases page and bundled archive.
We started playing a great little multi player game called BZFlag in the office some time ago. It became quickly apparently that I sucked terribly at the game, despite my extensive efforts to shift blame to the fact that I was the only user playing on win32 and had older hardware. While I can't play BZFlag, I can code- and BZFlag is open source. Within a short time I was able to level the playing field. In the spirit of April fools, here are the list of changes I made:
bzflag/RadarRenderer.cxx
- Stealth tanks appear on radar.
- Disabled color-blindess.
common/Flag.cxx
- Color bad flags black.
- Color laser flags red.
- Color guided missiles green.
- Color narrow/burrow flags blue.
- Color shockwave flags yellow.
bzflag/playing.cxx
- Disabled ability for other tanks to cloak on screen.
bzflag/ShotStrategy.cxx
- Reduced laser reload time.
bzflag/LocalPlayer.cxx
- Added 25% chance of a good shot missing me.
- Disabled burrow speed handicap.
- This was detectable so I disabled it.
- Disabled my own shots from killing myself.
common/ShotUpdate.cxx
- Made my shot velocity slightly faster when packing the shot packet.
- This appears to have broken my ability to kill others, so I disabled it.
When running a shell server, at some point you may find the need to monitor or interact with another user's terminal. A number of kernel-based solutions exist such as Sebek from The Honeynet Project. I wanted something simpler and more elegant and was suggested by a contact to look into ttysnoop. ttysnoop is great- it allows you to selectively "attach" to a target user's terminal, view/interact as you please and detach when you are done. There is no need for a separate data store, any kernel modules or recompiling of any sort. Here is how I set it up to work with SSH on my Gentoo system:
First, I commented out the block of code responsible for the annoying startup sound and the line that prints "bye bye" when users close their session from ttysnoops.c:
509: /*if (InitSound())
510: {
511: DoSound(466, SLEN); // A#4
512: DoSound(622, SLEN); // D#5
513: DoSound(784, SLEN); // G5
514: DoSound(932, SLEN*2); // A#5
515: DoSound(784, SLEN); // G5
516: DoSound(932, SLEN*3); // A#5
517: }*/
...
661: if ((n = read(ptyfd, buff, BUFF_SIZE)) < 1)
662: {
663: //errorf ("bye bye\n");
664: exit (0);
665: }
I then compiled and installed the binaries (ttysnoop and ttysnoops) to /sbin. Next I created the /etc/snooptab file with the following single entry:
* socket login /bin/login.orig
I then moved /bin/login to /bin/login.orig and created a symbolic link from /bin/login to /sbin/ttysnoops:
# mv /bin/login /bin/login.orig
# ln -s /sbin/ttysnoops /bin/login
Next, I modified the command line arguments to agetty in /etc/inittab to reference the original login binary:
agetty -l /bin/login.orig
I then enabled the UseLogin option in sshd_config and restarted both sshd and init. I also created the ttysnoop spool directory as that is not done automatically:
# echo "UseLogin yes" >> /etc/ssh/sshd_config
# /etc/init.d/sshd restart
# init q
# mkdir /var/spool/ttysnoop/
# chmod 700 /var/spool/ttysnoop/
At this point ttysnoop is up and running. I did come across one quirk with the control keys. While Ctrl + '\' was working for suspends, Ctrl + '-' was not detaching from the snoop device. I was about to change the TERM_CHAR define when I realized that Ctrl + '/' sends the appropriate key-code for me, so you may want to try that key combination if Ctrl + '-' is not working for you.
The Python WMI interface is very cool as it lets you write small yet functional snippets like the following print-job sniffer:
import wmi
w = wmi.WMI()
watcher = w.watch_for(
notification_type = "Creation",
wmi_class = "Win32_PrintJob",
delay_secs = 1)
while 1:
job = watcher()
owner = str(job.Owner)
print "user: %s" % (job.Owner)
print "printer: %s" % (job.Name)
print "title: %s" % (job.Document)
print "pages: %d " % (job.TotalPages)
print "-" * 80
The above snippet will watch the network for all print jobs and print the owner, document title, printer name and page count. More information about WMI (Windows Management Instrumentation) can be found on MSDN.
I am releasing the source for IDA Sync under the GPL license. IDA Sync is implemented as an IDA Pro plugin and stand alone server for the purpose of allowing multiple analysts to synchronize their reverse engineering efforts. IDA Sync is especially useful when speed reversing malware. This project has some quirks that need to be worked out still and is being released pre-production quality in hopes of getting some support from the open source community.
Metakit if you haven't heard of it is an extremely useful, lightweight and efficient embeddable database library. I use it in many of my internal projects, including IDA Sync which was released today. In the process of bundling IDA Sync, I found that the latest Python bindings are not compatible with Python 2.4. After some googling I still couldn't find the appropriate binding so I bit the bullet and did the compile myself. To save others the effort, I am making it available here.
Metakit Python 2.4 Windows Bindings
It's been at least 6 months since I last looked at PyTrAn (Python Traffic Analyzer), but I came across it today and decided to organize some documentation and release it on the research/code page.
It's an interesting little side-project the goal of which was to automate traffic camera image analysis for the purpose of generating real-time traffic congestion reports. It has already reached a usable state though definitely short of my grand vision for where it could be. I'm sure at some point in the distant future I will find another burst of motivation to further it along.
With the purchase of new server and the move to a new datacenter I figured it would also be the appropriate time to update my website.
I removed some stagnant content, added some projects / code I've had laying around and gave the whole site a face lift. While currently far from complete I have the vision in mind and will fill out the site in the coming weeks.