JavaScript (ECMAScript6), 2 ไบต์ต่อบรรทัด
'\
'[
'\
b\
i\
g'
][
'\
c\
o\
n\
s\
t\
r\
u\
c\
t\
o\
r'
][
'\
c\
a\
l\
l'
](
0,
`\
n\
=\
p\
r\
o\
m\
p\
t\
(\
'\
'\
)\
;\
i\
=\
0\
;\
f\
o\
r\
(\
;\
+\
+\
i\
<\
=\
n\
;\
c\
o\
n\
s\
o\
l\
e\
.\
l\
o\
g\
(\
i\
%\
5\
?\
f\
|\
|\
i\
:\
f\
+\
'\
P\
i\
e\
'\
)\
)\
f\
=\
i\
%\
3\
?\
'\
'\
:\
'\
A\
p\
p\
l\
e\
'\
`)
()
คำอธิบายยาว ๆ
วิธีที่เราสามารถทำให้บรรทัดที่สั้นกว่าคือการแปลงรหัสเป็นสตริงและหลบเลี่ยงการสิ้นสุดบรรทัดสิ่งนี้จะกำหนดขีด จำกัด 2 ไบต์ต่อบรรทัด
ดังนั้น alert(1)
กลายเป็น
"\
a\
l\
e\
r\
(\
1\
)"
แต่ตอนนี้รหัสของคุณเป็นสตริงดังนั้นเราต้องดำเนินการสตริงเป็นรหัส ฉันรู้ว่าอย่างน้อย 4 วิธีที่คุณสามารถรันสตริงเป็นรหัส:
- EVAL (รหัส)(รหัส) ซึ่งใช้เวลาอย่างน้อย 5 ไบต์ในการโทร
eval(
- setTimeout (รหัสหมดเวลา) เรียกใช้ฟังก์ชั่นแบบอะซิงโครนัส แต่เป็นทางเลือกถ้าคุณผ่านสตริงมันจะเรียกใช้ eval ภายใน
- คุณสามารถใช้ประโยชน์จาก DOM และใส่รหัสของคุณใน
onclick=""
แอตทริบิวต์ แต่ฉันไม่สามารถจัดการเพื่อทำให้องค์ประกอบการสร้างองค์ประกอบสั้น
- กล่าวอ้างถึง สร้างฟังก์ชั่นใหม่ Function ()จะแยกรหัสของคุณเป็นฟังก์ชั่นที่ไม่ระบุชื่อซึ่งคุณสามารถโทรได้ในภายหลัง (ฉันใช้สิ่งนี้)
ฟังก์ชั่นพื้นเมืองทั้งหมดอาศัยอยู่ภายใน หน้าต่างวัตถุและใน JavaScript คุณสามารถเข้าถึงคุณสมบัติของวัตถุโดยใช้สัญกรณ์จุดเพื่อให้eval()
กลายเป็นwindow.eval()
หรือคุณสามารถเข้าถึงคุณสมบัติการใช้สัญกรณ์วงเล็บ window['eval']()
คุณสามารถใช้ประโยชน์จากสิ่งนี้เพื่อแบ่งเป็นeval
หลายบรรทัดโดยใช้วิธีที่อธิบายไว้ก่อนหน้านี้ แต่คุณยังคงต้องพิมพ์หน้าต่างเคล็ดลับหนึ่งก็คือถ้าคุณไม่ได้อยู่ในกรอบด้านบนตัวแปรก็เป็นหน้าต่างด้วยดังนั้น window.eval จะกลายเป็น top.eval (น้อยกว่า 3 ไบต์)
w=top
w['eval']
You can shorten the assignment using parenthesis
w=(
top
)
w[
'e\
av\
al'
](
/*string*/
)
ดังนั้นนี่จะทำให้โค้ดมีค่าต่ำสุด 3 ไบต์ เพื่อให้รหัส 2 ไบต์ฉันใช้new Function(/*string*/);
สร้าง แต่ฉันต้องมีความคิดสร้างสรรค์ในการเข้าถึงโดยไม่ต้องพิมพ์
ครั้งแรกตัวสร้างฟังก์ชั่นช่วยให้คุณสามารถเรียกมันว่าเป็นฟังก์ชั่นที่ละเว้นคำหลักใหม่นี้ลด 4 ไบต์ แต่มันก็มีความสำคัญด้วยเหตุผลอื่น การเรียกนวกรรมิกในขณะที่ฟังก์ชั่นยังคงส่งคืนอินสแตนซ์นี้ช่วยให้เราหันnew Function(code)
ไปFunction(code)
การอีกสิ่งที่สำคัญคือตัวสร้างฟังก์ชั่นมีcall
วิธีการที่ช่วยให้คุณสามารถเรียกใช้ฟังก์ชันใด ๆ Function.call(null, code)
แต่เอาชนะอ้างอิงนี้และตัวสร้างฟังก์ชั่นของตัวเองเป็นฟังก์ชั่นที่คุณสามารถเรียกวิธีการที่มันเหมือนตัวเอง
ฟังก์ชันเนทีฟทั้งหมดเป็นอินสแตนซ์ของตัวสร้างฟังก์ชั่นและวัตถุทั้งหมดใน javascript มีคุณสมบัติคอนสตรัคเตอร์ ดังนั้นคุณสามารถเข้าถึงตัวสร้างฟังก์ชั่นในฟังก์ชั่นพื้นเมืองใด ๆ เช่นalert.constructor
และใช้วิธีการโทรที่เราสามารถเรียกใช้ตัวสร้างเป็นฟังก์ชั่น ตอนนี้เรามี alert.constructor.call (null, code) ส่งคืนฟังก์ชัน
การรวมสิ่งที่ผ่านมาก่อนหน้านี้เราสามารถเปลี่ยนเป็น alert['constructor']['call'](null, code)
ตอนนี้เราแค่ต้องหาชื่อฟังก์ชั่นหรือวิธีการแบบสั้นดังนั้นฉันจึงเลือกวิธีใหญ่ ()ภายในตัวสร้างสตริง ดังนั้นฉันสามารถเข้าถึงได้โดยตรงจากสตริงว่าง"".big
"".big.constructor.call(null, "code")();
''['big']['constructor']['call'](0,'/* code */')()
จากนั้นฉันก็หักทุกอย่างใน 2 ไบต์
สั้นเอ้อคำอธิบาย (TLDR)
ฉันเข้าถึงฟังก์ชั่น (รหัส) ใหม่คอนสตรัคจะแยกสตริงแทนEVAL (รหัส) ตัวสร้างนี้สามารถใช้ได้กับทุกฟังก์ชั่นพื้นเมืองโดยทำฟังก์ชั่นใด ๆ คอนสตรัคalert.constructor===Function
เช่น ฉันใช้ฟังก์ชั่น / วิธีการภายในString.prototype.big String.prototype.big.constructor.call(null, /*string*/)
แต่เข้าถึงได้โดยตรงจากตัวอักษรสตริง"".big
และหันไป สัญกรณ์วงเล็บ ""['big']['constructor']['call'](0, CODE)
ที่จะสามารถทำลายมันได้โดยใช้\
.