Last active
January 25, 2023 18:14
-
-
Save h4x5p4c3/da447b85a59a5defa4b5747d949f0a03 to your computer and use it in GitHub Desktop.
solve script for QilingLab x86_64
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# https://www.shielder.it/blog/2021/07/qilinglab-release/ | |
from qiling import Qiling | |
from qiling.const import QL_VERBOSE | |
from qiling.os.mapper import QlFsMappedObject | |
import struct | |
def u8(inp): | |
return struct.unpack("<Q", inp) | |
def level1(ql): | |
ql.mem.map(0x1000, 0x1000) #hex(0x1337//4096*4096) | |
ql.mem.write(0x1337, ql.pack16(1337)) | |
def ql_syscall_uname(ql, address, *args, **kw): | |
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 level2(ql): | |
ql.set_syscall("uname", ql_syscall_uname) | |
#https://hackmd.io/@ziqiaokong/BkbGuCJND | |
class Fake_urandom(QlFsMappedObject): | |
def read(self, size): | |
if size == 1: | |
return b"\xff" | |
else: | |
return b"\x00" * size | |
def fstat(self): # syscall fstat will ignore it if return -1 | |
return -1 | |
def close(self): | |
return 0 | |
#ssize_t getrandom(void *buf, size_t buflen, unsigned int flags); | |
def ql_syscall_getrandom(ql, buf, buflen, flags,*args, **kw): | |
regreturn = None | |
try: | |
ql.mem.write(buf, b"\x00" * buflen) | |
regreturn = len(data) | |
except: | |
regreturn = -1 | |
def level3(ql): | |
ql.add_fs_mapper("/dev/urandom", Fake_urandom()) | |
ql.set_syscall("getrandom", ql_syscall_getrandom) | |
''' level4 | |
0x00000e40 mov eax, dword [var_8h] | |
0x00000e43 cmp dword [var_4h], eax | |
''' | |
def level4_sol(ql): | |
ql.mem.write((ql.reg.rax), b'\x01') | |
def level4(ql): | |
ql.hook_address(level4_sol, ql.base+0x154e40) | |
def level5(ql): | |
ql.reg.rax = 0 | |
ql.set_api('rand', level5) | |
def level6(ql): | |
ql.patch(ql.base + 0xf18, b"\x74") | |
def loop(ql): | |
ql.reg.al = 0 #test al,al | |
def level6(ql): | |
ql.hook_address(loop, ql.base+0x154f16) | |
def level7(ql): | |
ql.set_api('sleep', lambda seconds: 0) | |
def write_target(ql): | |
addr = ql.mem.read(ql.reg.rax, 0x18) | |
ql.mem.write(u8(addr[0x10:])[0], b'\x01') | |
def level8(ql): | |
ql.hook_address(write_target, ql.base+0x154fb5) | |
def level9(ql): | |
ql.reg.rax = ql.reg.rdi | |
ql.set_api("tolower", level9) | |
class Fake_cmdline(QlFsMappedObject): | |
def read(self, size): | |
return b"qilinglab" # fixed value for reading | |
def fstat(self): # syscall fstat will ignore it if return -1 | |
return -1 | |
def close(self): | |
return 0 | |
def level10(ql): | |
ql.add_fs_mapper("/proc/self/cmdline", Fake_cmdline()) | |
''' | |
mov DWORD PTR [rbp-0x30],esi | |
mov DWORD PTR [rbp-0x34],ecx | |
mov DWORD PTR [rbp-0x2c],eax | |
''' | |
def cpuid(ql): | |
ql.reg.rsi = 0x696C6951 | |
ql.reg.rcx = 0x614C676E | |
ql.reg.rax = 0x20202062 | |
def level11(ql): | |
ql.hook_address(cpuid, ql.base+0x155195) | |
def solve(path, rootfs, verbose): | |
ql = Qiling(path, rootfs, verbose=verbose) | |
ql.base = 0x555555400000 | |
level1(ql) | |
level2(ql) | |
level3(ql) | |
level4(ql) | |
level5(ql) | |
level6(ql) | |
level7(ql) | |
level8(ql) | |
level9(ql) | |
level10(ql) | |
level11(ql) | |
ql.run() | |
if __name__ == "__main__": | |
solve(["x86_64/qilinglab-x86_64"], "rootfs/x8664_linux", QL_VERBOSE.OFF) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment