Qiling Lab Writeup
- 4 minsSo this was a long term plan as i wanted to learn about emulation and moreover qiling as this framework has so much capability as of it having less documention less people know about it but two days prior i found out a challenge named QilingLab – Release by @TheZero and @ShielderSec as of for now i solved 9/11 challenges for now 2 are left but would be done in the next update.
Here’s the script:
from qiling import *
from qiling.const import *
from capstone import *
import logging
from qiling.os.mapper import QlFsMappedObject
class Fake_urandom(QlFsMappedObject):
def read(self, size):
if size == 1:
return b"\xFF"
return b"\x00" * size # fixed value for reading /dev/urandom
def fstat(self):
return -1# syscall fstat will ignore it if return -1
def close(self):
return 0
class Fake_cmdline(QlFsMappedObject):
def read(self,size):
return b"qilinglab" # fixed value for reading /dev/urandom
def fstat(self):
return -1 # syscall fstat will ignore it if return -1
def close(self):
return 0
def getrandom_onexit(ql, buf, buflen, flags,*args, **kw):
data = None
regreturn = None
try:
data = b"\x00" * buflen
ql.mem.write(buf, data)
regreturn = len(data)
except:
regreturn = -1
if data:
ql.log.debug("getrandom() CONTENT:")
ql.log.debug(str(data))
return regreturn
def uname_onexit(ql,address ,arg1, arg2, arg3, *args):
print("exiting uname syscall and changing values accordingly!")
buf = b''
buf += b'QilingOS'.ljust(65, b'\x00')
buf += b'ql_vm'.ljust(65, b'\x00')
buf += b'99.0-RELEASE'.ljust(65, b'\x00')
buf += b'ChallengeStart'.ljust(65, b'\x00')
buf += b'ql_processor'.ljust(65, b'\x00')
buf += b''.ljust(65, b'\x00')
ql.mem.write(address, buf)
regreturn = 0
return regreturn
def solve_chall1(q1):
q1.mem.map(0x1000,0x1000)
q1.mem.write(0x1337,q1.pack16(1337))
def solve_chall3(q1):
q1.reg.eax = 1
def solve_chall5(q1):
q1.reg.eax = 0
def solve_chall6(q1):
q1.reg.al = 0
def solve_chall7(q1):
q1.reg.edi = 0
def solve_chall9(q1):
q1.reg.rdx = q1.reg.rax
if __name__ == '__main__':
q1 = Qiling(["qilinglab-x86_64"], "x8664_linux")
q1.mem.show_mapinfo()
solve_chall1(q1) #challenge 1
q1.set_syscall(63, uname_onexit) #challenge 2
q1.add_fs_mapper("/dev/urandom", Fake_urandom())
q1.set_syscall(318, getrandom_onexit)
q1.hook_address(solve_chall3, 0x555555554e43)
q1.hook_address(solve_chall5, 0x555555554e92)
q1.hook_address(solve_chall6, 0x555555554f16)
q1.hook_address(solve_chall7, 0x555555554f3c)
q1.hook_address(solve_chall9, 0x55555555504b)
q1.add_fs_mapper("/proc/self/cmdline", Fake_cmdline())
#two challenges still unsolved chall 8 chall 11
q1.run()
At some points I changed the registers by just putting the hook at the address rather than changing the function and it will be cleared by the next update.
Thank you so much @TheZero and @ShielderSec for these challenges : )