What's new arround internet

Last one

Src Date (GMT) Titre Description Tags Stories Notes
Blog.webp 2024-05-05 19:59:48 BSidesSF 2024 Writeups: No Tools (A puzzling Bash challenge) (lien direct) pas d'outils est un défi terminal assez simple, quelque chose pour les nouveaux joueursmâcher. Je soupçonne qu'il existe plusieurs façons différentes de le résoudre, mais l'idée de base est de lire un fichier en utilisant uniquement des fonctions intégrées de sh . Je l'ai personnellement résolu avec le lire intégré: $ lire file= "nv"> $ drapeau Ctf { where-are-mon-tools } Une autre solution que mon co-organisateur a développée a utilisé Exec : $ exec Tool Technical ★★★★
Blog.webp 2024-05-05 19:59:43 BSidesSF 2024 Writeups: Can\'t Give In (CGI exploitation) (lien direct) The premise of the three challenges cant-give-in, cant-give-in-secure, and cant-give-in-securer are to learn how to exploit and debug compiled code that\'s loaded as a CGI module. You might think that\'s unlikely, but a surprising number of enterprise applications (usually hardware stuff - firewalls, network “security” appliances, stuff like that) is powered by CGI scripts. You never know! This challenge was inspired by one of my co-workers at GreyNoise asking how to debug a CGI script. I thought it\'d be cool to make a multi-challenge series in case others didn\'t know! This write-up is intended to be fairly detailed, to help new players understand their first stack overflow! Part 1: cant-give-in The vulnerability First, let\'s look at the vuln! All three challenges have pretty similar vulnerabilities, but here\'s what the first looks like: char *strlength = getenv("CONTENT_LENGTH"); if(!strlength) { printf("ERROR: Please send data!"); exit(0); } int length = atoi(strlength); read(fileno(stdin), data, length); if(!strcmp(data, "password=MyCoolPassword")) { printf("SUCCESS: authenticated successfully!"); } else { printf("ERROR: Login failed!"); } The way CGI works - a fact that I\'d forgotten since learning Perl like 20 years ago - is that the headers are processed by Apache and sent to the script as environmental variables, and the body (ie, POST data) is sent on stdin. In that script, we read the Content-Length from a variable, then read that many bytes of the POST body into a static buffer. That\'s a fairly standard buffer overflow, with the twist that it\'s in a CGI application! We can demonstrate the issue pretty easily by running the CGI directly (I\'m using dd to produce 200 characters without cluttering up the screen): Tool Vulnerability Threat Technical ★★★★
Blog.webp 2024-05-05 00:00:00 BSIDESSF 2024 Écritures: ne peut pas donner (exploitation CGI)
BSidesSF 2024 Writeups: Can\\'t Give In (CGI exploitation)
(lien direct)
The premise of the three challenges cant-give-in, cant-give-in-secure, and cant-give-in-securer are to learn how to exploit and debug compiled code that\'s loaded as a CGI module. You might think that\'s unlikely, but a surprising number of enterprise applications (usually hardware stuff - firewalls, network “security” appliances, stuff like that) is powered by CGI scripts. You never know! This challenge was inspired by one of my co-workers at GreyNoise asking how to debug a CGI script. I thought it\'d be cool to make a multi-challenge series in case others didn\'t know! This write-up is intended to be fairly detailed, to help new players understand their first stack overflow! Part 1: cant-give-in The vulnerability First, let\'s look at the vuln! All three challenges have pretty similar vulnerabilities, but here\'s what the first looks like: char *strlength = getenv("CONTENT_LENGTH"); if(!strlength) { printf("ERROR: Please send data!"); exit(0); } int length = atoi(strlength); read(fileno(stdin), data, length); if(!strcmp(data, "password=MyCoolPassword")) { printf("SUCCESS: authenticated successfully!"); } else { printf("ERROR: Login failed!"); } The way CGI works - a fact that I\'d forgotten since learning Perl like 20 years ago - is that the headers are processed by Apache and sent to the script as environmental variables, and the body (ie, POST data) is sent on stdin. In that script, we read the Content-Length from a variable, then read that many bytes of the POST body into a static buffer. That\'s a fairly standard buffer overflow, with the twist that it\'s in a CGI application! We can demonstrate the issue pretty easily by running the CGI directly (I\'m using dd to produce 200 characters without cluttering up the screen): Tool Vulnerability Threat ★★★
Blog.webp 2024-05-05 00:00:00 BSIDESSF 2024 Écritures: pas d'outils (un défi de bash perplexe)
BSidesSF 2024 Writeups: No Tools (A puzzling Bash challenge)
(lien direct)
pas d'outils est un défi terminal assez simple, quelque chose pour les nouveaux joueursmâcher. Je soupçonne qu'il existe plusieurs façons différentes de le résoudre, mais l'idée de base est de lire un fichier en utilisant uniquement des fonctions intégrées de sh . Je l'ai personnellement résolu avec le lire intégré: $ lire file= "nv"> $ drapeau Ctf { where-are-mon-tools } Une autre solution que mon co-organisateur a développée a utilisé Exec : $ exec Tool ★★
Blog.webp 2023-06-27 16:14:05 Comment faire: inverser et déboguer les modules ISAPI
How-to: Reversing and debugging ISAPI modules
(lien direct)
Récemment, j'ai eu le privilège de Écrivez une analyse détaillée de CVE-2023-34362 , qui est une série de plusieurs vulnérabilités dans le transfert de fichiers Moveit application qui mène à l'exécution du code distant.L'un des nombreux Les vulnérabilités impliquaient un module ISAPI - en particulier, le moveItapi.dll Extension ISAPI.L'une des nombreuses vulnérabilités qui comprenaient le mouvement RCE était un problème d'injection d'en-tête, où les en-têtes analysés de la demande ISAPI différemment de l'application .NET.Ce point va creuser dans la façon de Analyser et insensier un service basé sur ISAPI! ce n'était pas la première fois du passé récent, je devais travailler sur quelque chose écrit comme un module Isapi, et chaque fois que je me sens comme je dois commencer plus et rappelez-vous comment il est censé fonctionner.Cette fois, je pensais que je combinerais Mes notes à la fermeture avec une Google, et essayez d'écrire quelque chose que je (et autres) peuvent utiliser à l'avenir.En tant que tel, ce sera une intro rapide à Applications ISAPI sous l'angle qui compte pour moi - comment insensé ingénieur et les déboguer! Je veux préfacer ceci: je ne suis pas un développeur Windows, et je n'ai jamais exécuté un IIS Server exprès.Cela signifie que j'approche cela avec une force brute ignorance!Je n'ai pas beaucoup de contexte d'arrière-plan et je ne connais pas le bon Terminologie pour beaucoup de ces choses.Au lieu de cela, je vais traiter ce sont DLL typiques des applications typiques et les approcher en tant que telles. Qu'est-ce que Isapi? Vous pouvez considérer Isapi comme l'équivalent iis \\ aux modules apache ou nginx - que est, ce sont des binaires écrits dans une langue de bas niveau comme C, C ++ ou Delphi (Non vraiment, la page Wikipedia répertorie Delphi !) qui sont chargés dans l'espace mémoire IIS en tant que bibliothèques partagées.Puisqu'ils \\ 're Code de bas niveau, ils peuvent souffrir de problèmes couramment trouvés dans le code de bas niveau, comme la corruption de la mémoire.Vous avez probablement utilisé ISAPI fourni par Microsoft modules sans s'en rendre compte - ils sont utilisés dans les coulisses pour .aspx Applications, par exemple! J'ai trouvé cet aperçu utile d'Isapi , qui relie les autres pages que je mentionne ci-dessous.Il a un avertissement de dépréciation, Mais afaict pas de page de remplacement, donc je peux dire qu'elle existait en juin / 2023 au cas où Vous devez utiliser les archives Internet pour le récupérer. Selon l'application, les modules ISAPI peuvent soit gérer les demandes entrantes par eux-mêmes (« Extensions Isapi ») ou modifiez les demandes en route vers leur maître dernier (« filtres Isapi »). Ils sont tous les deux implémentés en tant que fichiers .dll, mais vous pouvez en distinguer un de la Autre en regardant la liste des fonctions exportées (dans un fichier .dll, un «Fonction exportée» est une fonction qui peut être appelée par le service qui charge le fichier .dll).Vous pouvez afficher les exportations dans IDA Pro ou Ghidra ou d'autres outils, mais pour Ces exemples, j'ai trouvé un outil CLI simple écrit dans Ruby Tool appelé Pedump , que vous pouvez installer via la commande RubyGems Gem Installer Pedump . Voici les fo Tool ★★
Blog.webp 2023-05-02 22:37:26 Astuces d'ingénierie inverse: identifier les protocoles de réseau opaques
Reverse engineering tricks: identifying opaque network protocols
(lien direct)
Lately, I\'ve been reverse engineering a reasonably complex network protocol, and I ran into a mystery - while the protocol is generally an unencrypted binary protocol, one of the messages was large and random. In an otherwise unencrypted protocol, why is one of the messages unreadable? It took me a few hours to accomplish what should have been a couple minutes of effort, and I wanted to share the trick I ultimately used! I\'m going to be intentionally vague on the software, and even modify a few things to make it harder to identify; I\'ll probably publish a lot more on my work blog once I\'m finished this project! Binary protocols Let\'s take a look at the binary protocol! If you\'re familiar with protocols and just want to see the “good stuff”, feel free to skip down to the next header. A “binary protocol” is a network protocol that uses unprintable characters (as opposed to a protocol like HTTP, which is something you can type on your keyboard). Often, you\'ll use a tool like Wireshark to grab a sample of network traffic (a “packet capture”, or “PCAP”) and, if it\'s not encrypted, you can start drawing conclusions about what the client and server expect. In a PCAP, you might see requests / responses that look like this: Outbound: 08 00 00 00 2c 00 00 00 ....,... Inbound: 40 00 00 00 2c 00 00 00 55 53 52 53 05 00 00 00 @...,... USRS.... 2c 00 00 00 02 00 00 00 55 38 f9 ed 21 59 47 f5 ,....... U8..!YG. 8f 9d 43 59 33 5c 2e 92 00 00 00 00 c4 54 f4 01 ..CY3\.. .....T.. 8d b4 43 e7 9e 9f ea db 4e 76 1a 7a 00 00 00 00 ..C..... Nv.z.... I don\'t want to get too buried in the weeds on how this protocol actually works, but when you work with unknown binary protocols a lot, certain things start to stand out. First, let\'s talk about endianness! The way integers are encoded into protocols vary based on the protocol, but a very common way to encode a 4-byte (32-bit) number is either big endian (8 => 00 00 00 08) or little endian (8 => 08 00 00 00). There are historic reasons both exist, and both are common to see, but based on the structure of those messages, we can guess that the first 4 bytes are either a big-endian integer with the value 0x08000000 or a little-endian integer with the value 0x00000008. The latter seems more likely, because that would make a great length value; speaking of lengths… Second, let\'s talk about TCP - TCP is a streaming protocol, which means there is no guarantee that if you send 100 bytes, the receiver will receive those 100 bytes all at once. You ARE guaranteed that if you received data, it\'ll be the correct bytes in the correct order; however, you might get 50 now and 50 later, or 99 now and 1 later, or maybe the next 50 bytes will be attached and you\'ll get 150 bytes all at once. As a result, TCP-based services nearly always encode a length value near the start, allowing protocols to unambiguously receive complete messages. Because of all that, one of the first things I do when approaching a new protocol is try to identify the length field. In this case, you\'ll note that the packet that starts with 0x08 is 8 bytes long, and the packet that starts with 0x40 is 0x40 bytes long. That looks promising! And, as it turns out, is correct. Once we have a length field, the next thing to consider is how the client and server multiplex messages. In an HTTP protocol, there\'s a URI, which tells the server where to direct the request. In a binary protocol, there isn\'t typical Tool ★★★
Blog.webp 2023-04-24 00:08:44 BSIDESSF 2023 Écritures: Too-Latte (exploitation Java de difficulté moyenne)
BSidesSF 2023 Writeups: too-latte (medium-difficulty Java exploitation)
(lien direct)
too-latte is a challenge I wrote based on CVE-2023-0669, which is an unsafe deserialization vulnerability in Fortra\'s GoAnywhere MFT software. I modeled all the vulnerable code off, as much as I could, that codebase. It\'s obviously themed quite differently. Write-up If you use a tool like jadx to unpack the servlets, you\'ll find, through some layers of indirection, this code in TokenWorker.java (that operates on the token parameter): public static String unbundle(String token, KeyConfig keyConfig) throws Exception { token = token.substring(0, token.indexOf("$")); return new String(decompress(verify(decrypt(decode(token.getBytes(StandardCharsets.UTF_8)), keyConfig.getVersion()), keyConfig)), StandardCharsets.UTF_8); } The decode function decodes the token parameter from Base64. The decrypt function decrypts the token with a static key. The actual decryption code is under several layers of indirection, because Java is Java, but the TokenEncryptor class has a key, IV, and algorithm: private static final byte[] IV = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 Tool Vulnerability ★★
Blog.webp 2023-04-24 00:08:44 BSIDESSF 2023 Écritures: ROP TEPTING ZOO (Défi de l'éducation!)
BSidesSF 2023 Writeups: ROP Petting Zoo (educational challenge!)
(lien direct)
ROP Petting Zoo is a challenge designed to teach the principles of return-oriented programming. It\'s mostly written in Javascript, with a backend powered by a Ruby web server, along with a tool I wrote called Mandrake. Source code is shared between the three parts of the challenge, and is available here. Mandrake is a debugger / tracer I wrote that executes a binary and traces all code run between two points. It will show registers, memory, all the good stuff. ROP Petting Zoo is kind of a wrapper around that. Basically, you have a list of potential ROP gadgets and libc calls. You build a stack from all the ROP gadgets, hit Execute!, and the harness will return to the first address on the stack. Everything is running forreal in a container, so you get to see what would actually happen if this is a real exploit! The challenges are very guided / on-rails, with tutorials that show the exact steps you will need to take, but here are the solutions I wrote. It\'s helpful to remember that when a function is called, the arguments are, in order, passed in the registers rdi, rsi, rdx, and rcx. Level 1 print_flag() -> Immediately return to print_flag pop rdi / ret -> Pop the next value into register rdi 0 -> This is what\'s popped into rdi exit -> Return to exit(rdi) aka exit(0) Level 2 return_flag() -> Returns the flag in rax mov rdi, rax / ret -> Moves the flag pointer into rdi puts -> Return to puts(rdi) or puts(flag) pop rdi / ret -> Pop the next value into rdi 0 -> This is what\'s popped into rdi exit -> Return to exit(rdi) aka exit(0) Level 3 This part unfortunately ran a lot slower than I\'d intended, but hopefully it\'s educational enough: write_flag_to_file() -> Writes the flag to a file, returns the name in rax mov rdi, rax / ret -> Moves the filename to rdi, the first param Tool ★★★
Blog.webp 2023-01-23 20:14:17 Blast from the Past: How Attackers Compromised Zimbra With a Patched Vulnerability (lien direct) Last year, I worked on a vulnerability in Zimbra (CVE-2022-41352 - my AttackerKB analysis for Rapid7) that turned out to be a new(-ish) exploit path for a really old bug in cpio - CVE-2015-1194. But that was patched in 2019, so what happened? (I posted this as a tweet-thread awhile back, but I decided to flesh it out and make it into a full blog post!) cpio is an archive tool commonly used for system-level stuff (firmware images and such). It can also extract other format, like .tar, which we'll use since it's more familiar. cpio has a flag (--no-absolute-filenames), off by default, that purports to prevent writing files outside of the target directory. That's handy when, for example, extracting untrusted files with Amavis (like Zimbra does). The problem is, symbolic links can point to absolute paths, and therefore, even with --no-absolute-filenames, there was no safe way to extract an untrusted archive (outside of using a chroot environment or something similar, which they really ought to do). Much later, in 2019, the cpio team released cpio version 2.13, which includes a patch for CVE-2015-1194, with unit tests and everything. Some (not all) modern OSes include the patched version of cpio, which should be the end of the story, but it's not! I'm currently writing this on Fedora 35, so let's try exploiting it. We can confirm that the version of cpio installed with the OS is, indeed, the fixed version: ron@fedora ~ $ cpio --version cpio (GNU cpio) 2.13 Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Phil Nelson, David MacKenzie, John Oleynick, and Sergey Poznyakoff. That means that we shouldn't be able to use symlinks to write outside of the target directory, so let's create a .tar file that includes a symlink and a file written through that symlink (this is largely copied from this mailing list post: ron@fedora ~ $ mkdir cpiotest ron@fedora ~ $ cd cpiotest ron@fedora ~/cpiotest $ ln -s /tmp/ ./demo ron@fedora ~/cpiotest $ echo 'hello' > demo/imafile ron@fedora ~/cpiotest $ tar -cvf demo.tar demo demo/imafile demo demo/imafile ron@fedora ~/cpiotest $ Tool Vulnerability APT 17 ★★★★
Blog.webp 2023-01-10 18:02:16 GDB Tricks: Tricking the Application into Generating Test Data (lien direct) While reverse engineering a Linux binary, I ran into a fairly common situation: I wanted to understand how a decompression function works, but I didn't have compressed data to test with. In this blog, I'll look at how to we can manipulate the instruction pointer in the GNU debugger (gdb) to trick the software into generating test data for us! I posted this on Mastodon awhile back, but I cleaned it up and expanded it a bit to make it a full blog post. I did this work in the context of my research team at Rapid7 - you can check out all of our work on the Rapid7 Research Blog (secret rss link!)! Anyway, while working on an application, I ran into a function called LZ4_decompress_safe. I wanted to learn how it worked, but EVERYTHING I tried to decompress returned an error - even test data generated by a legitimtae LZ4 library! I'm not sure why it didn't work - maybe they modified it? Maybe it's a different version? Maybe the lz4 CLI tool has more or less file headers? - Dunno! But let's make the application create its own test data! I know (from Googling) that the signatures for the decompress and compress functions are: int __fastcall LZ4_decompress_safe(const char *src, char *dst, int compressedSize, int dstCapacity) int __fastcall LZ4_compress(const char *src, char *dst, int srcSize, int dstCapacity) The calling code looks like: mov ecx, dword ptr [rsp+80h+capacity] ; dstCapacity mov edx, dword ptr [rsp+88h+size] ; compressedSize mov rsi, cs:buffer ; dst mov rdi, [rsp+88h+out_buffer] ; src call LZ4_decompress_safe ; I can't figure out how to get this to work :( The functions have the exact same signature, which is super handy! I put a breakpoint on the function LZ4_decompress_safe, which will stop execution when the application attempts to decompress data: (gdb) b *LZ4_decompress_safe Breakpoint 4 at 0x40bc40 (gdb) run Starting program: [...] Then I sent a message to the server with the “this message is compressed!” flag set, but with uncompressed data (specifically, the contents of /etc/passwd - my go-to for longer test data). So basically, the server will think the data is compressed, but it's actually not. When the service tries to decompress the packet, it'll hit the breakpoint: (gdb) run Starting program: [...] Breakpoint 4, 0x000000000040bc40 in LZ4_decompress_safe () The calling convention on x64 Linux means that the first three arguments are placed in the rdi, rsi, and rdx registers. We want the dst buffer, which is the second argument, so we print out rsi: (gdb) print/x $rsi $63 = 0x6820f0 Tool ★★★★
Blog.webp 2022-06-17 20:19:14 BSidesSF 2022 Writeups: Tutorial Challenges (Shurdles, Loadit, Polyglot, NFT) (lien direct) Hey folks, This is my (Ron's / iagox86's) author writeups for the BSides San Francisco 2022 CTF. You can get the full source code for everything on github. Most have either a Dockerfile or instructions on how to run locally. Enjoy! Here are the four BSidesSF CTF blogs: shurdles1/2/3, loadit1/2/3, polyglot, and not-for-taking mod_ctfauth, refreshing turtle, guessme loca, reallyprettymundane Shurdles - Shellcode Hurdles The Shurdles challenges are loosely based on a challenge from last year, Hurdles, as well as a Holiday Hack Challenge 2021 challenge I wrote called Shellcode Primer. It uses a tool I wrote called Mandrake to instrument shellcode to tell the user what's going on. It's helpful for debugging, but even more helpful as a teaching tool! The difference between this and the Holiday Hack version was that this time, I didn't bother to sandbox it, so you could pop a shell and inspect the box. I'm curious if folks did that.. probably they couldn't damage anything, and there's no intellectual property to steal. :) I'm not going to write up the solutions, but I did include solutions in the repository. Although I don't work for Counter Hack anymore, a MUCH bigger version of this challenge that I wrote is included in the SANS NetWars version launching this year. It covers a huge amount, including how to write bind- and reverse-shell shellcode from scratch. It's super cool! Unfortunately, I don't think SANS is doing hybrid events anymore, but if you find yourself at a SANS event be sure to check out NetWars! Loadit - Learning how to use LD_PRELOAD I wanted to make a few challenges that can be solved with LD_PRELOAD, which is where loadit came from! These are designed to be tutorial-style, so I think the solutions mostly speak for themselves. One interesting tidbit is that the third loadit challenge requires some state to be kept - rand() needs to return several different values. I had a few folks ask me about that, so I'll show off my solution here: #include int rand(void) { int answers[] = { 20, 22, 12, 34, 56, 67 }; static int count = 0; return answers[count++]; } // Just for laziness unsigned int sleep(unsigned int seconds) { return 0; } I use the static variable type to keep track of how many times rand() has been called. When you declare something as static inside a function, it means that the variable is initialized the first time the function is called, but changes are maintained as if it's a global variable (at least conceptually - in reality, it's initialized when the program is loaded, even if the function is never called). Ironically, this solution actually has an overflow - the 7th time and onwards rand() is called, it will start manipulating random memory. Luckily, we know that'll never happen. :) Hack Tool ★★★★
Last update at: 2024-06-02 16:08:17
See our sources.
My email:

To see everything: Our RSS (filtrered) Twitter