zoukankan      html  css  js  c++  java
  • 【2019西电网信杯】线上赛部分题wp

    因为太菜了所以才打了全国第九...

    不过半小时AK了crypto是真的【呲牙】

    Dawn_whisper_解题报告

    MISC

    调查问卷

    随便填一填就能搞到flag了…

    HiddenImage

    Look "through" the image and get the flag.

    看到题目说明猜测可能是文件捆绑

    拿到ubuntu下binwalk一下:

     

    发现的确存在zip文件:

    Foremost一下,拿到gotflag.jpg

     

    打开之后发现flag并不是以图片形式显示的,那就用010 Editor打开查看文件尾部,

     

    看到这样可疑的编码

     

    OK,得到flag。

    Crypto

    RSA

    下载文件

     

    Interesting-RSA! You could finish it step by step and please use the search engine appropriately!

    看到提示和代码发现这个题是分步给出,所以我们需要一步步的解密。

    Part1:

     

    提示很贴心,c1是用p1加密得到的,看到e=3,而且n比c要大得多,就直接将c开3次方得到p。

    Part2:

     

    看了半天不知道这个部分对p和q有什么影响,所以直接跳过。

    Prat3:

     

    和Part1一样c3是用q加密得到的,所以掏出我们的神器分解一下n顺便求一下d:

     

    如图,该有的数据都有了。

    Part4:

     

    一样,flag_c是由flag加密的,所以写可以写出脚本并运行:

     

    直接转成ascii码

     

    Flag到手!

    Decrypt it!

    说实话拿到题目代码我吃了一惊(逃

     

    165行的代码我也是惊了

    不过出题人真的良心,所有的注释写的很详细(还把答案的计算方式写的很清楚),不然我觉得我也得做个半个小时左右。

    废话不多说,先分析代码:

    上面一大堆奇奇怪怪的代码不用太懂,重要的部分出题人标的很清楚(太良心了啊喂)

     

    其中一个函数,矩阵乘法(比赛的时候我还准备自己写后来发现已经有了2333)

    接着往下看:

     

    这么明显的格式基本就能猜到left和right矩阵互为逆矩阵,然而出题人在最后给了提示(太良心了啊喂):

     

    好了不扯这些没用的,接下来我们就看到了整个算法的核心:

    加密函数encrypt

     

    (这个注释也太详细了吧,这把难度降了多少啊)

    我们一句句分析:

     

    检查长度,不管,跳过,

     

    规定了随机数的种子(因为计算机生成的是伪随机数,所以规定了种子之后后续得到的随机数都是相同的)。

     

    随机生成16个数作为候选key,

     

    乱序,

     

    转为bytes,

     

    把明文和key异或一下

     

    将这时的plaintext(下文简称P)转为二维:

    我们将P[0:1]记为P[0],P[1:2]记为P[1]…以此类推,

    我们就能得到它将P转为二维的对应表格:

    P0

    P1

    P2

    P3

    P5

    P6

    P7

    P4

    P10

    P11

    P8

    P9

    P15

    P12

    P13

    P14

    接下来继续看:

     

    将这个矩阵和left相乘然后压成一维(这个地方要是没有提示我可能要卡半天)

     

    再把key乱序一下,

     

    再次和plaintext异或一下然后输出,

     

    解密函数,…显然是要我们自己写的。

     

    这里有flag加密后的密文,然而没多大用处,你要是不看的话下面出题人也很贴心:

     

    Flag的获得方式写的清清楚楚♂。

    所以分析完,这道题的关键就是写出加密函数的逆函数:

    为了方便,下午将cipher_text简称为c,第一次乱序得到的key记为key1,第二次乱序得到的key记为key2,

     

    先提前处理处key1和key2方便后面使用,

     

    我们逆着加密算法倒着进行,首先将c和key2进行异或

     

    然后将一维的c扩展成二维,

     

    将得到的矩阵乘以加密时用到的加密矩阵的逆矩阵,

    根据上面加密时对应的表格

    我们可以得到返回时所对应的表格:

    P0

    P1

    P2

    P3

    P7

    P4

    P5

    P6

    P10

    P11

    P8

    P9

    P13

    P14

    P15

    P12

     

    再把key1异或掉,就可以得到加密前的flag

    然后运行这个214行的代码(是真的累2333),就可以拿到flag:

     

    Reverse

    maze

    下载文件放进ubuntu用file看一下:

     

    ELF文件,看来是linux下的逆向,不过我们也可以拖进ida,找到main函数按F5

     

    程序使用了一个参数来表示整个map,其中找到了这么一句话:

     

    得知该map是50个一行。

    然后寻找map:

     

    在这个位置找到了map,提取出来之后如图:

     

    wasd顺着!走迷宫

     

    打开文件试一下:

     

    WTF?不对?

    再返回ida康康:

     

    map中间有两个奇怪的函数function,点开康康:

     

    发现这个function对map的两个位置进行了修改,根据地址找到位置,手动修改地图,wasd再来一遍,再打开试试:

     

    OK,得到flag。

    Programming

    死锁

    题目很简单,用edge连接事件,bfs即可

    代码如下:

      1 #include <algorithm>
      2 
      3 #include <iostream>
      4 
      5 #include <cstdio>
      6 
      7 #include <cmath>
      8 
      9 #include <queue>
     10 
     11 using namespace std;
     12 
     13 bool vis[1010];
     14 
     15 int ru[1010],nex[1010],len,n;
     16 
     17 queue<int> q;
     18 
     19 struct node
     20 
     21 {
     22 
     23          int v,nxt;
     24 
     25 }edge[1010*1010];
     26 
     27 void add(int u,int v)
     28 
     29 {
     30 
     31          edge[++len]=(node) {v,nex[u]},nex[u]=len;
     32 
     33 }
     34 
     35 void bfs()
     36 
     37 {
     38 
     39          while(!q.empty())
     40 
     41          {
     42 
     43                   int x=q.front();
     44 
     45                   q.pop();
     46 
     47                   vis[x]=1;
     48 
     49                   for(int i=nex[x];i;i=edge[i].nxt)
     50 
     51                   {
     52 
     53                           int v=edge[i].v;
     54 
     55                           ru[v]--;
     56 
     57                           if(!ru[v])
     58 
     59                                    q.push(v);
     60 
     61                   }
     62 
     63          }
     64 
     65 }
     66 
     67 int main()
     68 
     69 {
     70 
     71          scanf("%d",&n);
     72 
     73          for(int i=0;i<n;i++)
     74 
     75          {
     76 
     77                   scanf("%d",&ru[i]);
     78 
     79                   if(!ru[i])
     80 
     81                           q.push(i);
     82 
     83                   for(int j=1;j<=ru[i];j++)
     84 
     85                   {
     86 
     87                           int v;
     88 
     89                           scanf("%d",&v);
     90 
     91                           add(v,i);
     92 
     93                   }
     94 
     95          }
     96 
     97          bfs();
     98 
     99          for(int i=0;i<n;++i)
    100 
    101                   if(!vis[i])
    102 
    103                   {
    104 
    105                           printf("Y
    ");
    106 
    107                           return 0;
    108 
    109                   }
    110 
    111          printf("N
    ");
    112 
    113          return 0;
    114 
    115 }
  • 相关阅读:
    mysql分区
    pl/sql查看tnsnames.ora文件路径
    mysql之事务控制和锁定语句
    mysql返回查询行数fund_rows()
    mysql之视图
    Mysql之btree索引和hash索引的区别
    Java中反射 API 的使用
    zookeeper 客户端 Apache curator 分布式锁实操
    springBoot 整合 ZooKeeper Java客户端之 Apache Curator 实战
    初识 ZooKeeper
  • 原文地址:https://www.cnblogs.com/dawn-whisper/p/11543091.html
Copyright © 2011-2022 走看看