Ciscn2024
Web
Simple_php
这个Simple_php一点儿也不Simple (⋟﹏⋞)
源码放这儿了:
1 |
|
很明显,POST一个cmd进去,然后通过escapeshellcmd函数对参数进行转义,然后进行逆天的正则,之后RCE。
大概就是这样,还能干啥?全都给过滤了,还能咋绕过?
首先是信息搜集,不过有用的似乎没多少,查看进程发现一个MySQL的进程,可以试着打一下MySQL:
mysql 277 0.0 16.9 1083992 89076 pts/0 Sl+ 07:38 0:00 /usr/sbin/mariadbd –basedir=/usr –datadir=/var/lib/mysql –plugin-dir=/usr/lib/mysql/plugin –user=mysql –skip-log-error –pid-file=/run/mysqld/mysqld.pid –socket=/run/mysqld/mysqld.sock
看来是攻击MySQL了,猜测用户是root,密码随便猜,这道题也是root,运气好,猜中了,那么,先查数据库:
1 | //构造这个查询语句 |
1 | //构造这个查询语句 |
查一下这个F1ag_Se3Re7,不出意外的话,应该flag在这里面:
1 | //构造这个查询语句 |
flag:
1 | flag{e784d525-93a1-466b-9f22-38a3add54dfe} |
补充:
1.因为存在escapeshellcmd函数,所以在转义之后,在system函数中,”在经过hex2bin之后,就能够表示字符串”本身
2.在构造substr的时候,第一个参数没有引号也能正常使用,只是会出现一个报错
Re
asm_re
ex
数据段,数据段分配内存,每一个数据段会获得2个内存单元
计算机采用小端存储,小端字节序存储:把一个数据的低位字节的内容,存储在低地址处,把高位字节的内容,存储在高地址处;
数据段:存放数据的段。使用时候,用DS寄存器
大于一个字节长度的16进制数据进行高低位分割之后进行传输
DCB:用于分配一片连续的字节存储单元并用指定的数据初始化
DCB表示:它分配一段字节的内存单元,它每个操作数都占有一个字节,操作数范围为-128~255的数值或字符串。
关键部分
1 |
|
Pwn
gostack(复现):
go语言的栈溢出,没遇到过,赛后复现下,看看能否干出来。
首先是检查保护,不过64位,出了NX之外没有任何保护,那就简单不少,拖到IDA里看看,很轻松就能找到mainmain:
1 | // main.main |
不过这个很明显,有点看不懂,毕竟没接触过go语言,那么,先直接运行下看看程序是啥情况?:
1 | root@g01den-virtual-machine:/mnt/shared# ./pwn |
就结束了,没了,感觉很简单,有输入,但是只有一次写入。
这个运行里给了一部分信息,那么凭借这些信息很轻松就找到了主要部分函数的地方:
1 | // main.main.func3 |
作为一个新人,我敢保证我眼睛看瞎了也看不懂这玩意儿,因此,先gdb一下再说,在那之前,先下断点,
1 | .text:00000000004A0974 movups [rsp+208h+var_B0], xmm15 |
这里找到了需要下断点的大概的地址,就是最后这一行的这里是输入的函数,下断点之后,再继续进行调试,之后就发现了一点奇怪的东西,就是这儿:
1 | 02:0010│-1f8 0xc000044d68 —▸ 0xc0000b2000 ◂— 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n' |
栈的上下都没有写入的AAA……,但是这个题目又叫栈溢出,就很耐人寻味是为啥,不过,懒得考虑那么多了,再继续gdb走起,之后就发现了,AAA被逐渐逐渐地写入到了栈上:
1 | 00:0000│ rsp 0xc000049d60 ◂— 0x0 |
然后查看栈空间的布局:
1 | 07:0038│ rdx-7 0xc000049d98 ◂— 0x61616161616161 /* 'aaaaaaa' */ |
能清晰地看到,rbp与缓冲区的大小:
1 | pwndbg> distance 0xf60 0xd98 |
那么,之后就可以直接进行栈溢出了。但是,在经过多次溢出之后,发现了个致命的问题,就是关于这个输入函数,致命在哪里呢?在这儿:
1 | .text:000000000049A786 cmp byte ptr [rax+79h], 0 |
以及:
1 | .text:000000000049A79A loc_49A79A: ; CODE XREF: bufio__ptr_Scanner_Scan+2A↑j |
它会对这儿进行一次比对,如果是0,则不会跳转,如果不是0,则会跳转,直接停止输入的函数。
所以需要直接用\x00来填充是最保险的。之后就是syscall来打,但是exp我不是很会写,先借鉴借鉴大佬们的,之后再看看:
1 | from pwn import * |