import
struct
from
qiling
import
*
from
qiling.os.mapper
import
QlFsMappedObject
from
qiling.const
import
QL_INTERCEPT
from
ctfbox
import
printHex
def
challenge1(ql: Qiling):
ql.mem.
map
(
0x1000
,
0x1000
, info
=
'[challenge1]'
)
ql.mem.write(
0x1337
, ql.pack16(
1337
))
def
hook_uname_on_exit(ql: Qiling,
*
args):
rdi
=
ql.arch.regs.rdi
ql.mem.write(rdi, b
'QilingOS\x00'
)
ql.mem.write(rdi
+
65
*
3
, b
'ChallengeStart\x00'
)
def
challenge2(ql: Qiling):
ql.os.set_syscall(
'uname'
, hook_uname_on_exit, QL_INTERCEPT.EXIT)
class
Fake_urandom(QlFsMappedObject):
def
read(
self
, expected_len):
if
expected_len
=
=
1
:
return
b
'\x23'
else
:
return
b
'\x00'
*
expected_len
def
close(
self
):
return
0
def
hook_getrandom(ql: Qiling, buf, buflen, flags,
*
args):
ql.mem.write(buf, b
'\x00'
*
buflen)
ql.os.set_syscall_return(
0
)
def
challenge3(ql: Qiling):
ql.add_fs_mapper(
'/dev/urandom'
, Fake_urandom())
ql.os.set_syscall(
'getrandom'
, hook_getrandom)
def
enter_forbidden_loop_hook(ql: Qiling):
ql.arch.regs.eax
=
1
def
challenge4(ql: Qiling):
base
=
ql.mem.get_lib_base(ql.path)
hook_addr
=
base
+
0xE43
ql.hook_address(enter_forbidden_loop_hook, hook_addr)
def
hook_rand(ql: Qiling):
ql.arch.regs.rax
=
0
def
challenge5(ql: Qiling):
ql.os.set_api(
'rand'
, hook_rand)
def
hook_while_true(ql: Qiling):
ql.arch.regs.rax
=
0
def
challenge6(ql: Qiling):
base
=
ql.mem.get_lib_base(ql.path)
ql.hook_address(hook_while_true, base
+
0xF16
)
def
modify_arg(ql: Qiling):
ql.arch.regs.edi
=
0
def
i_slept_i_faked_it(ql: Qiling):
return
def
hook_nanosleep(ql: Qiling,
*
args,
*
*
kwargs):
return
def
challenge7(ql: Qiling):
ql.os.set_syscall(
'nanosleep'
, hook_nanosleep)
def
hook_struct(ql: Qiling):
heap_struct_addr
=
ql.unpack64(ql.mem.read(ql.reg.rbp
-
8
,
8
))
heap_struct
=
ql.mem.read(heap_struct_addr,
24
)
printHex(heap_struct)
_, _, check_addr
=
struct.unpack(
'QQQ'
, heap_struct)
ql.mem.write(check_addr, b
'\x01'
)
def
search_mem_to_find_struct(ql: Qiling):
MAGIC
=
ql.pack64(
0x3DFCD6EA00000539
)
candidate_addrs
=
ql.mem.search(MAGIC)
for
addr
in
candidate_addrs:
stru_addr
=
addr
-
8
stru
=
ql.mem.read(stru_addr,
24
)
string_addr, _, check_addr
=
struct.unpack(
'QQQ'
, stru)
if
ql.mem.string(string_addr)
=
=
'Random data'
:
ql.mem.write(check_addr, b
'\x01'
)
break
def
challenge8(ql: Qiling):
base
=
ql.mem.get_lib_base(ql.path)
ql.hook_address(search_mem_to_find_struct, base
+
0xFB5
)
def
fake_tolower(ql: Qiling):
return
def
challenge9(ql: Qiling):
ql.os.set_api(
'tolower'
, fake_tolower)
class
Fake_cmdline(QlFsMappedObject):
def
read(
self
, expected_len):
return
b
'qilinglab'
def
close(
self
):
return
0
def
challenge10(ql: Qiling):
ql.add_fs_mapper(
'/proc/self/cmdline'
, Fake_cmdline())
def
hook_cpuid(ql: Qiling, address, size):
if
ql.mem.read(address, size)
=
=
b
'\x0F\xA2'
:
regs
=
ql.arch.regs
regs.ebx
=
0x696C6951
regs.ecx
=
0x614C676E
regs.edx
=
0x20202062
regs.rip
+
=
2
def
challenge11(ql: Qiling):
begin, end
=
0
,
0
for
info
in
ql.mem.map_info:
print
(info)
if
info[
2
]
=
=
5
and
'qilinglab-x86_64'
in
info[
3
]:
begin, end
=
info[:
2
]
print
(f
"{begin} -> {end}"
)
ql.hook_code(hook_cpuid, begin
=
begin, end
=
end)
if
__name__
=
=
'__main__'
:
path
=
[
'qilinglab-x86_64'
]
rootfs
=
"./qiling/examples/rootfs/x8664_linux"
ql
=
Qiling(path, rootfs)
challenge1(ql)
challenge2(ql)
challenge3(ql)
challenge4(ql)
challenge5(ql)
challenge6(ql)
challenge7(ql)
challenge8(ql)
challenge9(ql)
challenge10(ql)
challenge11(ql)
ql.verbose
=
0
ql.run()