NSSCTF逆向刷题记录

目录

[GDOUCTF 2023]easy_pyc

[GWCTF 2019]xxor 

[MoeCTF 2022]checkin 

[LitCTF 2023]程序和人有一个能跑就行了 

[LitCTF 2023]For Aiur 

[HNCTF 2022 WEEK2]TTTTTTTTTea 

 [GKCTF 2020]Check_1n

​[SWPUCTF 2022 新生赛]py1

[HNCTF 2022 Week1]给阿姨倒一杯Jvav 

[CISCN 2023 初赛]babyRE 

[HGAME 2023 week1]encode 

[SWPUCTF 2022 新生赛]android 

[zer0pts 2020]easy strcmp 

 [HNCTF 2022 WEEK2]来解个方程?

[GDOUCTF 2023]easy_pyc

pyc在线反编译python反编译 - 在线工具 (tool.lu)

已知 pqec求m,套用密码学模板

【Crypto】RSA_轻闲一号机的博客-CSDN博客

import gmpy2​
import binascii​
​
​
e = 306645347334662727966285107364291531289​
q = 7021910101974335245794950722131367118195509913680915814438898999848788125908122655583911434165700354149914056221915541094395668546921268189522005629523759​
p = 8228801334907462855397256098699556584084854642543205682719705217859576250443629616812386484797164506834582095674143447181804355696220642775619711451990971​
c = 21812306272967730147845738706030680242331165675981994115949615844012361551700506020612445969402056602389411244248745130826969002161047213415607978602535719418999319494842608994479027676787499235277662156571617957720793923983451286566879014875330118016740706736991981355194846993958405444652507211603807160958​
​
# 计算私钥 d​
phi = (p - 1) * (q - 1)​
d = gmpy2.invert(e, phi)​
​
# 解密 m​
m = gmpy2.powmod(c, d, p * q)​
print(binascii.unhexlify(hex(m)[2:]))

 

[GWCTF 2019]xxor 

输入六个数,for ( j = 0; j <= 2; ++j )外循环三次

 sub_400686(&dword_601078, &unk_601060)函数 tea算法,找到key,delta,内循环64次

(unsigned int)sub_400770(v7) z3方程组

from z3 import *​
s=Solver()​
a1=[Int('a[' + str(i) + ']') for i in range(6)]​
for i in range(6):​
    s.add(a1[2] - a1[3] == 2225223423)​
    s.add(a1[3] + a1[4] == 4201428739)​
    s.add(a1[2] - a1[4] == 1121399208)​
    s.add(a1[0] == -548868226)​
    s.add(a1[5] == -2064448480)​
    s.add(a1[1] == 550153460)​
​
if s.check()==sat:​
    print()​
print(s.model())

 

Key

#include <stdio.h>​
#include <stdint.h>​
​
​
int main() {​
    uint32_t key[4] = { 2, 2, 3, 4 };​
    uint32_t a[6] = { -548868226, 550153460, 3774025685, 1548802262, 2652626477, -2064448480 };​
    unsigned int v5;​
    unsigned int v3;​
    unsigned int v4;​
​
    for (int j = 0; j <= 4; j += 2) ​
       {​
        v3 = a[j];​
        v4 = a[j + 1];​
        v5 = 1166789954 * 64;​
​
        for (int i = 0; i < 64; i++) {​
            v4 -= ((v3 + v5 + 20) ^ ((v3 << 6) + key[2]) ^ (v3 >> 9) + key[3]) ^ 0x10;​
            v3 -= ((v4 + v5 + 11) ^ ((v4 << 6) + key[0]) ^ (v4 >> 9) + key[1]) ^ 0x20;​
            v5 -= 1166789954;​
        }​
        a[j] = v3;​
        a[j + 1] = v4;​
       ​
​
    }​
    for (int i = 0; i < 6; i++)​
    {​
        printf("%x", a[i]);​
    }​
​
    return 0;​
}​

 在线hex转字符

[MoeCTF 2022]checkin 

flag直接喂嘴里

[LitCTF 2023]程序和人有一个能跑就行了 

流程图中发现两组数据

F5反编译

RC4解密一下为假的flag

from Crypto.Cipher import ARC4​
a = [0x8D, 0x6C, 0x85, 0x76, 0x32, 0x72, 0xB7, 0x40, 0x88, 0x7E, 0x95, 0xEE, 0xC5, 0xED, 0x2E, 0x71, 0x37, 0xF1, 0x4A, 0x99, 0x35, 0x18, 0xA7, 0xB0, 0x00, 0x96, 0xB7]​
​
aBytes = bytes(a)​
key = b"litctf"​
enc = ARC4.new(key)​
flag = enc.decrypt(aBytes)​
print(flag)

换另外一组数据,得到真正的flag,也可以通过动调去找真的加密数据​

下断点

一直F8步过到.text:00475BAF处看见另一组隐藏的数据

提取一下数据,解密 

from Crypto.Cipher import ARC4​
a = [0x8D ,0x6C ,0x85 ,0x76 ,0x32 ,0x72 ,0x0B7 ,0x43 ,0x85 ,0x7B ,0x85 ,0x0DE ,0x0C1 ,0x0FB ,0x2E ,0x64 ,0x7 ,0x0C8 ,0x5F ,0x9A ,0x35 ,0x18 ,0x0AD ,0x0B5 ,0x15 ,0x92 ,0x0BE ,0x1B ,0x88]​
​
aBytes = bytes(a)​
key = b"litctf"​
enc = ARC4.new(key)​
flag = enc.decrypt(aBytes)​
print(flag)

 

[LitCTF 2023]For Aiur 

pyinstxtractor解包,但是Skipping pyz extraction,故没有得到我们想要的pyz文件

由于 .pyz 文件已经被压缩为单个文件,其中包含多个Python模块和相关资源,解包操作可能比较复杂。因此,pyinstxtractor.py 工具在默认情况下会跳过 .pyz 文件的提取,以避免潜在的错误或问题。​

重新去官网重新下载了一个pyinstxtractor再次解包就好了:PyInstaller Extractor download | SourceForge.net

PYZ-00.pyz_extracted文件夹中找到ch.pyc进行反编译 

 uncompyle6反编译得到

# uncompyle6 version 3.5.0​
# Python bytecode 3.8 (3413)​
# Decompiled from: Python 2.7.5 (default, Jun 20 2023, 11:36:40) ​
# [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]​
# Embedded file name: ch.py​
enc = [​
 98, 77, 94, 91, 92, 107, 125, 66, 87, 70, 113, 92, 83, 70, 85, 81, 19, 21, 109, 99, 87, 107, 127, 65, 65, 64, 109, 87, 93, 90, 65, 64, 64, 65, 81, 3, 109, 85, 86, 80, 91, 64, 91, 91, 92, 0, 94, 107, 66, 77, 94, 91, 92, 71]​
lis = []​
​
def check(num):​
    flag = 'LitCTF{'​
    if num % 2 == 0 and num % 4 == 0 and num % 6 == 0 and num % 8 == 0 and num % 12 == 0:​
        if num % 13 == 11:​
            k = str(num)​
            for i in range(len(enc)):​
                flag += chr(ord(k[(i % len(k))]) ^ enc[i])​
                lis.append(ord(k[(i % len(k))]) ^ enc[i])​
​
            flag += '}'​
            from cv2 import imread, imshow, namedWindow, WINDOW_NORMAL, FONT_HERSHEY_SIMPLEX, getTickCount, getTickFrequency, putText, LINE_AA, waitKey, getTextSize, resize, moveWindow, IMREAD_UNCHANGED, destroyAllWindows​
            from numpy import uint8, zeros​
            img = zeros((200, 20000, 3), uint8)​
            img.fill(255)​
            text = flag​
            font = FONT_HERSHEY_SIMPLEX​
            pos = (50, 120)​
            color = (0, 0, 0)​
            thickness = 2​
            putText(img, text, pos, font, 1, color, thickness, LINE_AA)​
            imshow('flag', img)​
            waitKey(0)​
            destroyAllWindows()

num需要满足条件num % 2 == 0 and num % 4 == 0 and num % 6 == 0 and num % 8 == 0 and num % 12 == 0 and num % 13 == 11:​

flag += chr(ord(k[(i % len(k))]) ^ enc[i])

enc = [​
 98, 77, 94, 91, 92, 107, 125, 66, 87, 70, 113, 92, 83, 70, 85, 81, 19, 21, 109, 99, 87, 107, 127, 65, 65, 64, 109, 87, 93, 90, 65, 64, 64, 65, 81, 3, 109, 85, 86, 80, 91, 64, 91, 91, 92, 0, 94, 107, 66, 77, 94, 91, 92, 71]​
​
flag = ""​
num=0​
while True :​
    flag = 'LitCTF{'​
    if num % 2 == 0 and num % 4 == 0 and num % 6 == 0 and num % 8 == 0 and num % 12 == 0 and num % 13 == 11:​
        k = str(num)​
        for i in range(len(enc)):​
            flag += chr(ord(k[i % len(k)]) ^ enc[i])​
        flag += '}'​
        break​
    num=num+1​
print(flag)

[HNCTF 2022 WEEK2]TTTTTTTTTea 

检测到为tea算法,delta为正常值,xtea加密

tea_encrypt(&v4[2 * j + 8], &key)函数,找到密钥轮换加密方式

 打开key

左键按两下d

#include<stdio.h>​
#include<stdint.h>​
​
​
int main() {​
    uint32_t key[4] = { 0x00010203,0x04050607,0x08090A0B,0x0C0D0E0F };​
    uint32_t a[6] = { -1054939302,-1532163725,-165900264,853769165,768352038,876839116 };​
    unsigned int v5;​
    unsigned int v6;​
    unsigned int v4;​
    int b[8] = { 0 };​
    for (int j = 0; j <= 6; j+=2)​
    {​
        v6 = a[j];​
        v5 = a[j + 1];​
        v4 = -32 * 1640531527;​
        for (int i = 0; i <32; i++) {​
            v5 -= (((v6 >> 5) ^ (16 * v6)) + v6) ^ (key[(v4 >> 11)&3] + v4);​
            v4 += 1640531527;​
            v6 -= (((v5 >> 5) ^ (16 * v5)) + v5) ^  (key[(v4 & 3)] + v4);​
        }​
        b[j] = v6;​
        b[j + 1] = v5;​
    }​
    printf("%s", b);​
​
}           

 [GKCTF 2020]Check_1n

发现可疑字符

直接一把梭解密

 [SWPUCTF 2022 新生赛]py1

pyinstxtractor解包

反编译不了,直接搜索字符

strings re1.pyc | grep NSS

 或者记事本打开

[HNCTF 2022 Week1]给阿姨倒一杯Jvav 

KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]​
flag = ""​
for i in KEY:​
    flag += chr((i-64)^32)​
print(flag)

 

[CISCN 2023 初赛]babyRE 

找到加密的secret数据,其实是假的

 根据文件所给网站https://snap.berkeley.edu将html文件打开,得到加密逻辑为简单的异或运算

 

上面直接给的数据解出来的flag是错误的

再次回到这里仔细看secret数据

手提数据 

secret = [102, 10, 13, 6, 28, 74, 3, 1, 3, 7, 85, 0, 4, 75, 20, 92, 92, 8, 28, 25, 81, 83, 7, 28, 76, 88, 9, 0, 29, 73, 0, 86, 4, 87, 87, 82, 84, 85, 4, 85, 87, 30]​
flag = ""​
for i in range(1,len(secret)-1):​
    secret[i] = secret[i]^secret[i-1]​
​
for i in range(42):​
    print(chr(secret[i]),end="")

 

[HGAME 2023 week1]encode 

ida大小端序存储的问题​

记 IDA 中对内存小端逆序的理解_ida与大小端序_沐一 · 林的博客-CSDN博客

 其实自己用一个数去验证一下就知道哪个是高位哪个是低位了

 提取数据,转换为数组和

 

s = [8, 6, 7, 6, 1, 6, 0x0D, 6, 5, 6, 0x0B, 7, 5, 6, 0x0E, 6, 3, 6, 0x0F, 6, 4, 6, 5, 6, 0x0F, 5, 9, 6, 3, 7, 0x0F, 5, 5, 6, 1, 6, 3, 7, 9, 7, 0x0F, 5, 6, 6, 0x0F, 6, 2, 7, 0x0F, 5, 1, 6, 0x0F, 5, 2, 7, 5, 6, 6, 7, 5, 6, 2, 7, 3, 7, 5, 6, 0x0F, 5, 5, 6, 0x0E, 6, 7, 6, 9, 6, 0x0E, 6, 5, 6, 5, 6, 2, 7, 0x0D, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]​
flag = ""​
for i in range(50):​
    flag += chr((s[2*i+1]<<4)+s[2*i])​
print(flag)

 

[SWPUCTF 2022 新生赛]android 

找主函数,找不到就直接搜索字符

 

[zer0pts 2020]easy strcmp 

a2数组与zer0pts{********CENSORED********}进行比较,相同提示correct!

然而这个并不是正确的flag,说明strcmp函数有问题,从start函数开始看,跟进init

跟进funcs_889函数

分别调用了sub_6E0和sub_795两个函数,进入下面的offset sub_795函数看看

通过赋值off_2010288实际上是strcmp函数的地址,但现在它被替换成了sub_6EA,完成了一个简单的hook(劫持了原本调用的函数,在运行时替换为新的操作)的操作。程序时运行还令a1恒等于1,一直跳到Usage: %s < FLAG >的那个分支。

使用(uint64_t*) 强制将内存地址 (p + i*8) 转换为指向 uint64 类型的指针,然后使用解引用操作符 * 访问该地址对应的内存内容,并加上k[i]的值 

#include <stdio.h>​
#include <stdint.h>​
​
int main() {​
    char p[] = "zer0pts{********CENSORED********}";​
    uint64_t k[4] = { 0, 0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B };​
    for (int i = 0; i < 4; i++) {​
        *(uint64_t*)&(p[i * 8]) += k[i];​
    }​
    printf("%s\n", p);​
    return 0;​
}​

 [HNCTF 2022 WEEK2]来解个方程?

解多个方程

 z3方程求出数组之后转换为字符即flag

from z3 import *​
​
v=[Int('a' + str(i)) for i in range(23)]​
solver = Solver()​
​
solver.add(245 * v[4] + 395 * v[3] + 3541 * v[2] + 2051 * v[1] + 3201 * v[0] + 1345 * v[5] == 855009)​
solver.add(3270 * v[4] + 3759 * v[3] + 3900 * v[2] + 3963 * v[1] + 1546 * v[0] + 3082 * v[5] == 1515490)​
solver.add(526 * v[4] + 2283 * v[3] + 3349 * v[2] + 2458 * v[1] + 2012 * v[0] + 268 * v[5] == 854822)​
solver.add(3208 * v[4] + 2021 * v[3] + 3146 * v[2] + 1571 * v[1] + 2569 * v[0] + 1395 * v[5] == 1094422)​
solver.add(3136 * v[4] + 3553 * v[3] + 2997 * v[2] + 1824 * v[1] + 1575 * v[0] + 1599 * v[5] == 1136398)​
solver.add(2300 * v[4] + 1349 * v[3] + 86 * v[2] + 3672 * v[1] + 2908 * v[0] + 1681 * v[5] == 939991)​
solver.add(212 * v[20] + 153 * v[19] + 342 * v[18] + 490 * v[10] + 325 * v[9] + 485 * v[8] + 56 * v[7] + 202 * v[6] + 191 * v[21] == 245940)​
solver.add(348 * v[20] + 185 * v[19] + 134 * v[18] + 153 * v[10] + 460 * v[7] + 207 * v[6] + 22 * v[8] + 24 * v[9] + 22 * v[21] == 146392)​
solver.add(177 * v[20] + 231 * v[19] + 489 * v[18] + 339 * v[10] + 433 * v[9] + 311 * v[8] + 164 * v[7] + 154 * v[6] + 100 * v[21] == 239438)​
solver.add(68 * v[18] + 466 * v[10] + 470 * v[9] + 22 * v[8] + 270 * v[7] + 360 * v[6] + 337 * v[19] + 257 * v[20] + 82 * v[21] == 233887)​
solver.add(246 * v[20] + 235 * v[19] + 468 * v[18] + 91 * v[10] + 151 * v[9] + 197 * v[6] + 92 * v[7] + 73 * v[8] + 54 * v[21] == 152663)​
solver.add(241 * v[20] + 377 * v[19] + 131 * v[18] + 243 * v[10] + 233 * v[9] + 55 * v[8] + 376 * v[7] + 242 * v[6] + 343 * v[21] == 228375)​
solver.add(356 * v[20] + 200 * v[19] + 136 * v[9] + 301 * v[8] + 284 * v[7] + 364 * v[6] + 458 * v[10] + 5 * v[18] + 61 * v[21] == 211183)​
solver.add(154 * v[20] + 55 * v[19] + 406 * v[18] + 107 * v[10] + 80 * v[8] + 66 * v[6] + 71 * v[7] + 17 * v[9] + 71 * v[21] == 96788)​
solver.add(335 * v[20] + 201 * v[19] + 197 * v[9] + 280 * v[8] + 409 * v[7] + 56 * v[6] + 494 * v[10] + 63 * v[18] + 99 * v[21] == 204625)​
solver.add(428 * v[16] + 1266 * v[15] + 1326 * v[14] + 1967 * v[13] + 3001 * v[12] + 81 * v[11] + 2439 * v[17] == 1109296)​
solver.add(2585 * v[16] + 4027 * v[15] + 141 * v[14] + 2539 * v[13] + 3073 * v[12] + 164 * v[11] + 1556 * v[17] == 1368547)​
solver.add(2080 * v[16] + 358 * v[15] + 1317 * v[14] + 1341 * v[13] + 3681 * v[12] + 2197 * v[11] + 1205 * v[17] == 1320274)​
solver.add(840 * v[16] + 1494 * v[15] + 2353 * v[14] + 235 * v[13] + 3843 * v[12] + 1496 * v[11] + 1302 * v[17] == 1206735)​
solver.add(101 * v[16] + 2025 * v[15] + 2842 * v[14] + 1559 * v[13] + 2143 * v[12] + 3008 * v[11] + 981 * v[17] == 1306983)​
solver.add(1290 * v[16] + 3822 * v[15] + 1733 * v[14] + 292 * v[13] + 816 * v[12] + 1017 * v[11] + 3199 * v[17] == 1160573)​
solver.add(186 * v[16] + 2712 * v[15] + 2136 * v[14] + 98 * v[11] + 138 * v[12] + 3584 * v[13] + 1173 * v[17] == 1005746)​
solver.check()​
result = solver.model()​
flag = ""​
for i in range(0, 22):​
    flag += (chr(result[v[i]].as_long()))​
​
print(flag)

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值