2019/10/16


Linux の sudo に root 権限を奪取できるバグが見つかった。

Linuxの「sudo」コマンドにroot権限奪取の脆弱性。ユーザーID処理のバグで制限無効化 - Engadget 日本版

この脆弱性は、sudoコマンドのユーザーIDに-1もしくは4294967295を指定すると、誤って0(ゼロ)と認識して処理してしまうというもの。0(ゼロ)はrootのユーザーIDであるため、攻撃者は完全なrootとしてコマンドを実行できることになります。

https://japanese.engadget.com/2019/10/14/linux-sudo-root-id/

既に Ubuntu 等にはパッチが配布され始めているらしいですが、この記事ではこのバグが如何にして起こったのかを調査し今後の為に共有したい。

sudo のコードは以下からダウンロードできる。取得には mercurial が必要。

Sudo Source Repo
https://www.sudo.ws/hg.html

修正差分は以下。

sudo: 83db8dba09e7
https://www.sudo.ws/repos/sudo/rev/83db8dba09e7

差分だと分かりづらいので、この現象が起きうるソースを調べていく。sudo は実行されると plugins/sudoers/sudoers.cinit_vars が呼ばれ、続いて set_runaspwrunas_user ありで呼ばれる。set_runaspw では与えられたユーザID文字列(#-1 の # 以降)を解析する為に sudo_strtoid_v1 が呼ばれる。この sudo_strtoid_v1 が今回バグを生んだ関数。

id_t
sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr)
{
    char *ep;
    id_t ret = 0;
    long long llval;
    bool valid = false;
    debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)

    /* skip leading space so we can pick up the sign, if any */
    while (isspace((unsigned char)*p))
        p++;
    if (sep == NULL)
        sep = "";
    errno = 0;
    llval = strtoll(p, &ep, 10);
    if (ep != p) {
        /* check for valid separator (including '\0') */
        do {
            if (*ep == *sep)
                valid = true;
        } while (*sep++ != '\0');
    }
    if (!valid) {
        if (errstr != NULL)
            *errstr = N_("invalid value");
        errno = EINVAL;
        goto done;
    }
    if (errno == ERANGE) {
        if (errstr != NULL) {
            if (llval == LLONG_MAX)
                *errstr = N_("value too large");
            else
                *errstr = N_("value too small");
        }
        goto done;
    }
    ret = (id_t)llval;
    if (errstr != NULL)
        *errstr = NULL;
    if (endp != NULL)
        *endp = ep;
done:
    debug_return_id_t(ret);
}

勘のいい方であれば、これを見ただけで「アーーーッ!」と思うかもしれない。

    llval = strtoll(p, &ep, 10);
    if (ep != p) {
        /* check for valid separator (including '\0') */
        do {
            if (*ep == *sep)
                valid = true;
        } while (*sep++ != '\0');
    }

strtoll は文字列のポインタを基数と共に渡すと、long long 型整数値に変換し戻り値で返却します。数値として解釈された後は数値として解釈できなかった文字まで第二引数で指定されたポインタがシフトします。つまりこのコードでもし -1 が指定されると、正常な数値として扱われます。errno も設定されません。llval の範囲チェックもされていません。epp は異るアドレスとなり、今回呼び出されるケースでは sep が NULL なので -1 という単語のみをチェックする為に呼ばれたこの関数は、valid = true と認識してしまいます。後は時の流れに身を任せ、あなたの色に染められるだけになります。怖いですね。修正内容では strtoll 呼び出し直後に errno の確認が行われ、値の範囲も確認されています。正直なぜこれ strtoul を使わないんだろうなと思ったりもしますがソースの場所からするとユーティリティ関数なのでしょう。wandbox でお試しできる様にしてあるので遊びたい人は遊んで下さい。数字の横が (null) ならパスしたという事になります。

なお -1 が通ってしまうと何がまずいかについてはココを参照下さい。

教訓

境界値チェックを行わないと、死ぬ

Posted at by



2019/10/10


8月に Google Developers Expert となり、新米の様にオロオロとしています。過去の GDE ミーティングの議事録を見せて頂いているのですが Google Document に保存されており、Go だけでなく他のカテゴリの GDE に関する物も含めると全てに目を通すのはなかなか骨が折れます。技術者なので問題は技術で解決すべく、これらの資料を grep 検索できる様にしました。

Google Document はエクスポートすると Microsoft Word の形式となるので、Microsoft Word から Markdown に変換するプログラムを書けばテキスト検索もできるし、なんならそのまま GitHub に貼り付けてしまう事もできます。

GitHub - mattn/docx2md

docx2md Convert Microsoft Word Document to Markdown Usage -1 docx2md NewDocument.docx Installation -1 ...

https://github.com/mattn/docx2md

出力は UTF-8 のテキストファイルなので、grep コマンドを使って検索できます。Windows から日本語を使って検索するのであれば jvgrep を使って頂く事もできます。

docx2md

ぜひ御活用ください。また、まだ未対応の書式が幾つかあるのでプルリクエストをお待ちしています。

そうそう、GitHub Sponsors を開設したのでよろしくお願いします!

Sponsor @mattn on GitHub Sponsors
https://github.com/users/mattn/sponsorship
改訂2版 みんなのGo言語 改訂2版 みんなのGo言語
松木 雅幸, mattn, 藤原 俊一郎, 中島 大一, 上田 拓也, 牧 大輔, 鈴木 健太
技術評論社 / (2019-08-01)
 
発送可能時間:

Posted at by



2019/09/25


「.NET Core 3.0」正式版が登場。Windowsデスクトップアプリ開発可能、exeファイルを生成、マイクロサービス対応など - Publickey

最新記事10本 Kafka開発元のConfluentに聞いた。エンタープライズ市場への道筋、大手クラウドとの現在の関係について 最大32コアのAMD EPYCプロセッサを搭載、コストパフォーマンスを高...

https://www.publickey1.jp/blog/19/net_core_30windowsexe.html

これまで通り、dotnet コマンドで SDK テンプレートを使って色々なアプリケーションを作成できる様になっている。dotnet 3.0 から使える SDK テンプレートは以下の通り。

使用法: new [options]

オプション:
  -h, --help          Displays help for this command.
  -l, --list          Lists templates containing the specified name. If no name is specified, lists all templates.
  -n, --name          The name for the output being created. If no name is specified, the name of the current directory is used.
  -o, --output        Location to place the generated output.
  -i, --install       Installs a source or a template pack.
  -u, --uninstall     Uninstalls a source or a template pack.
  --nuget-source      Specifies a NuGet source to use during install.
  --type              Filters templates based on available types. Predefined values are "project", "item" or "other".
  --dry-run           Displays a summary of what would happen if the given command line were run if it would result in a template creation.
  --force             Forces content to be generated even if it would change existing files.
  -lang, --language   Filters templates based on language and specifies the language of the template to create.
  --update-check      Check the currently installed template packs for updates.
  --update-apply      Check the currently installed template packs for update, and install the updates.


Templates                                         Short Name               Language          Tags                                 
----------------------------------------------------------------------------------------------------------------------------------
Console Application                               console                  [C#], F#, VB      Common/Console                       
Class library                                     classlib                 [C#], F#, VB      Common/Library                       
WPF Application                                   wpf                      [C#]              Common/WPF                           
WPF Class library                                 wpflib                   [C#]              Common/WPF                           
WPF Custom Control Library                        wpfcustomcontrollib      [C#]              Common/WPF                           
WPF User Control Library                          wpfusercontrollib        [C#]              Common/WPF                           
Windows Forms (WinForms) Application              winforms                 [C#]              Common/WinForms                      
Windows Forms (WinForms) Class library            winformslib              [C#]              Common/WinForms                      
Worker Service                                    worker                   [C#]              Common/Worker/Web                    
Unit Test Project                                 mstest                   [C#], F#, VB      Test/MSTest                          
NUnit 3 Test Project                              nunit                    [C#], F#, VB      Test/NUnit                           
NUnit 3 Test Item                                 nunit-test               [C#], F#, VB      Test/NUnit                           
xUnit Test Project                                xunit                    [C#], F#, VB      Test/xUnit                           
Razor Component                                   razorcomponent           [C#]              Web/ASP.NET                          
Razor Page                                        page                     [C#]              Web/ASP.NET                          
MVC ViewImports                                   viewimports              [C#]              Web/ASP.NET                          
MVC ViewStart                                     viewstart                [C#]              Web/ASP.NET                          
Blazor Server App                                 blazorserver             [C#]              Web/Blazor                           
ASP.NET Core Empty                                web                      [C#], F#          Web/Empty                            
ASP.NET Core Web App (Model-View-Controller)      mvc                      [C#], F#          Web/MVC                              
ASP.NET Core Web App                              webapp                   [C#]              Web/MVC/Razor Pages                  
ASP.NET Core with Angular                         angular                  [C#]              Web/MVC/SPA                          
ASP.NET Core with React.js                        react                    [C#]              Web/MVC/SPA                          
ASP.NET Core with React.js and Redux              reactredux               [C#]              Web/MVC/SPA                          
Razor Class Library                               razorclasslib            [C#]              Web/Razor/Library/Razor Class Library
ASP.NET Core Web API                              webapi                   [C#], F#          Web/WebAPI                           
ASP.NET Core gRPC Service                         grpc                     [C#]              Web/gRPC                             
dotnet gitignore file                             gitignore                                  Config                               
global.json file                                  globaljson                                 Config                               
NuGet Config                                      nugetconfig                                Config                               
Dotnet local tool manifest file                   tool-manifest                              Config                               
Web Config                                        webconfig                                  Config                               
Solution File                                     sln                                        Solution                             
Protocol Buffer File                              proto                                      Web/gRPC                             

Examples:
    dotnet new mvc --auth Individual
    dotnet new --help

WinForms や WPF を使ったアプリケーションの開発もできる。すばらしい。

以下の手順でアプリケーションを作成すると、SayHello というメソッドを持った Greeter サービスが作られる。

$ dotnet new grpc -o mygrpc

proto ファイルは以下の通り。

syntax = "proto3";

option csharp_namespace = "mygrpc";

package Greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

dotnet コマンドを使ってそのまま実行できる。

試しにこの proto ファイルから Go のクライアントを作って接続してみる。以下のコマンドで Go のクライアントが作られる。

$ go get github.com/golang/protobuf/protoc-gen-go
$ protoc --go_out=plugins=grpc:. greet.proto

以下がそのクライアントを使ったサンプル。dotnet のサーバ側はポート 5000 番で通常ソケットの HTTP、5001 番で HTTP/2 で通信可能。dotnet run コマンドでは HTTP 通信のサーバは起動しないので dotnet build でビルドし、bin 配下にある exe ファイルを実行する。この exe ファイル出力も今回の .NET Core 3.0 の新しい機能になる。

package main

import (
    "fmt"
    "log"

    pb "github.com/mattn/grpc-greeter/Greet"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
)

func main() {
    conn, err := grpc.Dial("127.0.0.1:5000", grpc.WithInsecure())
    if err != nil {
        log.Fatal(err)
    }
    /*
        opts = append(opts, grpc.WithTransportCredentials(creds))
    */
    defer conn.Close()
    client := pb.NewGreeterClient(conn)

    hello := &pb.HelloRequest{
        Name: "おるみん",
    }

    result, err := client.SayHello(context.Background(), hello)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(result.GetMessage())
}

実行すると以下の結果が得られる。

Hello おるみん
Posted at by