from
qiling
import
Qiling
from
qiling.const
import
QL_VERBOSE
from
qiling.const
import
QL_INTERCEPT
from
qiling.os.mapper
import
QlFsMappedObject
from
pwn
import
*
import
struct
def
challenge1(ql):
ql.mem.
map
(
0x1337
/
/
4096
*
4096
,
0x1000
)
ql.mem.write(
0x1337
, b
"\x39\x05"
)
def
my_uname_ret(ql ,
*
args):
rdi_value
=
ql.arch.regs.read(
"rdi"
)
ql.mem.write(rdi_value,b
'QilingOS\x00'
)
ql.mem.write(rdi_value
+
65
*
3
,b
'ChallengeStart\x00'
)
return
0
def
challenge2(ql):
ql.os.set_syscall(
"uname"
,my_uname_ret,QL_INTERCEPT.EXIT)
class
FakeUrandom(QlFsMappedObject):
def
read(
self
, size
=
int
)
-
> bytes:
if
size
=
=
0x20
:
return
b
"\x02"
*
32
return
b
"\x01"
def
fstat(
self
)
-
>
int
:
return
-
1
def
close(
self
)
-
>
int
:
return
0
def
my_getrandom_func(ql, buf, count:
int
, flag:
int
)
-
>
int
:
ql.mem.write(buf,b
'\x02'
*
count)
return
count
def
challenge3(ql):
ql.add_fs_mapper(r
'/dev/urandom'
, FakeUrandom())
ql.os.set_syscall(
"getrandom"
,my_getrandom_func,QL_INTERCEPT.CALL)
def
write_rax_1(ql):
ql.arch.regs.write(
"rax"
,
1
)
def
challenge4(ql):
base_addr
=
ql.mem.get_lib_base(ql.path)
if
base_addr
is
None
:
raise
ValueError(
"base_addr is not set correctly"
)
ql.hook_address(write_rax_1,base_addr
+
0x0E43
)
def
rand_rets(ql ,
*
args):
ql.arch.regs.write(
"rax"
,
0
)
def
win(ql: Qiling):
print
(
'[*] win'
)
def
challenge5(ql):
ql.os.set_api(
'rand'
, rand_rets)
return
def
write_rax_0(ql):
ql.arch.regs.write(
"rax"
,
0
)
def
challenge6(ql):
base_addr
=
ql.mem.get_lib_base(ql.path)
if
base_addr
is
None
:
raise
ValueError(
"base_addr is not set correctly"
)
ql.hook_address(write_rax_0,base_addr
+
0xF16
)
def
write_rdi_0(ql):
ql.arch.regs.write(
"rdi"
,
0
)
def
my_sleep(ql,
*
args):
return
def
challenge7(ql):
base_addr
=
ql.mem.get_lib_base(ql.path)
if
base_addr
is
None
:
raise
ValueError(
"base_addr is not set correctly"
)
ql.hook_address(write_rdi_0,base_addr
+
0x00F3C
)
def
search_mem(ql):
MAGIC
=
0x3DFCD6EA00000539
struct_address
=
ql.mem.search(p64(MAGIC))
if
not
struct_address
or
len
(struct_address) <
1
:
raise
ValueError(
"struct_address is not properly initialized"
)
mem_value1, mem_value2 ,mem_value3
=
struct.unpack(
"QQQ"
, ql.mem.read(struct_address[
0
]
-
8
,
0x18
))
print
(
"[*] debug1"
,
hex
(mem_value1))
print
(
"[*] debug2"
,
hex
(mem_value2))
print
(
"[*] debug3"
,
hex
(mem_value3))
ql.mem.write(mem_value3, b
"\x01"
)
def
challenge8(ql):
base
=
ql.mem.get_lib_base(ql.path)
ql.hook_address(search_mem, base
+
0xFB5
)
def
my_strcmp(ql,
*
args)
-
>
int
:
ql.arch.regs.write(
"rax"
,
0
)
def
my_lower(ql,
*
args):
ql.arch.regs.rax
=
ql.arch.regs.rdi
def
challenge9(ql):
ql.os.set_api(
'tolower'
, my_lower,QL_INTERCEPT.EXIT)
class
FakeCmdline(QlFsMappedObject):
def
read(
self
, size
=
int
)
-
> bytes:
return
b
"qilinglab"
def
close(
self
)
-
>
int
:
return
0
def
challenge10(ql):
ql.add_fs_mapper(r
"/proc/self/cmdline"
,FakeCmdline)
def
set_regs(ql):
ql.arch.regs.write(
"esi"
,
0x696C6951
)
ql.arch.regs.write(
"ecx"
,
0x614C676E
)
ql.arch.regs.write(
"eax"
,
0x20202062
)
def
challenge11(ql):
base
=
ql.mem.get_lib_base(ql.path)
ql.hook_address(set_regs, base
+
0x1195
)
if
__name__
=
=
'__main__'
:
ql
=
Qiling([r
"qilinglab-x86_64"
], r
'./qiling/examples/rootfs/x8664_linux'
, verbose
=
QL_VERBOSE.OFF)
challenge1(ql)
challenge2(ql)
challenge3(ql)
challenge4(ql)
challenge5(ql)
challenge6(ql)
challenge7(ql)
challenge8(ql)
challenge9(ql)
challenge10(ql)
challenge11(ql)
ql.run()