大雨が2連夜続いた後は快適で、仕事から帰ってジャグを続けました。
昨夜、一握りの/ proc / $ pid / memを操作して、プロセスコードの挿入に関する記事を書きました
。https://blog.csdn.net/dog250/article/details/108618568
この方法は、カーネルを使用してエクスポートする方法にすぎません。 procfsのmemファイル、そしてありがたいことにそれは書き込み可能です!これは普遍的な方法ではありません。ptraceとstapに関しては、それらはクラフトというよりはツールです。
スワップスペースは十分に普遍的であり、どのシステムにもそれがあります。これは最新のオペレーティングシステムのインフラストラクチャの重要な部分です。この記事では、スワップスペースを使用して開始します。
先週末、コンピューターの仮想マシンのスワップスペースをひもでつなぎました。怖かったです。すべてが揃っていました。さまざまなアカウントパスワードとログインしたWebサイトの多くがスワップスペースにありました。そこで、すぐにスワップをオフにしました。 。
スワップスペースは漏れやすいバケットです!公共の乾燥ラック。
したがって、スワップスペースを使用してプロセスハックを実行できます。
ちなみに、スワップスペースの暗号化については考えないでください。スワップはすでに遅いです。暗号化と復号化を再度行うことができます。遅い方が遅いです。フラットなアドレススペースを取得するために、そうすることは無意味です。メモリを追加してください。それでおしまい。
しかし、メモリスティックを追加してメモリ全体をダンプすることはできませんか?たとえば、/ dev / mem、/ proc / $ pid / mem ...それでも、スワップよりも安全です。ハックの交換はとても簡単です!
まず、スワップスペースの特定の場所をカバーすることで、プロセスでプライベートデータを変更するという目的を達成したいと思います。
最初にコードを見てください:
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#define MADV_SOFT_OFFLINE 101
int main(int argc, const char **argv)
{
void *map[65536];
char buf[256];
int i = 0, which;
// 循环分配内存并写内存,目的是触发swap to disk操作。
while (i < 65535) {
// 65535也许有点小了,为了实验的目的,我特意将虚拟机内存缩小为64M,以更容易地触发内存swap。
map[i] = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
if (map[i] == NULL)
break;
// 眼睁睁看着是这些字符串复制进了buffer
snprintf(buf, 256, "E%d:ZheJiang Wenzhou skinshoe wet,down rain enter water not can fat", i);
strcpy(map[i], buf);
i ++;
}
printf("map:%d\n", i);
scanf("%d", &which);
printf("map after:%s\n", map[which]);
return 0;
}
次の手順は一度に実行されます。
- スワップスペース内の特性文字列の位置を見つけます。
- 文字列ddをスワップスペースの対応する位置に置き換えます。
参照してください:
# 在swap空间查找特征字符串的位置偏移
# 注意,我用1234做索引,目的后面我会导出进程map数组的第1234个元素,以查验它有没有被修改。
[root@localhost test]# strings -a -t x /dev/dm-1 |grep E1234:ZheJiang
391f000 E1234:ZheJiang Wenzhou skinshoe wet,down rain enter water not can fat
[root@localhost test]#
# 展示一下替换字符串以及其大小
[root@localhost test]# ll ./new
-rw-r--r-- 1 root root 70 9月 17 17:32 ./new
[root@localhost test]# cat new
DDDDD:Zhejiang Wenzhou pixie shi,xia yu jin shui bu hui pang
[root@localhost test]#
# 上述偏移 0x391f000 的十进制 59895808,用替换自负串覆盖swap空间的特征字符串
[root@localhost test]# dd if=./new of=/dev/dm-1 obs=1 bs=1 seek=59895808 count=70
记录了70+0 的读入
记录了70+0 的写出
70字节(70 B)已复制,0.00130832 秒,53.5 kB/秒
この記事では例として特徴的な文字列のみを使用していることに注意してください。実際には、任意のバイナリを使用して一致させることができます。ここでは、主に文字列コマンドの方が便利で、通常のルールも使用できるため、文字列を使用します。任意のバイナリ一致の場合は、他のバイナリパターンマッチング技術が必要です。
次に、mmapプログラムが実行されているターミナルのインデックスとして1234を入力して、状況を確認します。
1234 # 此为输入,根据特征字符串E1234:ZheJiang,需要输入1234为索引
map after:DDDDD:Zhejiang Wenzhou pixie shi,xia yu jin shui bu hui pang
[root@localhost test]#
正常に交換されました!今回はstapを使用せず、/ proc / $ pid / memを記述せず、swapを記述しました。
データを置き換えることができるので、スタックスペースはデータの一部であり、スワップアウトすることもできます。スワップを書き込んでスタックを操作できる場合、ROPと同様の操作を完了して、リターンアドレスを自由に置き換えることはできません。
次に、試してみましょう。
別のコードを見てください:
#include <stdio.h>
#include <stdlib.h>
void func()
{
char v[] = "555555555555555555555555";
getchar();
printf("after getchar\n");
}
int main(int argc, char **argv)
{
func();
printf("end\n");
return 0;
}
簡単です。一度実行してみましょう。
[root@localhost test]# ./a.out
A
after getchar
end
[root@localhost test]#
文字を入力し、2行のプロンプトを出力するだけです。
私の目標は、スワップスペースを操作し、printfをバイパスして、funから直接戻ることにより、プログラムが「getcharの後」という文を出力しないようにすることです。もちろんできます!
最初に実行しますが、次のように入力しないでください。
[root@localhost test]# ./a.out
... # 等待输入
objdumpを介してgetcharの元のリターンアドレスの場所を確認します。
400593: e8 b8 fe ff ff callq 400450 <getchar@plt>
400598: bf 60 06 40 00 mov $0x400660,%edi
40059d: e8 8e fe ff ff callq 400430 <puts@plt>
4005a2: c9 leaveq
まあ、それは0x400598です。スワップスペースを変更してから戻りアドレスを0x4005a2に変更することにより、objdumpに配置されるprintfをスキップしたいと思います。
次のステップは、スワップスペースでa.outプログラムのスタック位置を見つけることです。
スワップスペースを操作してプロセスのスタックを変更する場合は、そのスタックをスワップアウトする方法を見つける必要があります。o.outスタックをスワップアウトする場合は、この記事の冒頭にあるmmapプロセスを使用してメモリを割り当てます。次に、入力を待機している非アクティブなプロセスa.outのスタックメモリはもちろんスワップアウトされます。
それを確認します:
[root@localhost test]# ps -e|grep a.out
3230 pts/2 00:00:01 a.out
[root@localhost test]# cat /proc/3230/smaps |grep -A15 stack|grep Swap
Swap: 16 kB
次に、その近くにあるgetchar 0x400598の戻りアドレスを見つけようとして、特性文字列「555555555555555555555555」を探します。
[root@localhost test]# strings -a -t x /dev/dm-1 |grep 555555555555555555555555
2e5e09a 555555555555555555555555 # 2e5e09a向下附近确定为48619550,也可以是附近别的值。
[root@localhost test]# dd of=./stack if=/dev/dm-1 obs=1 bs=1 skip=48619550 count=4096
「vi-b./stack」の「:%!xxd」を使用してバイナリスタックファイルを編集し、次の場所を見つけます。
...
00000050: 647f 0000 0000 0000 0000 0000 9805 4000 d.............@.
00000060: 0000 0000 3535 3535 3535 3535 3535 3535 ....555555555555
00000070: 3535 3535 3535 3535 3535 3535 0000 0000 555555555555....
...
「98054000」を「a2054000」に変更します。
00000050: 647f 0000 0000 0000 0000 0000 a205 4000 d.............@.
「%!xxd-r」で保存してから、ddを戻します。
[root@localhost test]# dd if=./stack of=/dev/dm-1 obs=1 bs=1 seek=48619550 count=4096
a.outを実行している端末に文字「A」を入力します。
[root@localhost test]# ./a.out
A
end
[root@localhost test]#
printfのバイパスに成功しました!
この種の攻撃を完了したいのは非常に簡単です。システムをトリガーしてメモリをスワップスペースにスワップする必要があります。メモリを割り当ててから、システムメモリをプッシュしてスワップスペースのパブリックビジビリティを活用します。
プロセスのスタックがスワップアウトされた場合、スワップスペース内のスタックの位置を見つけることができれば、スタック上の任意のデータをスタックできると言わなければなりません。ReturnToLibcをオフラインで満たすROPを構築することは難しくありません。主に手の速度、速くなければなりません!
どのように言って?最新のオペレーティングシステムでスワップスペースは必要ですか?
最新のオペレーティングシステムは、仮想ストレージベースのオペレーティングシステムとして、原則としてメモリメディアの違いを保護し、プロセスにフラットなアドレス空間を提供することを目的としています。問題はありません。しかし、実際には、このメカニズムはもはや必要ないと思います。小さなメモリシステムにはより多くのスワップの価値が適用されますが、現在のシステムメモリは数十ギガバイトであることがよくあります。スワップが有効になっていると、セキュリティが保証されません。頻繁にスワップインおよびスワップアウトすると、プロセス操作の遅延やジッタも発生します。もう必要ありません。
スワップをオフにします。
浙江文州の革靴は濡れているので、雨でも太りません。