【CTF】咏春招新赛收获兼write up

前言

上一周SYSU网络安全学院的CTF战队“咏春”组织了招新赛

本篇文章就来分享一下本人在这次招新赛中的收获

本人是刚入门CTF的小萌新,所以只能挑挑其中比较容易的题练手

也算是幸运,趁着大佬们在攻克Pwn和Reverse的时侯,抢了两道Misc的一血和两道Crypto的一血

在最后混到第4的排名

【CTF】咏春招新赛收获兼write up_第1张图片

那么这篇文章会分记录这次比赛中本人解出来的且比较具有代表性的题目,并把每一题分为两个部分:第一个部分会分享本人在解题时的心路历程以及题目的write up;第二部分会谈谈本人在解题时学到的知识,以及一些工具的用法。

目录

  • 前言
  • 题目文件
  • 一.Misc
    • 1.vmdk
      • 解题思路
      • 收获到的知识
        • 7_Zip
    • 2.find_my_body
      • 解题思路
      • 收获到的知识
        • 010 Editor
        • PNG格式文件16进制编码分析
    • 3.can_you_find_me
      • 解题思路
      • 收获到的知识
        • Exif
    • 4.Strange_Base64
      • 解题思路
      • 收获到的知识
        • translate 和maketrans函数
          • maketrans
          • translate
  • 二.Crypto
    • 1.ezNTRUE
      • 解题思路
      • 收获到的知识
        • 理解密码题中调用的随机数函数库
        • NTRU公钥密码系统
    • 2.babyAES
      • 解题思路
      • 收获到的知识
        • AES加密
    • 3.Strange_Caesar
      • 解题思路
      • 收获到的知识
        • homo
  • 三.Reverse
    • 1.两极反转
      • 解题思路
      • 收获到的知识
        • Ida
    • 2.Xor
      • 解题思路
      • 收获到的知识
        • 异或
  • 四.Web
    • command1
      • 解题思路
      • 收获到的知识
        • PHP highlight_file() 函数
        • PHP eval() 函数
        • linux系统 ls和cat命令
          • ls命令
          • cat命令
  • 结语

题目文件

链接:https://pan.baidu.com/s/1eIq3EHbB07gGkD_8cW9prg?pwd=Rick
提取码:Rick
–来自百度网盘超级会员V3的分享

一.Misc

1.vmdk

解题思路

题目给的附件如下图

在这里插入图片描述

看到.vmdk后缀的文件,我首先想到的是能不能用vmware虚拟机将其打开。

但是在报错之后我觉得这题并没有那么简单。

看到题目描述里的“真真假假”时,我猜这个文件用常规的虚拟机是打不开的。

【CTF】咏春招新赛收获兼write up_第2张图片

于是将其改为txt后缀并打开,翻到最后发现了一些有关flag的信息:

​ flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}flag{hahaha_1ts_4_Fake_f1a9}and_Y0U_F1nd}}

可以发现有and_YOU_F1nd}这种极具语义的信息,推测其为flag的后半部分

结合题目中的“分分合合”一词,推测要将vmdk文件分解,于是将其丢入7zip里解压缩

得到如下几个文件:

【CTF】咏春招新赛收获兼write up_第3张图片

打开FLAG,可以得到flag的前半部分:flag{7z1p_1s_pvverfu1_

收获到的知识

7_Zip

本题运用到了工具7-Zip,正如flag所说,7-Zip在压缩和解压缩的功能上还是非常强大的

小知识点:

  • 7-Zip支持的解压缩格式有7z, XZ, BZIP2, GZIP, TAR, ZIP,ARJ, CAB, CHM, CPIO, DEB, DMG, FAT, HFS, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, RAR, RPM, UDF, VHD, WIM, XAR, Z

2.find_my_body

解题思路

该题给出的图片直接展示出flag的上半部分,结合语义,考虑图片隐写中png格式图片的IHDR问题

【CTF】咏春招新赛收获兼write up_第4张图片

使用010 Editor将png图片打开如下图

【CTF】咏春招新赛收获兼write up_第5张图片

在文件头中找到IHDR,即16进制49 48 44 52,修改其后的图片宽度00 00 01 0E和图片高度00 00 00 1E

将图片高度改为00 00 02 6E后可得到完整图片如下:

【CTF】咏春招新赛收获兼write up_第6张图片

故本题的flag为flag{where_is_my_body_BBBB_OOOO_DDDD_YYYY}

收获到的知识

010 Editor

首先本题用到了一款非常强大的16进制编辑器软件010 Editor。听战队里的前辈yh说,在做misc题时,经常会用到这款软件,同时其在将16进制与其他格式如二进制、文本相互转换时非常方便。

在这里贴一个大佬写的 010 Editor的进阶用法链接:

最好用的十六进制编辑器 010 Editor

PNG格式文件16进制编码分析

做ctf的misc题需要对各种格式的文件的16进制编码有影响,这样在不提供后缀时能第一时间反应到是什么格式的文件。

这里贴一个png文件格式的详解链接:

PNG文件格式详解

3.can_you_find_me

解题思路

本题为一道非常基础的社工题

【CTF】咏春招新赛收获兼write up_第7张图片

初步观察给出的图片可得出其为jpg格式的信息,所以先把图片用exiftool分析一下

【CTF】咏春招新赛收获兼write up_第8张图片

由 Date Original可知该照片于2022年7月8日拍摄,但是解析出的exif数据中并没有GPS经纬度信息

接下来看题目描述:

“在干啥呢,赶紧回来出题。” “恰拉面。” “偷偷溜出去恰拉面还不叫上我?小心我开你盒!” “开盒有啥意思,来玩点有意思的” 请问2019年10月拉面店门前大路的报亭的广告上的人的生日是什么时候(格式:YYYY_MM_DD)

结合题目描述中2019年10月

可知,该图片仅仅是用来定位拉面店地点,而报亭地址信息也只有在先锁定了拉面店再于附近寻找,无法从附件图片中直接得出。

【CTF】咏春招新赛收获兼write up_第9张图片

首先google店名“一龙拉面”可知,其为开设在广州的连锁店,一共有五家。

通过分析美食博主在小红书、大众点评等app上的种草图片可知,**一龍拉面·冲绳首里城旗舰店(天河南店)**符合图中的装修风格。

于是可以祭出社工神器Google地图以及其街景功能,但是由于地点是在国内,所以只能退而求其次,使用百度地图的街景

【CTF】咏春招新赛收获兼write up_第10张图片

在门口的大路上搜寻,正好找到下图的报刊亭,结合街景拍摄时间2020,基本上与答案八九不离十了

国内的朋友应该对这个主持人不陌生,而如果你觉得很面生,可以百度一下海报广告中的内容,无非是多几分钟的搜索时间。

这里就不把人名和flag贴出来了。

收获到的知识

Exif
  • Exif是可交换图像文件格式(Exchangeable image file format),是一种标准,定义了与数码相机捕获的图像(或其他媒体)有关的信息,用于存储重要的数据,比如相机的曝光、拍摄日期和时间,甚至GPS定位等。

  • Exif可以附加于 JPEG 、 TIFF 、 RIFF 等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。

本题运用到的工具是exiftool,在社工题中用处很大,而且在解析图片信息时也有妙用。

其实在kali里面也整合了exiftool的功能,同样是通过命令行实现,但是因为本题大部分工作是搜索,在电脑主机上进行比较方便,所以我索性就用win版本的exiftool了。

4.Strange_Base64

解题思路

收到的题目附件中一共有两个文件

在这里插入图片描述

先从提示hint.py看起:

import base64
import string

str1 = "something you don't know"
newtable = "QmWnE01bR2vT98cY75xUzI6aO4sPdLfKgJhH3jGkFlDpSoAiZ+uXyCtVrBeN/wMq"
table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

str2 = base64.b64encode(str1.encode()).decode()
print(str2)
print(str2.translate(str.maketrans(newtable,table)))

快速浏览一遍,发现是某种加密方式,那么flag.txt估计就是密文了

果然flag.txt中内容wBSiwk2w+o3eAFoYzF7V7ERjI3MTsE3e3qI1+T3e+EweAlAGILPFeA==为base64编码

通过查阅python中的translate函数可知其作用是将str2中的字符从table映射至newtable

理解了加密方法,那么写出解密脚本就不是问题了,只需将密文的字符映射回来并base64解码:即将table与newtable调换位置,并将密文的值附给str1,最后使用base64中自带的b64decode解码。

解题脚本如下

import base64
import string

str1 = "wBSiwk2w+o3eAFoYzF7V7ERjI3MTsE3e3qI1+T3e+EweAlAGILPFeA=="
newtable = "QmWnE01bR2vT98cY75xUzI6aO4sPdLfKgJhH3jGkFlDpSoAiZ+uXyCtVrBeN/wMq"
table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

str2 = str1.translate(str.maketrans(table,newtable))
print(base64.b64decode(str2))

解得flag为flag{Y0U_CAN_CH4NGE_THE_T4B1E_0F_B45E64}

收获到的知识

translate 和maketrans函数
maketrans
  • Python maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。

注:两个字符串的长度必须相同,为一一对应的关系。

  • maketrans()方法语法:
str.maketrans(intab, outtab)
  • 参数

    • intab – 字符串中要替代的字符组成的字符串。

    • outtab – 相应的映射字符的字符串。

translate
  • translate() 方法根据参数 table 给出的表(包含 256 个字符)转换字符串的字符,要过滤掉的字符放到 deletechars 参数中。

  • translate()方法语法:

str.translate(table)
bytes.translate(table[, delete])    
bytearray.translate(table[, delete]) 
  • 参数

    • table – 翻译表,翻译表是通过 maketrans() 方法转换而来。

    • deletechars – 字符串中要过滤的字符列表。

  • 返回值:返回翻译后的字符串,若给出了 delete 参数,则将原来的bytes中的属于delete的字符删除,剩下的字符要按照table中给出的映射来进行映射 。

二.Crypto

1.ezNTRUE

解题思路

看到题目中的ntrue就知道,这题应该与ntru格密码有关,那么ezNTRUE应该就是简单版咯,果不其然,学过《信息安全数学基础》这门课程就能将这题秒杀

附件中task.py代码如下:

from Crypto.Util.number import *
from secret import flag


def gen(p, q, fbits, gbits):
    f = getPrime(fbits)
    g = getRandomNBitInteger(gbits)
    fp = pow(f, -1, p)
    fq = pow(f, -1, q)
    h = p * fq * g % q
    pub = h
    pri = (f, fp)
    return pub, pri


def encrypt(pub, msg):
    h = pub
    r = getRandomNBitInteger(32)
    c = r * h + msg
    return c


fbits = 114
pbits = 514
qbits = 1919
gbits = 810

p = getPrime(pbits)
q = getRandomNBitInteger(qbits)
assert p < q
pub, pri = gen(p, q, fbits, gbits)
m = bytes_to_long(flag)
c = encrypt(pub, m)
print(f'p = {p}')
print(f'q = {q}')
print(f'pri = {pri}')
print(f'c = {c}')

输出output.txt内容如下:

p = 39696534708331497478078596949366551254458039906487063274519365557503525568966838603935883232293659554463107770308640259644533280664672534779600517649986059
q = 33845587450234387218683746145498488763698598229278276480458546928792339413769968077853526645950302533020194391650117905478087009591432416950736817012782717651336179207922943604296994050726509520053392703504721556619358895593098766009189861461947552976772454710544452208851897026895605248153578197013401411186916307408137513611146508413930414959309967905013809506695114035797439887986570609411887830819442498398343409098218109885525690946454737438608201754973097641820502436357029642135534233478940863384269857217395902679475540558919784564731798673197560087193097336780962879716
pri = (19865770721277618181876567504573333, 5489494441670054142937588114066774435471342108150158539209487762555020100543649641623797293358973310052946362271598968380588976187388814840494849823235305)
c = 53484871684975510809035045015775716498630895031029420037931060425708077051766065196920378110070387085519970158412204703986166126850226340099542405919853227775557183379431305778161817609150453505160858758972423992960925238580489233002719593829791807355167703736238566049294585651447631831076944446098692856797269525180505699282387563436841786837418375970556732852165591080721561888008116655275004997201356117473364059245846926508162387834931594057871475945194235459090643448870546189680276607867469805540458113547484179203670555638634018105999735351008081376754952824903738495151081874205

题目中泄露了私钥,如果已知公钥h的值,在比特长度合适的情况下可以利用最短向量规约解决。但是这里并未给出h的值。已知的条件有:
f p ⋅ f ≡ 1 (   m o d   p ) f q ⋅ f ≡ 1 (   m o d   p ) h ≡ p ⋅ f q ⋅ g (   m o d   q ) f_p\cdot f\equiv 1 (\bmod p) \\ f_q\cdot f\equiv 1 (\bmod p) \\ h \equiv p\cdot f_q\cdot g(\bmod q) fpf1(modp)fqf1(modp)hpfqg(modq)
密文c=r*h+mr是未知的32位随机数。已知f,推导:
c ⋅ f ⋅ f p ≡ r ⋅ p ⋅ f q ⋅ g ⋅ f ⋅ f p + m ⋅ f ⋅ f p ≡ m (   m o d   p ) c\cdot f\cdot f_p \equiv r \cdot p\cdot f_q\cdot g \cdot f \cdot f_p + m\cdot f \cdot f_p \equiv m(\bmod p) \\ cffprpfqgffp+mffpm(modp)

可写出如下解题脚本:

from Crypto.Util.number import *
p = 39696534708331497478078596949366551254458039906487063274519365557503525568966838603935883232293659554463107770308640259644533280664672534779600517649986059
q = 33845587450234387218683746145498488763698598229278276480458546928792339413769968077853526645950302533020194391650117905478087009591432416950736817012782717651336179207922943604296994050726509520053392703504721556619358895593098766009189861461947552976772454710544452208851897026895605248153578197013401411186916307408137513611146508413930414959309967905013809506695114035797439887986570609411887830819442498398343409098218109885525690946454737438608201754973097641820502436357029642135534233478940863384269857217395902679475540558919784564731798673197560087193097336780962879716
f, fp = (19865770721277618181876567504573333, 5489494441670054142937588114066774435471342108150158539209487762555020100543649641623797293358973310052946362271598968380588976187388814840494849823235305)
c = 53484871684975510809035045015775716498630895031029420037931060425708077051766065196920378110070387085519970158412204703986166126850226340099542405919853227775557183379431305778161817609150453505160858758972423992960925238580489233002719593829791807355167703736238566049294585651447631831076944446098692856797269525180505699282387563436841786837418375970556732852165591080721561888008116655275004997201356117473364059245846926508162387834931594057871475945194235459090643448870546189680276607867469805540458113547484179203670555638634018105999735351008081376754952824903738495151081874205
a = (c * f) % q
m = (a * fp) % p
print(long_to_bytes(m))

解得flag为flag{7cb5533c-62a1-11ed-b271-00155deaa0c6}

收获到的知识

理解密码题中调用的随机数函数库

对于初探Crypto类型题目的人(比如我QAQ)来说,理解题目的代码结构非常重要,而Crypto.Util.number是出现频次非常高的一个函数库模块

  • Number模块中涉及的主要函数功能
    size (N):输入long型数N返回其比特位数
    getRandomInteger(N, randfunc=None):获取N比特的随机数
    getRandomRange(a, b, randfunc=None):在[a,b)区间内获得一个随机数
    getRandomNBitInteger(N, randfunc=None):获得确实是N比特的随机数(也就是保证最高位非0)
    GCD(x,y):获得X和Y的最大公约数
    inverse(u, v):获得 uu modv的逆
    getPrime(N, randfunc=None):反复使用素性检测算法验证以获素随机数
    _rabinMillerTest(n, rounds, randfunc=None):使用Miller Rabin算法进行素性检测,其中rounds是检测轮数2
    getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None):获得满足RSA要求的大素数
    isPrime(N, false_positive_prob=1e-6, randfunc=None):使用小素数表和Miller-Rabin算法判定是否为素数
    long_to_bytes(n, blocksize=0):将long型数转为字节型数据,并且以blocksize分块
    bytes_to_long(s):将字节流转换为long型数
NTRU公钥密码系统

在这里列出一个大佬整理的笔记:

NTRU-密码学

有关ntru的进阶Crypto题目(相对于本题来说要难得多):

从一道CTF题初探NTRU格密码 - 先知社区 (aliyun.com)

2.babyAES

解题思路

还未打开附件时,我就意识到这题应该是考的AES加密,如果是babyAES,那一定很简单吧(坏笑.jpg)

题目所给附件chall.py代码如下

from Crypto.Cipher import AES
from secret import flag

key = b'I have practiced for 2.5 years!!'
iv = ???


def pad(s):
    return s + (16 - len(s) % 16) * b'\0'

def xor(a, b):
    return bytes([x ^ y for x, y in zip(a, b)])

aes = AES.new(key, AES.MODE_CBC, iv)
cipher = aes.encrypt(pad(flag)).hex()
hint = xor(key, iv).hex()
print(f'cipher = {cipher}')
print(f'hint = {hint}')

# cipher = 32a29b99cc0ab09329dcf199a2c0044daff1f5ea686545b1dacbcf4ff8ebd87b75b6e7d5b6c61f5ddb45330bbf36aa66
# hint = 08520d410f0a5550130f431d02160b5b

首先快速浏览一遍代码

偏移量iv是AES加密中非常重要的元素

看到xor函数,发现这题可能用到了异或的性质,于是以这一点为突破口来理解加密方式

结合题目所给条件,利用hint和key可以通过异或运算算出iv

接着发现原来cipher就是flag扩增后AES加密得到的密文,那么本题可以直接用到AES模块中的aes.decrypt()函数进行解密

于是可以写出如下解题脚本:

import binascii
from Crypto.Cipher import AES
import sys
hint =binascii.a2b_hex(b'08520d410f0a5550130f431d02160b5b')
key = b'I have practiced for 2.5 years!!'

def xor(a, b):
    return bytes([x ^ y for x, y in zip(a, b)])
iv =xor(hint,key)#使用xor还原出iv
#iv=b'Are you an ikun?'
print(sys.getsizeof(iv))#验证iv的bite长度是否为16的倍数
print(iv)
aes = AES.new(key,AES.MODE_CBC,iv)
cipher = b'32a29b99cc0ab09329dcf199a2c0044daff1f5ea686545b1dacbcf4ff8ebd87b75b6e7d5b6c61f5ddb45330bbf36aa66'

pad = aes.decrypt(binascii.a2b_hex(cipher)) #这里用a2b_hex函数把cipher还原成字符串
print(pad)#输出的pad中还包含补全的\x00

解得pad为b'flag{bca16c94-6713-11ed-83ea-00155d079966}\x00\x00\x00\x00\x00\x00'

那么flag便是除去\x00后的flag{bca16c94-6713-11ed-83ea-00155d079966}(哼,小黑子)

收获到的知识

AES加密

学习嘛,总归是一个不断去搜索,不断自己去看的过程。所以这里就不喂现成的给你了。

甩一个大佬的详解链接:

AES加密算法的详细介绍与实现

下面这题可能很臭,提前画一条分界线(其实ezNTRUE这题就很臭了hhh)

3.Strange_Caesar

解题思路

看到这里你一定会忍不住吐槽,凯撒密码多简单啊,值得挑出来讲吗?但是非也非也,这题还结合了更多元素,我觉得是拓展我们黑客发散性思维的好题(悲)

首先附件所给文件的标题就非常劲爆

在这里插入图片描述

一般来说凯撒密码题的变种都是偏移量有一定规律,那么这个114514很有可能就是hint了

打开之后得到密文:gmel_omkzydpr_tbm_lbovtin_eitv

将前几个字母与flag比对后发现,偏移量分别为"-1,-1,-4,-5"那么这题的偏移量估计就是114514的循环了

而这个_符号要便宜到{,那么就会打破114514的魔咒(悲),所以我猜这题并没有将凯撒密码扩展到ASCII码表上

于是将_符合全部抽离,并进行解密

随便写个C++的解题脚本(喜)

#include
#include
using namespace std;
string s1="gmelomkzydprtbmlbovtineitv";
int add[6]={-1,-1,-4,-5,-1,-4};
int main() 
{
	int tag=0;
	for(int i=0;i=6)
			tag=0;
	}
	cout<

运行得到flagnijyuyonsaigakuseidesu

此时你会感到疑惑,会不会算法错了?

我们又想到之前舍弃的_符号,会不会它是语义标签呢,遂加上

得到 flag_nijyuyon_sai_gakusei_desu

百度一下,发现居然是一句日语,“二十四岁是学生”,至于出题人为什么要这样出题,我们也不得而知(恼)

那么flag应该就是flag{nijyuyon_sai_gakusei_desu}(可恶啊,这题出的真的nt,我一开始纠结了半天第一个_是不是也要放在{}里,导致我错失了一血)

收获到的知识

homo

114514

甩一个链接给你,快去补课吧

三.Reverse

这次比赛中,Reverse里有几道西电Moe原题,我就不贴出来了,写写其他比较有意思的题

1.两极反转

解题思路

附件给的是exe文件如下图

在这里插入图片描述

直接把它丢到ida里先f5一下(不得不说ida真是反编译神器啊,我一定买的是正版,是?吧?)

得到如下代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[32]; // [rsp+20h] [rbp-90h] BYREF
  int v5[24]; // [rsp+40h] [rbp-70h]
  int v6; // [rsp+A0h] [rbp-10h]
  int v7; // [rsp+A4h] [rbp-Ch]
  int i; // [rsp+A8h] [rbp-8h]
  int v9; // [rsp+ACh] [rbp-4h]

  _main();
  v5[0] = 102;
  v5[1] = 198;
  v5[2] = 22;
  v5[3] = 118;
  v5[4] = 183;
  v5[5] = 69;
  v5[6] = 134;
  v5[7] = 150;
  v5[8] = 55;
  v5[9] = 245;
  v5[10] = 19;
  v5[11] = 55;
  v5[12] = 245;
  v5[13] = 163;
  v5[14] = 146;
  v5[15] = 245;
  v5[16] = 102;
  v5[17] = 87;
  v5[18] = 230;
  v5[19] = 230;
  v5[20] = 151;
  v5[21] = 215;
  puts("int ppppppputtttttt your flag,and i will reverse it!");
  scanf("%s", v4);
  v9 = 0;
  for ( i = 0; i <= 21; ++i )
  {
    v7 = (unsigned __int8)(16 * v4[i]);
    v6 = v4[i] >> 4;
    if ( (v6 | v7) == v5[i] )
      ++v9;
  }
  if ( v9 == 22 )
    printf("TTTTTTTTTTTQQQQQQQQLLLLLLLLLL!!!!!");
  else
    printf("it is a pity ~_~");
  return 0;
}

根据题目给的加密方式,遍历字符表暴力解密,稍微修改原代码得如下解题脚本:

#include
#include 
int main()
{ int v6,v7,i;
  int v4;
  int v5[22];
  v5[0] = 102;
  v5[1] = 198;
  v5[2] = 22;
  v5[3] = 118;
  v5[4] = 183;
  v5[5] = 69;
  v5[6] = 134;
  v5[7] = 150;
  v5[8] = 55;
  v5[9] = 245;
  v5[10] = 19;
  v5[11] = 55;
  v5[12] = 245;
  v5[13] = 163;
  v5[14] = 146;
  v5[15] = 245;
  v5[16] = 102;
  v5[17] = 87;
  v5[18] = 230;
  v5[19] = 230;
  v5[20] = 151;
  v5[21] = 215;
  for (i = 0; i <= 21; ++i )
  {
  	for(v4=33;v4<127;v4++)
  	{
  		v7 = (unsigned __int8)(16 * v4);
    	v6 = v4 >> 4;
    	if ( (v6 | v7) == v5[i] )
      	printf("%c",v4);
	}
  }
} 

得出flag为flag{This_1s_:)_funny}

收获到的知识

Ida

ida可谓是Reverse题的神器,在这里就贴一个下载链接吧:既然你贵的不仁,那我也不义(开玩笑,有钱还请支持正版)

2.Xor

解题思路

看到这题名字你应该大概知道该怎么解了

先把Xor.exe丢进ida并f5一下

得到如下代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[32]; // [rsp+20h] [rbp-C0h]
  char v5[32]; // [rsp+40h] [rbp-A0h] BYREF
  int v6[29]; // [rsp+60h] [rbp-80h]
  int j; // [rsp+D4h] [rbp-Ch]
  int i; // [rsp+D8h] [rbp-8h]
  int v9; // [rsp+DCh] [rbp-4h]

  _main();
  puts("In put your flag,and i will check for you");
  v6[0] = 102;
  v6[1] = 109;
  v6[2] = 99;
  v6[3] = 100;
  v6[4] = 127;
  v6[5] = 93;
  v6[6] = 54;
  v6[7] = 117;
  v6[8] = 87;
  v6[9] = 56;
  v6[10] = 121;
  v6[11] = 84;
  v6[12] = 127;
  v6[13] = 98;
  v6[14] = 81;
  v6[15] = 62;
  v6[16] = 126;
  v6[17] = 118;
  v6[18] = 102;
  v6[19] = 118;
  v6[20] = 102;
  v6[21] = 112;
  v6[22] = 101;
  v6[23] = 99;
  v6[24] = 113;
  v6[25] = 119;
  v6[26] = 35;
  v6[27] = 101;
  v6[28] = 97;
  scanf_s("%s", v5);
  v9 = 0;
  for ( i = 0; i <= 28; ++i )
    v4[i] = v5[i] ^ i;
  for ( j = 0; j <= 28; ++j )
  {
    if ( v4[j] == v6[j] )
      ++v9;
  }
  if ( v9 == 29 )
    printf("Yessssssss");
  else
    printf("Try again!");
  return 0;
}

利用Xor的性质,可将密文与密钥异或得到明文,这题密钥就是数组括号内数字,解题脚本如下:

clude<math.h>
int main()
{ 	char v5[32];
	int i;
	int v6[29];
	v6[0] = 102;
	v6[1] = 109;
	v6[2] = 99;
	v6[3] = 100;
	v6[4] = 127;
	v6[5] = 93;
	v6[6] = 54;
	v6[7] = 117;
	v6[8] = 87;
	v6[9] = 56;
	v6[10] = 121;
	v6[11] = 84;
	v6[12] = 127;
	v6[13] = 98;
	v6[14] = 81;
	v6[15] = 62;
	v6[16] = 126;
	v6[17] = 118;
	v6[18] = 102;
	v6[19] = 118;
	v6[20] = 102;
	v6[21] = 112;
	v6[22] = 101;
	v6[23] = 99;
	v6[24] = 113;
	v6[25] = 119;
	v6[26] = 35;
	v6[27] = 101;
	v6[28] = 97;
	for(i = 0;i<= 28;++i)
	    v5[i] = v6[i] ^ i;
	printf("%s",v5);
}

解得flag为flag{X0r_1s_so_1ngterestin9~}

收获到的知识

异或
  • 在密码学中加密的应用:

​ 明文^密钥=密文;

​ 密文^密钥=明文

  • 异或运算的特性:

    1: a^b=c;当c异或b时,结果还原成a

    2:一个数异或自己时等于0;

    3:一个数异或0的时候,结果是其本身

    4:交换律: A ^ B = B ^ A

    5:结合律: ( A ^ B ) ^ C = A ^ ( B ^ C )

四.Web

web这回没啥难的题,就记录一题当作php的学习了

command1

解题思路

打开所给域名后得到如下php代码

【CTF】咏春招新赛收获兼write up_第11张图片

理解完代码发现这题给我们提供了一个exp,即eval(),其将command作为php代码来计算

于是我们先查看一下根目录

在这里插入图片描述

得到如下文件:

【CTF】咏春招新赛收获兼write up_第12张图片

鉴于flag没有后缀,考虑其为文件夹的可能性,于是用cat命令查看flag/flag,得到题解

【CTF】咏春招新赛收获兼write up_第13张图片

收获到的知识

PHP highlight_file() 函数
  • 定义和用法

highlight_file() 函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。

**提示:**用于高亮的颜色可通过 php.ini 文件进行设置或者通过调用 ini_set() 函数进行设置。

**注释:**当使用该函数时,整个文件都将被显示,包括密码和其他敏感信息!

  • 语法

highlight_file(*filename,return*)

参数 描述
filename 必需。规定要显示的文件。
return 可选。如果该参数设置为 TRUE,该函数将以字符串形式返回高亮显示的代码,而不是直接进行输出。默认是 FALSE。
PHP eval() 函数
  • eval() 函数把字符串按照 PHP 代码来计算。

该字符串必须是合法的 PHP 代码,且必须以分号结尾。

**注释:**return 语句会立即终止对字符串的计算。

**提示:**该函数对于在数据库文本字段中供日后计算而进行的代码存储很有用。

  • 语法

eval(*phpcode*)

linux系统 ls和cat命令
ls命令
  • ls命令(list)可用于列出指定路径下的文件(Linux中一切皆文件,目录也是文件的一种),如果不指定路径,单独运行ls命令,则默认路径为当前路径。ls命令的使用方式如下:
ls [-options] [target path]
  • 单纯使用ls命令,显示的内容有限。在实际使用的时候,经常需要搭配一些选项来显示更加丰富的内容,ls常用的附加选项如下表所示:
选项 作用
-a 显示指定路径中的所有文件,包括隐藏文件
-l 显示文件的详细信息,包括文件类型,权限,所属用户,所属用户组,文件大小,上一次修改时间等
-h 文件大小以KBytes为单位显示
-S 按照文件大小顺序显示,默认从大到小;若要从小到大,可使用-Sr

上述各个选项可以叠加使用,从而能够显示出需要的信息。

第一位表示文件类型。d是目录文件,l是链接文件,-是普通文件,p是管道。

cat命令
  • 语法格式
cat [-AbeEnstTuv] [--help] [--version] fileName
  • 参数说明:

-n 或 --number:由 1 开始对所有输出的行数编号。

-b 或 --number-nonblank:和 -n 相似,只不过对于空白行不编号。

-s 或 --squeeze-blank:当遇到有连续两行以上的空白行,就代换为一行的空白行。

-v 或 --show-nonprinting:使用 ^ 和 M- 符号,除了 LFD 和 TAB 之外。

-E 或 --show-ends : 在每行结束处显示 $。

-T 或 --show-tabs: 将 TAB 字符显示为 ^I。

-A, --show-all:等价于 -vET。

**-e:**等价于"-vE"选项;

**-t:**等价于"-vT"选项;

结语

ctf之路任重而道远,希望我能坚持下去吧

你可能感兴趣的:(网络安全,web安全,密码学,python,c++)