awd pwn attack script

First Post:

Last Update:

Word Count:
1.4k

Read Time:
8 min

AWD PWN

打了好几次awd, 始终都没好好弄个批量攻击脚本与批量提交flag, 今天它来了, 环境是pwn docker

AWD WAF

awd waf方便抓取对方攻打的流量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* orignal author: yangshuangfu
* github link: https://github.com/yangshuangfu/PwnWAF
* modified author: i0gan
* github link: https://github.com/i0gan/pwn/env/awd/waf.c
* modified time : 2020-09-18
*/

// complie:
// gcc waf.c -o waf
// before you use it, you should backup your binary file, then rename waf as binary name

#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<error.h>
#include<sys/wait.h>
#include<sys/ptrace.h>
#include<sys/syscall.h>
#include<sys/user.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>

#define FILENAME "./pwn"
#define LOGNAME "./log"
#define MACHINE 64

#define NEW_CONNECT_SHOW_STR "\n************** new attack *************\n"
#define READ_SHOW_STR "\nread:\n"
#define WRITE_SHOW_STR "\nwrite:\n"

enum SYSTYPE {
READ,
WRITE
};

int state = -1;

int check_standard(int fd){
return fd == 1 || fd == 0;
}

void write_log(pid_t pid, char* addr, int size, enum SYSTYPE flag){

int fd = open(LOGNAME, O_CREAT|O_APPEND|O_WRONLY, 0666);
int i = 0,j = 0;
char data;
char* buf = (char*)malloc(size + 1);

for(i = 0; i < size; i++){
data = ptrace(PTRACE_PEEKDATA, pid, addr + i, NULL);
buf[i] = data;
}

// 判断是否状态是否发生变化,发生变化就写入不同的状态
if(state != flag) {
if(flag == READ)
write(fd, READ_SHOW_STR, sizeof(READ_SHOW_STR));
else
write(fd, WRITE_SHOW_STR, sizeof(WRITE_SHOW_STR));
state = flag;
}

write(fd, buf, size);
close(fd);
free(buf);
}


void write_new_attack() {
// 分割每次攻打的符号
int fd = open(LOGNAME, O_CREAT|O_APPEND|O_WRONLY, 0666);
write(fd, NEW_CONNECT_SHOW_STR, sizeof(NEW_CONNECT_SHOW_STR));
close(fd);
}

int main(int argc, char* argv[]){
setvbuf(stdin,0,2,0);
setvbuf(stdout,0,2,0);
pid_t pid;
struct user_regs_struct regs;
int status;
int insyscall = 0;
int first_time = 1;
pid = fork();
int sys_num;
enum SYSTYPE sys_status;
// we use child process to exec
if(pid == 0){
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
argv[1] = FILENAME;
status = execvp(FILENAME, argv+1);
if(status<0){
perror("ERROR EXEC\n");
return -1;
}
}
// parent to get child syscall
else if (pid > 0){
write_new_attack();
while(1){
wait(&status);
if(WIFEXITED(status))
break;
// get rax to ensure witch syscall
ptrace(PTRACE_GETREGS, pid, NULL, &regs);
#if MACHINE == 64
sys_num = regs.orig_rax;
#elif MACHINE == 32
sys_num = regs.orig_eax;
#endif
if (sys_num != SYS_read && sys_num != SYS_write){
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
continue;
}
if (insyscall==0){
insyscall = 1;
ptrace(PTRACE_SYSCALL, pid, 0, 0);
}
else{
// we should ignor the first time
// checl it is standard pipe or not
int is_standard = 0;
#if MACHINE == 64
is_standard = check_standard(regs.rdi);
#elif MACHINE == 32
is_standard = check_standard(regs.ebx);
#endif
if(!is_standard){
first_time = 0;
ptrace(PTRACE_SYSCALL, pid, NULL ,NULL);
insyscall ^= 1;
continue;
}
if(sys_num == SYS_read)
sys_status = READ;
else if (sys_num == SYS_write)
sys_status = WRITE;
int size = 0;
char* addr = NULL;
#if MACHINE == 64
size = regs.rdx;
// size = (size + sizeof(long)-1)/sizeof(long) * sizeof(long) +1;
addr = (char*)regs.rsi;
// printf(" the addr is %lx with size %lx", addr, size);
#elif MACHINE == 32
size = regs.edx;
addr = (char*)regs.ecx;

#endif
write_log(pid, addr, size, sys_status);
insyscall = 0;
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
}
}
return 0;
}
else{
perror("ERROR FORK!\n");
return -1;
}
}

AWD EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# author: i0gan
# a script for awd exp
# env: pwndocker [skysider/pwndocker (v: 2020/09/09)]

from pwn import *
import os

r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')

elf_path = 'pwn'
arch = '64'
libc_v = '2.27'
MODIFY_LD = 0
LOCAL = 0
LIBC = 0

if(len(sys.argv) < 3):
LOCAL = 1
context.log_level='debug'
else:
server_ip = sys.argv[1]
server_port = int(sys.argv[2], 10)

ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'

libc_path = './libc.so.6'

# change ld path
if(MODIFY_LD):
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)

#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)

def cat_flag(io):
sleep(1)
sl('cat flag')
flag = b'flag{' + ru('}') + b'}'
wd = flag
wd += b'\n'
fd = open('./flags', 'a')
fd.write(wd.decode())
fd.close()

#--------------------------exploit--------------------------
def exploit():
li('exploit...')

def finish():
ia()
c()

#--------------------------main-----------------------------
if __name__ == '__main__':

if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path, "LD_PRELOAD" : libc_path} )
else:
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path} )

else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)

exploit()
finish()

该脚本攻打成功后, 会在./flags文件中追加获得的flag

AWD 实现批量攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# author: i0gan
# script for awd mode
# env: pwndocker [skysider/pwndocker (v: 2020/09/09)]

import threading
import sys,os
import queue

li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')

class Exploit(threading.Thread):
def __init__(self,ips, ports):
threading.Thread.__init__(self)
self.ips_ = ips
self.ports_ = ports
def run(self):
while True:
if self.ips_.empty():
break
try:
# scrpt for it
ip = self.ips_.get(timeout=0.5)
port = self.ports_.get(timeout=0.5)
os.system('python3 ./exp.py') # run exp
li('ip: ' + ip + ' : ' + str(port))
except:
continue

def attack():
li('start loop attack...')
thread_count = 8 # thread number
threads = []
ips = queue.Queue()
ports = queue.Queue()
f = open("./hosts",'r') # read ip and port from hosts file
lines = f.readlines()
f.close()

for line in lines:
get_line = line.strip('\n')
info = get_line.split(':', 1)
#print(info)
ips.put(info[0])
ports.put(int(info[1], 10))

for i in range(thread_count):
threads.append(Exploit(ips, ports))

for t in threads:
t.start()

for t in threads:
t.join()

if __name__ == '__main__':
attack()

该脚本从./hosts文件中读取ip 和port, 同时攻打

AWD 实现批量提交flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
# auto submit flag script for fack awd

import os
import json
import requests
import time

li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')

csrf_token = 'a9e17a178bfcdf29291c495fd0e3175a138c8ae6555cba89c7c9d0a56dd23293'
cookie = 'session=5dd2b2c8-261f-4337-bce2-3885ab7de331'
ip = 'http://ltalk.co:1024'
submit_dir = '/api/v1/challenges/attempt'
url = ip + submit_dir
flag_file = './flags'
sleep_time = 120
challenge_id = 8

def submit():
with open(flag_file) as flag_txt:
flags = flag_txt.readlines()
for flag in flags:
flag = flag.strip()
dic = {'challenge_id': challenge_id,'submission':flag}
json_flag = json.dumps(dic)
print(json_flag)
try:
header = {'Cookie':cookie,'CSRF-Token':csrf_token,'Content-Type':'application/json'}
res = requests.post(url,data=json_flag,headers=header,timeout=1)
li(res.text)
except:
li('connect fail!')
continue
while True:
submit()
time.sleep(sleep_time)

该脚本从./flags文件中读取flag, 依次提交至平台

打赏点小钱
支付宝 | Alipay
微信 | WeChat