Skip to content

Instantly share code, notes, and snippets.

@dark-lbp
Created July 23, 2021 13:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dark-lbp/e957b43fee6df67cece4a58ccef633ab to your computer and use it in GitHub Desktop.
Save dark-lbp/e957b43fee6df67cece4a58ccef633ab to your computer and use it in GitHub Desktop.
This is my solution to QilingLabs challenge
# !/usr/bin/env python3
# coding=utf-8
import sys
from qiling import *
from qiling.os.mapper import QlFsMappedObject
from qiling.const import QL_VERBOSE
base_address = 0x555555554000
def solve_challenge_2(ql, address, *args, **kw):
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')
# solve_challenge_2
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
class Fake_urandom(QlFsMappedObject):
def read(self, size):
if size == 1:
return b"\xFF"
else:
return b"\x01" * size
def fstat(self):
return -1
def close(self):
return 0
class Fake_cmdline(QlFsMappedObject):
def read(self, size):
return b"qilinglab"
def fstat(self):
return -1
def close(self):
return 0
def fake_getrandom(ql, buf, buflen, flags, *args, **kw):
data = None
regreturn = None
try:
data = b'\x01' * 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 solve_challenge_4(ql, *args, **kw):
if ql.reg.w1 == 0:
ql.reg.w1 = -2
if ql.reg.w1 == 1:
ql.reg.w1 = 0
return
def solve_challenge_5(ql, *args, **kw):
ql.reg.w0 = ql.reg.w1
return
def solve_challenge_6(ql, *args, **kw):
ql.reg.w0 = 0
return
def solve_challenge_7(ql, *args, **kw):
ql.reg.w0 = 0
return
def solve_challenge_8(ql, *args, **kw):
malloc_1_address = ql.stack_read(0x30 - 0x08)
target_address = ql.unpack64(ql.mem.read(malloc_1_address + 16, ql.pointersize))
ql.mem.write(target_address, ql.pack64(0x01))
return
def solve_challenge_9(ql, *args, **kw):
original_string = ql.mem.string(ql.reg.x1)
new_string = original_string.lower()
ql.mem.write(ql.reg.x1, new_string.encode('utf-8'))
return
def solve_challenge_11(ql, *args, **kw):
# TODO: Find another way to solve.
ql.reg.x1 = ql.reg.x0
return
def my_sandbox(path, rootfs):
ql = Qiling(path, rootfs,
log_file='./qilingLab_challenge.log',
# verbose=QL_VERBOSE.DEBUG,
# verbose=QL_VERBOSE.DISASM,
# verbose=QL_VERBOSE.DEFAULT,
verbose=QL_VERBOSE.OFF,
)
need_link_dirs = [
"/dev",
"/proc",
"/sys",
"/run"
]
for need_link_dir in need_link_dirs:
ql.add_fs_mapper(need_link_dir, need_link_dir)
# Challenge 1
ql.mem.map(0x00001000, 0x1000, info="Challenge 1")
ql.mem.write(0x1337, ql.pack32(1337))
# Challenge 2
ql.set_syscall("uname", solve_challenge_2)
# Challenge 3
ql.add_fs_mapper("/dev/urandom", Fake_urandom())
ql.set_syscall("getrandom", fake_getrandom)
# Challenge 4
ql.hook_address(solve_challenge_4, base_address + 0x0FE0)
# Challenge 5
ql.hook_address(solve_challenge_5, base_address + 0x1090)
# Challenge 6
ql.hook_address(solve_challenge_6, base_address + 0x001118)
# Challenge 7
ql.hook_address(solve_challenge_7, base_address + 0x1154)
# Challenge 8
ql.hook_address(solve_challenge_8, base_address + 0x011E0)
# Challenge 9
ql.hook_address(solve_challenge_9, base_address + 0x1234)
# Challenge 10
ql.add_fs_mapper("/proc/self/cmdline", Fake_cmdline())
# Challenge 11
# TODO: Find hot to edit CPUID in Qiling
ql.hook_address(solve_challenge_11, base_address + 0x1400)
ql.run()
if __name__ == "__main__":
my_sandbox(["qilinglab-aarch64"], "rootfs/arm64_linux")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment