What's new arround internet

Last one

Src Date (GMT) Titre Description Tags Stories Notes
Blog.webp 2021-03-18 17:07:36 BSidesSF CTF 2021 Author writeup: glitter-printer, a buffer underflow where you modify the actual code (lien direct) Hi Everybody! This is going to be a challenge-author writeup for the Glitter Printer challenge from BSides San Francisco 2021. First, a bit of history: the original idea I had behind Glitter Printer was to make a video game challenge involving cartridge-swap, where I'd write a handful of simple video games in 100% x86 code with no imports or anything (like an old fashioned cartridge game), and the player could swap between them without memory being re-initialized. Folks used to do this sorta thing on NES, and maybe I'll use it in a future challenge, but I decided to make this a bit simpler. While experimenting with writing libraries without libc, I realized just how much work it was going to be to write a bunch of games, and decided to simplify. My next ide was to write a “driver” type thing, where a blob of code is loaded into +RWX memory and the player could go wild on it. The the name Glitter Printer came across my radar, I don't even remember why, and that gave me the idea to do an LPR server. That's quite the background! The code So I don't know if anybody actually noticed, but I implemented a good chunk of the Line Printer (LPR) RFC correctly. Well, I tried to anyways, I didn't actually test it with a real client. The hard part was introducing a realistic-looking vulnerability - in many of my CTF challenges, the vuln comes naturally. So naturally, in fact, that I often don't even need to plan it in advance! I ended up settling on an integer underflow. If you look at the source (specifically, core.c), you can see that the main loop reads a single byte, then performs an action accordingly: void _start(queue_t *queues) { while(1) { char command = read_byte(STDIN); if(command == 1) { print_waiting_jobs(); } else if(command == 2) { receive_job(queues); } else if(command == 3) { queue_state_list(queues, 0); } else if(command == 4) { queue_state_list(queues, 1); } else if(command == 5) { // 05 Queue SP Agent SP List LF - Remove jobs } else { exit(6); } } } As part of several commands (such as receive_job()), an ASCII number is sent to choose a queue to operate on. The queue number isn't a byte (like “\x01”), it's a number like “123” that needs to be parsed. And by the way, this is still how LPR actually works! Here's the code I used for parsing numbers.. I'm pretty sure I just grabbed this from Stack Overflow: int read_number(char *terminator) { int result = 0; while(1) { // Read a single byte char buffer = read_byte(); // If it's not a valid byte, we're done (and we consume the terminator) if(buffer < '0' || buffer > '9') { Vulnerability Guideline ★★★★
Last update at: 2024-05-19 23:08:19
See our sources.
My email:

To see everything: Our RSS (filtrered) Twitter