JavaScript for hackers

本文介绍了一些非常规的JavaScript技巧,这些技巧可用于绕过XSS过滤器。文章详细讲解了如何利用正则表达式的特性执行代码、使用Unicode转义字符、巧妙运用JavaScript解析器等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Introduction

I love to use JavaScript in unexpected ways, to create code that looks like it shouldn't work but does, or produces some unexpected behavior. This may sound trivial, but the results I've found lead to some very useful techniques. Each of the techniques described can be used for XSS filter evasion, which was my original intention when developing them. However, learning such JavaScript can dramatically increase your knowledge of the language, helping you become better at cleaning up input, and increase web application security.

So read on and enjoy my weird and wonderful JavaScript hacks.

RegExp replace can execute code

When using regular expressions with replace the second argument supports a function assignment. In Opera it seems you can use this argument to execute code. For example, check out the code snippet below:

'XSS'.replace(/XSS/g,alert)

This results in alert('XSS') ; this works because the match from the RegExp is passed to the alert function as an argument. Normally you would use a function to perform another routine on the matched text, like so:

'somestring'.replace(/some/,function($1){//do something with some})

But as you can see in the first example in this section, instead of a user defined function we are executing a native alert call, and the arguments are passed to the native call from the regular expression. It's a cool trick and could be used to evade some XSS filters, for example if you inject a string then proceed with a dot you can then call any function you like.

To see how this is used in a XSS context, imagine we have an unfiltered " in the string in which an injection occurs, such as a JavaScript event or a script tag. First we inject our payload alert(1) , then we break out of the quotes - " - and continue our regular expression:

.replace(/.+/,eval)//

Notice I use eval here to execute any code I like and the regular expression matches everything so that the full payload is passed to eval .

If I put all the code together and show you the output of the page it is easier to understand what is going on:

Page output:

<script>somevariableUnfiltered="YOUR INPUT"</script>

The above code is common in analytics scripts where your search string is stored by an advertising company. You often don't see these scripts but if you view the source of a web page you'll find that they are a regular occurrence; forums are another place where they are prevalent. "YOUR INPUT" is the string you have control of; this is also referred to as DOM based XSS if the input isn't filtered correctly.

Input:

alert(1)".replace(/.+/,eval)//

Resulting output:

<script>somevariableUnfiltered="alert(1)".replace(/.+/,eval)//"</script>

Notice the single line comment used to remove the trailing quote.

Unicode escapes

Although it's not possible to use parentheses when escaping unicode characters, you can escape the name of the function being called, for example:

/u0061/u006c/u0065/u0072/u0074(1)

This calls alert(1) ; /u indicates it's a unicode escape and the hex number after specifies the character. /u0061 is "a" and so on.

Mixing and matching unicode escapes is possible with normal characters; the example below demonstrates this:

/u0061lert(1)

You can also include them in strings and even evaluate them using eval . Unicode escapes are different to normal hex or octal escapes because they can be included in a string, or a reference to a function, variable or object.

The example below shows how to use unicode escapes that are evaluated and split into separate parts:

eval('//u'+'0061'+'lert(1)')

By avoiding normal function names like alert , we can fool XSS filters into injecting our code. This very example was used to bypass PHPIDS (an open source IDS system), which resulted in the rules subsequently being made much stronger. If you are considering decoding JavaScript for malware analysis at runtime you need to consider the possible ways that multiple levels of encoding can work; as you can see from this example it won't be a easy task.

JavaScript parser engine

JavaScript is a very dynamic language. It can execute a surprising amount of code that at first glance doesn't look valid, however once you know how the parsers work, you begin to understand the logic behind it.

JavaScript doesn't know the result of a function until it is executed, and obviously it has to call the function to return the variable type. This leads to an interesting quirk - for example, if the returning function doesn't return a valid value for the code block, a syntax error will occur after the execution of the function.

What does this mean in English? Well, code speaks louder than words - check this example out

+alert(1)--

The alert function executes and returns undefined but by that time it is too late - the decrement operator is expecting a number and therefore raises an error.

Here's a few more valid examples that don't raise errors but are interesting nevertheless.

+alert(1)

1/alert(1)

alert(1)>>>/abc/

You might think the above examples are pointless but in fact they offer great insight into how Javascript works. Once you understand the small details the bigger picture becomes clear and the way that your code executes can help you understand how the parser works. I find these sort of examples useful when tracking down syntax errors and DOM based XSS, and exploiting XSS Filters.

Throw, Delete what?

You can use the delete operator in ways that you wouldn't at first expect, which results in some pretty wacky syntax. Lets see what happens if we combine the throw , delete , not and typeof operators?

throw delete~typeof~alert(1)

Even though you'd think it couldn't possibly work, it's possible to call delete on a function call and it still executes:

delete alert(1)

Here are a few more examples

delete~[a=alert]/delete a(1)

delete [a=alert],delete a(1)

At first glance you'd think that they would raise a syntax error but when examining the code further it sorta makes sense. The parser finds a variable assignment first within a array, performs the assignment and then deletes the array. Likewise the delete is performed after a function call because it needs to know the result of the function before it can delete the returned object, even if it is null.

Again these examples have been used to defeat XSS filters because they are often trying to match valid syntax and they don't expect the obscure nature of the code. You should consider such examples when programming your application data validation.

Global objects are statements

In certain instances of XSS filter evasion, it can be useful to send English-like text hidden within a vector. Clever systems like PHPIDS use English and vector comparisons to determine if a request is an attack or not, so it is a useful way to test these systems.

Using global objects/functions on their own can produce English-like code blocks. In fact, on the sla.ckers security forum we had a little game to produce English-like sentences in JavaScript. To get an idea of how it works, check out the following example:

stop, open, print && alert(1)

I coined the name Javascriptlish because it's possible to produce some crazy looking code:

javascript : /is/^{ a : ' weird ' }[' & wonderful ']/" language "

the_fun: ['never '] + stop['s']

We use the regular expression /is/ with the operator ^ and then create a object { a : 'weird'} (which has a property a and an assignment of weird .) Then we look for a property ' & wonderful ' within the object we just created, which is then divided by a string of language .

Next we use a label called the_fun and an array with never , use a global function called stop and check for a property of s ... all of which is valid syntax.

Getters/Setters fun

When Firefox added the custom syntax for setters it enabled some interesting XSS vectors that didn't use parentheses. Opera doesn't support a custom syntax yet - this is good from a security point of view but not from a JavaScript hacker's perspective.

Opera does however support the standard defineSetter syntax. This enables us to call functions via assignments, which still has some use for XSS filter evasion:

defineSetter('x',alert); x=1;

In case you're not aware of setters/getters, the example above creates a setter for the global variable x . A setter is called whenever a variable is set with something and the argument is supplied from whatever has been assigned. The second argument is the function to be called on assignment, which is alert . Then, when x is assigned the value of 1 , the alert function is called with 1 as the argument.

Location allows url encoding

The location object allows url encoding within the JavaScript code. This allows you to further obfuscate XSS vectors by double encoding them.

location='javascript:%61%6c%65%72%74%28%31%29'

Combining them with unicode escapes can hide strings quite nicely:</ p>

location='javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c %75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(1)'

The first example works because the URL bar in Opera accepts urlencoded strings - you can hide JavaScript syntax by url encoding it. This is useful because when it is passed within a XSS vector you can double url encode it to help further with filter evasion.

The second example combines the first technique with the unicode escape technique mentioned previously. So when you decode the string it results in the unicode representation of alert which is /u0061/u006c/u0065/u0072/u0074 .

Hackvertor: Your second brain

As a JavaScript hacker I couldn't possibly remember every single encoding method that's possible with JavaScript, so I decided to create a open source tool to do the hard work for me. In the last example the string is double encoded, which can sometimes make it hard to understand. Using my Hackvertor tool makes it a piece of cake and it works nicely in Opera too.

Hackvertor works by using tags to perform multiple levels of conversion; this is similar to HTML tags but it runs code instead of changing the display of the containing text. It converts from the innermost tag outwards, eg to convert the last vector it url decodes and then decodes the unicode escapes, which results in javascript:alert (1) .


from: http://dev.opera.com/articles/view/opera-javascript-for-hackers-1/

1. 了解VoIP和SIP协议 在开始学习FreeSWITCH之前,您应该了解VoIP和SIP协议的基础知识。VoIP是“Voice over Internet Protocol”的简称,它使得可以通过互联网传输语音和多媒体信息。而SIP协议是 VoIP中最重要的协议之一,它负责建立、维护、修改、解散会话。 建议阅读材料: - Understanding VoIP: What is Voice over IP and How it Works - SIP Tutorial: Session Initiation Protocol 2. 学习Linux和命令行 FreeSWITCH是一款基于Linux操作系统的开源软件。因此,了解Linux并能够在命令行中有效使用是必要的。您需要知道如何安装和配置Linux操作系统,基本的命令和文件操作,以及如何管理系统和服务。 建议阅读材料: - The Linux Command Line - Linux Basics for Hackers 3. FreeSWITCH基础知识 学习FreeSWITCH的基础知识是必要的。了解FreeSWITCH的架构、组件、配置文件、模块等基础知识,可以使您更好地理解FreeSWITCH的工作原理。可以从官方的文档中开始学习,从Hello World的入门到API的使用都可以了解。 建议阅读材料: - FreeSWITCH Official Documentation - FreeSWITCH 1.6 Cookbook 4. 熟悉FreeSWITCH的模块 FreeSWITCH 是可扩展的,并内置了许多模块,可以通过配置文件启用。熟悉FreeSWITCH的各种模块可以帮助您更好地应用和扩展FreeSWITCH。这里列举一些常用的模块: - mod_sofia:SIP和SDP处理模块 - mod_dialplan_xml:用于呼叫路由的控制器 - mod_python:用于自定义应用程序以及与其他Web框架交互 - mod_conference:用于多方音频、视频会议 - mod_rtmp:用于流媒体传输 - mod_callcenter:用于呼入呼出中心的自动呼叫分配 建议阅读材料: - FreeSWITCH 1.6 Cookbook - FreeSWITCH 1.6.5 Documentation 5. 熟悉FreeSWITCH的API FreeSWITCH 提供了多种编程语言的接口,如 Python、Lua、JavaScript、Java、NET等。学习如何使用这些API可以让您更好地自定义和扩展FreeSWITCH。 您可以使用API来控制和监视FreeSWITCH,例如添加自定义应用程序、处理呼叫事件、监听录音文件等。 建议阅读材料: - FreeSWITCH Official Wiki - FreeSWITCH 1.6 Cookbook 6. 实际应用 通过实际应用,您可以将学到的知识应用到实际的场景中。例如,您可以构建一个呼叫中心应用程序、电话会议系统、多媒体流处理应用程序等。实践可以帮助您更好地了解FreeSWITCH的工作原理和解决问题。 建议阅读材料: - FreeSWITCH Official Wiki - FreeSWITCH 1.6 Cookbook 最后,需要注意的是,学习FreeSWITCH是一个长期的过程。您需要继续学习新的技术和应用,并了解最新的开发趋势。使用社区和在线资源,加入邮件列表和社交媒体,和其他人交流和分享经验,都可以帮助您不断提高技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值