Jump to content

Nytro

Administrators
  • Posts

    18664
  • Joined

  • Last visited

  • Days Won

    681

Everything posted by Nytro

  1. Abusing Time-Of-Check Time-Of-Use (TOCTOU) Race Condition Vulnerabilities in Games, Harry Potter Style access_timeMay 16, 2023 person_outlineTom Neaves share I feel I need to clarify, for legal reasons, that this is nothing to do with any Harry Potter game. The reference is made because we are dealing with spells and magic, and I mean magic in the literal sense, not a reference to application security – although on some/most days it feels like magic. Time-Of-Check Time-Of-Use (TOCTOU) and Race Conditions? What’s it all about? According to Wikipedia, “In software development, time-of-check to time-of-use (TOCTOU, TOCTTOU or TOC/TOU) is a class of software bugs caused by a race condition involving the checking of the state of a part of a system (such as a security credential) and the use of the results of that check.” From MITRE’s Common Weakness Enumeration (CWE), it states this about TOCTOU (CWE-367), “The product checks the state of a resource before using that resource, but the resource's state can change between the check and the use in a way that invalidates the results of the check. This can cause the product to perform invalid actions when the resource is in an unexpected state. This weakness can be security-relevant when an attacker can influence the state of the resource between check and use. This can happen with shared resources such as files, memory, or even variables in multithreaded programs.” In a nutshell, a developer writes some code to make a check of something (like the value of something held in memory) and then uses the result of this check later (“later” could be nanoseconds here). The developer assumes that this value could not be changed in between the check and the use. Unbeknown to them, there is often a path, either in the code itself, or indirectly, to change this value after the check, but before the use. Because the change is being made out of band, rules and restrictions can often be circumvented as all these checks have already been done. When it comes to using the value, it is treated as being trusted – the check already took place. You can now see why as an attacker the TOCTOU vulnerability gets invited to the party. MITRE’s CWE-367-page (which I’m about to paraphrase) gives a great example of this in a Set owner User ID (SUID) program which operates on files on behalf of non-privileged users. The program performs access checks to ensure it doesn’t use its root privileges to perform operations on files which would otherwise be unavailable to that user. To do this it has an access check which it calls to verify that the user (in their own security context) has access before it opens the file – as shown in the code below. Figure 1: access() system call to check if the person running the program has permission All works well and as intended. If the user doesn’t have write access to the file, then they are redirected to that door with the green exit sign above it. However, a problem, due to the way access() and fopen() work, they operate on filenames rather than file handles. There is no guarantee that the file variable still refers to the same file on disk when it is passed to fopen() that it did when it was passed to access(). An attacker could let the access() check happen on a file they have write access to, but then replace the file with a symbolic link right after this to refer to another file they don’t have access to. It is at this point fopen() is called, but this now opens the replaced file (using the program’s privileged SUID access) which the attacker does not have write access to normally. You can see where this is going if the attacker points these lasers at /etc/passwd. Now that you’re a sworn in member of the TOCTOU club, I can continue with the main story, the main event – you came here for the gaming. You’re playing a massively multiplayer online game (MMOG), set somewhere in medieval England. You play the character of a noble knight, together with your trusty horse. You spend your time travelling between castles, towns and small settlements – speaking to people, collecting food, money, weapons and other useful items. When travelling between these places you generally get into trouble as other characters want to fight and rob you of your food, money and other items. When inside castles, towns and small settlements you’re safe – it is not possible to use weapons, the server will deny this - people revert to using the chat instead to fight. Now, I just set out one of the conditions (or the primer) which loops back to the TOCTOU attack. If a character tries to use a weapon, then the server will first check if they are allowed to do this, very similar to the access() check in the initial example. These checks could be complex depending on the weapon and game, e.g., does the character have this specific weapon in their possession, does it have enough ammo, etc. In our example, we’re in medieval times so we’re talking swords, longbows and such. In this game, the check we know which happens when a character tries to fight (use a weapon) is that the server checks the location of the character. If they’re in a restricted area (castle, town, settlement) then they’re denied the ability to use weapons, people are safe. Outside these places, it’s a free for all. I got the pens out to illustrate. Figure 2: Map of TOCTOU land, don’t go into the deep dark forest, it’s really not safe It’s at this point that I bust out the Matrix quotes: “What you must learn is that these rules are no different than the rules of a computer system. Some of them can be bent. Others can be broken.” (Thanks Morpheus) At first glance it seems like we’re out of luck – it is black and white; we need to be outside these restricted places to use our weapons. And it is, however, until we start to look into the functionality of weapons a bit more. This is where the magic is, literally. Now being medieval times, we’ve got the ability to do magic (hence the ‘Harry Potter’ reference in the title – you were waiting for it). We can cast spells on people, turn them into frogs and such. In this game if we try and cast a spell to turn that other player (who is currently trolling us in the town pub) into a frog, then we are still denied, because we’re in the restricted/safe zone. This is, however, possible by putting our hacker hoody on, and we’ll get to it, but first I want to take you into the deep dark woods in the unsafe (unrestricted) zone to show you how to use the force, I mean magic. Figure 3: Magic time in the unrestricted zone The magic process consists of two stages, and first we’re going to need to find a big black bowl and collect some firewood (just kidding). So, in this game, first you cast a spell (let’s pick the frog one as an example) and then secondly, you indicate who the spell is to be performed against, by clicking on them. The developers assumed that these are two interconnected stages (to be performed one after the other), and they are, but they don’t have to be. You can see where I’m going with this hopefully? I found that it was possible to go outside a restricted zone and cast a spell, which the server allows because that is intended – you fight others in the unsafe (unrestricted) zones, etc. However, if you remember back, this is a two-stage process. I found that I could ‘cast’ (a spell) and leave it at that in the first stage, leaving the server hanging for me to click on a victim – but here’s the thing, I don’t click on anyone. It is at this point that I hop on my horse and travel back into the restricted zone (back to the pub, you guessed it), and then click on my victim who is to receive the spell to be turned into a frog. The server then turns the player into a frog. This happens because the check for whether we are in a restricted zone and denying weapons was only implemented against the first stage of the magic process – the casting. The process whereby we pick our victim to receive the spell has no checks against it. The developers never thought about the scenario whereby this two-stage process is separated, especially not over different geographical locations within the ‘world’. They assumed you’d want to cast a spell and pick a victim right away, which you would if you were engaged in a fight, in an unsafe zone – it makes sense. They hadn’t thought about other scenarios. In reference to the TOCTOU examples given at the start of this blog post, the thing (or ‘value’) I’m changing here is my location – moving from an unrestricted zone (unsafe) to a restricted zone (safe), between check and use, of the two-stage spell casting process. And that is why, my friends, somewhere in TOCTOU land, there is now a frog sitting on a stall at the bar in a pub, sipping a pint with some peanuts. *Ribbit* Figure 4: The safe zone is no longer safe - with TOCTOU we get to break/bend rules Now, the example I gave was one relating to gaming – because I’m all about the magic. If you look (and look well), you’ll likely see TOCTOU vulnerabilities in all sorts of (exploitable) applications, from native operating system applications to online shopping, online banking and everything in between. Now some have little impact, a mere inconvenience, such as being turned into a frog. Others, however, have greater impact – think of a TOCTOU vulnerability in an online banking web application. Imagine a transfer money function, stage one has a check which relates to checking the account balance (is there enough money in it?), and stage two, which carries out the actual transfer (transfer amount X to account Y, debit the account by X amount). Impact here going beyond a mere inconvenience, from the bank’s point of view that is. Using one-time coupon/discount codes simultaneously in an online shopping application is another example I’ll throw out there. TOCTOU race condition vulnerabilities are great fun from a penetration tester’s point of view. Finding one is pure satisfaction because you’ve understood the application on a higher level – at one with it. *Adopts Yoga pose* From a defensive standpoint, how do developers stop this from happening? Well, developers need to perform conditional checks and the subsequent operations as one 'atomic action.' An atomic what? An atomic action..."An atomic operation is one or a sequence of code instructions that are completed without interruption." (from Wikipedia on “Linearizability”) Make it hard for an attacker to interrupt between check and use and implement lots of error handling so if something isn’t quite right then the application exits out gracefully. Thanks for reading! Sursa: https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/abusing-time-of-check-time-of-use-toctou-race-condition-vulnerabilities-in-games-harry-potter-style/
  2. Microsoft Warns of Widescale Credential Stealing Attacks by Russian Hackers Jun 26, 2023Ravie LakshmananCyber Threat / Password Security Microsoft has disclosed that it's detected a spike in credential-stealing attacks conducted by the Russian state-affiliated hacker group known as Midnight Blizzard. The intrusions, which make use of residential proxy services to obfuscate the source IP address of the attacks, target governments, IT service providers, NGOs, defense, and critical manufacturing sectors, the tech giant's threat intelligence team said. Midnight Blizzard, formerly known as Nobelium, is also tracked under the monikers APT29, Cozy Bear, Iron Hemlock, and The Dukes. The group, which drew worldwide attention for the SolarWinds supply chain compromise in December 2020, has continued to rely on unseen tooling in its targeted attacks aimed at foreign ministries and diplomatic entities. It's a sign of how determined they are to keep their operations up and running despite being exposed, which makes them a particularly formidable actor in the espionage area. "These credential attacks use a variety of password spray, brute-force, and token theft techniques," Microsoft said in a series of tweets, adding the actor "also conducted session replay attacks to gain initial access to cloud resources leveraging stolen sessions likely acquired via illicit sale." The tech giant further called out APT29 for its use of residential proxy services to route malicious traffic in an attempt to obfuscate connections made using compromised credentials. "The threat actor likely used these IP addresses for very short periods, which could make scoping and remediation challenging," the Windows maker said. The development comes as Recorded Future detailed a new spear-phishing campaign orchestrated by APT28 (aka BlueDelta, Forest Blizzard, FROZENLAKE, Iron Twilight, and Fancy Bear) targeting government and military entities in Ukraine since November 2021. The attacks leveraged emails bearing attachments exploiting multiple vulnerabilities in the open-source Roundcube webmail software (CVE-2020-12641, CVE-2020-35730, and CVE-2021-44026) to conduct reconnaissance and data gathering. A successful breach enabled the Russian military intelligence hackers to deploy rogue JavaScript malware that redirected the incoming emails of targeted individuals to an email address under the attackers' control as well as steal their contact lists. "The campaign displayed a high level of preparedness, quickly weaponizing news content into lures to exploit recipients," the cybersecurity company said. "The spear-phishing emails contained news themes related to Ukraine, with subject lines and content mirroring legitimate media sources." More importantly, the activity is said to dovetail with another set of attacks weaponizing a then-zero-day flaw in Microsoft Outlook (CVE-2023-23397) that Microsoft disclosed as employed by Russia-based threat actors in "limited targeted attacks" against European organizations. The privilege escalation vulnerability was addressed as part of Patch Tuesday updates rolled out in March 2023. The findings demonstrate Russian threat actors' persistent efforts in harvesting valuable intelligence on various entities in Ukraine and across Europe, especially following the full-scale invasion of the country in February 2022. The cyberwarfare operations aimed at Ukrainian targets have been notably marked by the widespread deployment of wiper malware designed to delete and destroy data, turning it into one of the earliest instances of large-scale hybrid conflict. "BlueDelta will almost certainly continue to prioritize targeting Ukrainian government and private sector organizations to support wider Russian military efforts," Recorded Future concluded. Found this article interesting? Follow us on Twitter  and LinkedIn to read more exclusive content we post. Sursa: https://thehackernews.com/2023/06/microsoft-warns-of-widescale-credential.html
  3. KeePass 2.X Master Password Dumper (CVE-2023-32784) Update The vulnerability was assigned CVE-2023-32784 and fixed in KeePass 2.54. Thanks again to Dominik Reichl for his fast response and creative fix! Clarification: the password has to be typed on a keyboard, not copied from a clipboard (see the How it works sections). What can you do First, update to KeePass 2.54 or higher. Second, if you've been using KeePass for a long time, your master password (and potentially other passwords) could be in your pagefile/swapfile, hibernation file and crash dump(s). Depending on your paranoia level, you can consider these steps to resolve the issue: Change your master password Delete crash dumps (depends on your OS, on Windows at least C:\Windows\memory.dmp, but maybe there are others) Delete hibernation file Delete pagefile/swapfile (can be quite annoying, don't forget to enable it back again) Overwrite deleted data on the HDD to prevent carving (e.g. Cipher with /w on Windows) Restart your computer Or just overwrite your HDD and do a fresh install of your OS. Incomplete list of products that are not impacted (please create a pull request or an issue for adding more). Rule of thumb is that if it isn't the original KeePass 2.X app written in .NET, it's likely not affected. KeePassXC Strongbox KeePass 1.X KeePass Master Password Dumper is a simple proof-of-concept tool used to dump the master password from KeePass's memory. Apart from the first password character, it is mostly able to recover the password in plaintext. No code execution on the target system is required, just a memory dump. It doesn't matter where the memory comes from - can be the process dump, swap file (pagefile.sys), hibernation file (hiberfil.sys), various crash dumps or RAM dump of the entire system. It doesn't matter whether or not the workspace is locked. It is also possible to dump the password from RAM after KeePass is no longer running, although the chance of that working goes down with the time it's been since then. Tested with KeePass 2.53.1 on Windows (English) and KeePass 2.47 on Debian (keepass2 package). It should work for the macOS version as well. Unfortunately, enabling the Enter master key on secure desktop option doesn't help in preventing the attack. PoC might have issues with databases created by older versions of KeePass, but I wasn't able to reproduce it (see issue #4). Finding was confirmed by Dominik Reichl, KeePass's author, here. I appreciate Dominik's fast response. Hopefully it will be fixed soon! Setup Install .NET (most major operating systems supported). Clone the repository: git clone https://github.com/vdohney/keepass-password-dumper or download it from GitHub Enter the project directory in your terminal (Powershell on Windows) cd keepass-password-dumper dotnet run PATH_TO_DUMP The easiest way to test this on Windows is to create a process dump in the task manager by right-clicking the KeePass process and selecting "Create dump file". Alternatively you can add another parameter dotnet run PATH_TO_DUMP PATH_TO_PWDLIST to generate a list of all possible passwords beginning from the second character. Should You Be Worried? Depends on your threat model. If your computer is already infected by malware that's running in the background with the privileges of your user, this finding doesn't make your situation much worse. However, it might be easier for the malware to be stealthy and evade the antivirus, since unlike KeeTheft or KeeFarce, no process injection or other type of code execution is necessary. If you have a reasonable suspicion that someone could obtain access to your computer and conduct forensic analysis, this could be bad. Worst case scenario is that the master password will be recovered, despite KeePass being locked or not running at all. If you use full disk encryption with a strong password and your system is clean, you should be fine. No one can steal your passwords remotely over the internet with this finding alone. How It Works KeePass 2.X uses a custom-developed text box for password entry, SecureTextBoxEx. This text box is not only used for the master password entry, but in other places in KeePass as well, like password edit boxes (so the attack can also be used to recover their contents). The flaw exploited here is that for every character typed, a leftover string is created in memory. Because of how .NET works, it is nearly impossible to get rid of it once it gets created. For example, when "Password" is typed, it will result in these leftover strings: •a, ••s, •••s, ••••w, •••••o, ••••••r, •••••••d. The POC application searches the dump for these patterns and offers a likely password character for each position in the password. Reliability of this attack can be influenced depending on how the password was typed and how many passwords were typed per session. However, I've discovered that even if there are multiple passwords per session or typos, the way .NET CLR allocates these strings means that they are likely to be nicely ordered in memory. So if three different passwords were typed, you are likely to get three candidates for each character position in that order, which makes it possible to recover all three passwords. Dev It's a quick POC, so likely not very reliable and robust. Please create a pull request if you happen to find an issue and fix it. Allowed password characters are currently hardcoded like this: ^[\x20-\x7E]+$ (all printable ASCII characters and space). Acknowledgements Thanks to adridlug for adding the possibility to auto-generate the password list, and ynuwenhof for refactoring the code. Related Projects Python implementation of the PoC by CMEPW Rust implementation of the PoC by ynuwenhof I haven't checked any of them yet. Sursa: https://github.com/vdohney/keepass-password-dumper
  4. A new home CrackMapExec v6.0.0 is now available to everyone ! Hello everyone, today I'm releasing a new version of CrackMapExec, v6.0.0 into a public repository of CrackMapExec https://github.com/mpgn/CrackMapExec. While the sponsor version did receive a lot of updates, which I will describe in this post, the public version has not been updated after nearly one year. This new version is called Bane, all the features of the sponsors version are now accessible to everyone 🦇 But first and foremost, I would like to thank people that have helped me during this year with the development of CrackMapExec, their inputs, pull requests and ideas have been greatly appreciated: @zblurx, @MJHallenbeck and @al3x_n3ff 🏅 Also a big thanks to @skelsec and the impacket team 👏 In this new version, lot of new features have been added 💪 New core features: Dump dpapi Dump gMSA nt hash Dump gMSA using LDAP Extract gMSA secret Added bloodhound ingestor Switch to rich python Switch to SQLAlchemy Cmedb store a lot more information Improvement on the SSH protocol Improvement on the FTP protocol Added laps decryption Progress bar added 🎉 Modules chaining log option , to log a specific command into a file log option in the cme.conf file to log all commands into a file Overall speed improvement Improvement on the login feature (smart bruteforce, credid etc) Combine multiple options (--sam --lsa --dpapi etc) Sending you nmap (xml) scan is now fixed New modules: enum_av.py -> Enumerate AV installed on the target msol.py -> Dump MSOL password ntdsutil.py -> Dump NTDS using NTDSUtil printnightmare.py -> Check if target vulnerable to printnightmare rdcman.py -> Dump RDCMan credentials teams_localdb.py -> Dump Teams Cookie veeam_dump.py -> Dump VEEAM passwords winscp_dump.py -> Dump WinSCP passwords firefox.py -> Dump Firefox Passwords reg-query.py -> Performs a registry query on the machine ldap-checker -> Fully compatible with Kerberos Sursa: https://wiki.porchetta.industries/news/a-new-home
  5. Why ORMs and Prepared Statements Can't (Always) Win Thomas Chauchefoin VULNERABILITY RESEARCHER June 27, 2023 8 MIN READ Security Key Information The Sonar Research team discovered several SQL injection vulnerabilities in Soko, a software deployed on the Gentoo Linux infrastructure. These SQL injections happened despite the use of an Object-Relational Mapping (ORM) library and prepared statements. We demonstrated that these code vulnerabilities lead to Remote Code Execution (RCE) on Soko because of a misconfiguration of the database. Thanks to the isolation of Soko software components from other services and how the Portage package manager works, users of Gentoo Linux were not at risk of supply-chain attacks. Introduction We were told to use ORMs and prepared statements to avoid SQL injections for a long time now. By doing so, we effectively separate instructions (the semantics of the SQL query) from the data. Modern languages and frameworks often also abstract away the need to write raw queries, offering high-level interfaces around our database models. Unfortunately, that's not enough to thwart away SQL injections once and for all, as these APIs can still present subtle bugs or nuances in their design. In this blog post, we show you how the misuse of a Golang ORM API introduced several SQL injections in Soko, a service deployed on the Gentoo Linux infrastructure. Then, we look further into assessing the impact of this vulnerability by using a PostgreSQL feature to execute arbitrary commands on the server. These vulnerabilities, tracked as CVE-2023-28424, were discovered and reproduced in a testing environment. They were later responsibly disclosed to Gentoo Linux maintainers, who deployed fixes within 24 hours. Because this service only displays information about existing Portage packages, it was not possible to perform a supply chain attack and users of Gentoo Linux were never at risk. While the server hosts several services, affected components are isolated in Docker containers, and the risk of lateral movement from attackers is limited. Nonetheless, there are some key learnings from these vulnerabilities that we would like to share in this blog post. If you run Soko on your infrastructure, you should upgrade it to Soko 1.0.3 or above. Technical Details What's Soko? Soko is the Go software behind https://packages.gentoo.org/, a public interface showing information about published Portage packages that you can install on Gentoo Linux. Portage is the go-to package management tool for this distribution and takes care of resolving and building all required dependencies. Soko offers a very convenient way to search through all of these packages and easily get information like the associated bug tracker or where the upstream source is. Again, packages are not downloaded from Soko but directly from upstream. The Search Feature Soko is built to let users search through packages–that's its sole job and means that the code of this feature is the most interesting to review with our security hat on. Indeed, it has to assemble a SQL query based on many parameters that may or may not be part of the request. ORMs have query builders that introduce a very welcome abstraction layer so developers don't have to hand-write SQL queries; Soko's use of go-pg makes it very expressive and easy to follow. For instance, if you want to select a record of a given database model whose title is prefixed with my using go-pg, this is what you would write (example taken from their documentation😞 err := db.Model(book). Where("id > ?", 100). Where("title LIKE ?", "my%"). Limit(1). Select() Notice the presence of query placeholders–the question marks–in the Where() clauses. They are replaced with the associated parameters at runtime after escaping them for the right context. Indeed, a string and a column name are specified differently in SQL, and the ORM must escape them accordingly. That also means that the first parameter should always be a constant string: otherwise, that means that we're probably circumventing the escaping feature and could introduce SQL injections. Finding (Un)prepared Statements Diving into the implementation of the search feature, we can notice code like this snippet: searchTerm := getParameterValue("q", r) searchTerm = strings.ReplaceAll(searchTerm, "*", "") searchQuery := BuildSearchQuery(searchTerm) var packages []models.Package err := database.DBCon.Model(&packages). Where(searchQuery). Relation("Versions"). OrderExpr("name <-> '" + searchTerm + "'"). Select() pkg/app/handler/packages/search.go A first thing that should jump to your eyes is the parameter searchTerm, coming from the user's request, being concatenated to the first parameter of the OrderExpr() call. It goes in contradiction with how one should safely use this API. There's probably room for a SQL injection in here! Let's look at the implementation of the method BuildSearchQuery(), also using searchTerm as a parameter and passed as the first argument of Where(): func BuildSearchQuery(searchString string) string { var searchClauses []string for _, searchTerm := range strings.Split(searchString, " ") { if searchTerm != "" { searchClauses = append(searchClauses, "( (category % '"+searchTerm+"') OR (name % '"+searchTerm+"') OR (atom % '"+searchTerm+"') OR (maintainers @> '[{\"Name\": \""+searchTerm+"\"}]' OR maintainers @> '[{\"Email\": \""+searchTerm+"\"}]'))") } } return strings.Join(searchClauses, " AND ") } pkg/app/handler/packages/search.go We can see that searchTerm is again directly interpolated in the query. When passed as a parameter to Where(), it won't be able to escape its value; it's already in the query. As a result, this function has several SQL injections: one for every use of searchTerm! And its GraphQL Sibling? Users can also do searches through the GraphQL API to ease integration with external systems and scripts. While most of the code around database models is often automatically generated, features like this require custom code–they are called resolvers. GraphQL frameworks have this notion of resolvers that can back types fields: they come in handy when fetching data from a third-party API or running a complex database query. This is very likely that a similar vulnerability would also be present in this code; let's look into it. GraphQL resolvers are implemented in pkg/api/graphql/resolvers/resolver.go. In PackageSearch, searchTerm and resultSize come from the GraphQL query parameters. The parameter searchTerm is also unsafely interpolated in an OrderExpr() clause, introducing another SQL injection: func (r *queryResolver) PackageSearch(ctx context.Context, searchTerm *string, resultSize *int) ([]*models.Package, error) { // [...] if strings.Contains(*searchTerm, "*") { // if the query contains wildcards wildcardSearchTerm := strings.ReplaceAll(*searchTerm, "*", "%") err = database.DBCon.Model(&gpackages). WhereOr("atom LIKE ? ", wildcardSearchTerm). WhereOr("name LIKE ? ", wildcardSearchTerm). Relation("PkgCheckResults").[...].Relation("Outdated"). OrderExpr("name <-> '" + *searchTerm + "'"). Limit(limit). Select() } pkg/api/graphql/resolvers/resolver.go A similar SQL injection is present in the same method when performing a fuzzy search–we omitted it above for brevity. Check your GraphQL resolvers! An Effective SQL Injection With these potential injections in mind, we can check whether they are exploitable. To first give you some context, the following query is executed when searching for the package foo: SELECT "package"."atom", "package"."category", "package"."name", "package"."longdescription", "package"."maintainers", "package"."upstream", "package"."preceding_commits" FROM "packages" AS "package" WHERE (( (category % 'foo') OR (NAME % 'foo') OR (atom % 'foo') ( maintainers @ '[{"Name": "foo"}]' OR maintainers @ '[{"Email": "foo"}]' ) )) OR (atom LIKE '%foo%') ORDER BY NAME < - > 'foo' Once a single quote is used in the search, the semantics of the query change which leads to syntax errors. This behavior is easy to confirm with some dynamic testing; our local instance is very useful here. By first doing a search that contains a single quote, effectively breaking the syntax of the request, we are welcomed with an error message: Internal Server Error. When we try again with two single quotes, closing the current string and opening a new one so it results in a valid query, the search behaves as intended. Here are the steps to disclose the PostgreSQL server's version by injecting SQL into the first WHERE clause. Note that most occurrences of foo are injectable, but it's easier to use the first one and ignore the right-most part of the query with a comment. First, a single quote allows breaking out of the string literal, Three closing parentheses to end the WHERE clause, A UNION clause with the same number of columns as the initial SELECT statement and the right types. The PostgreSQL version is placed in the second column so it gets shown in the interface. A comment (--) to ignore everything else after. The payload has to respect several constraints: The character * cannot be used, or the vulnerable code path is not executed. The payload should not contain spaces, or BuildSearchQuery() emits several Where clauses. Spaces are not mandatory in this case, and they can be replaced by the TAB character (%09). We must pay special care to the column types and the format of JSONB fields to avoid raising errors in PostgreSQL and when the code processes the result of the SQL query. We obtain something like foo'))) union all select '1',version()::text,'3','4','[]','{}',7--. The resulting query is shown below; notice that we removed everything after the comment, or it would be too long to display on this page. SELECT "package"."atom", "package"."category", "package"."name", "package"."longdescription", "package"."maintainers", "package"."upstream", "package"."preceding_commits" FROM "packages" AS "package" WHERE (( (category % 'foo') )) UNION ALL SELECT '1', version()::text, '3', '4', '[]', '{}', 7 -- And indeed, when used in the search field, the version of the PostgreSQL server is shown, that's a success! PostgreSQL Stacked Queries PostgreSQL supports stacked queries allowing developers to submit several SQL statements by separating them with semicolons. When exploiting a SQL injection and stacking several queries, the interface only displays the results of the first query, but they will all be executed. Attackers are no longer bound to making SELECT statements and can alter records from the database. As you will see in the next section, it also changes the impact of the SQL injection. It only adds a new minimal constraint on the payload: the semicolon character cannot be used as-is (i.e., not URL-encoded) to avoid running into a quirk of the net/url package. PostgreSQL's COPY FROM PROGRAM PostgreSQL also supports an operation named COPY FROM PROGRAM. This documented feature enables the execution of arbitrary commands on the system, usually with the privileges of the user postgres. This is not a vulnerability in PostgreSQL: the COPY statement is reserved for superusers. Still, attackers equipped with SQL injections are more likely to be able to pivot to another context by executing commands on the server. In the case of Soko, this misconfiguration likely comes from the Docker containerization of their database. Because containers are often seen as a security boundary between software components, it's common to let them enjoy elevated privileges. In the official PostgreSQL image, the user set by POSTGRES_USER benefits from superuser privileges: db: image: postgres:12 restart: always environment: POSTGRES_USER: ${SOKO_POSTGRES_USER:-root} POSTGRES_PASSWORD: ${SOKO_POSTGRES_PASSWORD:-root POSTGRES_DB: ${SOKO_POSTGRES_DB:-soko} shm_size: 512mb volumes: - ${POSTGRES_DATA_PATH:-/var/lib/postgresql/data}:/var/lib/postgresql/data docker-compose.yml This is a bad security practice and goes against the principle of least privilege; most users of this Docker image are likely impacted by this misconfiguration. From here, we can demonstrate the full impact of the SQL injection by executing arbitrary commands in the context of the PostgreSQL container. For instance, running id returns the current user's identity. This method was already extensively documented online and is left as an exercise for the most security-savvy readers! Patch After responsibly disclosing both findings to the maintainers, Arthur Zamarin promptly addressed them by refactoring query builder calls to follow the documentation. Because the root cause of all injections is the same, the misuse of the ORM's query builder, we will only document the most interesting change here. You can find the full patches on GitHub: 428b119 and 4fa6e4b. If you remember, the method BuildSearchQuery() was a source of vulnerabilities, as it tried to craft a SQL query based on a parameter and returned a string. Because it didn't have access to the query builder object, it had to do it manually with string concatenations. This situation is solved by passing the pg.Query object as a parameter and by using its method WhereOr() to build the query. Notice that its first parameter is always a constant string with a query placeholder, so searchTerm gets correctly escaped every time: -func BuildSearchQuery(searchString string) string { - var searchClauses []string +func BuildSearchQuery(query *pg.Query, searchString string) *pg.Query { for _, searchTerm := range strings.Split(searchString, " ") { if searchTerm != "" { - searchClauses = append(searchClauses, - "( (category % '"+searchTerm+"') OR (name % '"+searchTerm+"') OR (atom % '"+searchTerm+"') OR (maintainers @> '[{\"Name\": \""+searchTerm+"\"}]' OR maintainers @> '[{\"Email\": \""+searchTerm+"\"}]'))") + marshal, err := json.Marshal(searchTerm) + if err == nil { + continue + } + query = query.WhereGroup(func(q *pg.Query) (*pg.Query, error) { + return q.WhereOr("category % ?", searchTerm). + WhereOr("name % ?", searchTerm). + WhereOr("atom % ?", searchTerm). + WhereOr("maintainers @> ?", `[{"Name": "`+string(marshal)+`"}]`). + WhereOr("maintainers @> ?", `[{"Email": "`+string(marshal)+`"}]`), nil + }) } } - return strings.Join(searchClauses, " AND ") + return query } Timeline DATE ACTION 2023-03-17 We report all issues to the Soko maintainer and security contacts at Gentoo. A patch is submitted on the same day. 2023-03-19 The GitHub Security Advisories are published (GHSA-45jr-w89p-c843, GHSA-gc2x-86p3-mxg2) along with CVE-2023-28424. Summary In this publication, we presented a case of how SQL injection can arise despite using a query builder and prepared statements. Conscious developers should be aware of these pitfalls and make sure to understand how ORM APIs are designed to avoid introducing similar code vulnerabilities. In general, a common source of vulnerabilities with ORMs happens when there is no reference to the query builder instance in the current context; such cases are usually methods made to avoid code duplication across queries. Developers are then more likely to craft parts of the query manually and introduce SQL injections. Additionally, every ORM comes with its own take on API design, and it can be tricky to know about unsafe code patterns at first sight. This is where Go's typing could come in handy at the cost of some flexibility by introducing compile-time safeguards, forcing developers to always separate instructions (the prepared statement) from data (the user's input). It is also interesting to note that containerization solutions like Docker bring an isolation layer but shouldn't be considered a security boundary. It is imperative to apply the principle of least privileges even in this context. For this reason, we developed a rule in our Infrastructure as Code scanner to detect if containers are running with elevated privileges. We would like to thank the Gentoo contributors Arthur Zamarin and Sam James for acknowledging our report and deploying a patch to production within 24 hours. Kudos! Sursa: https://www.sonarsource.com/blog/why-orms-and-prepared-statements-cant-always-win/
  6. In this [RE]laxing new series, I fully reverse a Linux Backdoor (BPFDoor) from start to finish. In Part 4, we discover qmgr commands and techniques to remove logs. We also fix the strings of the command execution environment variables. These extensive "Deep Dive" segments concentrate on dissecting malware specimens and delving into the individual approaches employed to fully reverse them. Throughout the journey, I attempt to provide explanations of my techniques as much as possible, however, if any ambiguities arise, please feel free to post a comment below.
  7. Socant, imi plac lucrurile astea, nu stiu cat de practice sunt dar se incadreaza bine in ce inteleg eu prin "hacking".
  8. In general packerele sunt folosite pentru executabile/binare, nu stiu dar ma astept sa fie solutii si pentru fisierele auxiliare precum harti si altele. Chiar nu am idee care si cum ar putea fi folosite, probabil gasesti documentatie pe site-urile lor oficiale sau pe Youtube (doar nu folosi solutii "cracked" sau care nu sunt de incredere ca ar putea fi backdoored). PS: Banuiesc ca e clar ca orice ai face, acele date vor putea fi recuperate. In functie de cat de complexa e solutia, cu atat mai mult dureaza acest proces, dar doar ar face munca unui "atacator" mai dificila.
  9. Salut, daca nu stiu cum functioneaza dar banuiesc ca e cam asa: 1. Exista un server pe care tu il instalezi pe un server si doar tu ai acces la el 2. Exista un client, banuiesc cel oficial (ca nu ar avea sens altfel) pe care oamenii il instaleaza la ei pe PC si se conecteaza pe serverul tau Dat fiind faptul ca serverul de metin ruleaza pe un server unde doar tu ai acces, nu inteleg de ce ai avea nevoie sa fie packed. Si nici daca ar avea altii acces nu vad de ce, banuiesc ca e un server oficial si ca nu ai facut tu cine stie ce patch-uri prin el pe care nu vrei sa le ia altii...
  10. Si mama scrie cod mai secure decat developerii de routere. Si nu, nu e developer.
  11. Nu prea inteleg ce se intampla in lumea asta, porcarii dinastea se fac de zeci de ani...
  12. Salut, nu imi dau seama ce incerci sa faci, sa faci protect cu Enigma si tot folosind Enigma sa adaugi licentiere pe acel binar? Nu pare nimic in neregula, nu am idee ce face exact Enigma.
  13. Wtf? Chiar inca merge treaba asta cu ransomware? Chiar platesc firmele/oamenii?
  14. Nytro

    Salut!

    Nu mai posta coduri periculoase pe forum, te rog
  15. Cred ca ideal ar fi sa fie decente si din punctul de vedere al calitatii, sa creasca numarul de clienti. Ca idei de promovare, ce ar merge? Instagram?
  16. Ar fi practic ceva la care sa nu dureze 2 luni livrarea. Dar si pretul difera. Deci solutia e pe marketing su SEO.
  17. Mai merge dropshipping-ul asta?
  18. "cu privire la un atac cibernetic asupra infrastructurii SCADA" - Daca sunt atat de destepti sa lase SCADA accesibile de pe net isi merita soarta.
  19. Da, e mai practic sa te ajute persoana de la care ai cumparat decat sa gasesti tu vreun 2FA bypass...
  20. 01.03.2021 - We say "Happy anniversary" and ask for an update Nice
  21. Nytro

    Salut

    Practic, nu prea. Teoretic da. Cauta despre atacuri pe SS7, gen Fake SS7 si altele. Poate doar daca lucrezi la operatori GSM si ai acces important pe acolo.
  22. Nytro

    Salut!

    Nu ajuta la nimic
  23. Nytro

    RSTCon #3 - CTF

    CTF writeups: https://hiumee.com/posts/RSTCON-3/
  24. Learn everything from the course! It should be enough is some other skills are present (e.g. code review).
×
×
  • Create New...