Pages

2/18/2011

Javascript Obfuscation

หลังจากคุยกับคุณ Gen0Type เลยได้เห็น javascript แบบที่โดนเข้ารหัสทำให้อ่านไม่ออกไว้ แบบนี้
($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__
[_+~$]+$_[_]+$$](_/_)
นี่เป็น Javascript ที่ทำงานได้จริง และถูกแปลออกมาเป็นคำสั่งแค่
alert(1)

ซึ่งก็เลยเกิดฉงนขึ้นมาว่ามันเขียนได้ยังไงฟะ
พอไปนั่งค้นออกมาปรากฎว่าเจอเวปนี้
http://adamcecc.blogspot.com/2011/01/javascript.html
ทำการอธิบายไว้อย่างดีเลยว่าแต่ละstepมาได้ยังไง
เช่นว่า
$=[] สร้าง empty array
__=!$+$  โดยที่ถ้า$==[] อยู่ ก็จะกลายเป็น ![] + [] แล้วก็จะเป็น false+[] และก็จะกลายเป็น "false" ใส่ไว้ในตัวแปรชื่อ __
_=-~-~-~$ นี่ก็เทพมาก ต้องเกริ่นก่อนว่า เมื่อ $==[] อยู่ พอเจอ operator ไม่ว่าจะเป็น ~(bitwise not) หรือ - (negative) แอเรย์เปล่าๆก็จะกลายมีค่าเป็น 0
แต่ที่เทพจริงๆก็คือ ~0 จะได้ออกมาเป็น -1 แล้วพอใส่ลบนำหน้าไป ก็จะออกมาเป็น -(-1)==1 ง่ายๆ
ดังนั้น -~ นำหน้าอะไรก็ตามจะได้ผลลัพธ์ทำนองเดียวกันกับ ค่านั้น+1
มาดูว่าจริงๆแล้วทำงานยังไง
~0 หมายถึงเราทำ bitwise not กับค่าศูนย์ทุกบิต
จาก ~ 00000000 ก็จะกลายเป็น 11111111
ซึ่งพอทำ 2's complement กลับมา มันก็จะกลายเป็น -1 นั่นเอง
แต่พอใส่ - นำหน้า -1 จะเปลี่ยนเป็น +1 (อันนี้ปกติไม่แปลก)
พอเราใส่เป็น ~-~0 ก็จะเหมือนทำ ~1 ก็จะเป็นแบบนี้อีก
~1 == ~00000001 == 11111110 == -2
แบบนี้ไปเรื่อยๆ
เอาเป็นว่า สรุปเป็นหลักๆ ได้แบบนี้ เวลาอยากจะ obfuscate javascript
1. มี javascript ก่อน ว่าจะเอาอะไรเวลา obfuscate
2. สร้างทริคโค้ดเพื่อให้ได้ตัวอักษรนั้นๆออกมา เช่น !''==true แล้วเอามาทำเป็นสตริง
3. ใช้การเข้าถึงstringแบบarray เช่น "true"[1] == "r"
4. เอามาต่อกันเพื่อให้เป็น string
5. ใช้ทริ๊ค javascript เพื่อให้ได้ object window ออกมา เช่น ($=[]["sort"])()=window
6. แล้วก็เรียกใช้คำสั่งแบบ  window["alert"](1)  แทนที่จะเป็น window.alert(1)

มีคนทำวีดีโอบรรยายเรื่องแบบนี้ที่

Javascript With No Letters or Numbers: Joey Tyson NoVa Hackers Oct 2010 from Georgia Weidman on Vimeo.

แต่ถ้าไม่ทำก็คงไม่เห็นภาพ งั้นเดี๋ยวจะ derive ให้ดูทีละ step
1:($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_)
2:($=[[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[]
3:($=[[]][(__=![]+[])[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[]
4:($=[[]][(__=false+[])[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[]
5:($=[[]][(__="false")[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[]
6:($=[[]]["false"[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
7:($=[[]]["false"[_=-~-~-~[]]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
8:($=[[]]["false"[_=-~-~-(-1)]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
9:($=[[]]["false"[_=-~-~1]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
10:($=[[]]["false"[_=-~-(-2)]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
11:($=[[]]["false"[_=-~2]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
12:($=[[]]["false"[_=-(-3)]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
13:($=[[]]["false"[_=3]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false"
14:($=[[]]["false"[3]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3
15:($=[[]]["s"+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3
15:($=[[]]["s"+"[object Object]"[3/3]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3
16:($=[[]]["s"+"o"+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3
17:($=[[]]["s"+"o"+($$=($_=true+[])[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3
18:($=[[]]["s"+"o"+($$=($_="true")[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3
19:($=[[]]["s"+"o"+($$="true"[1]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3,$_="true"
20:($=[[]]["s"+"o"+($$="r"+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3,$_="true"
21:($=[[]]["s"+"o"+($$="r"+"true"[0])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3,$_="true"
22:($=[[]]["s"+"o"+($$="r"+"t")])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3,$_="true"
23:($=[[]]["s"+"o"+"rt"])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3,$_="true",$$="rt"
24:($=[[]]["sort"])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=[],__="false",_=3,$_="true",$$="rt"
25:window[__[_/_]+__[_+~$]+$_[_]+$$](_/_):$=window,__="false",_=3,$_="true",$$="rt"
26:window["false"[1]+"false"[3+(-1)]+"true"[3]+"rt"](1):$=window,__="false",_=3,$_="true",$$="rt"
27:window["a"+"l"+"e"+"rt"](1):$=window,__="false",_=3,$_="true",$$="rt"
28:window["alert"](1):$=window,__="false",_=3,$_="true",$$="rt"

มีบางส่วนที่ย่อไปเช่น _/_ คือหมายถึง 3/3 ซึ่งก็คือ 1
แล้วก็มีเสต็ป ($=[[]]["sort"])() ซึ่งเป้นทริกของ(ช่องโหว่)ของ Javascript ที่จะให้ผลลัพธ์ออกมาแล้วได้ออปเจ็ค window ออกมา


ref:
- คำบรรยาย http://adamcecc.blogspot.com/2011/01/javascript.html
- วีดีโอบรรยายเรื่องนี้ เนื้อหาเยอะ http://vimeo.com/15961577
- เนื้อหาเทคนิคobfuscateแบบต่างๆ http://sla.ckers.org/forum/list.php?24
- converter http://discogscounter.getfreehosting.co.uk/js-noalnum_com.php
- converter http://utf-8.jp/public/jsfuck.html
- converter(แบบใช้emoticon) http://utf-8.jp/public/aaencode.html

No comments:

Post a Comment