当前位置:网站首页>浅谈jsfuck编码
浅谈jsfuck编码
2022-08-10 22:31:00 【ek1ng】
参考: https://zh.wikipedia.org/wiki/JSFuckhttps://blog.csdn.net/qq_36539075/category_7591719.htmlhttps://chinese.freecodecamp.org/news/javascript-implicit-type-conversion/
前言
第一次看到jsfuck编码还是在hgame 2022的week1中一个在线小游戏的ctf题目,只是在注释中发现了一段有很多[]的内容,搜索后发现是jsfuck编码,在控制台中执行就得到了flag,其实也不是很懂jsfuck的原理,只是单纯觉得比较神奇,今天又在一篇安全相关的文章中看到了jsfuck cheat sheet于是就想深入了解一下jsfuck。
什么是jsfuck
先贴一段wiki对jsfuck的解释,JSFuck是一种深奥的 JavaScript编程风格。以这种风格写成的代码中仅使用 [
、]
、(
、)
、!
和 +
六种字符。此编程风格的名字派生自仅使用较少符号写代码的Brainfuck语言。与其他深奥的编程语言不同,以JSFuck风格写出的代码不需要另外的编译器或解释器来执行,无论浏览器或JavaScript引擎中的原生 JavaScript 解释器皆可直接运行。鉴于 JavaScript 是弱类型语言,编写者可以用数量有限的字符重写 JavaScript 中的所有功能,且可以用这种方式执行任何类型的表达式。
为什么可以只用6种字符编码js
显然一段js代码只用6种字符去写,毫无疑问可以绕过很多关键词的过滤,但是在使用之前会有一个疑问就是为什么可以这样编码一段js代码。
其实这是由于js的隐式类型转换导致的,对于逻辑表达式[]==![]
,js会返回true
先来说说对于运算符==
的运算规则
NaN
和其他任何类型比较永远返回false
(包括和他自己)NaN == NaN // false
Boolean
和其他任何类型比较,Boolean 首先被转换为 Number 类型。true == '2' // false true -> 1
String
和Number
比较,先将String
转换为Number
类型。123 == '123' // true, '123' -> 123
null == undefined
比较结果是true
,除此之外,null
、undefined
和其他任何结果的比较值都为false
。原始类型
和引用类型
做比较时,引用类型会依照ToPrimitive
规则转换为原始类型。
️
ToPrimitive
规则,是引用类型向原始类型转变的规则,它遵循先valueOf
后toString
的模式期望得到一个原始类型。如果还是没法得到一个原始类型,就会抛出TypeError
。
我们再来看看[]==![]
,取非运算优先级最高,[]
是空数组,对一个空数组取非得到false
,那么[]==![]
会变成 []==false
,然后因为Boolean
和其他任何类型比较,Boolean 首先被转换为 Number 类型,false -> 0
,变成[]==0
,然后再因为原始类型
和引用类型
做比较时,引用类型会依照ToPrimitive
规则转换为原始类型,[].valueOf().toString()
的值为''
,String
和``Number比较会把
String转换成
Number,也就是
‘’ -> 0,最终变成
0==0`得到true。
看明白上面的例子后会发现,js的隐式类型转换使得我们可以组合上述的6个符号来替换一些我们希望得到的字符,符号等等内容,所以这也是为什么js代码可以用这样简单的6个符号用来表达,当然这么说其实也还是很难有信服力,我们接下来解析一下如何使用jsfuck编码alert()
。
数字的话比较简单有1有0我们一直加想要多少就多少,然后我们肯定需要26个字符对吧,那字符的话其实是用截取的方式,alert
的话我们可以用true
和false
截取就可以实现
'a' == 'false'[1] == (false + '')[1] == (![]+[])[+!+[]]
'l' == 'false'[2] == (false + '')[2] == (![]+[])[!+[]+!+[]]
'e' == 'true'[0] == (true + '')[3] == (!![]+[])[!+[]+!+[]+!+[]]
'r' == 'true'[0] == (true + '')[1] == (!![]+[])[+!+[]]
't' == 'true'[0] == (true + '')[0] == (!![]+[])[+[]]
'alert' == (![]+[])[+!+[]] + (![]+[])[!+[]+!+[]] + (!![]+[])[!+[]+!+[]+!+[]] + (!![]+[])[+!+[]] + (!![]+[])[+[]]
但是26个字母其他的又该怎么实现呢,我们这里看一下jsfuck的官方仓库中是如何获取指定字符的,那更多的字符就需要去看jsfuck的源码啦
'a': '(false+"")[1]',
'b': '([]["entries"]()+"")[2]',
'c': '([]["flat"]+"")[3]',
'd': '(undefined+"")[2]',
'e': '(true+"")[3]',
'f': '(false+"")[0]',
'g': '(false+[0]+String)[20]',
'h': '(+(101))["to"+String["name"]](21)[1]',
'i': '([false]+undefined)[10]',
'j': '([]["entries"]()+"")[3]',
'k': '(+(20))["to"+String["name"]](21)',
'l': '(false+"")[2]',
'm': '(Number+"")[11]',
'n': '(undefined+"")[1]',
'o': '(true+[]["flat"])[10]',
'p': '(+(211))["to"+String["name"]](31)[1]',
'q': '("")["fontcolor"]([0]+false+")[20]',
'r': '(true+"")[1]',
's': '(false+"")[3]',
't': '(true+"")[0]',
'u': '(undefined+"")[0]',
'v': '(+(31))["to"+String["name"]](32)',
'w': '(+(32))["to"+String["name"]](33)',
'x': '(+(101))["to"+String["name"]](34)[1]',
'y': '(NaN+[Infinity])[10]',
'z': '(+(35))["to"+String["name"]](36)',
利用jsfuck绕过过滤
因为jsfuck只用6个字符编码,这样的话很多时候可以绕过一些对恶意代码的检测,看到渗透测试中大多数对jsfuck的运用就是绕XSS的过滤,比如这篇文章,文章中xss的payload结合jsfuck编码绕过对alert
等一些危险函数的利用。ctf中我也没怎么看到过jsfuck绕过过滤的题目,只看到过一段js代码里面就直接是flag的题,因此也没有机会仔细研究一下,也许明年hgame可以出个有意思的题考考新生hhh。
边栏推荐
猜你喜欢
二叉树 | 翻转二叉树 | leecode刷题笔记
EL表达式
file IO-buffer
Pro-test is effective | A method to deal with missing features of risk control data
MySQL学习笔记(2)——简单操作
Research on multi-element N-k fault model of power system based on AC power flow (implemented by Matlab code) [Power System Fault]
文件IO-缓冲区
《DevOps围炉夜话》- Pilot - CNCF开源DevOps项目DevStream简介 - feat. PMC成员胡涛
面试官: AMS在Android起到什么作用,简单的分析下Android的源码
阿里云张新涛:支持沉浸式体验应用快速落地,阿里云云XR平台发布
随机推荐
【Maui正式版】创建可跨平台的Maui程序,以及有关依赖注入、MVVM双向绑定的实现和演示
How does the Weiluntong touch screen display the current value of abnormal data while alarming?
RK3399 platform development series explanation (kernel-driven peripherals) 6.35, IAM20680 gyroscope introduction
JS中使用正则表达式g模式和非g模式的区别
实例054:位取反、位移动
二叉树 | 迭代遍历 | leecode刷题笔记
MySQL: MySQL Cluster - Principle and Configuration of Master-Slave Replication
LeetCode每日两题01:反转字符串 (均1200道)方法:双指针
fme csmapreprojector转换器使用高程异常模型进行高程基准转换
面试官: AMS在Android起到什么作用,简单的分析下Android的源码
3598. Binary tree traversal (Huazhong University of Science and Technology exam questions)
诺诚健华通过注册:施一公家族身价15亿 高瓴浮亏5亿港元
leetcode:355. 设计推特
EL表达式
解码2022中国网安强星丨正向建、反向查,华为构建数字化时代的网络安全防线
常用代码扩展点设计方式
LabVIEW分配多少线程?
Glide缓存核心原理详解
阿里云架构师金云龙:基于云XR平台的视觉计算应用部署
基于交流潮流的电力系统多元件N-k故障模型研究(Matlab代码实现)【电力系统故障】