Tags: reversing pwn 


[Link to original writeup](https://github.com/babaiserror/ctf/tree/main/%5B210813-16%5D%20ReallyAwesomeCTF%202021#dodgy-databases-pwnreversing-350-pts)

We're conveniently given the source code. Reading through it, a `User` struct consists of `name[USERNAME_LEN]; Role role;`; `USERNAME_LEN` is 20. There are three roles - `ROLE_USER`, `ROLE_ADMIN`, and `ROLE_GOD = 0xBEEFACAFE`. When `users_register_user` is called, if the `admin` is `ROLE_GOD`, then it will print out the flag. `user_create` creates a user by allocating memory on the heap.

The `main` function takes an input of `username` that is 30 characters long. Then, it creates an admin user; when it checks that there is no such user in the database as given in the input, it will `free(admin)`, `user_create(username)`, and `users_register_user(users, admin, user)`. Alright, we can overwrite our user's role because the struct has 20 characters for the name and the rest for the role, whereas our input string is 30 bytes. Moreover, `admin` is freed and used; it's a use-after-free. After freeing admin, the database conveniently creates a user, which is likely to create that user where the admin was previously at. Because of the first vulnerability, we can control the role of the admin and the user given as arguments for `users_register_user`; also, if the admin has the role `ROLE_GOD`, then it will spit out the flag.

$ echo -e 'AAAAAAAAAAAAAAAAAAAA\xfe\xca\xef\xbe' | nc 44340
Hi, welcome to my users database.
Please enter a user to register: ractf{w0w_1_w0nD3r_wH4t_free(admin)_d0e5}