Writeup | old_driver题目

admin 2024年2月7日23:51:18评论9 views字数 16258阅读54分11秒阅读模式

old_driver

官方WP

本题考查选手对对抗样本及相关防御技术的了解。

题目中生成对抗样本使用了经典的C&W攻击,且kappa很小,因此对抗样本会分布在两个分类的决策边界上,可以根据classification score来找分布在决策边界附近的样本从而找到对抗样本。此外,也有很多其他解法可以使用,比如重新训练一个新的模型来检测;或是使用常规的对抗样本防御方法(如对输入加filter)对使用防御前后的output进行比较。

from glob import glob
import torch
from torch import nn, optim
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torchattacks # https://github.com/Harry24k/adversarial-attacks-pytorch
from torchvision import transforms
from PIL import Image
import random
import os
from hashlib import md5, sha256
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(31005)
        self.conv1_bn = nn.BatchNorm2d(100)
        self.pool = nn.MaxPool2d(22)
        self.conv2 = nn.Conv2d(1001503)
        self.conv2_bn = nn.BatchNorm2d(150)
        self.conv3 = nn.Conv2d(1502501)
        self.conv3_bn = nn.BatchNorm2d(250)
        self.fc1 = nn.Linear(250 * 3 * 3350)
        self.fc1_bn = nn.BatchNorm1d(350)
        self.fc2 = nn.Linear(35010)
        self.dropout = nn.Dropout(p=0.5)

    def forward(self, x):
        x = self.pool(F.elu(self.conv1(x)))
        x = self.dropout(self.conv1_bn(x))
        x = self.pool(F.elu(self.conv2(x)))
        x = self.dropout(self.conv2_bn(x))
        x = self.pool(F.elu(self.conv3(x)))
        x = self.dropout(self.conv3_bn(x))
        x = x.view(-1250 * 3 * 3)
        x = F.elu(self.fc1(x))
        x = self.dropout(self.fc1_bn(x))
        x = self.fc2(x)
        return x
# load pretrained model
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
transform = transforms.ToTensor()
model = Model().to(device)
check_point = torch.load('model.pt', map_location=device)
model.load_state_dict(check_point)
model.eval()
Model(
  (conv1): Conv2d(3100, kernel_size=(55), stride=(11))
  (conv1_bn): BatchNorm2d(100, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (conv2): Conv2d(100150, kernel_size=(33), stride=(11))
  (conv2_bn): BatchNorm2d(150, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv3): Conv2d(150250, kernel_size=(11), stride=(11))
  (conv3_bn): BatchNorm2d(250, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (fc1): Linear(in_features=2250, out_features=350, bias=True)
  (fc1_bn): BatchNorm1d(350, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (fc2): Linear(in_features=350, out_features=10, bias=True)
  (dropout): Dropout(p=0.5, inplace=False)
dataset = []
images = glob('imgs/1/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 1))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[1].permute(120))
<ipython-input-4-d76776ea6971>:17: UserWarning: This overload of nonzero is deprecated:
    nonzero(Tensor input, *, Tensor out)
Consider using one of the following signatures instead:
    nonzero(Tensor input, *, bool as_tuple) (Triggered internally at  /tmp/pip-req-build-as628lz5/torch/csrc/utils/python_arg_parser.cpp:766.)
  candidates = torch.nonzero((diff<2) * (labels[:,0] == 1))

19 [[10.330801963806152, 8.862082481384277]] [[1, 0]]
128 [[14.271539688110352, 14.26427936553955]] [[1, 9]]
171 [[10.529718399047852, 9.856830596923828]] [[1, 0]]

Writeup | old_driver题目

对照benign样本,很容易发现128171为对抗样本,符合hint1中的0->1, 9->1

dataset = []
images = glob('imgs/0/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 0))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
34 [[10.157703399658203, 10.141921997070312]] [01]]
99 [[6.645545959472656, 5.240039348602295]] [03]]
212 [[7.364688873291016, 5.5696306228637695]] [[0, 3]]

Writeup | old_driver题目

对照benign样本,很容易发现34为对抗样本,符合hint1中的1->0

dataset = []
images = glob('imgs/6/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 6))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
8 [[3.92341685295105, 1.930528998374939]] [[6, ]]
44 [[13.969378471374512, 12.090963363647461]] [65]]
167 [[8.315347671508789, 7.1767144203186035]] [60]]
214 [[6.206953048706055, 5.905989646911621]] [62]]
284 [[4.233434200286865, 4.125830173492432]] [60]]
302 [[3.7329397201538086, 2.3108153343200684]] [67]]
391 [[18.115943908691406, 18.073213577270508]] [[6, 5]]

Writeup | old_driver题目

对照benign样本,很容易发现214,391为对抗样本,符合hint1中的2->6, 5->6

dataset = []
images = glob('imgs/4/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 4))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
36 [[6.250286102294922, 6.000677108764648]] [40]]
50 [[9.46463394165039, 7.811725616455078]] [40]]
61 [[14.604730606079102, 13.94554328918457]] [43]]
76 [[7.9692583084106445, 6.7764787673950195]] [40]]
80 [[8.397534370422363, 8.131750106811523]] [40]]
149 [[16.59321403503418, 16.373197555541992]] [43]]
180 [[10.952032089233398, 10.29800033569336]] [43]]
201 [[6.7305755615234375, 6.548830509185791]] [40]]
257 [[7.356083869934082, 6.452930450439453]] [40]]
273 [[15.939336776733398, 15.877418518066406]] [43]]
277 [[16.802980422973633, 15.91077995300293]] [43]]
352 [[7.009323596954346, 6.297818183898926]] [[4, 0]]

Writeup | old_driver题目

对照benign样本,很容易发现273为对抗样本,符合hint1中的3->4

dataset = []
images = glob('imgs/3/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 3))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
116 [[19.149414062519.01301383972168]] [[34]]

Writeup | old_driver题目

对照benign样本,很容易发现116为对抗样本,符合hint1中的4->3

dataset = []
images = glob('imgs/5/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 5))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
7 [[9.4365863800048838.46451187133789]] [[56]]
10 [[10.5232505798339848.977357864379883]] [[56]]
16 [[11.4447364807128911.173833847045898]] [[56]]
20 [[8.5878782272338878.520938873291016]] [[56]]
21 [[9.6437253952026377.751104354858398]] [[56]]
24 [[12.7618885040283212.530357360839844]] [[56]]
31 [[14.85756683349609414.418084144592285]] [[56]]
46 [[13.96209621429443413.051092147827148]] [[56]]
53 [[10.2103137969970710.173200607299805]] [[56]]
68 [[13.73441696166992211.935338973999023]] [[56]]
79 [[7.7379465103149416.343132972717285]] [[56]]
100 [[15.55479049682617214.059501647949219]] [[56]]
101 [[14.02905082702636713.515676498413086]] [[56]]
112 [[10.6978750228881849.460480690002441]] [[56]]
119 [[8.5579013824462896.617669582366943]] [[50]]
120 [[13.06632804870605512.191879272460938]] [[56]]
124 [[8.6675090789794927.228110313415527]] [[56]]
130 [[14.43569183349609414.335365295410156]] [[56]]
139 [[9.2712450027465829.001958847045898]] [[56]]
146 [[14.41243362426757813.142959594726562]] [[56]]
219 [[14.20075893402099612.73554801940918]] [[56]]
230 [[7.6147270202636726.99611759185791]] [[56]]
234 [[14.79042816162109413.05992317199707]] [[56]]
239 [[9.6507606506347668.966289520263672]] [[56]]
241 [[11.70835304260253911.589008331298828]] [[56]]
248 [[12.06055641174316410.089497566223145]] [[56]]
256 [[9.7232589721679698.10781478881836]] [[56]]
293 [[16.7404041290283216.495595932006836]] [[56]]
327 [[15.10475158691406213.598688125610352]] [[56]]
342 [[9.0774288177490238.786874771118164]] [[56]]
351 [[13.75986957550048811.78742504119873]] [[56]]
367 [[14.5404396057128912.767509460449219]] [[56]]

Writeup | old_driver题目

由于56两个class相似度较高,因此classification score也比较相近,仔细观察一下可以发现293是对抗样本

dataset = []
images = glob('imgs/8/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 8))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
99 [[11.6402130126953129.784014701843262]] [[89]]
127 [[12.06866264343261712.007749557495117]] [[87]]
166 [[9.303185462951668.16383171081543]] [[87]]
233 [[5.6221051216125494.620823860168457]] [[89]]
269 [[3.4993615150451662.3027079105377197]] [[81]]
322 [[10.4740915298461919.613511085510254]] [[89]]
342 [[9.1524028778076177.786888599395752]] [[87]]
356 [[6.6926622390747074.8316850662231445]] [[89]]
372 [[5.54667901992797854.865174293518066]] [[89]]

Writeup | old_driver题目

对照benign样本,很容易发现127为对抗样本,符合hint1中的7->8

dataset = []
images = glob('imgs/7/*.png')
images.sort(key=lambda fname: int(fname[7:-4]))
for fname in images:
    dataset.append((transform(Image.open(fname)).to(device), torch.tensor(0, device=device)))

dl = DataLoader(dataset, batch_size=64, shuffle=False)

plt.figure(figsize=(1616))
cnt = 1
with torch.no_grad():
    for idx, xy in enumerate(dl):
        x, y = xy
        output = model(x)
        topk, labels = torch.topk(output, k=2, dim=1)
        diff = topk[:,0] - topk[:,1]
        candidates = torch.nonzero((diff<2) * (labels[:,0] == 7))
        for candidate in candidates:
            print((candidate + idx*64).item(), topk[candidate].tolist(), labels[candidate].tolist())
            plt.subplot(88, cnt)
            cnt += 1
            plt.axis('off')
            plt.title('idx: {}'.format((candidate + idx*64).item()))
            plt.imshow(x[candidate[0]].permute(120))
plt.subplot(88, cnt-cnt%8+9)
plt.axis('off')
plt.title('benign')
plt.imshow(x[0].permute(120))
59 [[6.8438167572021486.5867600440979]] [[78]]

Writeup | old_driver题目

对照benign样本,很容易发现59为对抗样本,符合hint1中的8->7

最后计算flag

adversarial_images = [128, 171, 34, 214, 391, 273, 116, 293, 127, 59]
flag = 'flag{' + md5(str(sorted(adversarial_images)).encode()).hexdigest() + '}'
hint2 = sha256(str(sorted(adversarial_images)).encode()).hexdigest()
print('flag:', flag)
print('hint2:', hint2)

大佬WP by NanoApe

看题目是要你找出所有对抗样本,那众所周知对抗样本的改动肯定很小,所以直接人眼遍历全部图片,找不同,就可以了。

from hashlib import md5, sha256
for i in range(0749):
  a = [1281711162732932143915912734]
  if (sha256(str(sorted(a)).encode()).hexdigest() =='502e0423b82c251f280e4c3261ee4d01dca4f6fe0b663817e9fd43dffefc5ce9'):
    print(md5(str(sorted(a)).encode()).hexdigest())
    break

大佬WP by Ha1c9on  

⾮预期⽼玩家。

分析 attack.py 可知 代码基本就是找出样本攻击中错误的图⽚序号,然后带到adversarial_images = [171,34,214,273,116,391,293,127,59,128]数组,加密下就是flag。出题⼈还贴⼼的给了哪个⾥⾯有攻击图⽚,以及flag验证的sha1。

众所周知,这种题⽤时间排序就可以秒⼀切。

Writeup | old_driver题目

只需要按修改时间排序,就可以拿到错误的图⽚啦。找不到的⼿动找⼀下就好了!找到如下数据:

Writeup | old_driver题目

打印下sha1 ⼀致则打印flag

from glob import glob
import torch
from torch import nn, optim
import torch.nn.functional as F
import torchattacks # https://github.com/Harry24k/adversarial-attacks-pytorch
from torchvision import transforms
from PIL import Image
import random
import os
from hashlib import md5, sha256
adversarial_images = [171,34,214,273,116,391,293,127,59,128]
hint2 = sha256(str(sorted(adversarial_images)).encode()).hexdigest()
flag = 'flag{' + md5(str(sorted(adversarial_images)).encode()).hexdigest() + '}'
print(flag)
Writeup | old_driver题目

赛事交流QQ群:1028988858

有任何问题欢迎进群交流学习

或者私窗万能的果子姐姐(。・∀・)ノ゙

明日将继续放出剩余题目wp 

请锁定【春秋伽玛】 ~

Writeup | old_driver题目

原文始发于微信公众号(春秋伽玛):Writeup | old_driver题目

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月7日23:51:18
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Writeup | old_driver题目http://cn-sec.com/archives/1020340.html

发表评论

匿名网友 填写信息