Phonebook HTB Walkthrough

This post documents my process for solving the Phonebook box on Hack The Box. The box focuses on LDAP injection and brute-forcing credentials using knowledge of LDAP search/filter syntax. Solve I didn’t find any obvious attack vectors except for a DOM-based HTML injection. After checking a writeup, I learned the challenge was about LDAP injection—a topic I had little prior experience with. What is LDAP Injection? According to PayloadAllTheThings, LDAP Injection is a vulnerability that occurs when user-supplied input is used to construct LDAP queries without proper sanitization or escaping. ...

April 19, 2025 · Joon Kim

HackTheBox: You know 0xDiablos

Description This is one of the challenges of the beginner track in HackTheBox. I was given a binary with no source code. This indicated that I would need to use Ghidra to look at the decompiled source code. First, some checks on the binary: ─$ file ./vuln ./vuln: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=ab7f19bb67c16ae453d4959fba4e6841d930a6dd, for GNU/Linux 3.2.0, not stripped No defensive mechanisms are turned on for this challenge. ...

March 13, 2023 · Joon Kim

LA CTF - pwn: bot

Description I made a bot to automatically answer all of your questions. nc lac.tf 31180 My approach Again, the source code, its binary, and the Dockerfile were given. Looking at the sour code code: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(void) { setbuf(stdout, NULL); char input[64]; volatile int give_flag = 0; puts("hi, how can i help?"); gets(input); if (strcmp(input, "give me the flag") == 0) { puts("lol no"); } else if (strcmp(input, "please give me the flag") == 0) { puts("no"); } else if (strcmp(input, "help, i have no idea how to solve this") == 0) { puts("L"); } else if (strcmp(input, "may i have the flag?") == 0) { puts("not with that attitude"); } else if (strcmp(input, "please please please give me the flag") == 0) { puts("i'll consider it"); sleep(15); if (give_flag) { puts("ok here's your flag"); system("cat flag.txt"); } else { puts("no"); } } else { puts("sorry, i didn't understand your question"); exit(1); } } After looking at the source code, I noticed that there is a give_flag variable and a buffer that we can overflow since the user input is received with gets(). Unlike the previous challenge I worked on, give_flag variable would always be located after the buffer input so we won’t be able to modify the value of give_flag this time. ...

February 14, 2023 · Joon Kim

LA CTF - pwn: gatekeep

Description If I gaslight you enough, you won’t be able to get my flag! :) nc lac.tf 31121 Note: The attached binary is the exact same as the one executing on the remote server. Source code The source code, its binary, and the Dockerfile were given. Looking at the sour code code: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> void print_flag() { char flag[256]; FILE* flagfile = fopen("flag.txt", "r"); if (flagfile == NULL) { puts("Cannot read flag.txt."); } else { fgets(flag, 256, flagfile); flag[strcspn(flag, "\n")] = '\0'; puts(flag); } } int check(){ char input[15]; char pass[10]; int access = 0; // If my password is random, I can gatekeep my flag! :) int data = open("/dev/urandom", O_RDONLY); if (data < 0) { printf("Can't access /dev/urandom.\n"); exit(1); } else { ssize_t result = read(data, pass, sizeof pass); if (result < 0) { printf("Data not received from /dev/urandom\n"); exit(1); } } close(data); printf("Password:\n"); gets(input); if(strcmp(input, pass)) { printf("I swore that was the right password ...\n"); } else { access = 1; } if(access) { printf("Guess I couldn't gaslight you!\n"); print_flag(); } } int main(){ setbuf(stdout, NULL); printf("If I gaslight you enough, you won't be able to guess my password! :)\n"); check(); return 0; } within check(), the password is being stored into a buffer using gets(). So I immediately thought that if I can control the return address of check() function to print_flag(), then we can get the flag. I checked the security properties of this binary by running pwn checksec --file=./gatekeep. ...

February 13, 2023 · Joon Kim

diceCTF 2023 - pwn: bop

PWN: bop I didn’t get to solve this by my own but there were many interesting things that I wasn’t aware of that can be used to solve this challenge. However, I wanted to talk about a few things I got to know during the struggle of working on this challenge. ret2dlresovle References: https://syst3mfailure.io/ret2dl_resolve https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve When a binary uses the shared libraries by dynamically linking to them, they do not have (or know) all the addresses for those library functions as the program starts up. They would resolve this issue (finding the addresses of those functions) when the functions are actually called. And the trick in this technique is to force the dynamic linker to resolve (or relocate) all the addresses of the library functions as the program starts. The pwntools python library allows us to choose the functions of our choice and and use them as their addresses were already resolved. ...

February 6, 2023 · Joon Kim

picoCTF 2020 - pwn: guessing game 1

References 1: https://mregraoncyber.com/picoctf-writeup-guessing-game-1/ 2: https://github.com/dannyc-dev/Building-the-ROP-Chain 3: https://cyb3rwhitesnake.medium.com/picoctf-guessing-game-1-pwn-bdc1c87016f9 Investigation file ./vuln vuln: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=94924855c14a01a7b5b38d9ed368fba31dfd4f60, not stripped This tells us that this executable contains all the libraries so we will be able to find a lot of gadgets if we have to find some. Checksec result Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) PIE is disabled and NX is enabled so we won’t be able to execute anything by putting things onto the stack. We will need to do some ROP. ...

December 27, 2022 · Joon Kim

BuckeyeCTF 2022 - pwn: ronin

References https://git.mbund.org/mbund/buckeyectf-2022/src/branch/main/writeups/ronin/ronin.md Decompiled code After decompiling the binary, I was able to take a look at those major funtions that make up this program. main(): int __cdecl main(int argc, const char **argv, const char **envp) { char shellcode_buffer[80]; // [rsp+0h] [rbp-50h] BYREF setvbuf(_bss_start, 0LL, 2, 0LL); scroll(txt); fgets(shellcode_buffer, 80, stdin); if ( !strncmp("Chase after it.", shellcode_buffer, 15uLL) ) { scroll(off_4028); chase(); } scroll(off_4030); return 0; } scroll(): ize_t __fastcall scroll(const char *addr_to_some_buffer) { __useconds_t v1; // eax size_t result; // rax char single_char; // [rsp+1Fh] [rbp-11h] size_t v4; // [rsp+20h] [rbp-10h] size_t i; // [rsp+28h] [rbp-8h] v4 = strlen(addr_to_some_buffer); for ( i = 0LL; ; ++i ) { result = i; if ( i >= v4 ) break; single_char = addr_to_some_buffer[i]; // printing a single char from the string array putchar(single_char); if ( single_char == 10 ) v1 = 1000000; else v1 = 50000; usleep(v1); } return result; } encounter(): ...

November 29, 2022 · Joon Kim

BuckeyeCTF 2022 - pwn: samurai

BuckeyeCTF 2022 - pwn: samurai What I didn’t understand was the program inserts ./n which can be represented as 0x2ea. This is just a part of the string that it gets printed out to STDOUT. How this program works is it reads in some input from STDIN using fgets. fgets inserts a newline char after reading everything in (EOF or newline). But, if the input that I pass in to overflow the buffer that does not end with a newline char, then it will keep going (or being read) until it overflows the variable I want to overwrite. It can still work but there is this line of code strcpy(&s[strlen(s) - 1], ".\n"); that puts a new line character at strlen(s) - 1. So, when I was naively giving an input that I would think should overwrite the variable, the last bit was always replaced by 2ea which is .\n. AH!!!!!!!!!!!! So, what we would want to do is at least have a newline char in the middle of the string so strcpy does not insert that .\n where the last bit is (this bit is still needed to be overwritten with some value to make the attack happen). ...

November 29, 2022 · Joon Kim