One Article Review

Accueil - L'article:
Source Blog.webp SkullSecurity
Identifiant 8300182
Date de publication 2021-03-18 17:07:36 (vue: 2023-01-11 16:56:04)
Titre BSidesSF CTF 2021 Author writeup: glitter-printer, a buffer underflow where you modify the actual code
Texte 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') {
Envoyé Oui
Condensat *buf *queues *terminator +rwx +wx /sploit 0000 00000000 0x00000000 0x02eb 0x11 0x4 0x79c 0x7fffffff 0x80000000 0x80; 0xffffffff 100 11b1 19256 2021 2eb 30c9 373f4c45 4000 4008 4010 4018 4020 4028 4030 4038 4040 4048 4050 4058 4060 4068 4070 4078 4080 4088 4090 4098 40a0 40a8 4990 4b38 515 5190 5690 5990 65536 6a00 798 9049 9051 9056 9059 able about above absolute accordingly: across action action: active actual actually add adding additional address addresses adds advance after again agent all alone already also always analyze and another any anybody anything anytime anyways anywhere app application arbitrary are arg1 arg2 arg3 argument arguments around arrive artificially ascii asm assembly attempts attribute author automatically b111 b32 background bad based basically be: because been beginning behind being below bet between big bigger biggest binary bit blob block blocks blow broken bsides bsidessf buf buffer buffer; build bunch but byte bytes c930 calculates call call; called calls came can cancel care cartridge case certain chain challenge challenge/ challenges change change: changes char check choose chose chunk chunks clear client code comes command commands comment concept concepts conclusion consume container contains core correctly could count covered cram creating ctf current current: data days dec decided decrement decrements desired: destroys detail didn directly docker does doesn doing don done during e1ff each earlier earlier: eax eb02 ebp ebp+12 ebp+16 ebp+8 ebp; ebx ebx; echo ecx edx effectively efficient either else empty end endeavour ended enjoyed enough esi esp; even eventually everybody everything everything: exceptionally executable execute executes execution exit experimenting exploit exploit: fact familiar fashioned fast few ff7885c7 ff78d0ff ffd0 ffe1 field figures filled finally find finished first fit flexible folder folks for francisco from full function function: future game games gave get gets given glitter going gonna good got grab grabbed hacker hackin had handful handling happens hard has have helper helps here hex higher history: hopefully how ide idea identified implemented implies imports increment incremental incremented incrementing increments information initialized input instead instruction instructions int integer integers intended interesting into introducing invoking involving isn it: its itself jmp job jobs jobs; jump just keep keeps kinda know larger later leads least leaves leaving left length less let leverage libc libraries lieu like limitation limited limiting line list literally loaded loader long longer look looking looks loop lot low lower lpr main make many match math maybe means memory mentioned menu message migghhhhht mildly mind missing mix modified modify more mov move much multiple myself naked name naturally ndisasm neat need needed needs negative nes net never new next nicely nop not noticed now nudge number numbers offset often old oldschool once one online only operate option original other our out over overflow overflow: overview overwrite own pack parameter parameters parsed parsing part particular pass past payload performs pick plan planned play player point points pop positive prepared pretty primitive print printer probably problems process program proud pun push pushed put queue queued queued; queues queuing quite radar read reading reads real realistic realized realizing really reasonably recall receive redirect register registers remember remove repeat replace replaces request/response requests require rest result result; ret; retrospect return returning returns rfc right rop round ruby run runme runs san saw scratch second section see send sending sent server set sets setting settling several shellcode shellcode: short should simple simpler simplify simultaneously since single situation size slightly slowly small smartly solutions some something somewhat sorta source special specifically speed stack start starting state stdin still stone stop store stored straight struct structure style sub subtract such summary super supposed sure swap sys syscall
Tags Vulnerability Guideline
Stories
Notes ★★★★
Move


L'article ne semble pas avoir été repris aprés sa publication.


L'article ne semble pas avoir été repris sur un précédent.
My email: