我正在盯着这个prolog代码而头疼,我似乎无法围绕着必须做的事情......
基本上,代码试图打破给定的协议,这意味着攻击者想要了解一些秘密数据。 所以攻击者试图攻击以获得这个秘密。要做到这一点,他必须成功运行协议。
successfulRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1)
Init,Resp和Xchd是发送的消息的名称。 该谓词基本上表示成功运行是在发送一些Init_X(X是消息部分)时,Init_X的接收者发送RespGet_X作为响应,攻击者截获RespGet_X并自己发送Resp_X,Resp_X的接收者发送XchdGet_X作为响应
然后我有一个完整的运行,我注意到了。
asserta(fullRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1))
如果攻击者在成功运行后知道秘密,则秘密会泄露。 如果秘密没有泄漏,则必须删除攻击期间获得的知识(因为实际上你不应该能够攻击一次交互的两个实例)。 然后开始新的攻击尝试。
如果攻击成功并且秘密被泄露,则会写一些关于攻击者如何获得秘密的信息。
tryToAttack(Secret) :-
successfulRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1),
asserta(fullRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1)),
(
(
leaks(Secret),!
);
(
\+leaks(secret),
(
deleteAttackKnowledge;
(
tryToAttack(Secret),
true
)
)
)
),
writeAttackPattern(Secret,Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1).
好的,这是问题的开始: 在成功运行期间,提取攻击知识。这种知识被认为是事实!如果它没有持久性,那就不会有问题。所以另一种选择可能是不要让攻击知识持久化。
如果运行成功,但我们已经完成了这样的完整运行,我想从头开始执行另一次运行,这与上一次运行不同。我还希望在上次运行期间获得的所有攻击知识都被删除。
我看到的问题是:如果我把
(
fullRun(...),
deleteAttackKnowledge
)
在successRun结束时,Prolog尝试返回init或resp,攻击者在其中构建他的消息。如果Prolog回到resp,新的运行不会从respGet获得攻击知识。
我想 跑步 2.看看这次运行是否已经完成 3.如果已经完成,请删除所有攻击知识并转到(1),执行不同的运行。
successfulRun(Init_1,Init_2,Init_3,RespGet_1,RespGet_2,RespGet_3,Resp_1,Resp_2,Resp_3,XchdGet_1) :-
init(Init_1,Init_2,Init_3),
canBuild(Init_1),
canBuild(Init_2),
canBuild(Init_3),
respGet(RespGet_1,RespGet_2,RespGet_3,Init_1,Init_2,Init_3),
extractAttackKnowledge(RespGet_1),
extractAttackKnowledge(RespGet_2),
extractAttackKnowledge(RespGet_3),
resp(Resp_1,Resp_2,Resp_3),
canBuild(Resp_1),
canBuild(Resp_2),
canBuild(Resp_3),
xchdGet(XchdGet_1,Resp_1,Resp_2,Resp_3),
extractAttackKnowledge(XchdGet_1).
成功运行注意事项: init,resp:攻击者发送的内容 respGet,XchdGet:攻击者发出消息后对方发送的内容 canBuild:攻击者可以根据他的知识(开始知识+攻击知识)构建消息部分吗? extractAttackKnowledge:从消息部分中提取新的攻击知识
提前致谢, 丹尼尔W。
P.S。:如果有任何不清楚的地方,请随时发表评论。
答案 0 :(得分:0)
要从失败的尝试中删除学到的信息,可以使用retractall / 1谓词。
例如:
deleteAttackKnowledge :- retractall(fullRun(_,_,_,_,_,_,_,_,_,_)).
注意:如果声明fullRun / 10是动态的(通过在代码顶部添加“: - dynamic(fullRun / 10)。”行),解释器将更容易处理。
由于我还不完全明白你到目前为止所做的事情,我现在就打算留下我的答案,如果我找到了可能有用的东西,我会回来再增加一个答案或者给你发一条消息。