9 Replies
      Latest reply on Sep 20, 2019 1:30 AM by eskimo
      weichao119 Level 1 Level 1 (0 points)

        Hi,

         

        I am studying of Network Extension to filter network traffic on OSX 10.15 beta version.

        I can run the demo on

        https://developer.apple.com/documentation/networkextension/filtering_network_traffic

         

        But when I try to filter the outbound stream, I can't get the info of which process setup the new flow in handleNewFlow function.

        I need the process info to decide whether to do the following filter.

         

        Is there any method to get the process info?

         

        I noticed that there is a sourceAppIdentifier property for NEFilterFlow in the document, but it seems no such property in real.

        And there is  a sourceAppAuditToken property, how can I get the process info from this property?

         

        Thank you very much!

        • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
          eskimo Apple Staff Apple Staff (11,835 points)

          What are you planning to do with the PID?  In general, using PIDs is a bad idea because PIDs can be reused (search the ’net for “pid reuse attack”).

          As such, sourceAppAuditToken is your friend.  If you need to map that to properties of the code, you can feed it into the code signing APIs (specifically, SecCodeCopyGuestWithAttributes with the kSecGuestAttributeAudit attribute).

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
              weichao119 Level 1 Level 1 (0 points)

              Hi  Eskimo,

               

              Thank you for your answer.

               

              I want to get the PID's binary's path with PID (I can use proc_selfpid() API in kernel to get it with socket filter, and then get it's binary's path).

              If the path match the setting, I can decide to filter it or let it go.

               

              And I also need to log the binary's path if I block the new flow to show to customers.

               

              Is there a methord to get the binary path with Network Extension?

               

              And more questions about sourceAppAuditToken:

              1.If a command line tool is accessing the network (such as curl), can I get this sourceAppAuditToken?

              2.If an unsigned command line tool is accessing the network, can I also get this sourceAppAuditToken?

               

              Thank you very much!

                • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                  eskimo Apple Staff Apple Staff (11,835 points)

                  I want to get the PID's binary's path with PID (I can use proc_selfpid API in kernel to get it with socket filter, and then get it's binary's path).

                  If the path match the setting, I can decide to filter it or let it go.

                  OK, so, to be clear, this is an example of what you’re currently doing, and you’re looking for info on how to do the equivalent in a NetworkExtension world, right?

                  If so, sourceAppAuditToken is definitely your friend.  You can use SecCodeCopyGuestWithAttributes with the kSecGuestAttributeAudit attribute to map it to a code object (SecCode) and then use various code signing routines to get properties from that code object.

                  IMPORTANT One of those routines is SecCodeCopyPath, although I strongly advise you to not track code identity by path.  The problem with doing that is that the user can move code around on the disk, and that will confuse your tracking.  It is much better to track code via its code signature, and you can get information about its code signature using SecCodeCopySigningInformation and, most critically, SecCodeCopyDesignatedRequirement.

                  If a command line tool is accessing the network (such as curl), can I get this sourceAppAuditToken?

                  Yes.  All code on our system is signed, and signed code always has a designated requirement (DR).  For example, the DR for curl is:

                  $ codesign -d --requirements - `which curl`
                  Executable=/usr/bin/curl
                  designated => identifier "com.apple.curl" and anchor apple

                  If an unsigned command line tool is accessing the network, can I also get this sourceAppAuditToken?

                  Yes, but you won’t be able to map this to a code signature as explained above because the code is not signed.  My recommendation is that you simply block all unsigned code.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                    • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                      weichao119 Level 1 Level 1 (0 points)

                      Hi  Eskimo,

                       

                      Thank you very much for your great help!

                      I will try to do this.

                       

                      And I have another related question:

                      There is a NEFilterBrowserFlow class on IOS, but not on Mac.

                       

                      Can I filter the browser's flow with NEFilterSocketFlow?

                      I did some test with the demo, but it seems can't get the flow from Safari.

                      Is there any setting?

                       

                      Thank you very much!

                      • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                        weichao119 Level 1 Level 1 (0 points)

                        Hi Eskimo,

                         

                        I tried your suggestion, and it worked!

                        Thank you very much!

                         

                        But one more question:

                         

                        If an unsigned command line tool is accessing the network, can I also get this sourceAppAuditToken?

                        Yes, but you won’t be able to map this to a code signature as explained above because the code is not signed.  My recommendation is that you simply block all unsigned code.

                         

                        If I block the flow, how do I show customer which process is blocked?If customer think it should be allowed, he maybe add it to exception list. How can I do this with unsigned code?

                         

                        And I  still can't get the flow from Safari.Could you please help?

                          • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                            eskimo Apple Staff Apple Staff (11,835 points)

                            There is a NEFilterBrowserFlow class on iOS, but not on Mac.

                            Correct.

                            Can I filter the browser's flow with NEFilterSocketFlow?

                            I would expect so, yes.  The absence of NEFilterBrowserFlow simply means that you don’t get the nice features associated with that class; the browser still generates traffic on the wire and this should be seen by the socket flow.

                            I did some test with the demo, but it seems can't get the flow from Safari.

                            Weird.  I don’t have an easy explanation for that.

                            If you create a small web view test app (using WKWebView), can you see its traffic?


                            If I block the flow, how do I show customer which process is blocked? If customer think it should be allowed, he maybe add it to exception list.  How can I do this with unsigned code?

                            Have you tried calling SecCodeCopySigningInformation on that audit token?  It’s possible it’ll return some info even though the process isn’t signed.

                            If not, you have to drop down to much lower-level code.  Specifically, you can get various properties from an audit token using the API in <bsm/libbsm.h>, for example, audit_token_to_pid.

                            WARNING To reiterate my comment above, identifying code by PID is a terrible idea security-wise.  Only do this when dealing with unsigned code.  Even then, if I were doing this I’d simply block all unsigned code.  There are two source of unsigned code:

                            • Code that the user has created themselves (A)

                            • Code generated by an attacker (B)

                            Any user who is smart enough to do A is smart enough to sign that code (even if it’s only ad hoc signing).  And by not holding the line here, you’re opening yourself up to B.

                            Share and Enjoy

                            Quinn “The Eskimo!”
                            Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                            let myEmail = "eskimo" + "1" + "@apple.com"

                              • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                                weichao119 Level 1 Level 1 (0 points)

                                Hi Eskimo,

                                 

                                Thank you very much!

                                I will try your suggestion.

                                • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                                  weichao119 Level 1 Level 1 (0 points)

                                  Hi Eskimo,

                                   

                                  Sorry for bothering you again.

                                   

                                  I tried a small tool by using WKWebView, and I can't filter it's flow.

                                  With the same network extension demo, I can filter others, such as  /usr/bin/curl, /usr/sbin/httpd.

                                   

                                  Do you have any suggestion?

                                   

                                  And a new question is:

                                  There is a sock_inject_data_in API in kernel for injecting special content to socket.

                                  I use this API to inject the block reason to socket to show customer why the connection is blocked.

                                   

                                  I didn't find such API in current network extension document.

                                  Is there a same API in network extension?

                                   

                                  Thank you very much!

                                    • Re: how to get the pid of NEFilterFlow in handleNewFlow of Network Extension?
                                      eskimo Apple Staff Apple Staff (11,835 points)

                                      I tried a small tool by using WKWebView, and I can't filter it's flow.

                                      Weird.  I’m not sure what’s going on there.  Please file a bug about this, and then post your bug number.


                                      Is there a same API in network extension?

                                      No, because a content filter can only filter, it can’t modify the traffic.  You have two options here:

                                      • The content filter can notify the user via other means.  For example, the sample code using IPC to route such prompts to its container app.

                                      • You can build a transparent proxy, which lets you modify the traffic.

                                      Share and Enjoy

                                      Quinn “The Eskimo!”
                                      Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                                      let myEmail = "eskimo" + "1" + "@apple.com"