'How do I interact with a Qiling emulation through standard input?
In pwntools, where a program is waiting for user input (via fgets
or similar) an exploit might look like:
from pwn import *
p = process("./vuln")
nop_sled = asm(shellcraft.nop() * 100)
p.sendline(nop_sled)
But I want to use Qiling (a spin-off of Unicorn), which I thought might look something like:
from pwn import *
from qiling import *
from qiling.const import QL_VERBOSE
from qiling.os.const import STRING
def my_fgets(ql):
pass
def sandbox(path, rootfs):
# Setup Qiling engine
ql = Qiling(path, rootfs, verbose=QL_VERBOSE.DISASM)
# ql.os.set_api('fgets', my_fgets) # I thought maybe this would
# be involved, but unsure.
return ql
p = sandbox(["vuln"], "qiling/examples/rootfs/x8664_linux")
p.run()
nop_sled = asm(shellcraft.nop() * 100)
p.sendline(nop_sled)
I tried variations of this, reading through the documentation about hijacking, particularly ql.os.set_api
but am unsure how this works. The documentation doesn't really elaborate about what the syntax represents, nor link any resource to learn more. Basically I know what I want to do but don't understand the underlying systems enough to do it.
The reason I want to use Qiling instead of a typical process is it seems much easier to observe state with qiling than a debugger. Also Qiling offers a unique ability to apply conditional hooks. I could do things like:
- Hook all jumps with destination addresses that seem unusual (not the start address of any local or imported subroutine, nor loop). This would be an effective analysis option against ROPing and dynamically executing code.
- Hook any subroutines which accept untrusted external input. This would be effective as part of taint analysis.
- If new data gets made dynamically executable, these hooks still apply instead of me having to go set breakpoints in the dynamic code as I would would with debuggers / IDA / Ghidra, etc.
But Qiling runs differently, it doesn't pause to await stdin input on API calls like fgets
/ gets
. Or maybe it does and I just don't know how to send it. So I think I need to implement that behavior, and as stated above I read the documentation on how to do something similar, but am struggling to understand how to go further.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|