Conversion

String conversion and/or encoding is an important part of exploitation and firewall bypass

Convert String/Binary to Hex

If no prefix is needed, you just do the following

"Rubyfu".unpack("H*")

Otherwise, see the below ways

for a single character

'\x%02x' % "A".ord

Note: the symbols *"" are equal of .join

"ABCD".unpack('H*')[0].scan(/../).map {|h| '\x'+h }.join

or

"ABCD".unpack('C*').map { |c| '\x%02x' % c }.join

or

"ABCD".split("").map {|h| '\x'+h.unpack('H*')[0] }*""

or

"ABCD".split("").map {|c|'\x' + c.ord.to_s(16)}.join

or

"ABCD".split("").map {|c|'\x' + c.ord.to_s(16)}*""

or

"ABCD".chars.map {|c| '\x' + c.ord.to_s(16)}*""

or

"ABCD".each_byte.map {|b| b.to_s(16)}.join

or

"ABCD".each_char.map {|c| '\x'+(c.unpack('H*')[0])}.join

or

"ABCD".chars.map {|c| '\x%x' % c.ord}.join

Source: Ruby | Convert ASCII to HEX

Returns

\x41\x42\x43\x44

Convert Hex to String/Binary

["41424344"].pack('H*')

or

"41424344".scan(/../).map { |x| x.hex.chr }.join

or for raw socket

"41424344".scan(/../).map(&:hex).pack("C*")

Return

ABCD

in-case of binary that out of .chr range. For example you may need to convert IP-address to hex raw then send it through socket. The case of just converting it to hex would not work for your

>> ip
=> "192.168.100.10"
>> ip.split(".").map {|c| '\x%02x' % c.to_i}.join 
=> "\\xc0\\xa8\\x64\\x0a"

As you can see, Ruby reads returns "\\xc0\\xa8\\x64\\x0a" which doesn't equal "\xc0\xa8\x64\x0a". Try to inter this value(with double-quotes) "\xc0\xa8\x64\x0a" into your irb directly and you'll notice that the return is "\xC0\xA8d\n" which what should be passed to the raw socket not the "\\xc0\\xa8\\x64\\x0a". The main cause is ruby escapes the backslash(\).

To solve this issue, use pack to convert integers to 8-bit unsigned (unsigned char)

ip.split(".").map(&:to_i).pack("C*")

Note about hex: Sometimes you might face a none printable characters especially due dealing with binary raw. In this case, append (# -*- coding: binary -*-) at top of your file to fix any interpretation issue.

Convert Hex(Return address) to Little-Endian format

Little-Endian format is simply reversing the string such as reversing/backwarding "Rubyfu" to "ufybuR" which can be done by calling reverse method of String class

"Rubyfu".reverse

In exploitation, this is not as simple as that since we're dealing with hex values that may not represent printable characters.

So assume we have 0x77d6b141 return address which we've to convert it to Little-Endian format to allow CPU to read it correctly.

Generally speaking, it's really a trivial task to convert 0x77d6b141 to \x41\xb1\xd6\x77 since it's one time process but this is not the case of you have ROP chain that has to be staged in your exploit. To do so simply pack it as array

[0x77d6b141].pack('V')

It happens that sometime you get an error because of none Unicode string issue. To solve this issue, just force encoding to UTF-8 but most of the time you will not face this issue

[0x77d6b141].pack('V').force_encoding("UTF-8")

If you have ROP chain then it's not decent to apply this each time so you can use the first way and append (# -*- coding: binary -*-) at top of your exploit file.

Convert to Unicode Escape

Hexadecimal unicode escape

"Rubyfu".each_char.map {|c| '\u' + c.ord.to_s(16).rjust(4, '0')}.join

Or using unpack

"Rubyfu".unpack('U*').map{ |i| '\u' + i.to_s(16).rjust(4, '0') }.join

shorter way

"Rubyfu".unpack('U*').map{ |i| "\\u00%x" % i }.join

Octal unicode escape

For octal escape is exact the same except we convert the string to octal instead of hexadecimal

"Rubyfu".each_char.map {|c| '\u' + c.ord.to_s(8).rjust(4, '0')}.join

En/Decode base-64 String

We'll present it by many ways

Encode string

["RubyFu"].pack('m0')

or

require 'base64'
Base64.encode64 "RubyFu"

Decode

"UnVieUZ1".unpack('m0')

or

 Base64.decode64 "UnVieUZ1"

TIP: The string unpack method is incredibly useful for converting data we read as strings back to their original form. To read more, visit the String class reference at www.ruby-doc.org/core/classes/String.html.

En/Decode URL String

URL encoding/decoding is something known to most people. From hacker's point of view, we need it a lot in client-side vulnerability the most.

Encoding string

require 'uri'
puts URI.encode 'http://vulnerable.site/search.aspx?txt="><script>alert(/Rubyfu/.source)</script>'

Decoding string

require 'uri'
puts URI.decode "http://vulnerable.site/search.aspx?txt=%22%3E%3Cscript%3Ealert(/Rubyfu/.source)%3C/script%3E"

You can encode/decode and none URL string, of-course.

The above way will encode any non URL standard strings only(ex. <>"{}) however if you want to encode the full string use URI.encode_www_form_component

puts URI.encode_www_form_component 'http://vulnerable.site/search.aspx?txt="><script>alert(/Rubyfu/.source)</script>'

HTML En/Decode

Encoding HTML

require 'cgi'
CGI.escapeHTML('"><script>alert("Rubyfu!")</script>')

Returns

&quot;&gt;&lt;script&gt;alert(&quot;Rubyfu!&quot;)&lt;/script&gt;

Decoding HTML

require 'cgi'
CGI.unescapeHTML("&quot;&gt;&lt;script&gt;alert(&quot;Rubyfu!&quot;)&lt;/script&gt;")

Returns

"><script>alert("Rubyfu!")</script>

En/Decode SAML String

Decoding SAML

# SAML Request 
saml = "fZJNT%2BMwEIbvSPwHy%2Fd8tMvHympSdUGISuwS0cCBm%2BtMUwfbk%2FU4zfLvSVMq2Euv45n3fd7xzOb%2FrGE78KTRZXwSp5yBU1hpV2f8ubyLfvJ5fn42I2lNKxZd2Lon%2BNsBBTZMOhLjQ8Y77wRK0iSctEAiKLFa%2FH4Q0zgVrceACg1ny9uMy7rCdaM2%2Bs0BWrtppK2UAdeoVjW2ruq1bevGImcvR6zpHmtJ1MHSUZAuDKU0vY7Si2h6VU5%2BiMuJuLx65az4dPql3SHBKaz1oYnEfVkWUfG4KkeBna7A%2Fxm6M14j1gZihZazBRH4MODcoKPOgl%2BB32kFz08PGd%2BG0JJIkr7v46%2BhRCaEpod17DCRivYZCkmkd4N28B3wfNyrGKP5bws9DS6PKDz%2FMpsl36Tyz%2F%2Fax1jeFmi0emcLY7C%2F8SDD0Z7dobcynHbbV3QVbcZW0TlqQemNhoqzJD%2B4%2Fn8Yw7l8AA%3D%3D"

require 'cgi'
require 'base64'
require 'zlib'

inflated = Base64::decode64(CGI.unescape(saml))
# You don't need below code if it's not deflated/compressed
zlib = Zlib::Inflate.new(-Zlib::MAX_WBITS)
zlib.inflate(inflated)

Returns

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"agdobjcfikneommfjamdclenjcpcjmgdgbmpgjmo\" Version=\"2.0\" IssueInstant=\"2007-04-26T13:51:56Z\" ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" ProviderName=\"google.com\" AssertionConsumerServiceURL=\"https://www.google.com/a/solweb.no/acs\" IsPassive=\"true\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">google.com</saml:Issuer><samlp:NameIDPolicy AllowCreate=\"true\" Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified\" /></samlp:AuthnRequest>\r\n"

Source

More about SAML




results matching ""

    No results matching ""