Syscall hijacking from kernel











up vote
1
down vote

favorite
1












I want to intercept the open() syscall, for testing each time a file is opened by the user, the message “OPEN IS!” should be displayed in dmesg.



The syscall table and open-call addresses in dmesg are displayed, but the message “OPEN IS!” is not visible. Kernel v. 4.18



I would like to know what the problem is. The code:



unsigned long cr0;
static unsigned long *__sys_call_table;

typedef asmlinkage int (*orig_open_t)(const char *, int, int);

orig_open_t orig_open;

unsigned long *
get_syscall_table_bf(void)
{
unsigned long *syscall_table;
unsigned long int i;

for (i = (unsigned long int)ksys_close; i < ULONG_MAX;
i += sizeof(void *)) {
syscall_table = (unsigned long *)i;

if (syscall_table[__NR_close] == (unsigned long)ksys_close) {
printk(KERN_INFO "syscall: %08lxn", syscall_table);
return syscall_table;
}
}
return NULL;
}

asmlinkage int
hacked_open(const char *filename, int flags, int mode)
{
printk(KERN_INFO "OPEN IS!n");
return 0;
}

static inline void
protect_memory(void)
{
write_cr0(cr0);
}

static inline void
unprotect_memory(void)
{
write_cr0(cr0 & ~0x00010000);
}

static int __init
diamorphine_init(void)
{
__sys_call_table = get_syscall_table_bf();
if (!__sys_call_table)
return -1;

cr0 = read_cr0();

orig_open = (orig_open_t)__sys_call_table[__NR_open];

unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)hacked_open;
printk(KERN_INFO "WE DO IT!n");
printk(KERN_INFO "hacked is: %08lxn", hacked_open);
protect_memory();

return 0;
}

static void __exit
diamorphine_cleanup(void)
{
unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)orig_open;
protect_memory();
}

module_init(diamorphine_init);
module_exit(diamorphine_cleanup);

MODULE_LICENSE("GPL");









share|improve this question















migrated from unix.stackexchange.com Dec 1 at 22:04


This question came from our site for users of Linux, FreeBSD and other Un*x-like operating systems.















  • Do you know what is hijacking?
    – 1st Sentinel 31 Year Perl Hist
    Dec 1 at 12:49










  • Why do you not just recompile Linux Kernel with your changes?
    – Vladimir Pustovalov
    Dec 4 at 16:20










  • Why don't you just use ftrace or kprobes? Some info: 1 and 2. Or your goal is foremost to write some kernel code for yourself?
    – red0ct
    Dec 5 at 23:07

















up vote
1
down vote

favorite
1












I want to intercept the open() syscall, for testing each time a file is opened by the user, the message “OPEN IS!” should be displayed in dmesg.



The syscall table and open-call addresses in dmesg are displayed, but the message “OPEN IS!” is not visible. Kernel v. 4.18



I would like to know what the problem is. The code:



unsigned long cr0;
static unsigned long *__sys_call_table;

typedef asmlinkage int (*orig_open_t)(const char *, int, int);

orig_open_t orig_open;

unsigned long *
get_syscall_table_bf(void)
{
unsigned long *syscall_table;
unsigned long int i;

for (i = (unsigned long int)ksys_close; i < ULONG_MAX;
i += sizeof(void *)) {
syscall_table = (unsigned long *)i;

if (syscall_table[__NR_close] == (unsigned long)ksys_close) {
printk(KERN_INFO "syscall: %08lxn", syscall_table);
return syscall_table;
}
}
return NULL;
}

asmlinkage int
hacked_open(const char *filename, int flags, int mode)
{
printk(KERN_INFO "OPEN IS!n");
return 0;
}

static inline void
protect_memory(void)
{
write_cr0(cr0);
}

static inline void
unprotect_memory(void)
{
write_cr0(cr0 & ~0x00010000);
}

static int __init
diamorphine_init(void)
{
__sys_call_table = get_syscall_table_bf();
if (!__sys_call_table)
return -1;

cr0 = read_cr0();

orig_open = (orig_open_t)__sys_call_table[__NR_open];

unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)hacked_open;
printk(KERN_INFO "WE DO IT!n");
printk(KERN_INFO "hacked is: %08lxn", hacked_open);
protect_memory();

return 0;
}

static void __exit
diamorphine_cleanup(void)
{
unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)orig_open;
protect_memory();
}

module_init(diamorphine_init);
module_exit(diamorphine_cleanup);

MODULE_LICENSE("GPL");









share|improve this question















migrated from unix.stackexchange.com Dec 1 at 22:04


This question came from our site for users of Linux, FreeBSD and other Un*x-like operating systems.















  • Do you know what is hijacking?
    – 1st Sentinel 31 Year Perl Hist
    Dec 1 at 12:49










  • Why do you not just recompile Linux Kernel with your changes?
    – Vladimir Pustovalov
    Dec 4 at 16:20










  • Why don't you just use ftrace or kprobes? Some info: 1 and 2. Or your goal is foremost to write some kernel code for yourself?
    – red0ct
    Dec 5 at 23:07















up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





I want to intercept the open() syscall, for testing each time a file is opened by the user, the message “OPEN IS!” should be displayed in dmesg.



The syscall table and open-call addresses in dmesg are displayed, but the message “OPEN IS!” is not visible. Kernel v. 4.18



I would like to know what the problem is. The code:



unsigned long cr0;
static unsigned long *__sys_call_table;

typedef asmlinkage int (*orig_open_t)(const char *, int, int);

orig_open_t orig_open;

unsigned long *
get_syscall_table_bf(void)
{
unsigned long *syscall_table;
unsigned long int i;

for (i = (unsigned long int)ksys_close; i < ULONG_MAX;
i += sizeof(void *)) {
syscall_table = (unsigned long *)i;

if (syscall_table[__NR_close] == (unsigned long)ksys_close) {
printk(KERN_INFO "syscall: %08lxn", syscall_table);
return syscall_table;
}
}
return NULL;
}

asmlinkage int
hacked_open(const char *filename, int flags, int mode)
{
printk(KERN_INFO "OPEN IS!n");
return 0;
}

static inline void
protect_memory(void)
{
write_cr0(cr0);
}

static inline void
unprotect_memory(void)
{
write_cr0(cr0 & ~0x00010000);
}

static int __init
diamorphine_init(void)
{
__sys_call_table = get_syscall_table_bf();
if (!__sys_call_table)
return -1;

cr0 = read_cr0();

orig_open = (orig_open_t)__sys_call_table[__NR_open];

unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)hacked_open;
printk(KERN_INFO "WE DO IT!n");
printk(KERN_INFO "hacked is: %08lxn", hacked_open);
protect_memory();

return 0;
}

static void __exit
diamorphine_cleanup(void)
{
unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)orig_open;
protect_memory();
}

module_init(diamorphine_init);
module_exit(diamorphine_cleanup);

MODULE_LICENSE("GPL");









share|improve this question















I want to intercept the open() syscall, for testing each time a file is opened by the user, the message “OPEN IS!” should be displayed in dmesg.



The syscall table and open-call addresses in dmesg are displayed, but the message “OPEN IS!” is not visible. Kernel v. 4.18



I would like to know what the problem is. The code:



unsigned long cr0;
static unsigned long *__sys_call_table;

typedef asmlinkage int (*orig_open_t)(const char *, int, int);

orig_open_t orig_open;

unsigned long *
get_syscall_table_bf(void)
{
unsigned long *syscall_table;
unsigned long int i;

for (i = (unsigned long int)ksys_close; i < ULONG_MAX;
i += sizeof(void *)) {
syscall_table = (unsigned long *)i;

if (syscall_table[__NR_close] == (unsigned long)ksys_close) {
printk(KERN_INFO "syscall: %08lxn", syscall_table);
return syscall_table;
}
}
return NULL;
}

asmlinkage int
hacked_open(const char *filename, int flags, int mode)
{
printk(KERN_INFO "OPEN IS!n");
return 0;
}

static inline void
protect_memory(void)
{
write_cr0(cr0);
}

static inline void
unprotect_memory(void)
{
write_cr0(cr0 & ~0x00010000);
}

static int __init
diamorphine_init(void)
{
__sys_call_table = get_syscall_table_bf();
if (!__sys_call_table)
return -1;

cr0 = read_cr0();

orig_open = (orig_open_t)__sys_call_table[__NR_open];

unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)hacked_open;
printk(KERN_INFO "WE DO IT!n");
printk(KERN_INFO "hacked is: %08lxn", hacked_open);
protect_memory();

return 0;
}

static void __exit
diamorphine_cleanup(void)
{
unprotect_memory();
__sys_call_table[__NR_open] = (unsigned long)orig_open;
protect_memory();
}

module_init(diamorphine_init);
module_exit(diamorphine_cleanup);

MODULE_LICENSE("GPL");






c ubuntu linux-kernel kernel






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 5 at 19:07









red0ct

1,1233822




1,1233822










asked Nov 30 at 21:51









Ilya Timokhin

242




242




migrated from unix.stackexchange.com Dec 1 at 22:04


This question came from our site for users of Linux, FreeBSD and other Un*x-like operating systems.






migrated from unix.stackexchange.com Dec 1 at 22:04


This question came from our site for users of Linux, FreeBSD and other Un*x-like operating systems.














  • Do you know what is hijacking?
    – 1st Sentinel 31 Year Perl Hist
    Dec 1 at 12:49










  • Why do you not just recompile Linux Kernel with your changes?
    – Vladimir Pustovalov
    Dec 4 at 16:20










  • Why don't you just use ftrace or kprobes? Some info: 1 and 2. Or your goal is foremost to write some kernel code for yourself?
    – red0ct
    Dec 5 at 23:07




















  • Do you know what is hijacking?
    – 1st Sentinel 31 Year Perl Hist
    Dec 1 at 12:49










  • Why do you not just recompile Linux Kernel with your changes?
    – Vladimir Pustovalov
    Dec 4 at 16:20










  • Why don't you just use ftrace or kprobes? Some info: 1 and 2. Or your goal is foremost to write some kernel code for yourself?
    – red0ct
    Dec 5 at 23:07


















Do you know what is hijacking?
– 1st Sentinel 31 Year Perl Hist
Dec 1 at 12:49




Do you know what is hijacking?
– 1st Sentinel 31 Year Perl Hist
Dec 1 at 12:49












Why do you not just recompile Linux Kernel with your changes?
– Vladimir Pustovalov
Dec 4 at 16:20




Why do you not just recompile Linux Kernel with your changes?
– Vladimir Pustovalov
Dec 4 at 16:20












Why don't you just use ftrace or kprobes? Some info: 1 and 2. Or your goal is foremost to write some kernel code for yourself?
– red0ct
Dec 5 at 23:07






Why don't you just use ftrace or kprobes? Some info: 1 and 2. Or your goal is foremost to write some kernel code for yourself?
– red0ct
Dec 5 at 23:07














1 Answer
1






active

oldest

votes

















up vote
1
down vote













I'm guessing something in your hooking is wrong. Either you're hooking a wrong offset of the syscall table or you're completely off. I couldn't understand why explicitly you start searching with ksys_close(), especially when it's an inlined function. You should try looking for the syscall table symbol as such:



typedef void (*_syscall_ptr_t)(void); 
_syscall_ptr_t *_syscall_table = NULL;
_syscall_table=(_syscall_ptr_t *)kallsyms_lookup_name("sys_call_table");


A different (huge) issue I see with this is resetting CR0, which allows anything within your system to write to a read only memory at the time of your writing, instead of page-walking and setting the W bit on the specific page you're about to edit.



Additional one small word of advice: You should complete your hook to redirect to the original open syscall. Otherwise, you'll result in the entire system reading from STDIN for every newly opened file descriptor (which will kill your system, eventually)






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53575454%2fsyscall-hijacking-from-kernel%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    I'm guessing something in your hooking is wrong. Either you're hooking a wrong offset of the syscall table or you're completely off. I couldn't understand why explicitly you start searching with ksys_close(), especially when it's an inlined function. You should try looking for the syscall table symbol as such:



    typedef void (*_syscall_ptr_t)(void); 
    _syscall_ptr_t *_syscall_table = NULL;
    _syscall_table=(_syscall_ptr_t *)kallsyms_lookup_name("sys_call_table");


    A different (huge) issue I see with this is resetting CR0, which allows anything within your system to write to a read only memory at the time of your writing, instead of page-walking and setting the W bit on the specific page you're about to edit.



    Additional one small word of advice: You should complete your hook to redirect to the original open syscall. Otherwise, you'll result in the entire system reading from STDIN for every newly opened file descriptor (which will kill your system, eventually)






    share|improve this answer

























      up vote
      1
      down vote













      I'm guessing something in your hooking is wrong. Either you're hooking a wrong offset of the syscall table or you're completely off. I couldn't understand why explicitly you start searching with ksys_close(), especially when it's an inlined function. You should try looking for the syscall table symbol as such:



      typedef void (*_syscall_ptr_t)(void); 
      _syscall_ptr_t *_syscall_table = NULL;
      _syscall_table=(_syscall_ptr_t *)kallsyms_lookup_name("sys_call_table");


      A different (huge) issue I see with this is resetting CR0, which allows anything within your system to write to a read only memory at the time of your writing, instead of page-walking and setting the W bit on the specific page you're about to edit.



      Additional one small word of advice: You should complete your hook to redirect to the original open syscall. Otherwise, you'll result in the entire system reading from STDIN for every newly opened file descriptor (which will kill your system, eventually)






      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        I'm guessing something in your hooking is wrong. Either you're hooking a wrong offset of the syscall table or you're completely off. I couldn't understand why explicitly you start searching with ksys_close(), especially when it's an inlined function. You should try looking for the syscall table symbol as such:



        typedef void (*_syscall_ptr_t)(void); 
        _syscall_ptr_t *_syscall_table = NULL;
        _syscall_table=(_syscall_ptr_t *)kallsyms_lookup_name("sys_call_table");


        A different (huge) issue I see with this is resetting CR0, which allows anything within your system to write to a read only memory at the time of your writing, instead of page-walking and setting the W bit on the specific page you're about to edit.



        Additional one small word of advice: You should complete your hook to redirect to the original open syscall. Otherwise, you'll result in the entire system reading from STDIN for every newly opened file descriptor (which will kill your system, eventually)






        share|improve this answer












        I'm guessing something in your hooking is wrong. Either you're hooking a wrong offset of the syscall table or you're completely off. I couldn't understand why explicitly you start searching with ksys_close(), especially when it's an inlined function. You should try looking for the syscall table symbol as such:



        typedef void (*_syscall_ptr_t)(void); 
        _syscall_ptr_t *_syscall_table = NULL;
        _syscall_table=(_syscall_ptr_t *)kallsyms_lookup_name("sys_call_table");


        A different (huge) issue I see with this is resetting CR0, which allows anything within your system to write to a read only memory at the time of your writing, instead of page-walking and setting the W bit on the specific page you're about to edit.



        Additional one small word of advice: You should complete your hook to redirect to the original open syscall. Otherwise, you'll result in the entire system reading from STDIN for every newly opened file descriptor (which will kill your system, eventually)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 4 at 11:59









        Knightingale

        1467




        1467






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53575454%2fsyscall-hijacking-from-kernel%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre